Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / ebtables / extensions / ebt_arp.c
blob64d337d5967cf587043d7faf8ba25e635486a931
1 /* ebt_arp
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 * Tim Gardner <timg@tpi.com>
7 * April, 2002
8 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <getopt.h>
14 #include "../include/ebtables_u.h"
15 #include "../include/ethernetdb.h"
16 #include <linux/if_ether.h>
17 #include <linux/netfilter_bridge/ebt_arp.h>
19 #define ARP_OPCODE '1'
20 #define ARP_HTYPE '2'
21 #define ARP_PTYPE '3'
22 #define ARP_IP_S '4'
23 #define ARP_IP_D '5'
24 #define ARP_MAC_S '6'
25 #define ARP_MAC_D '7'
26 #define ARP_GRAT '8'
27 static struct option opts[] =
29 { "arp-opcode" , required_argument, 0, ARP_OPCODE },
30 { "arp-op" , required_argument, 0, ARP_OPCODE },
31 { "arp-htype" , required_argument, 0, ARP_HTYPE },
32 { "arp-ptype" , required_argument, 0, ARP_PTYPE },
33 { "arp-ip-src" , required_argument, 0, ARP_IP_S },
34 { "arp-ip-dst" , required_argument, 0, ARP_IP_D },
35 { "arp-mac-src" , required_argument, 0, ARP_MAC_S },
36 { "arp-mac-dst" , required_argument, 0, ARP_MAC_D },
37 { "arp-gratuitous", no_argument, 0, ARP_GRAT },
38 { 0 }
41 #define NUMOPCODES 9
42 /* a few names */
43 static char *opcodes[] =
45 "Request",
46 "Reply",
47 "Request_Reverse",
48 "Reply_Reverse",
49 "DRARP_Request",
50 "DRARP_Reply",
51 "DRARP_Error",
52 "InARP_Request",
53 "ARP_NAK",
56 static void print_help()
58 int i;
60 printf(
61 "arp options:\n"
62 "--arp-opcode [!] opcode : ARP opcode (integer or string)\n"
63 "--arp-htype [!] type : ARP hardware type (integer or string)\n"
64 "--arp-ptype [!] type : ARP protocol type (hexadecimal or string)\n"
65 "--arp-ip-src [!] address[/mask]: ARP IP source specification\n"
66 "--arp-ip-dst [!] address[/mask]: ARP IP target specification\n"
67 "--arp-mac-src [!] address[/mask]: ARP MAC source specification\n"
68 "--arp-mac-dst [!] address[/mask]: ARP MAC target specification\n"
69 "[!] --arp-gratuitous : ARP gratuitous packet\n"
70 " opcode strings: \n");
71 for (i = 0; i < NUMOPCODES; i++)
72 printf(" %d = %s\n", i + 1, opcodes[i]);
73 printf(
74 " hardware type string: 1 = Ethernet\n"
75 " protocol type string: see "_PATH_ETHERTYPES"\n");
78 static void init(struct ebt_entry_match *match)
80 struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data;
82 arpinfo->invflags = 0;
83 arpinfo->bitmask = 0;
87 #define OPT_OPCODE 0x01
88 #define OPT_HTYPE 0x02
89 #define OPT_PTYPE 0x04
90 #define OPT_IP_S 0x08
91 #define OPT_IP_D 0x10
92 #define OPT_MAC_S 0x20
93 #define OPT_MAC_D 0x40
94 #define OPT_GRAT 0x80
95 static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
96 unsigned int *flags, struct ebt_entry_match **match)
98 struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)(*match)->data;
99 long int i;
100 char *end;
101 uint32_t *addr;
102 uint32_t *mask;
103 unsigned char *maddr;
104 unsigned char *mmask;
106 switch (c) {
107 case ARP_OPCODE:
108 ebt_check_option2(flags, OPT_OPCODE);
109 if (ebt_check_inverse2(optarg))
110 arpinfo->invflags |= EBT_ARP_OPCODE;
111 i = strtol(optarg, &end, 10);
112 if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
113 for (i = 0; i < NUMOPCODES; i++)
114 if (!strcasecmp(opcodes[i], optarg))
115 break;
116 if (i == NUMOPCODES)
117 ebt_print_error2("Problem with specified ARP opcode");
118 i++;
120 arpinfo->opcode = htons(i);
121 arpinfo->bitmask |= EBT_ARP_OPCODE;
122 break;
124 case ARP_HTYPE:
125 ebt_check_option2(flags, OPT_HTYPE);
126 if (ebt_check_inverse2(optarg))
127 arpinfo->invflags |= EBT_ARP_HTYPE;
128 i = strtol(optarg, &end, 10);
129 if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
130 if (!strcasecmp("Ethernet", argv[optind - 1]))
131 i = 1;
132 else
133 ebt_print_error2("Problem with specified ARP hardware type");
135 arpinfo->htype = htons(i);
136 arpinfo->bitmask |= EBT_ARP_HTYPE;
137 break;
139 case ARP_PTYPE:
141 uint16_t proto;
143 ebt_check_option2(flags, OPT_PTYPE);
144 if (ebt_check_inverse2(optarg))
145 arpinfo->invflags |= EBT_ARP_PTYPE;
147 i = strtol(optarg, &end, 16);
148 if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
149 struct ethertypeent *ent;
151 ent = getethertypebyname(argv[optind - 1]);
152 if (!ent)
153 ebt_print_error2("Problem with specified ARP "
154 "protocol type");
155 proto = ent->e_ethertype;
157 } else
158 proto = i;
159 arpinfo->ptype = htons(proto);
160 arpinfo->bitmask |= EBT_ARP_PTYPE;
161 break;
164 case ARP_IP_S:
165 case ARP_IP_D:
166 if (c == ARP_IP_S) {
167 ebt_check_option2(flags, OPT_IP_S);
168 addr = &arpinfo->saddr;
169 mask = &arpinfo->smsk;
170 arpinfo->bitmask |= EBT_ARP_SRC_IP;
171 } else {
172 ebt_check_option2(flags, OPT_IP_D);
173 addr = &arpinfo->daddr;
174 mask = &arpinfo->dmsk;
175 arpinfo->bitmask |= EBT_ARP_DST_IP;
177 if (ebt_check_inverse2(optarg)) {
178 if (c == ARP_IP_S)
179 arpinfo->invflags |= EBT_ARP_SRC_IP;
180 else
181 arpinfo->invflags |= EBT_ARP_DST_IP;
183 ebt_parse_ip_address(optarg, addr, mask);
184 break;
186 case ARP_MAC_S:
187 case ARP_MAC_D:
188 if (c == ARP_MAC_S) {
189 ebt_check_option2(flags, OPT_MAC_S);
190 maddr = arpinfo->smaddr;
191 mmask = arpinfo->smmsk;
192 arpinfo->bitmask |= EBT_ARP_SRC_MAC;
193 } else {
194 ebt_check_option2(flags, OPT_MAC_D);
195 maddr = arpinfo->dmaddr;
196 mmask = arpinfo->dmmsk;
197 arpinfo->bitmask |= EBT_ARP_DST_MAC;
199 if (ebt_check_inverse2(optarg)) {
200 if (c == ARP_MAC_S)
201 arpinfo->invflags |= EBT_ARP_SRC_MAC;
202 else
203 arpinfo->invflags |= EBT_ARP_DST_MAC;
205 if (ebt_get_mac_and_mask(optarg, maddr, mmask))
206 ebt_print_error2("Problem with ARP MAC address argument");
207 break;
208 case ARP_GRAT:
209 ebt_check_option2(flags, OPT_GRAT);
210 arpinfo->bitmask |= EBT_ARP_GRAT;
211 if (ebt_invert)
212 arpinfo->invflags |= EBT_ARP_GRAT;
213 break;
215 default:
216 return 0;
218 return 1;
221 static void final_check(const struct ebt_u_entry *entry,
222 const struct ebt_entry_match *match, const char *name,
223 unsigned int hookmask, unsigned int time)
225 if ((entry->ethproto != ETH_P_ARP && entry->ethproto != ETH_P_RARP) ||
226 entry->invflags & EBT_IPROTO)
227 ebt_print_error("For (R)ARP filtering the protocol must be specified as ARP or RARP");
230 static void print(const struct ebt_u_entry *entry,
231 const struct ebt_entry_match *match)
233 struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data;
234 int i;
236 if (arpinfo->bitmask & EBT_ARP_OPCODE) {
237 int opcode = ntohs(arpinfo->opcode);
238 printf("--arp-op ");
239 if (arpinfo->invflags & EBT_ARP_OPCODE)
240 printf("! ");
241 if (opcode > 0 && opcode <= NUMOPCODES)
242 printf("%s ", opcodes[opcode - 1]);
243 else
244 printf("%d ", opcode);
246 if (arpinfo->bitmask & EBT_ARP_HTYPE) {
247 printf("--arp-htype ");
248 if (arpinfo->invflags & EBT_ARP_HTYPE)
249 printf("! ");
250 printf("%d ", ntohs(arpinfo->htype));
252 if (arpinfo->bitmask & EBT_ARP_PTYPE) {
253 struct ethertypeent *ent;
255 printf("--arp-ptype ");
256 if (arpinfo->invflags & EBT_ARP_PTYPE)
257 printf("! ");
258 ent = getethertypebynumber(ntohs(arpinfo->ptype));
259 if (!ent)
260 printf("0x%x ", ntohs(arpinfo->ptype));
261 else
262 printf("%s ", ent->e_name);
264 if (arpinfo->bitmask & EBT_ARP_SRC_IP) {
265 printf("--arp-ip-src ");
266 if (arpinfo->invflags & EBT_ARP_SRC_IP)
267 printf("! ");
268 for (i = 0; i < 4; i++)
269 printf("%d%s", ((unsigned char *)&arpinfo->saddr)[i],
270 (i == 3) ? "" : ".");
271 printf("%s ", ebt_mask_to_dotted(arpinfo->smsk));
273 if (arpinfo->bitmask & EBT_ARP_DST_IP) {
274 printf("--arp-ip-dst ");
275 if (arpinfo->invflags & EBT_ARP_DST_IP)
276 printf("! ");
277 for (i = 0; i < 4; i++)
278 printf("%d%s", ((unsigned char *)&arpinfo->daddr)[i],
279 (i == 3) ? "" : ".");
280 printf("%s ", ebt_mask_to_dotted(arpinfo->dmsk));
282 if (arpinfo->bitmask & EBT_ARP_SRC_MAC) {
283 printf("--arp-mac-src ");
284 if (arpinfo->invflags & EBT_ARP_SRC_MAC)
285 printf("! ");
286 ebt_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk);
287 printf(" ");
289 if (arpinfo->bitmask & EBT_ARP_DST_MAC) {
290 printf("--arp-mac-dst ");
291 if (arpinfo->invflags & EBT_ARP_DST_MAC)
292 printf("! ");
293 ebt_print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk);
294 printf(" ");
296 if (arpinfo->bitmask & EBT_ARP_GRAT) {
297 if (arpinfo->invflags & EBT_ARP_GRAT)
298 printf("! ");
299 printf("--arp-gratuitous ");
303 static int compare(const struct ebt_entry_match *m1,
304 const struct ebt_entry_match *m2)
306 struct ebt_arp_info *arpinfo1 = (struct ebt_arp_info *)m1->data;
307 struct ebt_arp_info *arpinfo2 = (struct ebt_arp_info *)m2->data;
309 if (arpinfo1->bitmask != arpinfo2->bitmask)
310 return 0;
311 if (arpinfo1->invflags != arpinfo2->invflags)
312 return 0;
313 if (arpinfo1->bitmask & EBT_ARP_OPCODE) {
314 if (arpinfo1->opcode != arpinfo2->opcode)
315 return 0;
317 if (arpinfo1->bitmask & EBT_ARP_HTYPE) {
318 if (arpinfo1->htype != arpinfo2->htype)
319 return 0;
321 if (arpinfo1->bitmask & EBT_ARP_PTYPE) {
322 if (arpinfo1->ptype != arpinfo2->ptype)
323 return 0;
325 if (arpinfo1->bitmask & EBT_ARP_SRC_IP) {
326 if (arpinfo1->saddr != arpinfo2->saddr)
327 return 0;
328 if (arpinfo1->smsk != arpinfo2->smsk)
329 return 0;
331 if (arpinfo1->bitmask & EBT_ARP_DST_IP) {
332 if (arpinfo1->daddr != arpinfo2->daddr)
333 return 0;
334 if (arpinfo1->dmsk != arpinfo2->dmsk)
335 return 0;
337 if (arpinfo1->bitmask & EBT_ARP_SRC_MAC) {
338 if (memcmp(arpinfo1->smaddr, arpinfo2->smaddr, ETH_ALEN))
339 return 0;
340 if (memcmp(arpinfo1->smmsk, arpinfo2->smmsk, ETH_ALEN))
341 return 0;
343 if (arpinfo1->bitmask & EBT_ARP_DST_MAC) {
344 if (memcmp(arpinfo1->dmaddr, arpinfo2->dmaddr, ETH_ALEN))
345 return 0;
346 if (memcmp(arpinfo1->dmmsk, arpinfo2->dmmsk, ETH_ALEN))
347 return 0;
349 return 1;
352 static struct ebt_u_match arp_match =
354 .name = "arp",
355 .size = sizeof(struct ebt_arp_info),
356 .help = print_help,
357 .init = init,
358 .parse = parse,
359 .final_check = final_check,
360 .print = print,
361 .compare = compare,
362 .extra_ops = opts,
365 void _init(void)
367 ebt_register_match(&arp_match);