Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ipf / tools / ippool_y.y
blobb9c100f533d4078e20c7d1a50f9d8d0c8736de65
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8 %{
9 #include <sys/types.h>
10 #include <sys/time.h>
11 #include <sys/param.h>
12 #include <sys/socket.h>
13 #if defined(BSD) && (BSD >= 199306)
14 # include <sys/cdefs.h>
15 #endif
16 #include <sys/ioctl.h>
18 #include <net/if.h>
19 #if __FreeBSD_version >= 300000
20 # include <net/if_var.h>
21 #endif
22 #include <netinet/in.h>
24 #include <arpa/inet.h>
26 #include <stdio.h>
27 #include <fcntl.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <netdb.h>
31 #include <ctype.h>
32 #include <unistd.h>
34 #include "ipf.h"
35 #include "netinet/ip_lookup.h"
36 #include "netinet/ip_pool.h"
37 #include "netinet/ip_htable.h"
38 #include "ippool_l.h"
39 #include "kmem.h"
41 #define YYDEBUG 1
42 #define YYSTACKSIZE 0x00ffffff
44 extern int yyparse __P((void));
45 extern int yydebug;
46 extern FILE *yyin;
48 static iphtable_t ipht;
49 static iphtent_t iphte;
50 static ip_pool_t iplo;
51 static ioctlfunc_t poolioctl = NULL;
52 static char poolname[FR_GROUPLEN];
54 static iphtent_t *add_htablehosts __P((char *));
55 static ip_pool_node_t *add_poolhosts __P((char *));
59 %union {
60 char *str;
61 u_32_t num;
62 struct in_addr addr;
63 struct alist_s *alist;
64 struct in_addr adrmsk[2];
65 iphtent_t *ipe;
66 ip_pool_node_t *ipp;
67 union i6addr ip6;
70 %token <num> YY_NUMBER YY_HEX
71 %token <str> YY_STR
72 %token YY_COMMENT
73 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
74 %token YY_RANGE_OUT YY_RANGE_IN
75 %token <ip6> YY_IPV6
77 %token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
78 %token IPT_TABLE IPT_GROUPMAP IPT_HASH
79 %token IPT_ROLE IPT_TYPE IPT_TREE
80 %token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
81 %type <num> role table inout
82 %type <ipp> ipftree range addrlist
83 %type <adrmsk> addrmask
84 %type <ipe> ipfgroup ipfhash hashlist hashentry
85 %type <ipe> groupentry setgrouplist grouplist
86 %type <addr> ipaddr mask ipv4
87 %type <str> number setgroup
90 file: line
91 | assign
92 | file line
93 | file assign
96 line: table role ipftree eol { iplo.ipo_unit = $2;
97 iplo.ipo_list = $3;
98 load_pool(&iplo, poolioctl);
99 resetlexer();
101 | table role ipfhash eol { ipht.iph_unit = $2;
102 ipht.iph_type = IPHASH_LOOKUP;
103 load_hash(&ipht, $3, poolioctl);
104 resetlexer();
106 | groupmap role number ipfgroup eol
107 { ipht.iph_unit = $2;
108 strncpy(ipht.iph_name, $3,
109 sizeof(ipht.iph_name));
110 ipht.iph_type = IPHASH_GROUPMAP;
111 load_hash(&ipht, $4, poolioctl);
112 resetlexer();
114 | YY_COMMENT
117 eol: ';'
120 assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
121 resetlexer();
122 free($1);
123 free($3);
124 yyvarnext = 0;
128 assigning:
129 '=' { yyvarnext = 1; }
132 table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht));
133 bzero((char *)&iphte, sizeof(iphte));
134 bzero((char *)&iplo, sizeof(iplo));
135 *ipht.iph_name = '\0';
136 iplo.ipo_flags = IPHASH_ANON;
137 iplo.ipo_name[0] = '\0';
141 groupmap:
142 IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht));
143 bzero((char *)&iphte, sizeof(iphte));
144 *ipht.iph_name = '\0';
145 ipht.iph_unit = IPHASH_GROUPMAP;
146 ipht.iph_flags = $2;
150 inout: IPT_IN { $$ = FR_INQUE; }
151 | IPT_OUT { $$ = FR_OUTQUE; }
153 role:
154 IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; }
155 | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; }
156 | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; }
157 | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; }
160 ipftree:
161 IPT_TYPE '=' IPT_TREE number start addrlist end
162 { strncpy(iplo.ipo_name, $4,
163 sizeof(iplo.ipo_name));
164 $$ = $6;
168 ipfhash:
169 IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
170 { strncpy(ipht.iph_name, $4,
171 sizeof(ipht.iph_name));
172 $$ = $7;
176 ipfgroup:
177 setgroup hashopts start grouplist end
178 { iphtent_t *e;
179 for (e = $4; e != NULL;
180 e = e->ipe_next)
181 if (e->ipe_group[0] == '\0')
182 strncpy(e->ipe_group,
184 FR_GROUPLEN);
185 $$ = $4;
187 | hashopts start setgrouplist end { $$ = $3; }
190 number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3);
191 $$ = poolname;
193 | IPT_NAME '=' YY_STR { $$ = $3; }
194 | { $$ = ""; }
197 setgroup:
198 IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1];
199 strncpy(tmp, $3, FR_GROUPLEN);
200 $$ = strdup(tmp);
202 | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1];
203 sprintf(tmp, "%u", $3);
204 $$ = strdup(tmp);
208 hashopts:
209 | size
210 | seed
211 | size seed
214 addrlist:
215 next { $$ = NULL; }
216 | range next addrlist { $1->ipn_next = $3; $$ = $1; }
217 | range next { $$ = $1; }
220 grouplist:
221 next { $$ = NULL; }
222 | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
223 | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t));
224 bcopy((char *)&($1[0]),
225 (char *)&($$->ipe_addr),
226 sizeof($$->ipe_addr));
227 bcopy((char *)&($1[1]),
228 (char *)&($$->ipe_mask),
229 sizeof($$->ipe_mask));
230 $$->ipe_next = $3;
232 | groupentry next { $$ = $1; }
233 | addrmask next { $$ = calloc(1, sizeof(iphtent_t));
234 bcopy((char *)&($1[0]),
235 (char *)&($$->ipe_addr),
236 sizeof($$->ipe_addr));
237 bcopy((char *)&($1[1]),
238 (char *)&($$->ipe_mask),
239 sizeof($$->ipe_mask));
243 setgrouplist:
244 next { $$ = NULL; }
245 | groupentry next { $$ = $1; }
246 | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; }
249 groupentry:
250 addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
251 bcopy((char *)&($1[0]),
252 (char *)&($$->ipe_addr),
253 sizeof($$->ipe_addr));
254 bcopy((char *)&($1[1]),
255 (char *)&($$->ipe_mask),
256 sizeof($$->ipe_mask));
257 strncpy($$->ipe_group, $3,
258 FR_GROUPLEN);
259 free($3);
261 | YY_STR { $$ = add_htablehosts($1); }
264 range: addrmask { $$ = calloc(1, sizeof(*$$));
265 $$->ipn_info = 0;
266 $$->ipn_addr.adf_len = sizeof($$->ipn_addr) + 4;
267 $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr;
268 $$->ipn_mask.adf_len = sizeof($$->ipn_mask) + 4;
269 $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr;
271 | '!' addrmask { $$ = calloc(1, sizeof(*$$));
272 $$->ipn_info = 1;
273 $$->ipn_addr.adf_len = sizeof($$->ipn_addr) + 4;
274 $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr;
275 $$->ipn_mask.adf_len = sizeof($$->ipn_mask) + 4;
276 $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr;
278 | YY_STR { $$ = add_poolhosts($1); }
280 hashlist:
281 next { $$ = NULL; }
282 | hashentry next { $$ = $1; }
283 | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; }
286 hashentry:
287 addrmask { $$ = calloc(1, sizeof(iphtent_t));
288 bcopy((char *)&($1[0]),
289 (char *)&($$->ipe_addr),
290 sizeof($$->ipe_addr));
291 bcopy((char *)&($1[1]),
292 (char *)&($$->ipe_mask),
293 sizeof($$->ipe_mask));
295 | YY_STR { $$ = add_htablehosts($1); }
298 addrmask:
299 ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr;
300 yyexpectaddr = 0;
302 | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff;
303 yyexpectaddr = 0;
307 ipaddr: ipv4 { $$ = $1; }
308 | YY_NUMBER { $$.s_addr = htonl($1); }
311 mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); }
312 | ipv4 { $$ = $1; }
315 start: '{' { yyexpectaddr = 1; }
318 end: '}' { yyexpectaddr = 0; }
321 next: ';' { yyexpectaddr = 1; }
324 size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
327 seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; }
330 ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
331 { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
332 yyerror("Invalid octet string for IP address");
333 return 0;
335 $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
336 $$.s_addr = htonl($$.s_addr);
340 static wordtab_t yywords[] = {
341 { "auth", IPT_AUTH },
342 { "count", IPT_COUNT },
343 { "group", IPT_GROUP },
344 { "group-map", IPT_GROUPMAP },
345 { "hash", IPT_HASH },
346 { "in", IPT_IN },
347 { "ipf", IPT_IPF },
348 { "name", IPT_NAME },
349 { "nat", IPT_NAT },
350 { "number", IPT_NUM },
351 { "out", IPT_OUT },
352 { "role", IPT_ROLE },
353 { "seed", IPT_SEED },
354 { "size", IPT_SIZE },
355 { "table", IPT_TABLE },
356 { "tree", IPT_TREE },
357 { "type", IPT_TYPE },
358 { NULL, 0 }
362 int ippool_parsefile(fd, filename, iocfunc)
363 int fd;
364 char *filename;
365 ioctlfunc_t iocfunc;
367 FILE *fp = NULL;
368 char *s;
370 yylineNum = 1;
371 (void) yysettab(yywords);
373 s = getenv("YYDEBUG");
374 if (s)
375 yydebug = atoi(s);
376 else
377 yydebug = 0;
379 if (strcmp(filename, "-")) {
380 fp = fopen(filename, "r");
381 if (!fp) {
382 fprintf(stderr, "fopen(%s) failed: %s\n", filename,
383 STRERROR(errno));
384 return -1;
386 } else
387 fp = stdin;
389 while (ippool_parsesome(fd, fp, iocfunc) == 1)
391 if (fp != NULL)
392 fclose(fp);
393 return 0;
397 int ippool_parsesome(fd, fp, iocfunc)
398 int fd;
399 FILE *fp;
400 ioctlfunc_t iocfunc;
402 char *s;
403 int i;
405 poolioctl = iocfunc;
407 if (feof(fp))
408 return 0;
409 i = fgetc(fp);
410 if (i == EOF)
411 return 0;
412 if (ungetc(i, fp) == EOF)
413 return 0;
414 if (feof(fp))
415 return 0;
416 s = getenv("YYDEBUG");
417 if (s)
418 yydebug = atoi(s);
419 else
420 yydebug = 0;
422 yyin = fp;
423 yyparse();
424 return 1;
428 static iphtent_t *
429 add_htablehosts(url)
430 char *url;
432 iphtent_t *htop, *hbot, *h;
433 alist_t *a, *hlist;
435 if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
436 hlist = load_url(url);
437 } else {
438 use_inet6 = 0;
440 hlist = calloc(1, sizeof(*hlist));
441 if (hlist == NULL)
442 return NULL;
444 if (gethost(url, &hlist->al_addr) == -1)
445 yyerror("Unknown hostname");
448 hbot = NULL;
449 htop = NULL;
451 for (a = hlist; a != NULL; a = a->al_next) {
452 h = calloc(1, sizeof(*h));
453 if (h == NULL)
454 break;
456 bcopy((char *)&a->al_addr, (char *)&h->ipe_addr,
457 sizeof(h->ipe_addr));
458 bcopy((char *)&a->al_mask, (char *)&h->ipe_mask,
459 sizeof(h->ipe_mask));
461 if (hbot != NULL)
462 hbot->ipe_next = h;
463 else
464 htop = h;
465 hbot = h;
468 alist_free(hlist);
470 return htop;
474 static ip_pool_node_t *
475 add_poolhosts(url)
476 char *url;
478 ip_pool_node_t *ptop, *pbot, *p;
479 alist_t *a, *hlist;
481 if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
482 hlist = load_url(url);
483 } else {
484 use_inet6 = 0;
486 hlist = calloc(1, sizeof(*hlist));
487 if (hlist == NULL)
488 return NULL;
490 if (gethost(url, &hlist->al_addr) == -1)
491 yyerror("Unknown hostname");
494 pbot = NULL;
495 ptop = NULL;
497 for (a = hlist; a != NULL; a = a->al_next) {
498 p = calloc(1, sizeof(*p));
499 if (p == NULL)
500 break;
502 p->ipn_addr.adf_len = offsetof(addrfamily_t, adf_addr) + 4;
503 p->ipn_mask.adf_len = offsetof(addrfamily_t, adf_addr) + 4;
505 p->ipn_info = a->al_not;
507 bcopy((char *)&a->al_addr, (char *)&p->ipn_addr.adf_addr,
508 sizeof(p->ipn_addr.adf_addr));
509 bcopy((char *)&a->al_mask, (char *)&p->ipn_mask.adf_addr,
510 sizeof(p->ipn_mask.adf_addr));
512 if (pbot != NULL)
513 pbot->ipn_next = p;
514 else
515 ptop = p;
516 pbot = p;
519 alist_free(hlist);
521 return ptop;