3 * Copyright (C) 2003 by Darren Reed.
5 * See the IPFILTER.LICENCE file for details on licencing.
7 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
8 * Use is subject to license terms.
11 #pragma ident "%Z%%M% %I% %E% SMI"
13 #include <sys/types.h>
15 #include <sys/param.h>
16 #include <sys/socket.h>
17 #if defined(BSD) && (BSD >= 199306)
18 # include <sys/cdefs.h>
20 #include <sys/ioctl.h>
23 #if __FreeBSD_version >= 300000
24 # include <net/if_var.h>
26 #include <netinet/in.h>
28 #include <arpa/inet.h>
39 #include "netinet/ip_lookup.h"
40 #include "netinet/ip_pool.h"
41 #include "netinet/ip_htable.h"
47 extern
int yyparse __P
((void));
51 static iphtable_t ipht
;
52 static iphtent_t iphte
;
53 static ip_pool_t iplo
;
54 static ioctlfunc_t poolioctl
= NULL
;
55 static char poolname
[FR_GROUPLEN
];
56 static int set_ipv6_addr
= 0;
64 struct alist_s
*alist
;
65 union i6addr adrmsk
[2];
71 %token
<num
> YY_NUMBER YY_HEX
74 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
75 %token YY_RANGE_OUT YY_RANGE_IN
78 %token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
79 %token IPT_TABLE IPT_GROUPMAP IPT_HASH
80 %token IPT_ROLE IPT_TYPE IPT_TREE
81 %token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
82 %type
<num
> role table inout
83 %type
<ipp
> ipftree range addrlist
84 %type
<adrmsk
> addrmask
85 %type
<ipe
> ipfgroup ipfhash hashlist hashentry
86 %type
<ipe
> groupentry setgrouplist grouplist
87 %type
<ip6
> ipaddr mask ipv4
88 %type
<str
> number setgroup
97 line: table role ipftree eol
{ iplo.ipo_unit
= $2;
99 load_pool
(&iplo
, poolioctl
);
102 | table role ipfhash eol
{ ipht.iph_unit
= $2;
103 ipht.iph_type
= IPHASH_LOOKUP
;
104 load_hash
(&ipht
, $3, poolioctl
);
107 | groupmap role number ipfgroup eol
108 { ipht.iph_unit
= $2;
109 strncpy
(ipht.iph_name
, $3,
110 sizeof
(ipht.iph_name
));
111 ipht.iph_type
= IPHASH_GROUPMAP
;
112 load_hash
(&ipht
, $4, poolioctl
);
121 assign: YY_STR assigning YY_STR
';' { set_variable
($1, $3);
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';
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
;
150 inout: IPT_IN
{ $$
= FR_INQUE
; }
151 | IPT_OUT
{ $$
= FR_OUTQUE
; }
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
; }
161 IPT_TYPE
'=' IPT_TREE number start addrlist end
162 { strncpy
(iplo.ipo_name
, $4,
163 sizeof
(iplo.ipo_name
));
169 IPT_TYPE
'=' IPT_HASH number hashopts start hashlist end
170 { strncpy
(ipht.iph_name
, $4,
171 sizeof
(ipht.iph_name
));
177 setgroup hashopts start grouplist end
179 for
(e
= $4; e
!= NULL
;
181 if
(e
->ipe_group
[0] == '\0')
182 strncpy
(e
->ipe_group
,
187 | hashopts start setgrouplist end
{ $$
= $3; }
190 number: IPT_NUM
'=' YY_NUMBER
{ snprintf
(poolname
, FR_GROUPLEN
, "%u", $3);
193 | IPT_NAME
'=' YY_STR
{ $$
= $3; }
198 IPT_GROUP
'=' YY_STR
{ char tmp
[FR_GROUPLEN
+1];
199 strncpy
(tmp
, $3, FR_GROUPLEN
);
202 | IPT_GROUP
'=' YY_NUMBER
{ char tmp
[FR_GROUPLEN
+1];
203 snprintf
(tmp
, FR_GROUPLEN
, "%u", $3);
216 | range next addrlist
{ $1->ipn_next
= $3; $$
= $1; }
217 | range next
{ $$
= $1; }
223 | groupentry next grouplist
{ $$
= $1; $1->ipe_next
= $3; }
224 | addrmask next grouplist
{ $$
= calloc
(1, sizeof
(iphtent_t
));
226 yyerror("sorry, out of memory");
228 $$
->ipe_family
= AF_INET6
;
230 $$
->ipe_family
= AF_INET
;
231 bcopy
((char *)&($1[0]),
232 (char *)&($$
->ipe_addr
),
233 sizeof
($$
->ipe_addr
));
234 bcopy
((char *)&($1[1]),
235 (char *)&($$
->ipe_mask
),
236 sizeof
($$
->ipe_mask
));
240 | groupentry next
{ $$
= $1; }
241 | addrmask next
{ $$
= calloc
(1, sizeof
(iphtent_t
));
243 yyerror("sorry, out of memory");
245 $$
->ipe_family
= AF_INET6
;
247 $$
->ipe_family
= AF_INET
;
248 bcopy
((char *)&($1[0]),
249 (char *)&($$
->ipe_addr
),
250 sizeof
($$
->ipe_addr
));
251 bcopy
((char *)&($1[1]),
252 (char *)&($$
->ipe_mask
),
253 sizeof
($$
->ipe_mask
));
260 | groupentry next
{ $$
= $1; }
261 | groupentry next setgrouplist
{ $1->ipe_next
= $3; $$
= $1; }
265 addrmask
',' setgroup
{ $$
= calloc
(1, sizeof
(iphtent_t
));
267 yyerror("sorry, out of memory");
269 $$
->ipe_family
= AF_INET6
;
271 $$
->ipe_family
= AF_INET
;
272 bcopy
((char *)&($1[0]),
273 (char *)&($$
->ipe_addr
),
274 sizeof
($$
->ipe_addr
));
275 bcopy
((char *)&($1[1]),
276 (char *)&($$
->ipe_mask
),
277 sizeof
($$
->ipe_mask
));
279 strncpy
($$
->ipe_group
, $3,
285 range: addrmask
{ $$
= calloc
(1, sizeof
(*$$
));
287 yyerror("sorry, out of memory");
289 $$
->ipn_addr.adf_len
= sizeof
($$
->ipn_addr
);
290 $$
->ipn_mask.adf_len
= sizeof
($$
->ipn_mask
);
292 $$
->ipn_addr.adf_family
= AF_INET6
;
293 $$
->ipn_addr.adf_addr
= $1[0];
294 $$
->ipn_mask.adf_addr
= $1[1];
297 $$
->ipn_addr.adf_family
= AF_INET
;
298 $$
->ipn_addr.adf_addr.in4.s_addr
= $1[0].in4.s_addr
;
299 $$
->ipn_mask.adf_addr.in4.s_addr
= $1[1].in4.s_addr
;
303 |
'!' addrmask
{ $$
= calloc
(1, sizeof
(*$$
));
305 yyerror("sorry, out of memory");
307 $$
->ipn_addr.adf_len
= sizeof
($$
->ipn_addr
);
308 $$
->ipn_mask.adf_len
= sizeof
($$
->ipn_mask
);
310 $$
->ipn_addr.adf_family
= AF_INET6
;
311 $$
->ipn_addr.adf_addr
= $2[0];
312 $$
->ipn_mask.adf_addr
= $2[1];
314 $$
->ipn_addr.adf_family
= AF_INET
;
315 $$
->ipn_addr.adf_addr.in4.s_addr
= $2[0].in4.s_addr
;
316 $$
->ipn_mask.adf_addr.in4.s_addr
= $2[1].in4.s_addr
;
323 | hashentry next
{ $$
= $1; }
324 | hashentry next hashlist
{ $1->ipe_next
= $3; $$
= $1; }
328 addrmask
{ $$
= calloc
(1, sizeof
(iphtent_t
));
330 yyerror("sorry, out of memory");
332 $$
->ipe_family
= AF_INET6
;
334 $$
->ipe_family
= AF_INET
;
335 bcopy
((char *)&($1[0]),
336 (char *)&($$
->ipe_addr
),
337 sizeof
($$
->ipe_addr
));
338 bcopy
((char *)&($1[1]),
339 (char *)&($$
->ipe_mask
),
340 sizeof
($$
->ipe_mask
));
345 ipaddr
'/' mask
{ $$
[0] = $1; $$
[1] = $3;
348 | ipaddr
{ $$
[0] = $1;
351 fill6bits
(128, (u_32_t
*)$$
[1].in6.s6_addr
);
353 $$
[1].in4.s_addr
= 0xffffffff;
357 ipaddr: ipv4
{ $$
= $1; }
358 | YY_NUMBER
{ $$.in4.s_addr
= htonl
($1); }
359 | YY_IPV6
{ set_ipv6_addr
= 1;
360 bcopy
(&$1, &$$
, sizeof
($$
));
362 | YY_STR
{ if
(gethost
($1, &$$
, 0) == -1)
363 yyerror("Unknown hostname");
367 mask: YY_NUMBER
{ if
(set_ipv6_addr
)
368 ntomask
(6, $1, (u_32_t
*)$$.in6.s6_addr
);
370 ntomask
(4, $1, (u_32_t
*)&$$.in4.s_addr
); }
374 start: '{' { yyexpectaddr
= 1; }
377 end: '}' { yyexpectaddr
= 0; }
380 next: ',' { yyexpectaddr
= 1; }
381 |
';' { yyexpectaddr
= 1; }
384 size: IPT_SIZE
'=' YY_NUMBER
{ ipht.iph_size
= $3; }
387 seed: IPT_SEED
'=' YY_NUMBER
{ ipht.iph_seed
= $3; }
390 ipv4: YY_NUMBER
'.' YY_NUMBER
'.' YY_NUMBER
'.' YY_NUMBER
391 { if
($1 > 255 ||
$3 > 255 ||
$5 > 255 ||
$7 > 255) {
392 yyerror("Invalid octet string for IP address");
395 $$.in4.s_addr
= ($1 << 24) |
($3 << 16) |
($5 << 8) |
$7;
396 $$.in4.s_addr
= htonl
($$.in4.s_addr
);
400 static wordtab_t yywords
[] = {
401 { "auth", IPT_AUTH
},
402 { "count", IPT_COUNT
},
403 { "group", IPT_GROUP
},
404 { "group-map", IPT_GROUPMAP
},
405 { "hash", IPT_HASH
},
408 { "name", IPT_NAME
},
410 { "number", IPT_NUM
},
412 { "role", IPT_ROLE
},
413 { "seed", IPT_SEED
},
414 { "size", IPT_SIZE
},
415 { "table", IPT_TABLE
},
416 { "tree", IPT_TREE
},
417 { "type", IPT_TYPE
},
422 int ippool_parsefile
(fd
, filename
, iocfunc
)
431 (void) yysettab
(yywords
);
433 s
= getenv
("YYDEBUG");
439 if
(strcmp
(filename
, "-")) {
440 fp
= fopen
(filename
, "r");
442 fprintf
(stderr
, "fopen(%s) failed: %s\n", filename
,
449 while
(ippool_parsesome
(fd
, fp
, iocfunc
) == 1)
457 int ippool_parsesome
(fd
, fp
, iocfunc
)
472 if
(ungetc
(i
, fp
) == EOF
)
476 s
= getenv
("YYDEBUG");