K2.6 patches and update.
[tomato.git] / release / src / router / iptables / extensions / libipt_pkttype.c
blobea6439efd2fade4cdcdbd86ca31a512f77086777
1 /*
2 * Shared library add-on to iptables to match
3 * packets by their type (BROADCAST, UNICAST, MULTICAST).
5 * Michal Ludvig <michal@logix.cz>
6 */
7 #include <stdio.h>
8 #include <netdb.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <getopt.h>
12 #if defined(__GLIBC__) && __GLIBC__ == 2
13 #include <net/ethernet.h>
14 #else
15 #include <linux/if_ether.h>
16 #endif
17 #include <iptables.h>
18 #include <linux/if_packet.h>
19 #include <linux/netfilter_ipv4/ipt_pkttype.h>
21 #define PKTTYPE_VERSION "0.1"
23 struct pkttypes {
24 const char *name;
25 unsigned char pkttype;
26 unsigned char printhelp;
27 const char *help;
30 static const struct pkttypes supported_types[] = {
31 {"unicast", PACKET_HOST, 1, "to us"},
32 {"broadcast", PACKET_BROADCAST, 1, "to all"},
33 {"multicast", PACKET_MULTICAST, 1, "to group"},
35 {"otherhost", PACKET_OTHERHOST, 1, "to someone else"},
36 {"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"},
38 /* aliases */
39 {"bcast", PACKET_BROADCAST, 0, NULL},
40 {"mcast", PACKET_MULTICAST, 0, NULL},
41 {"host", PACKET_HOST, 0, NULL}
44 static void print_types()
46 unsigned int i;
48 printf("Valid packet types:\n");
49 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
51 if(supported_types[i].printhelp == 1)
52 printf("\t%-14s\t\t%s\n", supported_types[i].name, supported_types[i].help);
54 printf("\n");
57 /* Function which prints out usage message. */
58 static void help(void)
60 printf(
61 "pkt_type v%s options:\n"
62 " --pkt-type [!] packettype\tmatch packet type\n"
63 "\n", PKTTYPE_VERSION);
64 print_types();
67 static struct option opts[] = {
68 {"pkt-type", 1, 0, '1'},
69 {0}
72 static void parse_pkttype(const char *pkttype, struct ipt_pkttype_info *info)
74 unsigned int i;
76 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
78 if(strcasecmp(pkttype, supported_types[i].name)==0)
80 info->pkttype=supported_types[i].pkttype;
81 return;
85 exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
88 static int parse(int c, char **argv, int invert, unsigned int *flags,
89 const struct ipt_entry *entry,
90 unsigned int *nfcache,
91 struct ipt_entry_match **match)
93 struct ipt_pkttype_info *info = (struct ipt_pkttype_info *)(*match)->data;
95 switch(c)
97 case '1':
98 check_inverse(optarg, &invert, &optind, 0);
99 parse_pkttype(argv[optind-1], info);
100 if(invert)
101 info->invert=1;
102 *flags=1;
103 break;
105 default:
106 return 0;
109 return 1;
112 static void final_check(unsigned int flags)
114 if (!flags)
115 exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
118 static void print_pkttype(struct ipt_pkttype_info *info)
120 unsigned int i;
122 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
124 if(supported_types[i].pkttype==info->pkttype)
126 printf("%s ", supported_types[i].name);
127 return;
131 printf("%d ", info->pkttype); /* in case we didn't find an entry in named-packtes */
134 static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric)
136 struct ipt_pkttype_info *info = (struct ipt_pkttype_info *)match->data;
138 printf("PKTTYPE %s= ", info->invert?"!":"");
139 print_pkttype(info);
142 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
144 struct ipt_pkttype_info *info = (struct ipt_pkttype_info *)match->data;
146 printf("--pkt-type %s", info->invert?"! ":"");
147 print_pkttype(info);
150 static struct iptables_match pkttype = {
151 .next = NULL,
152 .name = "pkttype",
153 .version = IPTABLES_VERSION,
154 .size = IPT_ALIGN(sizeof(struct ipt_pkttype_info)),
155 .userspacesize = IPT_ALIGN(sizeof(struct ipt_pkttype_info)),
156 .help = &help,
157 .parse = &parse,
158 .final_check = &final_check,
159 .print = &print,
160 .save = &save,
161 .extra_opts = opts
164 void _init(void)
166 register_match(&pkttype);