4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
11 #include <sys/param.h>
12 #include <sys/socket.h>
13 #if defined(BSD) && (BSD >= 199306)
14 # include <sys/cdefs.h>
16 #include <sys/ioctl.h>
19 #if __FreeBSD_version >= 300000
20 # include <net/if_var.h>
22 #include <netinet/in.h>
24 #include <arpa/inet.h>
35 #include "netinet/ip_lookup.h"
36 #include "netinet/ip_pool.h"
37 #include "netinet/ip_htable.h"
42 #define YYSTACKSIZE 0x00ffffff
44 extern
int yyparse __P
((void));
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 *));
63 struct alist_s
*alist
;
64 struct in_addr adrmsk
[2];
70 %token
<num
> YY_NUMBER YY_HEX
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
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
96 line: table role ipftree eol
{ iplo.ipo_unit
= $2;
98 load_pool
(&iplo
, poolioctl
);
101 | table role ipfhash eol
{ ipht.iph_unit
= $2;
102 ipht.iph_type
= IPHASH_LOOKUP
;
103 load_hash
(&ipht
, $3, poolioctl
);
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
);
120 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
{ sprintf
(poolname
, "%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 sprintf
(tmp
, "%u", $3);
216 | range next addrlist
{ $1->ipn_next
= $3; $$
= $1; }
217 | range next
{ $$
= $1; }
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
));
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
));
245 | groupentry next
{ $$
= $1; }
246 | groupentry next setgrouplist
{ $1->ipe_next
= $3; $$
= $1; }
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,
261 | YY_STR
{ $$
= add_htablehosts
($1); }
264 range: addrmask
{ $$
= calloc
(1, sizeof
(*$$
));
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
(*$$
));
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); }
282 | hashentry next
{ $$
= $1; }
283 | hashentry next hashlist
{ $1->ipe_next
= $3; $$
= $1; }
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); }
299 ipaddr
'/' mask
{ $$
[0] = $1; $$
[1].s_addr
= $3.s_addr
;
302 | ipaddr
{ $$
[0] = $1; $$
[1].s_addr
= 0xffffffff;
307 ipaddr: ipv4
{ $$
= $1; }
308 | YY_NUMBER
{ $$.s_addr
= htonl
($1); }
311 mask: YY_NUMBER
{ ntomask
(4, $1, (u_32_t
*)&$$.s_addr
); }
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");
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
},
348 { "name", IPT_NAME
},
350 { "number", IPT_NUM
},
352 { "role", IPT_ROLE
},
353 { "seed", IPT_SEED
},
354 { "size", IPT_SIZE
},
355 { "table", IPT_TABLE
},
356 { "tree", IPT_TREE
},
357 { "type", IPT_TYPE
},
362 int ippool_parsefile
(fd
, filename
, iocfunc
)
371 (void) yysettab
(yywords
);
373 s
= getenv
("YYDEBUG");
379 if
(strcmp
(filename
, "-")) {
380 fp
= fopen
(filename
, "r");
382 fprintf
(stderr
, "fopen(%s) failed: %s\n", filename
,
389 while
(ippool_parsesome
(fd
, fp
, iocfunc
) == 1)
397 int ippool_parsesome
(fd
, fp
, iocfunc
)
412 if
(ungetc
(i
, fp
) == EOF
)
416 s
= getenv
("YYDEBUG");
432 iphtent_t
*htop
, *hbot
, *h
;
435 if
(!strncmp
(url
, "file://", 7) ||
!strncmp
(url
, "http://", 7)) {
436 hlist
= load_url
(url
);
440 hlist
= calloc
(1, sizeof
(*hlist
));
444 if
(gethost
(url
, &hlist
->al_addr
) == -1)
445 yyerror("Unknown hostname");
451 for
(a
= hlist
; a
!= NULL
; a
= a
->al_next
) {
452 h
= calloc
(1, sizeof
(*h
));
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
));
474 static ip_pool_node_t
*
478 ip_pool_node_t
*ptop
, *pbot
, *p
;
481 if
(!strncmp
(url
, "file://", 7) ||
!strncmp
(url
, "http://", 7)) {
482 hlist
= load_url
(url
);
486 hlist
= calloc
(1, sizeof
(*hlist
));
490 if
(gethost
(url
, &hlist
->al_addr
) == -1)
491 yyerror("Unknown hostname");
497 for
(a
= hlist
; a
!= NULL
; a
= a
->al_next
) {
498 p
= calloc
(1, sizeof
(*p
));
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
));