Print this page
OS-7667 IPFilter needs to keep and report state for cloud firewall logging
Portions contributed by: Mike Gerdts <mike.gerdts@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ipf/tools/ipf_y.y
+++ new/usr/src/cmd/ipf/tools/ipf_y.y
1 1 %{
2 2 /*
3 3 * Copyright (C) 2003 by Darren Reed.
4 4 *
5 5 * See the IPFILTER.LICENCE file for details on licencing.
6 6 *
7 7 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
8 8 * Use is subject to license terms.
9 + * Copyright 2019 Joyent, Inc.
9 10 */
10 11
11 12 #include "ipf.h"
12 13 #include <sys/ioctl.h>
13 14 #include <syslog.h>
14 15 #ifdef IPFILTER_BPF
15 16 # include "pcap-bpf.h"
16 17 # define _NET_BPF_H_
17 18 # include <pcap.h>
18 19 #endif
20 +#include <uuid/uuid.h>
19 21 #include "netinet/ip_pool.h"
20 22 #include "netinet/ip_htable.h"
21 23 #include "netinet/ipl.h"
22 24 #include "ipf_l.h"
23 25
24 26 #define YYDEBUG 1
25 27 #define DOALL(x) for (fr = frc; fr != NULL; fr = fr->fr_next) { x }
26 28 #define DOREM(x) for (; fr != NULL; fr = fr->fr_next) { x }
27 29
28 30 #define OPTION_LOG 0x1
29 31 #define OPTION_QUICK 0x2
30 32 #define OPTION_DUP 0x4
31 33 #define OPTION_PROUTE 0x8
32 34 #define OPTION_ON 0x10
33 35 #define OPTION_REPLYTO 0x20
34 36 #define OPTION_FROUTE 0x40
35 37
36 38 extern void yyerror __P((char *));
37 39 extern int yyparse __P((void));
38 40 extern int yylex __P((void));
39 41 extern int yydebug;
40 42 extern FILE *yyin;
41 43 extern int yylineNum;
42 44
43 45 static void newrule __P((void));
44 46 static void setipftype __P((void));
45 47 static u_32_t lookuphost __P((char *, i6addr_t *));
46 48 static void dobpf __P((int, char *));
47 49 static void resetaddr __P((void));
48 50 static struct alist_s *newalist __P((struct alist_s *));
49 51 static u_int makehash __P((struct alist_s *));
50 52 static int makepool __P((struct alist_s *));
51 53 static frentry_t *addrule __P((void));
52 54 static void setsyslog __P((void));
53 55 static void unsetsyslog __P((void));
54 56 static void fillgroup __P((frentry_t *));
55 57
56 58 frentry_t *fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL;
57 59
58 60 static int ifpflag = 0;
59 61 static int nowith = 0;
60 62 static int dynamic = -1;
61 63 static int pooled = 0;
62 64 static int hashed = 0;
63 65 static int nrules = 0;
64 66 static int newlist = 0;
65 67 static int added = 0;
66 68 static int ipffd = -1;
67 69 static int ruleopts = 0;
68 70 static int *yycont = 0;
69 71 static ioctlfunc_t ipfioctl[IPL_LOGSIZE];
70 72 static addfunc_t ipfaddfunc = NULL;
71 73 static struct wordtab ipfwords[96];
72 74 static struct wordtab addrwords[4];
73 75 static struct wordtab maskwords[5];
74 76 static struct wordtab icmpcodewords[17];
75 77 static struct wordtab icmptypewords[16];
76 78 static struct wordtab ipv4optwords[25];
77 79 static struct wordtab ipv4secwords[9];
78 80 static struct wordtab ipv6optwords[8];
79 81 static struct wordtab logwords[33];
80 82 static int set_ipv6_addr = 0;
81 83
82 84 %}
83 85 %union {
84 86 char *str;
85 87 u_32_t num;
86 88 struct in_addr ipa;
87 89 frentry_t fr;
88 90 frtuc_t *frt;
89 91 struct alist_s *alist;
90 92 u_short port;
|
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
91 93 struct {
92 94 u_short p1;
93 95 u_short p2;
94 96 int pc;
95 97 } pc;
96 98 struct {
97 99 union i6addr a;
98 100 union i6addr m;
99 101 } ipp;
100 102 union i6addr ip6;
103 + uuid_t uuid;
101 104 };
102 105
103 106 %type <port> portnum
104 107 %type <num> facility priority icmpcode seclevel secname icmptype
105 108 %type <num> opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
106 109 %type <num> portc porteq
107 110 %type <ipa> ipv4 ipv4_16 ipv4_24
108 111 %type <ip6> hostname mask
109 112 %type <ipp> addr ipaddr
110 113 %type <str> servicename name interfacename
111 114 %type <pc> portrange portcomp
112 115 %type <alist> addrlist poollist
113 116
114 117 %token <num> YY_NUMBER YY_HEX
115 118 %token <str> YY_STR
116 119 %token YY_COMMENT
117 120 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
118 121 %token YY_RANGE_OUT YY_RANGE_IN
119 122 %token <ip6> YY_IPV6
123 +%token <uuid> YY_UUID
120 124
121 125 %token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL
122 126 %token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
123 127 %token IPFY_IN IPFY_OUT
124 128 %token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
125 129 %token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
126 130 %token IPFY_TOS IPFY_TTL IPFY_PROTO
127 131 %token IPFY_HEAD IPFY_GROUP
128 132 %token IPFY_AUTH IPFY_PREAUTH
129 133 %token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK
134 +%token IPFY_UUID IPFY_CFWLOG
130 135 %token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP
131 136 %token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
132 137 %token IPFY_PPS
133 138 %token IPFY_ESP IPFY_AH
134 139 %token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
135 140 %token IPFY_TCPUDP IPFY_TCP IPFY_UDP
136 141 %token IPFY_FLAGS IPFY_MULTICAST
137 142 %token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER
138 143 %token IPFY_PORT
139 144 %token IPFY_NOW
140 145 %token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE
141 146 %token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
142 147 %token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
143 148 %token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
144 149 %token IPFY_SYNC IPFY_FRAGBODY
145 150 %token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
146 151 %token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
147 152 %token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
148 153 %token IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA
149 154 %token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS
150 155 %token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP
151 156 %token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2
152 157 %token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3
153 158
154 159 %token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
155 160 %token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING
156 161
157 162 %token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH
158 163 %token IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST
159 164 %token IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP
160 165 %token IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD
161 166 %token IPFY_ICMPT_ROUTERSOL
162 167
163 168 %token IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR
164 169 %token IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK
165 170 %token IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO
166 171 %token IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE
167 172 %token IPFY_ICMPC_CUTPRE
168 173
169 174 %token IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH
170 175 %token IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON
171 176 %token IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3
172 177 %token IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7
173 178 %token IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT
174 179 %token IPFY_FAC_LFMT IPFY_FAC_CONSOLE
175 180
176 181 %token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN
177 182 %token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG
178 183 %token IPFY_SET_LOOPBACK IPFY_SET
179 184 %%
180 185 file: line
181 186 | assign
182 187 | file line
183 188 | file assign
184 189 ;
185 190
186 191 line: xx rule { while ((fr = frtop) != NULL) {
187 192 frtop = fr->fr_next;
188 193 fr->fr_next = NULL;
189 194 (*ipfaddfunc)(ipffd, ipfioctl[IPL_LOGIPF], fr);
190 195 fr->fr_next = frold;
191 196 frold = fr;
192 197 }
193 198 resetlexer();
194 199 }
195 200 | YY_COMMENT
196 201 | set
197 202 ;
198 203
199 204 xx: { newrule(); }
200 205 ;
201 206
202 207 assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
203 208 resetlexer();
204 209 free($1);
205 210 free($3);
206 211 yyvarnext = 0;
207 212 }
208 213 ;
209 214
210 215 assigning:
211 216 '=' { yyvarnext = 1; }
212 217 ;
213 218
214 219 set:
215 220 IPFY_SET IPFY_SET_LOOPBACK YY_STR ';'
216 221 {
217 222 int data;
218 223 if (frold != NULL) {
219 224 yyerror("ipf rules before \"set\"");
220 225 return 0;
221 226 }
222 227 if (!strcmp($3, "true"))
223 228 data = 1;
224 229 else if (!strcmp($3, "false"))
225 230 data = 0;
226 231 else {
227 232 yyerror("invalid argument for ipf_loopback");
228 233 return 0;
229 234 }
230 235 if (((opts & OPT_DONOTHING) == 0) &&
231 236 (ioctl(ipffd, SIOCIPFLP, &data) == -1))
232 237 perror("ioctl(SIOCIPFLP)");
233 238 }
234 239 ;
235 240
236 241 rule: inrule eol
237 242 | outrule eol
238 243 ;
239 244
240 245 eol: | ';'
241 246 ;
242 247
243 248 inrule:
244 249 rulehead markin { ruleopts = 0; } inopts rulemain ruletail intag ruletail2
245 250 ;
246 251
247 252 outrule:
248 253 rulehead markout { ruleopts = 0; } outopts rulemain ruletail outtag ruletail2
249 254 ;
250 255
251 256 rulehead:
252 257 collection action
253 258 | insert collection action
254 259 ;
255 260
256 261 markin: IPFY_IN { fr->fr_flags |= FR_INQUE; }
257 262 ;
258 263
259 264 markout:
260 265 IPFY_OUT { fr->fr_flags |= FR_OUTQUE; }
261 266 ;
262 267
263 268 rulemain:
264 269 ipfrule
265 270 | bpfrule
266 271 ;
267 272
268 273 ipfrule:
269 274 tos ttl proto ip
270 275 ;
271 276
272 277 bpfrule:
273 278 IPFY_BPFV4 '{' YY_STR '}' { dobpf(4, $3); free($3); }
274 279 | IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); }
275 280 ;
276 281
277 282 ruletail:
278 283 with keep head group
279 284 ;
280 285
281 286 ruletail2:
282 287 pps age new
283 288 ;
284 289
285 290 intag: settagin matchtagin
286 291 ;
287 292
288 293 outtag: settagout matchtagout
289 294 ;
290 295
291 296 insert:
292 297 '@' YY_NUMBER { fr->fr_hits = (U_QUAD_T)$2 + 1; }
293 298 ;
294 299
295 300 collection:
296 301 | YY_NUMBER { fr->fr_collect = $1; }
297 302 ;
298 303
299 304 action: block
300 305 | IPFY_PASS { fr->fr_flags |= FR_PASS; }
301 306 | log
302 307 | IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; }
303 308 | auth
304 309 | IPFY_SKIP YY_NUMBER { fr->fr_flags |= FR_SKIP;
305 310 fr->fr_arg = $2; }
306 311 | IPFY_CALL func
307 312 | IPFY_CALL IPFY_NOW func { fr->fr_flags |= FR_CALLNOW; }
308 313 ;
309 314
310 315 block: blocked
311 316 | blocked blockreturn
312 317 ;
313 318
314 319 blocked:
315 320 IPFY_BLOCK { fr->fr_flags = FR_BLOCK; }
316 321 ;
317 322 blockreturn:
318 323 IPFY_RETICMP { fr->fr_flags |= FR_RETICMP; }
319 324 | IPFY_RETICMP returncode { fr->fr_flags |= FR_RETICMP; }
320 325 | IPFY_RETICMPASDST { fr->fr_flags |= FR_FAKEICMP; }
321 326 | IPFY_RETICMPASDST returncode { fr->fr_flags |= FR_FAKEICMP; }
322 327 | IPFY_RETRST { fr->fr_flags |= FR_RETRST; }
323 328 ;
324 329
325 330 log: IPFY_LOG { fr->fr_flags |= FR_LOG; }
326 331 | IPFY_LOG logoptions { fr->fr_flags |= FR_LOG; }
327 332 ;
328 333
329 334 auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; }
330 335 | IPFY_AUTH IPFY_RETRST { fr->fr_flags |= (FR_AUTH|FR_RETRST);}
331 336 | IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; }
332 337 ;
333 338
334 339 func: YY_STR '/' YY_NUMBER { fr->fr_func = nametokva($1,
335 340 ipfioctl[IPL_LOGIPF]);
336 341 fr->fr_arg = $3;
337 342 free($1); }
338 343 ;
339 344
340 345 inopts:
341 346 | inopts inopt
342 347 ;
343 348
344 349 inopt:
345 350 logopt
346 351 {
347 352 if ( ruleopts & OPTION_LOG )
348 353 yyerror("Duplicate log option");
349 354 ruleopts |= OPTION_LOG;
350 355 }
351 356 | quick
352 357 {
353 358 if ( ruleopts & OPTION_QUICK )
354 359 yyerror("Duplicate quick option");
355 360 ruleopts |= OPTION_QUICK;
356 361 }
357 362 | on
358 363 {
359 364 if ( ruleopts & OPTION_ON )
360 365 yyerror("Duplicate on option");
361 366 ruleopts |= OPTION_ON;
362 367 }
363 368 | dup
364 369 {
365 370 if ( ruleopts & OPTION_DUP )
366 371 yyerror("Duplicate dup option");
367 372 ruleopts |= OPTION_DUP;
368 373 }
369 374 | froute
370 375 {
371 376 if ( ruleopts & OPTION_FROUTE )
372 377 yyerror("Duplicate froute option");
373 378 ruleopts |= OPTION_FROUTE;
374 379 }
375 380 | proute
376 381 {
377 382 if ( ruleopts & OPTION_PROUTE )
378 383 yyerror("Duplicate proute option");
379 384 ruleopts |= OPTION_PROUTE;
380 385 }
381 386 | replyto
382 387 {
383 388 if ( ruleopts & OPTION_REPLYTO )
384 389 yyerror("Duplicate replyto option");
385 390 ruleopts |= OPTION_REPLYTO;
386 391 }
387 392 ;
388 393
389 394 outopts:
390 395 | outopts outopt
391 396 ;
392 397
393 398 outopt:
394 399 logopt
395 400 {
396 401 if ( ruleopts & OPTION_LOG )
397 402 yyerror("Duplicate log option");
398 403 ruleopts |= OPTION_LOG;
399 404 }
400 405 | quick
401 406 {
402 407 if ( ruleopts & OPTION_QUICK )
403 408 yyerror("Duplicate quick option");
404 409 ruleopts |= OPTION_QUICK;
405 410 }
406 411 | on
407 412 {
408 413 if ( ruleopts & OPTION_ON )
409 414 yyerror("Duplicate on option");
410 415 ruleopts |= OPTION_ON;
411 416 }
412 417 | dup
413 418 {
414 419 if ( ruleopts & OPTION_DUP )
415 420 yyerror("Duplicate dup option");
416 421 ruleopts |= OPTION_DUP;
417 422 }
418 423 | proute
419 424 {
420 425 if ( ruleopts & OPTION_PROUTE )
421 426 yyerror("Duplicate proute option");
422 427 ruleopts |= OPTION_PROUTE;
423 428 }
424 429 | replyto
425 430 {
426 431 if ( ruleopts & OPTION_REPLYTO )
427 432 yyerror("Duplicate replyto option");
428 433 ruleopts |= OPTION_REPLYTO;
429 434 }
430 435 ;
431 436
432 437 tos: | settos YY_NUMBER { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
433 438 | settos YY_HEX { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
434 439 | settos lstart toslist lend
435 440 ;
436 441
437 442 settos: IPFY_TOS { setipftype(); }
438 443 ;
439 444
440 445 toslist:
441 446 YY_NUMBER { DOALL(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
442 447 | YY_HEX { DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
443 448 | toslist lmore YY_NUMBER
444 449 { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
445 450 | toslist lmore YY_HEX
446 451 { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
447 452 ;
448 453
449 454 ttl: | setttl YY_NUMBER
450 455 { DOALL(fr->fr_ttl = $2; fr->fr_mttl = 0xff;) }
451 456 | setttl lstart ttllist lend
452 457 ;
453 458
454 459 lstart: '(' { newlist = 1; fr = frc; added = 0; }
455 460 ;
456 461
457 462 lend: ')' { nrules += added; }
458 463 ;
459 464
460 465 lmore: lanother { if (newlist == 1) {
461 466 newlist = 0;
462 467 }
463 468 fr = addrule();
464 469 if (yycont != NULL)
465 470 *yycont = 1;
466 471 }
467 472 ;
468 473
469 474 lanother:
470 475 | ','
471 476 ;
472 477
473 478 setttl: IPFY_TTL { setipftype(); }
474 479 ;
475 480
476 481 ttllist:
477 482 YY_NUMBER { DOREM(fr->fr_ttl = $1; fr->fr_mttl = 0xff;) }
478 483 | ttllist lmore YY_NUMBER
479 484 { DOREM(fr->fr_ttl = $3; fr->fr_mttl = 0xff;) }
480 485 ;
481 486
482 487 proto: | protox protocol { yyresetdict(); }
483 488 ;
484 489
485 490 protox: IPFY_PROTO { setipftype();
486 491 fr = frc;
487 492 yysetdict(NULL); }
488 493 ;
489 494
490 495 ip: srcdst flags icmp
491 496 ;
492 497
493 498 group: | IPFY_GROUP YY_STR { DOALL(strncpy(fr->fr_group, $2, \
494 499 FR_GROUPLEN); \
495 500 fillgroup(fr););
496 501 free($2); }
497 502 | IPFY_GROUP YY_NUMBER { DOALL(sprintf(fr->fr_group, "%d", \
498 503 $2); \
499 504 fillgroup(fr);) }
500 505 ;
501 506
502 507 head: | IPFY_HEAD YY_STR { DOALL(strncpy(fr->fr_grhead, $2, \
503 508 FR_GROUPLEN););
504 509 free($2); }
505 510 | IPFY_HEAD YY_NUMBER { DOALL(sprintf(fr->fr_grhead, "%d", \
506 511 $2);) }
507 512 ;
508 513
509 514 settagin:
510 515 | IPFY_SETTAG '(' taginlist ')'
|
↓ open down ↓ |
371 lines elided |
↑ open up ↑ |
511 516 ;
512 517
513 518 taginlist:
514 519 taginspec
515 520 | taginlist ',' taginspec
516 521 ;
517 522
518 523 taginspec:
519 524 logtag
520 525 |nattag
526 + |uuidtag
527 + |cfwtag
521 528 ;
522 529
523 530 nattag: IPFY_NAT '=' YY_STR { DOALL(strncpy(fr->fr_nattag.ipt_tag,\
524 531 $3, IPFTAG_LEN););
525 532 free($3); }
526 533 | IPFY_NAT '=' YY_NUMBER { DOALL(sprintf(fr->fr_nattag.ipt_tag,\
527 534 "%d", $3 & 0xffffffff);) }
528 535 ;
529 536
530 537 logtag: IPFY_LOG '=' YY_NUMBER { DOALL(fr->fr_logtag = $3;) }
531 538 ;
532 539
540 +cfwtag: IPFY_CFWLOG { DOALL(fr->fr_flags |= FR_CFWLOG;) }
541 + ;
542 +
543 +uuidtag: IPFY_UUID '=' YY_UUID { DOALL(uuid_copy(fr->fr_uuid, $3);) }
544 + ;
545 +
533 546 settagout:
534 547 | IPFY_SETTAG '(' tagoutlist ')'
535 548 ;
536 549
537 550 tagoutlist:
538 551 tagoutspec
539 552 | tagoutlist ',' tagoutspec
540 553 ;
541 554
542 555 tagoutspec:
543 556 logtag
544 557 | nattag
558 + | uuidtag
559 + | cfwtag
545 560 ;
546 561
547 562 matchtagin:
548 563 | IPFY_MATCHTAG '(' tagoutlist ')'
549 564 ;
550 565
551 566 matchtagout:
552 567 | IPFY_MATCHTAG '(' taginlist ')'
553 568 ;
554 569
555 570 pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) }
556 571 ;
557 572
558 573 new: | savegroup file restoregroup
559 574 ;
560 575
561 576 savegroup:
562 577 '{'
563 578 ;
564 579
565 580 restoregroup:
566 581 '}'
567 582 ;
568 583
569 584 logopt: log
570 585 ;
571 586
572 587 quick:
573 588 IPFY_QUICK { fr->fr_flags |= FR_QUICK; }
574 589 ;
575 590
576 591 on: IPFY_ON onname
577 592 | IPFY_ON onname IPFY_INVIA vianame
578 593 | IPFY_ON onname IPFY_OUTVIA vianame
579 594 ;
580 595
581 596 onname: interfacename
582 597 { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
583 598 free($1);
584 599 }
585 600 | interfacename ',' interfacename
586 601 { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
587 602 free($1);
588 603 strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1]));
589 604 free($3);
590 605 }
591 606 ;
592 607
593 608 vianame:
594 609 name
595 610 { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
596 611 free($1);
597 612 }
598 613 | name ',' name
599 614 { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
600 615 free($1);
601 616 strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3]));
602 617 free($3);
603 618 }
604 619 ;
605 620
606 621 dup: IPFY_DUPTO name
607 622 { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
608 623 free($2);
609 624 fr->fr_flags |= FR_DUP;
610 625 }
611 626 | IPFY_DUPTO name duptoseparator hostname
612 627 { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
613 628 if (use_inet6 == 0)
614 629 fr->fr_dif.fd_ip = $4.in4;
615 630 else
616 631 bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6));
617 632 yyexpectaddr = 0;
618 633 fr->fr_flags |= FR_DUP;
619 634 free($2);
620 635 }
621 636 | IPFY_DUPTO name duptoseparator YY_IPV6
622 637 { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
623 638 bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6));
624 639 yyexpectaddr = 0;
625 640 fr->fr_flags |= FR_DUP;
626 641 free($2);
627 642 }
628 643 ;
629 644
630 645 duptoseparator:
631 646 ':' { yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); }
632 647 ;
633 648
634 649 froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; }
635 650 ;
636 651
637 652 proute: routeto name
638 653 { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
639 654 free($2);
640 655 }
641 656 | routeto name duptoseparator hostname
642 657 { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
643 658 if (use_inet6 == 0)
644 659 fr->fr_tif.fd_ip = $4.in4;
645 660 else
646 661 bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6));
647 662 yyexpectaddr = 0;
648 663 free($2);
649 664 }
650 665 | routeto name duptoseparator YY_IPV6
651 666 { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
652 667 bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6));
653 668 yyexpectaddr = 0;
654 669 free($2);
655 670 }
656 671 ;
657 672
658 673 routeto:
659 674 IPFY_TO
660 675 | IPFY_ROUTETO
661 676 ;
662 677
663 678 replyto:
664 679 IPFY_REPLY_TO name
665 680 { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
666 681 free($2);
667 682 }
668 683 | IPFY_REPLY_TO name duptoseparator hostname
669 684 { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
670 685 if (use_inet6 == 0)
671 686 fr->fr_rif.fd_ip = $4.in4;
672 687 else
673 688 bcopy(&$4, &fr->fr_rif.fd_ip6, sizeof(fr->fr_rif.fd_ip6));
674 689 yyexpectaddr = 0;
675 690 free($2);
676 691 }
677 692 | IPFY_REPLY_TO name duptoseparator YY_IPV6
678 693 { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
679 694 bcopy(&$4, &fr->fr_rif.fd_ip6, sizeof(fr->fr_rif.fd_ip6));
680 695 yyexpectaddr = 0;
681 696 free($2);
682 697 }
683 698 ;
684 699
685 700 logoptions:
686 701 logoption
687 702 | logoptions logoption
688 703 ;
689 704
690 705 logoption:
691 706 IPFY_BODY { fr->fr_flags |= FR_LOGBODY; }
692 707 | IPFY_FIRST { fr->fr_flags |= FR_LOGFIRST; }
693 708 | IPFY_ORBLOCK { fr->fr_flags |= FR_LOGORBLOCK; }
694 709 | level loglevel { unsetsyslog(); }
695 710 ;
696 711
697 712 returncode:
698 713 starticmpcode icmpcode ')' { fr->fr_icode = $2; yyresetdict(); }
699 714 ;
700 715
701 716 starticmpcode:
702 717 '(' { yysetdict(icmpcodewords); }
703 718 ;
704 719
705 720 srcdst: | IPFY_ALL
706 721 | fromto
707 722 ;
708 723
709 724 protocol:
710 725 YY_NUMBER { DOREM(fr->fr_proto = $1; \
711 726 fr->fr_mproto = 0xff;) }
712 727 | YY_STR { if (!strcmp($1, "tcp-udp")) {
713 728 DOREM(fr->fr_flx |= FI_TCPUDP; \
714 729 fr->fr_mflx |= FI_TCPUDP;)
715 730 } else {
716 731 int p = getproto($1);
717 732 if (p == -1)
718 733 yyerror("protocol unknown");
719 734 DOREM(fr->fr_proto = p; \
720 735 fr->fr_mproto = 0xff;)
721 736 }
722 737 free($1);
723 738 }
724 739 | YY_STR nextstring YY_STR
725 740 { if (!strcmp($1, "tcp") &&
726 741 !strcmp($3, "udp")) {
727 742 DOREM(fr->fr_flx |= FI_TCPUDP; \
728 743 fr->fr_mflx |= FI_TCPUDP;)
729 744 } else
730 745 YYERROR;
731 746 free($1);
732 747 free($3);
733 748 }
734 749 ;
735 750
736 751 nextstring:
737 752 '/' { yysetdict(NULL); }
738 753 ;
739 754
740 755 fromto: from srcobject to dstobject { yyexpectaddr = 0; yycont = NULL; }
741 756 | to dstobject { yyexpectaddr = 0; yycont = NULL; }
742 757 | from srcobject { yyexpectaddr = 0; yycont = NULL; }
743 758 ;
744 759
745 760 from: IPFY_FROM { setipftype();
746 761 if (fr == NULL)
747 762 fr = frc;
748 763 yyexpectaddr = 1;
749 764 if (yydebug)
750 765 printf("set yyexpectaddr\n");
751 766 yycont = &yyexpectaddr;
752 767 yysetdict(addrwords);
753 768 resetaddr(); }
754 769 ;
755 770
756 771 to: IPFY_TO { if (fr == NULL)
757 772 fr = frc;
758 773 yyexpectaddr = 1;
759 774 if (yydebug)
760 775 printf("set yyexpectaddr\n");
761 776 yycont = &yyexpectaddr;
762 777 yysetdict(addrwords);
763 778 resetaddr(); }
764 779 ;
765 780
766 781 with: | andwith withlist
767 782 ;
768 783
769 784 andwith:
770 785 IPFY_WITH { nowith = 0; setipftype(); }
771 786 | IPFY_AND { nowith = 0; setipftype(); }
772 787 ;
773 788
774 789 flags: | startflags flagset
775 790 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
776 791 | startflags flagset '/' flagset
777 792 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
778 793 | startflags '/' flagset
779 794 { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
780 795 | startflags YY_NUMBER
781 796 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
782 797 | startflags '/' YY_NUMBER
783 798 { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
784 799 | startflags YY_NUMBER '/' YY_NUMBER
785 800 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
786 801 | startflags flagset '/' YY_NUMBER
787 802 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
788 803 | startflags YY_NUMBER '/' flagset
789 804 { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
790 805 ;
791 806
792 807 startflags:
793 808 IPFY_FLAGS { if (frc->fr_type != FR_T_IPF)
794 809 yyerror("flags with non-ipf type rule");
795 810 if (frc->fr_proto != IPPROTO_TCP)
796 811 yyerror("flags with non-TCP rule");
797 812 }
798 813 ;
799 814
800 815 flagset:
801 816 YY_STR { $$ = tcpflags($1); free($1); }
802 817 | YY_HEX { $$ = $1; }
803 818 ;
804 819
805 820 srcobject:
806 821 { yyresetdict(); } fromport
807 822 | srcaddr srcport
808 823 | '!' srcaddr srcport
809 824 { DOALL(fr->fr_flags |= FR_NOTSRCIP;) }
810 825 ;
811 826
812 827 srcaddr:
813 828 addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
814 829 bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
815 830 if (dynamic != -1) { \
816 831 fr->fr_satype = ifpflag; \
817 832 fr->fr_ipf->fri_sifpidx = dynamic; \
818 833 } else if (pooled || hashed) \
819 834 fr->fr_satype = FRI_LOOKUP;)
820 835 }
821 836 | lstart srcaddrlist lend
822 837 ;
823 838
824 839 srcaddrlist:
825 840 addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
826 841 bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
827 842 if (dynamic != -1) { \
828 843 fr->fr_satype = ifpflag; \
829 844 fr->fr_ipf->fri_sifpidx = dynamic; \
830 845 } else if (pooled || hashed) \
831 846 fr->fr_satype = FRI_LOOKUP;)
832 847 }
833 848 | srcaddrlist lmore addr
834 849 { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_src, sizeof($3.a)); \
835 850 bcopy(&($3.m), &fr->fr_mip.fi_src, sizeof($3.m)); \
836 851 if (dynamic != -1) { \
837 852 fr->fr_satype = ifpflag; \
838 853 fr->fr_ipf->fri_sifpidx = dynamic; \
839 854 } else if (pooled || hashed) \
840 855 fr->fr_satype = FRI_LOOKUP;)
841 856 }
842 857 ;
843 858
844 859 srcport:
845 860 | portcomp
846 861 { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
847 862 | portrange
848 863 { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
849 864 fr->fr_stop = $1.p2;) }
850 865 | porteq lstart srcportlist lend
851 866 { yyresetdict(); }
852 867 ;
853 868
854 869 fromport:
855 870 portcomp
856 871 { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
857 872 | portrange
858 873 { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
859 874 fr->fr_stop = $1.p2;) }
860 875 | porteq lstart srcportlist lend
861 876 { yyresetdict(); }
862 877 ;
863 878
864 879 srcportlist:
865 880 portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) }
866 881 | srcportlist lmore portnum
867 882 { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) }
868 883 ;
869 884
870 885 dstobject:
871 886 { yyresetdict(); } toport
872 887 | dstaddr dstport
873 888 | '!' dstaddr dstport
874 889 { DOALL(fr->fr_flags |= FR_NOTDSTIP;) }
875 890 ;
876 891
877 892 dstaddr:
878 893 addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
879 894 bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
880 895 if (dynamic != -1) { \
881 896 fr->fr_datype = ifpflag; \
882 897 fr->fr_ipf->fri_difpidx = dynamic; \
883 898 } else if (pooled || hashed) \
884 899 fr->fr_datype = FRI_LOOKUP;)
885 900 }
886 901 | lstart dstaddrlist lend
887 902 ;
888 903
889 904 dstaddrlist:
890 905 addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
891 906 bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
892 907 if (dynamic != -1) { \
893 908 fr->fr_datype = ifpflag; \
894 909 fr->fr_ipf->fri_difpidx = dynamic; \
895 910 } else if (pooled || hashed) \
896 911 fr->fr_datype = FRI_LOOKUP;)
897 912 }
898 913 | dstaddrlist lmore addr
899 914 { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_dst, sizeof($3.a)); \
900 915 bcopy(&($3.m), &fr->fr_mip.fi_dst, sizeof($3.m)); \
901 916 if (dynamic != -1) { \
902 917 fr->fr_datype = ifpflag; \
903 918 fr->fr_ipf->fri_difpidx = dynamic; \
904 919 } else if (pooled || hashed) \
905 920 fr->fr_datype = FRI_LOOKUP;)
906 921 }
907 922 ;
908 923
909 924
910 925 dstport:
911 926 | portcomp
912 927 { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
913 928 | portrange
914 929 { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
915 930 fr->fr_dtop = $1.p2;) }
916 931 | porteq lstart dstportlist lend
917 932 { yyresetdict(); }
918 933 ;
919 934
920 935 toport:
921 936 portcomp
922 937 { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
923 938 | portrange
924 939 { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
925 940 fr->fr_dtop = $1.p2;) }
926 941 | porteq lstart dstportlist lend
927 942 { yyresetdict(); }
928 943 ;
929 944
930 945 dstportlist:
931 946 portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) }
932 947 | dstportlist lmore portnum
933 948 { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) }
934 949 ;
935 950
936 951 addr: pool '/' YY_NUMBER { pooled = 1;
937 952 yyexpectaddr = 0;
938 953 $$.a.iplookuptype = IPLT_POOL;
939 954 $$.a.iplookupnum = $3; }
940 955 | pool '=' '(' poollist ')' { pooled = 1;
941 956 yyexpectaddr = 0;
942 957 $$.a.iplookuptype = IPLT_POOL;
943 958 $$.a.iplookupnum = makepool($4); }
944 959 | hash '/' YY_NUMBER { hashed = 1;
945 960 yyexpectaddr = 0;
946 961 $$.a.iplookuptype = IPLT_HASH;
947 962 $$.a.iplookupnum = $3; }
948 963 | hash '=' '(' addrlist ')' { hashed = 1;
949 964 yyexpectaddr = 0;
950 965 $$.a.iplookuptype = IPLT_HASH;
951 966 $$.a.iplookupnum = makehash($4); }
952 967 | ipaddr { bcopy(&$1, &$$, sizeof($$));
953 968 yyexpectaddr = 0; }
954 969 ;
955 970
956 971 ipaddr: IPFY_ANY { bzero(&($$), sizeof($$));
957 972 yyresetdict();
958 973 yyexpectaddr = 0; }
959 974 | hostname { if (use_inet6 == 0) {
960 975 $$.a.in4 = $1.in4;
961 976 $$.m.in4_addr = 0xffffffff;
962 977 } else {
963 978 set_ipv6_addr = 1;
964 979 bcopy(&$1, &$$.a, sizeof($$.a));
965 980 fill6bits(128, (u_32_t *)&$$.m);
966 981 }
967 982 yyexpectaddr = 0; }
968 983 | hostname { yyresetdict();
969 984 if (use_inet6 == 0)
970 985 $$.a.in4 = $1.in4;
971 986 else {
972 987 set_ipv6_addr = 1;
973 988 bcopy(&$1, &$$.a, sizeof($$.a));
974 989 }
975 990 }
976 991 maskspace { yysetdict(maskwords); }
977 992 mask { if (use_inet6 == 0) {
978 993 $$.m.in4_addr = $5.in4.s_addr;
979 994 $$.a.in4_addr &= $5.in4.s_addr;
980 995 } else
981 996 bcopy(&$5, &$$.m, sizeof($$.m));
982 997 yyresetdict();
983 998 yyexpectaddr = 0; }
984 999 | YY_IPV6 { set_ipv6_addr = 1;
985 1000 bcopy(&$1, &$$.a, sizeof($$.a));
986 1001 fill6bits(128, (u_32_t *)&$$.m);
987 1002 yyresetdict();
988 1003 yyexpectaddr = 0; }
989 1004 | YY_IPV6 { set_ipv6_addr = 1;
990 1005 yyresetdict();
991 1006 bcopy(&$1, &$$.a, sizeof($$.a)); }
992 1007 maskspace { yysetdict(maskwords); }
993 1008 mask { bcopy(&$5, &$$.m, sizeof($$.m));
994 1009 yyresetdict();
995 1010 yyexpectaddr = 0; }
996 1011 ;
997 1012
998 1013 maskspace:
999 1014 '/'
1000 1015 | IPFY_MASK
1001 1016 ;
1002 1017
1003 1018 mask:
1004 1019 ipv4 { $$.in4 = $1; }
1005 1020 | YY_HEX { $$.in4.s_addr = htonl($1); }
1006 1021 | YY_NUMBER { if ((use_inet6 == 0) && ($1 <= 32))
1007 1022 ntomask(4, $1, (u_32_t *)&$$.in4);
1008 1023 else if ((use_inet6 != 0) && ($1 <= 128))
1009 1024 ntomask(6, $1, $$.i6);
1010 1025 else {
1011 1026 yyerror("Bad value specified for netmask");
1012 1027 return 0;
1013 1028 }
1014 1029 }
1015 1030 | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
1016 1031 bzero(&$$, sizeof($$));
1017 1032 ifpflag = FRI_BROADCAST;
1018 1033 } else
1019 1034 YYERROR;
1020 1035 }
1021 1036 | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) {
1022 1037 bzero(&$$, sizeof($$));
1023 1038 ifpflag = FRI_NETWORK;
1024 1039 } else
1025 1040 YYERROR;
1026 1041 }
1027 1042 | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) {
1028 1043 bzero(&$$, sizeof($$));
1029 1044 ifpflag = FRI_NETMASKED;
1030 1045 } else
1031 1046 YYERROR;
1032 1047 }
1033 1048 | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) {
1034 1049 bzero(&$$, sizeof($$));
1035 1050 ifpflag = FRI_PEERADDR;
1036 1051 } else
1037 1052 YYERROR;
1038 1053 }
1039 1054 ;
1040 1055
1041 1056 hostname:
1042 1057 ipv4 { $$.in4 = $1; }
1043 1058 | YY_NUMBER { $$.in4.s_addr = $1; }
1044 1059 | YY_HEX { $$.in4.s_addr = $1; }
1045 1060 | YY_STR { if (lookuphost($1, &$$) == 1)
1046 1061 free($1);
1047 1062 else {
1048 1063 free($1);
1049 1064 if (ifpflag != FRI_DYNAMIC)
1050 1065 yyerror("Unknown hostname");
1051 1066 }
1052 1067 }
1053 1068 ;
1054 1069
1055 1070 addrlist:
1056 1071 ipaddr { $$ = newalist(NULL);
1057 1072 if (set_ipv6_addr)
1058 1073 $$->al_family = AF_INET6;
1059 1074 else
1060 1075 $$->al_family = AF_INET;
1061 1076 set_ipv6_addr = 0;
1062 1077 bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
1063 1078 bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
1064 1079 | addrlist ',' ipaddr
1065 1080 { $$ = newalist($1);
1066 1081 if (set_ipv6_addr)
1067 1082 $$->al_family = AF_INET6;
1068 1083 else
1069 1084 $$->al_family = AF_INET;
1070 1085 set_ipv6_addr = 0;
1071 1086 bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
1072 1087 bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
1073 1088 ;
1074 1089
1075 1090 pool: IPFY_POOL { yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
1076 1091 ;
1077 1092
1078 1093 hash: IPFY_HASH { yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
1079 1094 ;
1080 1095
1081 1096 poollist:
1082 1097 ipaddr { $$ = newalist(NULL);
1083 1098 if (set_ipv6_addr)
1084 1099 $$->al_family = AF_INET6;
1085 1100 else
1086 1101 $$->al_family = AF_INET;
1087 1102 set_ipv6_addr = 0;
1088 1103 bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
1089 1104 bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
1090 1105 | '!' ipaddr { $$ = newalist(NULL);
1091 1106 $$->al_not = 1;
1092 1107 if (set_ipv6_addr)
1093 1108 $$->al_family = AF_INET6;
1094 1109 else
1095 1110 $$->al_family = AF_INET;
1096 1111 set_ipv6_addr = 0;
1097 1112 bcopy(&($2.a), &($$->al_i6addr), sizeof($2.a));
1098 1113 bcopy(&($2.m), &($$->al_i6mask), sizeof($2.m)); }
1099 1114 | poollist ',' ipaddr
1100 1115 { $$ = newalist($1);
1101 1116 if (set_ipv6_addr)
1102 1117 $$->al_family = AF_INET6;
1103 1118 else
1104 1119 $$->al_family = AF_INET;
1105 1120 set_ipv6_addr = 0;
1106 1121 bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
1107 1122 bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
1108 1123 | poollist ',' '!' ipaddr
1109 1124 { $$ = newalist($1);
1110 1125 $$->al_not = 1;
1111 1126 if (set_ipv6_addr)
1112 1127 $$->al_family = AF_INET6;
1113 1128 else
1114 1129 $$->al_family = AF_INET;
1115 1130 set_ipv6_addr = 0;
1116 1131 bcopy(&($4.a), &($$->al_i6addr), sizeof($4.a));
1117 1132 bcopy(&($4.m), &($$->al_i6mask), sizeof($4.m)); }
1118 1133 ;
1119 1134
1120 1135 port: IPFY_PORT { yyexpectaddr = 0;
1121 1136 yycont = NULL;
1122 1137 }
1123 1138 ;
1124 1139
1125 1140 portc: port compare { $$ = $2;
1126 1141 yysetdict(NULL); }
1127 1142 | porteq { $$ = $1; }
1128 1143 ;
1129 1144
1130 1145 porteq: port '=' { $$ = FR_EQUAL;
1131 1146 yysetdict(NULL); }
1132 1147 ;
1133 1148
1134 1149 portr: IPFY_PORT { yyexpectaddr = 0;
1135 1150 yycont = NULL;
1136 1151 yysetdict(NULL); }
1137 1152 ;
1138 1153
1139 1154 portcomp:
1140 1155 portc portnum { $$.pc = $1;
1141 1156 $$.p1 = $2;
1142 1157 yyresetdict(); }
1143 1158 ;
1144 1159
1145 1160 portrange:
1146 1161 portr portnum range portnum { $$.p1 = $2;
1147 1162 $$.pc = $3;
1148 1163 $$.p2 = $4;
1149 1164 yyresetdict(); }
1150 1165 ;
1151 1166
1152 1167 icmp: | itype icode
1153 1168 ;
1154 1169
1155 1170 itype: seticmptype icmptype
1156 1171 { DOALL(fr->fr_icmp = htons($2 << 8); fr->fr_icmpm = htons(0xff00););
1157 1172 yyresetdict();
1158 1173 }
1159 1174 | seticmptype lstart typelist lend { yyresetdict(); }
1160 1175 ;
1161 1176
1162 1177 seticmptype:
1163 1178 IPFY_ICMPTYPE { setipftype();
1164 1179 yysetdict(icmptypewords); }
1165 1180 ;
1166 1181
1167 1182 icode: | seticmpcode icmpcode
1168 1183 { DOALL(fr->fr_icmp |= htons($2); fr->fr_icmpm |= htons(0xff););
1169 1184 yyresetdict();
1170 1185 }
1171 1186 | seticmpcode lstart codelist lend { yyresetdict(); }
1172 1187 ;
1173 1188
1174 1189 seticmpcode:
1175 1190 IPFY_ICMPCODE { yysetdict(icmpcodewords); }
1176 1191 ;
1177 1192
1178 1193 typelist:
1179 1194 icmptype
1180 1195 { DOREM(fr->fr_icmp = htons($1 << 8); fr->fr_icmpm = htons(0xff00);) }
1181 1196 | typelist lmore icmptype
1182 1197 { DOREM(fr->fr_icmp = htons($3 << 8); fr->fr_icmpm = htons(0xff00);) }
1183 1198 ;
1184 1199
1185 1200 codelist:
1186 1201 icmpcode
1187 1202 { DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) }
1188 1203 | codelist lmore icmpcode
1189 1204 { DOREM(fr->fr_icmp |= htons($3); fr->fr_icmpm |= htons(0xff);) }
1190 1205 ;
1191 1206
1192 1207 age: | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \
1193 1208 fr->fr_age[1] = $2;) }
1194 1209 | IPFY_AGE YY_NUMBER '/' YY_NUMBER
1195 1210 { DOALL(fr->fr_age[0] = $2; \
1196 1211 fr->fr_age[1] = $4;) }
1197 1212 ;
1198 1213
1199 1214 keep: | IPFY_KEEP keepstate
1200 1215 | IPFY_KEEP keepfrag
1201 1216 | IPFY_KEEP keepstate IPFY_KEEP keepfrag
1202 1217 | IPFY_KEEP keepfrag IPFY_KEEP keepstate
1203 1218 ;
1204 1219
1205 1220 keepstate:
1206 1221 IPFY_STATE stateoptlist { DOALL(fr->fr_flags |= FR_KEEPSTATE;)}
1207 1222 ;
1208 1223
1209 1224 keepfrag:
1210 1225 IPFY_FRAGS fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
1211 1226 | IPFY_FRAG fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
1212 1227 ;
1213 1228
1214 1229 fragoptlist:
1215 1230 | '(' fragopts ')'
1216 1231 ;
1217 1232
1218 1233 fragopts:
1219 1234 fragopt lanother fragopts
1220 1235 | fragopt
1221 1236 ;
1222 1237
1223 1238 fragopt:
1224 1239 IPFY_STRICT { DOALL(fr->fr_flags |= FR_FRSTRICT;) }
1225 1240 ;
1226 1241
1227 1242 stateoptlist:
1228 1243 | '(' stateopts ')'
1229 1244 ;
1230 1245
1231 1246 stateopts:
1232 1247 stateopt lanother stateopts
1233 1248 | stateopt
1234 1249 ;
1235 1250
1236 1251 stateopt:
1237 1252 IPFY_LIMIT YY_NUMBER { DOALL(fr->fr_statemax = $2;) }
1238 1253 | IPFY_STRICT { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
1239 1254 YYERROR; \
1240 1255 } else \
1241 1256 fr->fr_flags |= FR_STSTRICT;)
1242 1257 }
1243 1258 | IPFY_NEWISN { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
1244 1259 YYERROR; \
1245 1260 } else \
1246 1261 fr->fr_flags |= FR_NEWISN;)
1247 1262 }
1248 1263 | IPFY_NOICMPERR { DOALL(fr->fr_flags |= FR_NOICMPERR;) }
1249 1264
1250 1265 | IPFY_SYNC { DOALL(fr->fr_flags |= FR_STATESYNC;) }
1251 1266 ;
1252 1267
1253 1268 portnum:
1254 1269 servicename { if (getport(frc, $1, &($$)) == -1)
1255 1270 yyerror("service unknown");
1256 1271 else
1257 1272 $$ = ntohs($$);
1258 1273 free($1);
1259 1274 }
1260 1275 | YY_NUMBER { if ($1 > 65535) /* Unsigned */
1261 1276 yyerror("invalid port number");
1262 1277 else
1263 1278 $$ = $1;
1264 1279 }
1265 1280 ;
1266 1281
1267 1282 withlist:
1268 1283 withopt
1269 1284 | withlist withopt
1270 1285 | withlist ',' withopt
1271 1286 ;
1272 1287
1273 1288 withopt:
1274 1289 opttype { DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) }
1275 1290 | notwith opttype
1276 1291 { DOALL(fr->fr_mflx |= $2;) }
1277 1292 | ipopt ipopts { yyresetdict(); }
1278 1293 | notwith ipopt ipopts { yyresetdict(); }
1279 1294 | startv6hdrs ipv6hdrs { yyresetdict(); }
1280 1295 ;
1281 1296
1282 1297 ipopt: IPFY_OPT { yysetdict(ipv4optwords); }
1283 1298 ;
1284 1299
1285 1300 startv6hdrs:
1286 1301 IPF6_V6HDRS { if (use_inet6 == 0)
1287 1302 yyerror("only available with IPv6");
1288 1303 yysetdict(ipv6optwords);
1289 1304 }
1290 1305 ;
1291 1306
1292 1307 notwith:
1293 1308 IPFY_NOT { nowith = 1; }
1294 1309 | IPFY_NO { nowith = 1; }
1295 1310 ;
1296 1311
1297 1312 opttype:
1298 1313 IPFY_IPOPTS { $$ = FI_OPTIONS; }
1299 1314 | IPFY_SHORT { $$ = FI_SHORT; }
1300 1315 | IPFY_NAT { $$ = FI_NATED; }
1301 1316 | IPFY_BAD { $$ = FI_BAD; }
1302 1317 | IPFY_BADNAT { $$ = FI_BADNAT; }
1303 1318 | IPFY_BADSRC { $$ = FI_BADSRC; }
1304 1319 | IPFY_LOWTTL { $$ = FI_LOWTTL; }
1305 1320 | IPFY_FRAG { $$ = FI_FRAG; }
1306 1321 | IPFY_FRAGBODY { $$ = FI_FRAGBODY; }
1307 1322 | IPFY_FRAGS { $$ = FI_FRAG; }
1308 1323 | IPFY_MBCAST { $$ = FI_MBCAST; }
1309 1324 | IPFY_MULTICAST { $$ = FI_MULTICAST; }
1310 1325 | IPFY_BROADCAST { $$ = FI_BROADCAST; }
1311 1326 | IPFY_STATE { $$ = FI_STATE; }
1312 1327 | IPFY_OOW { $$ = FI_OOW; }
1313 1328 ;
1314 1329
1315 1330 ipopts: optlist { DOALL(fr->fr_mip.fi_optmsk |= $1;
1316 1331 if (!nowith)
1317 1332 fr->fr_ip.fi_optmsk |= $1;)
1318 1333 }
1319 1334 ;
1320 1335
1321 1336 optlist:
1322 1337 opt { $$ |= $1; }
1323 1338 | optlist ',' opt { $$ |= $1 | $3; }
1324 1339 ;
1325 1340
1326 1341 ipv6hdrs:
1327 1342 ipv6hdrlist { DOALL(fr->fr_mip.fi_optmsk |= $1;
1328 1343 if (!nowith)
1329 1344 fr->fr_ip.fi_optmsk |= $1;)
1330 1345 }
1331 1346 ;
1332 1347
1333 1348 ipv6hdrlist:
1334 1349 ipv6hdr { $$ |= $1; }
1335 1350 | ipv6hdrlist ',' ipv6hdr { $$ |= $1 | $3; }
1336 1351 ;
1337 1352
1338 1353 secname:
1339 1354 seclevel { $$ |= $1; }
1340 1355 | secname ',' seclevel { $$ |= $1 | $3; }
1341 1356 ;
1342 1357
1343 1358 seclevel:
1344 1359 IPFY_SEC_UNC { $$ = secbit(IPSO_CLASS_UNCL); }
1345 1360 | IPFY_SEC_CONF { $$ = secbit(IPSO_CLASS_CONF); }
1346 1361 | IPFY_SEC_RSV1 { $$ = secbit(IPSO_CLASS_RES1); }
1347 1362 | IPFY_SEC_RSV2 { $$ = secbit(IPSO_CLASS_RES2); }
1348 1363 | IPFY_SEC_RSV3 { $$ = secbit(IPSO_CLASS_RES3); }
1349 1364 | IPFY_SEC_RSV4 { $$ = secbit(IPSO_CLASS_RES4); }
1350 1365 | IPFY_SEC_SEC { $$ = secbit(IPSO_CLASS_SECR); }
1351 1366 | IPFY_SEC_TS { $$ = secbit(IPSO_CLASS_TOPS); }
1352 1367 ;
1353 1368
1354 1369 icmptype:
1355 1370 YY_NUMBER { $$ = $1; }
1356 1371 | IPFY_ICMPT_UNR { $$ = ICMP_UNREACH; }
1357 1372 | IPFY_ICMPT_ECHO { $$ = ICMP_ECHO; }
1358 1373 | IPFY_ICMPT_ECHOR { $$ = ICMP_ECHOREPLY; }
1359 1374 | IPFY_ICMPT_SQUENCH { $$ = ICMP_SOURCEQUENCH; }
1360 1375 | IPFY_ICMPT_REDIR { $$ = ICMP_REDIRECT; }
1361 1376 | IPFY_ICMPT_TIMEX { $$ = ICMP_TIMXCEED; }
1362 1377 | IPFY_ICMPT_PARAMP { $$ = ICMP_PARAMPROB; }
1363 1378 | IPFY_ICMPT_TIMEST { $$ = ICMP_TSTAMP; }
1364 1379 | IPFY_ICMPT_TIMESTREP { $$ = ICMP_TSTAMPREPLY; }
1365 1380 | IPFY_ICMPT_INFOREQ { $$ = ICMP_IREQ; }
1366 1381 | IPFY_ICMPT_INFOREP { $$ = ICMP_IREQREPLY; }
1367 1382 | IPFY_ICMPT_MASKREQ { $$ = ICMP_MASKREQ; }
1368 1383 | IPFY_ICMPT_MASKREP { $$ = ICMP_MASKREPLY; }
1369 1384 | IPFY_ICMPT_ROUTERAD { $$ = ICMP_ROUTERADVERT; }
1370 1385 | IPFY_ICMPT_ROUTERSOL { $$ = ICMP_ROUTERSOLICIT; }
1371 1386 ;
1372 1387
1373 1388 icmpcode:
1374 1389 YY_NUMBER { $$ = $1; }
1375 1390 | IPFY_ICMPC_NETUNR { $$ = ICMP_UNREACH_NET; }
1376 1391 | IPFY_ICMPC_HSTUNR { $$ = ICMP_UNREACH_HOST; }
1377 1392 | IPFY_ICMPC_PROUNR { $$ = ICMP_UNREACH_PROTOCOL; }
1378 1393 | IPFY_ICMPC_PORUNR { $$ = ICMP_UNREACH_PORT; }
1379 1394 | IPFY_ICMPC_NEEDF { $$ = ICMP_UNREACH_NEEDFRAG; }
1380 1395 | IPFY_ICMPC_SRCFAIL { $$ = ICMP_UNREACH_SRCFAIL; }
1381 1396 | IPFY_ICMPC_NETUNK { $$ = ICMP_UNREACH_NET_UNKNOWN; }
1382 1397 | IPFY_ICMPC_HSTUNK { $$ = ICMP_UNREACH_HOST_UNKNOWN; }
1383 1398 | IPFY_ICMPC_ISOLATE { $$ = ICMP_UNREACH_ISOLATED; }
1384 1399 | IPFY_ICMPC_NETPRO { $$ = ICMP_UNREACH_NET_PROHIB; }
1385 1400 | IPFY_ICMPC_HSTPRO { $$ = ICMP_UNREACH_HOST_PROHIB; }
1386 1401 | IPFY_ICMPC_NETTOS { $$ = ICMP_UNREACH_TOSNET; }
1387 1402 | IPFY_ICMPC_HSTTOS { $$ = ICMP_UNREACH_TOSHOST; }
1388 1403 | IPFY_ICMPC_FLTPRO { $$ = ICMP_UNREACH_ADMIN_PROHIBIT; }
1389 1404 | IPFY_ICMPC_HSTPRE { $$ = 14; }
1390 1405 | IPFY_ICMPC_CUTPRE { $$ = 15; }
1391 1406 ;
1392 1407
1393 1408 opt:
1394 1409 IPFY_IPOPT_NOP { $$ = getoptbyvalue(IPOPT_NOP); }
1395 1410 | IPFY_IPOPT_RR { $$ = getoptbyvalue(IPOPT_RR); }
1396 1411 | IPFY_IPOPT_ZSU { $$ = getoptbyvalue(IPOPT_ZSU); }
1397 1412 | IPFY_IPOPT_MTUP { $$ = getoptbyvalue(IPOPT_MTUP); }
1398 1413 | IPFY_IPOPT_MTUR { $$ = getoptbyvalue(IPOPT_MTUR); }
1399 1414 | IPFY_IPOPT_ENCODE { $$ = getoptbyvalue(IPOPT_ENCODE); }
1400 1415 | IPFY_IPOPT_TS { $$ = getoptbyvalue(IPOPT_TS); }
1401 1416 | IPFY_IPOPT_TR { $$ = getoptbyvalue(IPOPT_TR); }
1402 1417 | IPFY_IPOPT_SEC { $$ = getoptbyvalue(IPOPT_SECURITY); }
1403 1418 | IPFY_IPOPT_LSRR { $$ = getoptbyvalue(IPOPT_LSRR); }
1404 1419 | IPFY_IPOPT_ESEC { $$ = getoptbyvalue(IPOPT_E_SEC); }
1405 1420 | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); }
1406 1421 | IPFY_IPOPT_SATID { $$ = getoptbyvalue(IPOPT_SATID); }
1407 1422 | IPFY_IPOPT_SSRR { $$ = getoptbyvalue(IPOPT_SSRR); }
1408 1423 | IPFY_IPOPT_ADDEXT { $$ = getoptbyvalue(IPOPT_ADDEXT); }
1409 1424 | IPFY_IPOPT_VISA { $$ = getoptbyvalue(IPOPT_VISA); }
1410 1425 | IPFY_IPOPT_IMITD { $$ = getoptbyvalue(IPOPT_IMITD); }
1411 1426 | IPFY_IPOPT_EIP { $$ = getoptbyvalue(IPOPT_EIP); }
1412 1427 | IPFY_IPOPT_FINN { $$ = getoptbyvalue(IPOPT_FINN); }
1413 1428 | IPFY_IPOPT_DPS { $$ = getoptbyvalue(IPOPT_DPS); }
1414 1429 | IPFY_IPOPT_SDB { $$ = getoptbyvalue(IPOPT_SDB); }
1415 1430 | IPFY_IPOPT_NSAPA { $$ = getoptbyvalue(IPOPT_NSAPA); }
1416 1431 | IPFY_IPOPT_RTRALRT { $$ = getoptbyvalue(IPOPT_RTRALRT); }
1417 1432 | IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); }
1418 1433 | setsecclass secname
1419 1434 { DOALL(fr->fr_mip.fi_secmsk |= $2;
1420 1435 if (!nowith)
1421 1436 fr->fr_ip.fi_secmsk |= $2;)
1422 1437 $$ = 0;
1423 1438 yyresetdict();
1424 1439 }
1425 1440 ;
1426 1441
1427 1442 setsecclass:
1428 1443 IPFY_SECCLASS { yysetdict(ipv4secwords); }
1429 1444 ;
1430 1445
1431 1446 ipv6hdr:
1432 1447 IPFY_AH { $$ = getv6optbyvalue(IPPROTO_AH); }
1433 1448 | IPFY_IPV6OPT_DSTOPTS { $$ = getv6optbyvalue(IPPROTO_DSTOPTS); }
1434 1449 | IPFY_ESP { $$ = getv6optbyvalue(IPPROTO_ESP); }
1435 1450 | IPFY_IPV6OPT_HOPOPTS { $$ = getv6optbyvalue(IPPROTO_HOPOPTS); }
1436 1451 | IPFY_IPV6OPT_IPV6 { $$ = getv6optbyvalue(IPPROTO_IPV6); }
1437 1452 | IPFY_IPV6OPT_NONE { $$ = getv6optbyvalue(IPPROTO_NONE); }
1438 1453 | IPFY_IPV6OPT_ROUTING { $$ = getv6optbyvalue(IPPROTO_ROUTING); }
1439 1454 | IPFY_FRAG { $$ = getv6optbyvalue(IPPROTO_FRAGMENT); }
1440 1455 ;
1441 1456
1442 1457 level: IPFY_LEVEL { setsyslog(); }
1443 1458 ;
1444 1459
1445 1460 loglevel:
1446 1461 priority { fr->fr_loglevel = LOG_LOCAL0|$1; }
1447 1462 | facility '.' priority { fr->fr_loglevel = $1 | $3; }
1448 1463 ;
1449 1464
1450 1465 facility:
1451 1466 IPFY_FAC_KERN { $$ = LOG_KERN; }
1452 1467 | IPFY_FAC_USER { $$ = LOG_USER; }
1453 1468 | IPFY_FAC_MAIL { $$ = LOG_MAIL; }
1454 1469 | IPFY_FAC_DAEMON { $$ = LOG_DAEMON; }
1455 1470 | IPFY_FAC_AUTH { $$ = LOG_AUTH; }
1456 1471 | IPFY_FAC_SYSLOG { $$ = LOG_SYSLOG; }
1457 1472 | IPFY_FAC_LPR { $$ = LOG_LPR; }
1458 1473 | IPFY_FAC_NEWS { $$ = LOG_NEWS; }
1459 1474 | IPFY_FAC_UUCP { $$ = LOG_UUCP; }
1460 1475 | IPFY_FAC_CRON { $$ = LOG_CRON; }
1461 1476 | IPFY_FAC_FTP { $$ = LOG_FTP; }
1462 1477 | IPFY_FAC_AUTHPRIV { $$ = LOG_AUTHPRIV; }
1463 1478 | IPFY_FAC_AUDIT { $$ = LOG_AUDIT; }
1464 1479 | IPFY_FAC_LFMT { $$ = LOG_LFMT; }
1465 1480 | IPFY_FAC_LOCAL0 { $$ = LOG_LOCAL0; }
1466 1481 | IPFY_FAC_LOCAL1 { $$ = LOG_LOCAL1; }
1467 1482 | IPFY_FAC_LOCAL2 { $$ = LOG_LOCAL2; }
1468 1483 | IPFY_FAC_LOCAL3 { $$ = LOG_LOCAL3; }
1469 1484 | IPFY_FAC_LOCAL4 { $$ = LOG_LOCAL4; }
1470 1485 | IPFY_FAC_LOCAL5 { $$ = LOG_LOCAL5; }
1471 1486 | IPFY_FAC_LOCAL6 { $$ = LOG_LOCAL6; }
1472 1487 | IPFY_FAC_LOCAL7 { $$ = LOG_LOCAL7; }
1473 1488 | IPFY_FAC_SECURITY { $$ = LOG_SECURITY; }
1474 1489 ;
1475 1490
1476 1491 priority:
1477 1492 IPFY_PRI_EMERG { $$ = LOG_EMERG; }
1478 1493 | IPFY_PRI_ALERT { $$ = LOG_ALERT; }
1479 1494 | IPFY_PRI_CRIT { $$ = LOG_CRIT; }
1480 1495 | IPFY_PRI_ERR { $$ = LOG_ERR; }
1481 1496 | IPFY_PRI_WARN { $$ = LOG_WARNING; }
1482 1497 | IPFY_PRI_NOTICE { $$ = LOG_NOTICE; }
1483 1498 | IPFY_PRI_INFO { $$ = LOG_INFO; }
1484 1499 | IPFY_PRI_DEBUG { $$ = LOG_DEBUG; }
1485 1500 ;
1486 1501
1487 1502 compare:
1488 1503 YY_CMP_EQ { $$ = FR_EQUAL; }
1489 1504 | YY_CMP_NE { $$ = FR_NEQUAL; }
1490 1505 | YY_CMP_LT { $$ = FR_LESST; }
1491 1506 | YY_CMP_LE { $$ = FR_LESSTE; }
1492 1507 | YY_CMP_GT { $$ = FR_GREATERT; }
1493 1508 | YY_CMP_GE { $$ = FR_GREATERTE; }
1494 1509 ;
1495 1510
1496 1511 range: YY_RANGE_IN { $$ = FR_INRANGE; }
1497 1512 | YY_RANGE_OUT { $$ = FR_OUTRANGE; }
1498 1513 | ':' { $$ = FR_INCRANGE; }
1499 1514 ;
1500 1515
1501 1516 servicename:
1502 1517 YY_STR { $$ = $1; }
1503 1518 ;
1504 1519
1505 1520 interfacename: YY_STR { $$ = $1; }
1506 1521 | YY_STR ':' YY_NUMBER
1507 1522 { $$ = $1;
1508 1523 fprintf(stderr, "%d: Logical interface %s:%d unsupported, "
1509 1524 "use the physical interface %s instead.\n",
1510 1525 yylineNum, $1, $3, $1);
1511 1526 }
1512 1527 ;
1513 1528
1514 1529 name: YY_STR { $$ = $1; }
1515 1530 ;
1516 1531
1517 1532 ipv4_16:
1518 1533 YY_NUMBER '.' YY_NUMBER
1519 1534 { if ($1 > 255 || $3 > 255) {
1520 1535 yyerror("Invalid octet string for IP address");
1521 1536 return 0;
1522 1537 }
1523 1538 $$.s_addr = ($1 << 24) | ($3 << 16);
1524 1539 $$.s_addr = htonl($$.s_addr);
1525 1540 }
1526 1541 ;
1527 1542
1528 1543 ipv4_24:
1529 1544 ipv4_16 '.' YY_NUMBER
1530 1545 { if ($3 > 255) {
1531 1546 yyerror("Invalid octet string for IP address");
1532 1547 return 0;
1533 1548 }
1534 1549 $$.s_addr |= htonl($3 << 8);
1535 1550 }
1536 1551 ;
1537 1552
1538 1553 ipv4: ipv4_24 '.' YY_NUMBER
1539 1554 { if ($3 > 255) {
1540 1555 yyerror("Invalid octet string for IP address");
1541 1556 return 0;
1542 1557 }
1543 1558 $$.s_addr |= htonl($3);
1544 1559 }
1545 1560 | ipv4_24
1546 1561 | ipv4_16
1547 1562 ;
1548 1563
1549 1564 %%
1550 1565
1551 1566
1552 1567 static struct wordtab ipfwords[96] = {
1553 1568 { "age", IPFY_AGE },
1554 1569 { "ah", IPFY_AH },
1555 1570 { "all", IPFY_ALL },
1556 1571 { "and", IPFY_AND },
1557 1572 { "auth", IPFY_AUTH },
1558 1573 { "bad", IPFY_BAD },
|
↓ open down ↓ |
1004 lines elided |
↑ open up ↑ |
1559 1574 { "bad-nat", IPFY_BADNAT },
1560 1575 { "bad-src", IPFY_BADSRC },
1561 1576 { "bcast", IPFY_BROADCAST },
1562 1577 { "block", IPFY_BLOCK },
1563 1578 { "body", IPFY_BODY },
1564 1579 { "bpf-v4", IPFY_BPFV4 },
1565 1580 #ifdef USE_INET6
1566 1581 { "bpf-v6", IPFY_BPFV6 },
1567 1582 #endif
1568 1583 { "call", IPFY_CALL },
1584 + { "cfwlog", IPFY_CFWLOG },
1569 1585 { "code", IPFY_ICMPCODE },
1570 1586 { "count", IPFY_COUNT },
1571 1587 { "dup-to", IPFY_DUPTO },
1572 1588 { "eq", YY_CMP_EQ },
1573 1589 { "esp", IPFY_ESP },
1574 1590 { "fastroute", IPFY_FROUTE },
1575 1591 { "first", IPFY_FIRST },
1576 1592 { "flags", IPFY_FLAGS },
1577 1593 { "frag", IPFY_FRAG },
1578 1594 { "frag-body", IPFY_FRAGBODY },
1579 1595 { "frags", IPFY_FRAGS },
1580 1596 { "from", IPFY_FROM },
1581 1597 { "ge", YY_CMP_GE },
1582 1598 { "group", IPFY_GROUP },
1583 1599 { "gt", YY_CMP_GT },
1584 1600 { "head", IPFY_HEAD },
1585 1601 { "icmp", IPFY_ICMP },
1586 1602 { "icmp-type", IPFY_ICMPTYPE },
1587 1603 { "in", IPFY_IN },
1588 1604 { "in-via", IPFY_INVIA },
1589 1605 { "intercept_loopback", IPFY_SET_LOOPBACK },
1590 1606 { "ipopt", IPFY_IPOPTS },
1591 1607 { "ipopts", IPFY_IPOPTS },
1592 1608 { "keep", IPFY_KEEP },
1593 1609 { "le", YY_CMP_LE },
1594 1610 { "level", IPFY_LEVEL },
1595 1611 { "limit", IPFY_LIMIT },
1596 1612 { "log", IPFY_LOG },
1597 1613 { "lowttl", IPFY_LOWTTL },
1598 1614 { "lt", YY_CMP_LT },
1599 1615 { "mask", IPFY_MASK },
1600 1616 { "match-tag", IPFY_MATCHTAG },
1601 1617 { "mbcast", IPFY_MBCAST },
1602 1618 { "mcast", IPFY_MULTICAST },
1603 1619 { "multicast", IPFY_MULTICAST },
1604 1620 { "nat", IPFY_NAT },
1605 1621 { "ne", YY_CMP_NE },
1606 1622 { "net", IPFY_NETWORK },
1607 1623 { "newisn", IPFY_NEWISN },
1608 1624 { "no", IPFY_NO },
1609 1625 { "no-icmp-err", IPFY_NOICMPERR },
1610 1626 { "now", IPFY_NOW },
1611 1627 { "not", IPFY_NOT },
1612 1628 { "oow", IPFY_OOW },
1613 1629 { "on", IPFY_ON },
1614 1630 { "opt", IPFY_OPT },
1615 1631 { "or-block", IPFY_ORBLOCK },
1616 1632 { "out", IPFY_OUT },
1617 1633 { "out-via", IPFY_OUTVIA },
1618 1634 { "pass", IPFY_PASS },
1619 1635 { "port", IPFY_PORT },
1620 1636 { "pps", IPFY_PPS },
1621 1637 { "preauth", IPFY_PREAUTH },
1622 1638 { "proto", IPFY_PROTO },
1623 1639 { "quick", IPFY_QUICK },
1624 1640 { "reply-to", IPFY_REPLY_TO },
1625 1641 { "return-icmp", IPFY_RETICMP },
1626 1642 { "return-icmp-as-dest", IPFY_RETICMPASDST },
1627 1643 { "return-rst", IPFY_RETRST },
1628 1644 { "route-to", IPFY_ROUTETO },
1629 1645 { "sec-class", IPFY_SECCLASS },
1630 1646 { "set-tag", IPFY_SETTAG },
1631 1647 { "set", IPFY_SET },
1632 1648 { "skip", IPFY_SKIP },
1633 1649 { "short", IPFY_SHORT },
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
1634 1650 { "state", IPFY_STATE },
1635 1651 { "state-age", IPFY_AGE },
1636 1652 { "strict", IPFY_STRICT },
1637 1653 { "sync", IPFY_SYNC },
1638 1654 { "tcp", IPFY_TCP },
1639 1655 { "tcp-udp", IPFY_TCPUDP },
1640 1656 { "tos", IPFY_TOS },
1641 1657 { "to", IPFY_TO },
1642 1658 { "ttl", IPFY_TTL },
1643 1659 { "udp", IPFY_UDP },
1660 + { "uuid", IPFY_UUID },
1644 1661 { "v6hdrs", IPF6_V6HDRS },
1645 1662 { "with", IPFY_WITH },
1646 1663 { NULL, 0 }
1647 1664 };
1648 1665
1649 1666 static struct wordtab addrwords[4] = {
1650 1667 { "any", IPFY_ANY },
1651 1668 { "hash", IPFY_HASH },
1652 1669 { "pool", IPFY_POOL },
1653 1670 { NULL, 0 }
1654 1671 };
1655 1672
1656 1673 static struct wordtab maskwords[5] = {
1657 1674 { "broadcast", IPFY_BROADCAST },
1658 1675 { "netmasked", IPFY_NETMASKED },
1659 1676 { "network", IPFY_NETWORK },
1660 1677 { "peer", IPFY_PEER },
1661 1678 { NULL, 0 }
1662 1679 };
1663 1680
1664 1681 static struct wordtab icmptypewords[16] = {
1665 1682 { "echo", IPFY_ICMPT_ECHO },
1666 1683 { "echorep", IPFY_ICMPT_ECHOR },
1667 1684 { "inforeq", IPFY_ICMPT_INFOREQ },
1668 1685 { "inforep", IPFY_ICMPT_INFOREP },
1669 1686 { "maskrep", IPFY_ICMPT_MASKREP },
1670 1687 { "maskreq", IPFY_ICMPT_MASKREQ },
1671 1688 { "paramprob", IPFY_ICMPT_PARAMP },
1672 1689 { "redir", IPFY_ICMPT_REDIR },
1673 1690 { "unreach", IPFY_ICMPT_UNR },
1674 1691 { "routerad", IPFY_ICMPT_ROUTERAD },
1675 1692 { "routersol", IPFY_ICMPT_ROUTERSOL },
1676 1693 { "squench", IPFY_ICMPT_SQUENCH },
1677 1694 { "timest", IPFY_ICMPT_TIMEST },
1678 1695 { "timestrep", IPFY_ICMPT_TIMESTREP },
1679 1696 { "timex", IPFY_ICMPT_TIMEX },
1680 1697 { NULL, 0 },
1681 1698 };
1682 1699
1683 1700 static struct wordtab icmpcodewords[17] = {
1684 1701 { "cutoff-preced", IPFY_ICMPC_CUTPRE },
1685 1702 { "filter-prohib", IPFY_ICMPC_FLTPRO },
1686 1703 { "isolate", IPFY_ICMPC_ISOLATE },
1687 1704 { "needfrag", IPFY_ICMPC_NEEDF },
1688 1705 { "net-prohib", IPFY_ICMPC_NETPRO },
1689 1706 { "net-tos", IPFY_ICMPC_NETTOS },
1690 1707 { "host-preced", IPFY_ICMPC_HSTPRE },
1691 1708 { "host-prohib", IPFY_ICMPC_HSTPRO },
1692 1709 { "host-tos", IPFY_ICMPC_HSTTOS },
1693 1710 { "host-unk", IPFY_ICMPC_HSTUNK },
1694 1711 { "host-unr", IPFY_ICMPC_HSTUNR },
1695 1712 { "net-unk", IPFY_ICMPC_NETUNK },
1696 1713 { "net-unr", IPFY_ICMPC_NETUNR },
1697 1714 { "port-unr", IPFY_ICMPC_PORUNR },
1698 1715 { "proto-unr", IPFY_ICMPC_PROUNR },
1699 1716 { "srcfail", IPFY_ICMPC_SRCFAIL },
1700 1717 { NULL, 0 },
1701 1718 };
1702 1719
1703 1720 static struct wordtab ipv4optwords[25] = {
1704 1721 { "addext", IPFY_IPOPT_ADDEXT },
1705 1722 { "cipso", IPFY_IPOPT_CIPSO },
1706 1723 { "dps", IPFY_IPOPT_DPS },
1707 1724 { "e-sec", IPFY_IPOPT_ESEC },
1708 1725 { "eip", IPFY_IPOPT_EIP },
1709 1726 { "encode", IPFY_IPOPT_ENCODE },
1710 1727 { "finn", IPFY_IPOPT_FINN },
1711 1728 { "imitd", IPFY_IPOPT_IMITD },
1712 1729 { "lsrr", IPFY_IPOPT_LSRR },
1713 1730 { "mtup", IPFY_IPOPT_MTUP },
1714 1731 { "mtur", IPFY_IPOPT_MTUR },
1715 1732 { "nop", IPFY_IPOPT_NOP },
1716 1733 { "nsapa", IPFY_IPOPT_NSAPA },
1717 1734 { "rr", IPFY_IPOPT_RR },
1718 1735 { "rtralrt", IPFY_IPOPT_RTRALRT },
1719 1736 { "satid", IPFY_IPOPT_SATID },
1720 1737 { "sdb", IPFY_IPOPT_SDB },
1721 1738 { "sec", IPFY_IPOPT_SEC },
1722 1739 { "ssrr", IPFY_IPOPT_SSRR },
1723 1740 { "tr", IPFY_IPOPT_TR },
1724 1741 { "ts", IPFY_IPOPT_TS },
1725 1742 { "ump", IPFY_IPOPT_UMP },
1726 1743 { "visa", IPFY_IPOPT_VISA },
1727 1744 { "zsu", IPFY_IPOPT_ZSU },
1728 1745 { NULL, 0 },
1729 1746 };
1730 1747
1731 1748 static struct wordtab ipv4secwords[9] = {
1732 1749 { "confid", IPFY_SEC_CONF },
1733 1750 { "reserv-1", IPFY_SEC_RSV1 },
1734 1751 { "reserv-2", IPFY_SEC_RSV2 },
1735 1752 { "reserv-3", IPFY_SEC_RSV3 },
1736 1753 { "reserv-4", IPFY_SEC_RSV4 },
1737 1754 { "secret", IPFY_SEC_SEC },
1738 1755 { "topsecret", IPFY_SEC_TS },
1739 1756 { "unclass", IPFY_SEC_UNC },
1740 1757 { NULL, 0 },
1741 1758 };
1742 1759
1743 1760 static struct wordtab ipv6optwords[8] = {
1744 1761 { "dstopts", IPFY_IPV6OPT_DSTOPTS },
1745 1762 { "esp", IPFY_ESP },
1746 1763 { "frag", IPFY_FRAG },
1747 1764 { "hopopts", IPFY_IPV6OPT_HOPOPTS },
1748 1765 { "ipv6", IPFY_IPV6OPT_IPV6 },
1749 1766 { "none", IPFY_IPV6OPT_NONE },
1750 1767 { "routing", IPFY_IPV6OPT_ROUTING },
1751 1768 { NULL, 0 },
1752 1769 };
1753 1770
1754 1771 static struct wordtab logwords[33] = {
1755 1772 { "kern", IPFY_FAC_KERN },
1756 1773 { "user", IPFY_FAC_USER },
1757 1774 { "mail", IPFY_FAC_MAIL },
1758 1775 { "daemon", IPFY_FAC_DAEMON },
1759 1776 { "auth", IPFY_FAC_AUTH },
1760 1777 { "syslog", IPFY_FAC_SYSLOG },
1761 1778 { "lpr", IPFY_FAC_LPR },
1762 1779 { "news", IPFY_FAC_NEWS },
1763 1780 { "uucp", IPFY_FAC_UUCP },
1764 1781 { "cron", IPFY_FAC_CRON },
1765 1782 { "ftp", IPFY_FAC_FTP },
1766 1783 { "authpriv", IPFY_FAC_AUTHPRIV },
1767 1784 { "audit", IPFY_FAC_AUDIT },
1768 1785 { "logalert", IPFY_FAC_LFMT },
1769 1786 { "console", IPFY_FAC_CONSOLE },
1770 1787 { "security", IPFY_FAC_SECURITY },
1771 1788 { "local0", IPFY_FAC_LOCAL0 },
1772 1789 { "local1", IPFY_FAC_LOCAL1 },
1773 1790 { "local2", IPFY_FAC_LOCAL2 },
1774 1791 { "local3", IPFY_FAC_LOCAL3 },
1775 1792 { "local4", IPFY_FAC_LOCAL4 },
1776 1793 { "local5", IPFY_FAC_LOCAL5 },
1777 1794 { "local6", IPFY_FAC_LOCAL6 },
1778 1795 { "local7", IPFY_FAC_LOCAL7 },
1779 1796 { "emerg", IPFY_PRI_EMERG },
1780 1797 { "alert", IPFY_PRI_ALERT },
1781 1798 { "crit", IPFY_PRI_CRIT },
1782 1799 { "err", IPFY_PRI_ERR },
1783 1800 { "warn", IPFY_PRI_WARN },
1784 1801 { "notice", IPFY_PRI_NOTICE },
1785 1802 { "info", IPFY_PRI_INFO },
1786 1803 { "debug", IPFY_PRI_DEBUG },
1787 1804 { NULL, 0 },
1788 1805 };
1789 1806
1790 1807
1791 1808
1792 1809
1793 1810 int ipf_parsefile(fd, addfunc, iocfuncs, filename)
1794 1811 int fd;
1795 1812 addfunc_t addfunc;
1796 1813 ioctlfunc_t *iocfuncs;
1797 1814 char *filename;
1798 1815 {
1799 1816 FILE *fp = NULL;
1800 1817 char *s;
1801 1818
1802 1819 yylineNum = 1;
1803 1820 yysettab(ipfwords);
1804 1821
1805 1822 s = getenv("YYDEBUG");
1806 1823 if (s != NULL)
1807 1824 yydebug = atoi(s);
1808 1825 else
1809 1826 yydebug = 0;
1810 1827
1811 1828 if (strcmp(filename, "-")) {
1812 1829 fp = fopen(filename, "r");
1813 1830 if (fp == NULL) {
1814 1831 fprintf(stderr, "fopen(%s) failed: %s\n", filename,
1815 1832 STRERROR(errno));
1816 1833 return -1;
1817 1834 }
1818 1835 } else
1819 1836 fp = stdin;
1820 1837
1821 1838 while (ipf_parsesome(fd, addfunc, iocfuncs, fp) == 1)
1822 1839 ;
1823 1840 if (fp != NULL)
1824 1841 fclose(fp);
1825 1842 return 0;
1826 1843 }
1827 1844
1828 1845
1829 1846 int ipf_parsesome(fd, addfunc, iocfuncs, fp)
1830 1847 int fd;
1831 1848 addfunc_t addfunc;
1832 1849 ioctlfunc_t *iocfuncs;
1833 1850 FILE *fp;
1834 1851 {
1835 1852 char *s;
1836 1853 int i;
1837 1854
1838 1855 ipffd = fd;
1839 1856 for (i = 0; i <= IPL_LOGMAX; i++)
1840 1857 ipfioctl[i] = iocfuncs[i];
1841 1858 ipfaddfunc = addfunc;
1842 1859
1843 1860 if (feof(fp))
1844 1861 return 0;
1845 1862 i = fgetc(fp);
1846 1863 if (i == EOF)
1847 1864 return 0;
1848 1865 if (ungetc(i, fp) == 0)
1849 1866 return 0;
1850 1867 if (feof(fp))
1851 1868 return 0;
1852 1869 s = getenv("YYDEBUG");
1853 1870 if (s != NULL)
1854 1871 yydebug = atoi(s);
1855 1872 else
1856 1873 yydebug = 0;
1857 1874
1858 1875 yyin = fp;
1859 1876 yyparse();
1860 1877 return 1;
1861 1878 }
1862 1879
1863 1880
1864 1881 static void newrule()
1865 1882 {
1866 1883 frentry_t *frn;
1867 1884
1868 1885 frn = (frentry_t *)calloc(1, sizeof(frentry_t));
1869 1886 if (frn == NULL)
1870 1887 yyerror("sorry, out of memory");
1871 1888 for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next)
1872 1889 ;
1873 1890 if (fr != NULL)
1874 1891 fr->fr_next = frn;
1875 1892 if (frtop == NULL)
1876 1893 frtop = frn;
1877 1894 fr = frn;
1878 1895 frc = frn;
1879 1896 fr->fr_loglevel = 0xffff;
1880 1897 fr->fr_isc = (void *)-1;
1881 1898 fr->fr_logtag = FR_NOLOGTAG;
1882 1899 fr->fr_type = FR_T_NONE;
1883 1900 if (use_inet6 != 0)
1884 1901 fr->fr_v = 6;
1885 1902 else
1886 1903 fr->fr_v = 4;
1887 1904
1888 1905 nrules = 1;
1889 1906 }
1890 1907
1891 1908
1892 1909 static void setipftype()
1893 1910 {
1894 1911 for (fr = frc; fr != NULL; fr = fr->fr_next) {
1895 1912 if (fr->fr_type == FR_T_NONE) {
1896 1913 fr->fr_type = FR_T_IPF;
1897 1914 fr->fr_data = (void *)calloc(sizeof(fripf_t), 1);
1898 1915 if (fr->fr_data == NULL)
1899 1916 yyerror("sorry, out of memory");
1900 1917 fr->fr_dsize = sizeof(fripf_t);
1901 1918 fr->fr_ip.fi_v = frc->fr_v;
1902 1919 fr->fr_mip.fi_v = 0xf;
1903 1920 fr->fr_ipf->fri_sifpidx = -1;
1904 1921 fr->fr_ipf->fri_difpidx = -1;
1905 1922 }
1906 1923 if (fr->fr_type != FR_T_IPF) {
1907 1924 fprintf(stderr, "IPF Type not set\n");
1908 1925 }
1909 1926 }
1910 1927 }
1911 1928
1912 1929
1913 1930 static frentry_t *addrule()
1914 1931 {
1915 1932 frentry_t *f, *f1, *f2;
1916 1933 int count;
1917 1934
1918 1935 for (f2 = frc; f2->fr_next != NULL; f2 = f2->fr_next)
1919 1936 ;
1920 1937
1921 1938 count = nrules;
1922 1939 if (count == 0) {
1923 1940 f = (frentry_t *)calloc(sizeof(*f), 1);
1924 1941 if (f == NULL)
1925 1942 yyerror("sorry, out of memory");
1926 1943 added++;
1927 1944 f2->fr_next = f;
1928 1945 bcopy(f2, f, sizeof(*f));
1929 1946 if (f2->fr_caddr != NULL) {
1930 1947 f->fr_caddr = malloc(f->fr_dsize);
1931 1948 if (f->fr_caddr == NULL)
1932 1949 yyerror("sorry, out of memory");
1933 1950 bcopy(f2->fr_caddr, f->fr_caddr, f->fr_dsize);
1934 1951 }
1935 1952 f->fr_next = NULL;
1936 1953 return f;
1937 1954 }
1938 1955 f = f2;
1939 1956 for (f1 = frc; count > 0; count--, f1 = f1->fr_next) {
1940 1957 f->fr_next = (frentry_t *)calloc(sizeof(*f), 1);
1941 1958 if (f->fr_next == NULL)
1942 1959 yyerror("sorry, out of memory");
1943 1960 added++;
1944 1961 f = f->fr_next;
1945 1962 bcopy(f1, f, sizeof(*f));
1946 1963 f->fr_next = NULL;
1947 1964 if (f->fr_caddr != NULL) {
1948 1965 f->fr_caddr = malloc(f->fr_dsize);
1949 1966 if (f->fr_caddr == NULL)
1950 1967 yyerror("sorry, out of memory");
1951 1968 bcopy(f1->fr_caddr, f->fr_caddr, f->fr_dsize);
1952 1969 }
1953 1970 }
1954 1971
1955 1972 return f2->fr_next;
1956 1973 }
1957 1974
1958 1975
1959 1976 static u_32_t lookuphost(name, addr)
1960 1977 char *name;
1961 1978 i6addr_t *addr;
1962 1979 {
1963 1980 int i;
1964 1981
1965 1982 hashed = 0;
1966 1983 pooled = 0;
1967 1984 dynamic = -1;
1968 1985
1969 1986 for (i = 0; i < 4; i++) {
1970 1987 if (strncmp(name, frc->fr_ifnames[i],
1971 1988 sizeof(frc->fr_ifnames[i])) == 0) {
1972 1989 ifpflag = FRI_DYNAMIC;
1973 1990 dynamic = i;
1974 1991 return 0;
1975 1992 }
1976 1993 }
1977 1994
1978 1995 if (gethost(name, addr, use_inet6) == -1) {
1979 1996 fprintf(stderr, "unknown name \"%s\"\n", name);
1980 1997 return 0;
1981 1998 }
1982 1999 return 1;
1983 2000 }
1984 2001
1985 2002
1986 2003 static void dobpf(v, phrase)
1987 2004 int v;
1988 2005 char *phrase;
1989 2006 {
1990 2007 #ifdef IPFILTER_BPF
1991 2008 struct bpf_program bpf;
1992 2009 struct pcap *p;
1993 2010 #endif
1994 2011 fakebpf_t *fb;
1995 2012 u_32_t l;
1996 2013 char *s;
1997 2014 int i;
1998 2015
1999 2016 for (fr = frc; fr != NULL; fr = fr->fr_next) {
2000 2017 if (fr->fr_type != FR_T_NONE) {
2001 2018 fprintf(stderr, "cannot mix IPF and BPF matching\n");
2002 2019 return;
2003 2020 }
2004 2021 fr->fr_v = v;
2005 2022 fr->fr_type = FR_T_BPFOPC;
2006 2023
2007 2024 if (!strncmp(phrase, "\"0x", 2)) {
2008 2025 phrase++;
2009 2026 fb = malloc(sizeof(fakebpf_t));
2010 2027 if (fb == NULL)
2011 2028 yyerror("sorry, out of memory");
2012 2029
2013 2030 for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL;
2014 2031 s = strtok(NULL, " \r\n\t"), i++) {
2015 2032 fb = realloc(fb, (i / 4 + 1) * sizeof(*fb));
2016 2033 if (fb == NULL)
2017 2034 yyerror("sorry, out of memory");
2018 2035 l = (u_32_t)strtol(s, NULL, 0);
2019 2036 switch (i & 3)
2020 2037 {
2021 2038 case 0 :
2022 2039 fb[i / 4].fb_c = l & 0xffff;
2023 2040 break;
2024 2041 case 1 :
2025 2042 fb[i / 4].fb_t = l & 0xff;
2026 2043 break;
2027 2044 case 2 :
2028 2045 fb[i / 4].fb_f = l & 0xff;
2029 2046 break;
2030 2047 case 3 :
2031 2048 fb[i / 4].fb_k = l;
2032 2049 break;
2033 2050 }
2034 2051 }
2035 2052 if ((i & 3) != 0) {
2036 2053 fprintf(stderr,
2037 2054 "Odd number of bytes in BPF code\n");
2038 2055 exit(1);
2039 2056 }
2040 2057 i--;
2041 2058 fr->fr_dsize = (i / 4 + 1) * sizeof(*fb);
2042 2059 fr->fr_data = fb;
2043 2060 return;
2044 2061 }
2045 2062
2046 2063 #ifdef IPFILTER_BPF
2047 2064 bzero((char *)&bpf, sizeof(bpf));
2048 2065 p = pcap_open_dead(DLT_RAW, 1);
2049 2066 if (!p) {
2050 2067 fprintf(stderr, "pcap_open_dead failed\n");
2051 2068 return;
2052 2069 }
2053 2070
2054 2071 if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) {
2055 2072 pcap_perror(p, "ipf");
2056 2073 pcap_close(p);
2057 2074 fprintf(stderr, "pcap parsing failed (%s)\n", phrase);
2058 2075 return;
2059 2076 }
2060 2077 pcap_close(p);
2061 2078
2062 2079 fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn);
2063 2080 fr->fr_data = malloc(fr->fr_dsize);
2064 2081 if (fr->fr_data == NULL)
2065 2082 yyerror("sorry, out of memory");
2066 2083 bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize);
2067 2084 if (!bpf_validate(fr->fr_data, bpf.bf_len)) {
2068 2085 fprintf(stderr, "BPF validation failed\n");
2069 2086 return;
2070 2087 }
2071 2088 #endif
2072 2089 }
2073 2090
2074 2091 #ifdef IPFILTER_BPF
2075 2092 if (opts & OPT_DEBUG)
2076 2093 bpf_dump(&bpf, 0);
2077 2094 #else
2078 2095 fprintf(stderr, "BPF filter expressions not supported\n");
2079 2096 exit(1);
2080 2097 #endif
2081 2098 }
2082 2099
2083 2100
2084 2101 static void resetaddr()
2085 2102 {
2086 2103 hashed = 0;
2087 2104 pooled = 0;
2088 2105 dynamic = -1;
2089 2106 }
2090 2107
2091 2108
2092 2109 static alist_t *newalist(ptr)
2093 2110 alist_t *ptr;
2094 2111 {
2095 2112 alist_t *al;
2096 2113
2097 2114 al = malloc(sizeof(*al));
2098 2115 if (al == NULL)
2099 2116 return NULL;
2100 2117 al->al_not = 0;
2101 2118 al->al_next = ptr;
2102 2119 return al;
2103 2120 }
2104 2121
2105 2122
2106 2123 static int makepool(list)
2107 2124 alist_t *list;
2108 2125 {
2109 2126 ip_pool_node_t *n, *top;
2110 2127 ip_pool_t pool;
2111 2128 alist_t *a;
2112 2129 int num;
2113 2130
2114 2131 if (list == NULL)
2115 2132 return 0;
2116 2133 top = calloc(1, sizeof(*top));
2117 2134 if (top == NULL)
2118 2135 return 0;
2119 2136
2120 2137 for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
2121 2138 n->ipn_addr.adf_family = a->al_family;
2122 2139 n->ipn_mask.adf_family = a->al_family;
2123 2140 (void *)bcopy((void *)&a->al_i6addr,
2124 2141 (void *)&n->ipn_addr.adf_addr,
2125 2142 sizeof(n->ipn_addr.adf_addr));
2126 2143 (void *)bcopy((void *)&a->al_i6mask,
2127 2144 (void *)&n->ipn_mask.adf_addr,
2128 2145 sizeof(n->ipn_mask.adf_addr));
2129 2146 n->ipn_info = a->al_not;
2130 2147 if (a->al_next != NULL) {
2131 2148 n->ipn_next = calloc(1, sizeof(*n));
2132 2149 if (n->ipn_next == NULL)
2133 2150 yyerror("sorry, out of memory");
2134 2151 n = n->ipn_next;
2135 2152 }
2136 2153 }
2137 2154
2138 2155 bzero((char *)&pool, sizeof(pool));
2139 2156 pool.ipo_unit = IPL_LOGIPF;
2140 2157 pool.ipo_list = top;
2141 2158 num = load_pool(&pool, ipfioctl[IPL_LOGLOOKUP]);
2142 2159
2143 2160 while ((n = top) != NULL) {
2144 2161 top = n->ipn_next;
2145 2162 free(n);
2146 2163 }
2147 2164 return num;
2148 2165 }
2149 2166
2150 2167
2151 2168 static u_int makehash(list)
2152 2169 alist_t *list;
2153 2170 {
2154 2171 iphtent_t *n, *top;
2155 2172 iphtable_t iph;
2156 2173 alist_t *a;
2157 2174 int num;
2158 2175
2159 2176 if (list == NULL)
2160 2177 return 0;
2161 2178 top = calloc(1, sizeof(*top));
2162 2179 if (top == NULL)
2163 2180 return 0;
2164 2181
2165 2182 for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
2166 2183 n->ipe_family = a->al_family;
2167 2184 (void *)bcopy((void *)&a->al_i6addr,
2168 2185 (void *)&n->ipe_addr,
2169 2186 sizeof(n->ipe_addr));
2170 2187 (void *)bcopy((void *)&a->al_i6mask,
2171 2188 (void *)&n->ipe_mask,
2172 2189 sizeof(n->ipe_mask));
2173 2190 n->ipe_value = 0;
2174 2191 if (a->al_next != NULL) {
2175 2192 n->ipe_next = calloc(1, sizeof(*n));
2176 2193 if (n->ipe_next == NULL)
2177 2194 yyerror("sorry, out of memory");
2178 2195 n = n->ipe_next;
2179 2196 }
2180 2197 }
2181 2198
2182 2199 bzero((char *)&iph, sizeof(iph));
2183 2200 iph.iph_unit = IPL_LOGIPF;
2184 2201 iph.iph_type = IPHASH_LOOKUP;
2185 2202 *iph.iph_name = '\0';
2186 2203
2187 2204 if (load_hash(&iph, top, ipfioctl[IPL_LOGLOOKUP]) == 0)
2188 2205 sscanf(iph.iph_name, "%u", &num);
2189 2206 else
2190 2207 num = 0;
2191 2208
2192 2209 while ((n = top) != NULL) {
2193 2210 top = n->ipe_next;
2194 2211 free(n);
2195 2212 }
2196 2213 return num;
2197 2214 }
2198 2215
2199 2216
2200 2217 void ipf_addrule(fd, ioctlfunc, ptr)
2201 2218 int fd;
2202 2219 ioctlfunc_t ioctlfunc;
2203 2220 void *ptr;
2204 2221 {
2205 2222 ioctlcmd_t add, del;
2206 2223 frentry_t *fr;
2207 2224 ipfobj_t obj;
2208 2225
2209 2226 fr = ptr;
2210 2227 add = 0;
2211 2228 del = 0;
2212 2229
2213 2230 bzero((char *)&obj, sizeof(obj));
2214 2231 obj.ipfo_rev = IPFILTER_VERSION;
2215 2232 obj.ipfo_size = sizeof(*fr);
2216 2233 obj.ipfo_type = IPFOBJ_FRENTRY;
2217 2234 obj.ipfo_ptr = ptr;
2218 2235
2219 2236 if ((opts & OPT_DONOTHING) != 0)
2220 2237 fd = -1;
2221 2238
2222 2239 if (opts & OPT_ZERORULEST) {
2223 2240 add = SIOCZRLST;
2224 2241 } else if (opts & OPT_INACTIVE) {
2225 2242 add = (u_int)fr->fr_hits ? SIOCINIFR :
2226 2243 SIOCADIFR;
2227 2244 del = SIOCRMIFR;
2228 2245 } else {
2229 2246 add = (u_int)fr->fr_hits ? SIOCINAFR :
2230 2247 SIOCADAFR;
2231 2248 del = SIOCRMAFR;
2232 2249 }
2233 2250
2234 2251 if (fr && (opts & OPT_OUTQUE))
2235 2252 fr->fr_flags |= FR_OUTQUE;
2236 2253 if (fr->fr_hits)
2237 2254 fr->fr_hits--;
2238 2255 if (fr && (opts & OPT_VERBOSE))
2239 2256 printfr(fr, ioctlfunc);
2240 2257
2241 2258 if (opts & OPT_DEBUG) {
2242 2259 binprint(fr, sizeof(*fr));
2243 2260 if (fr->fr_data != NULL)
2244 2261 binprint(fr->fr_data, fr->fr_dsize);
2245 2262 }
2246 2263
2247 2264 if ((opts & OPT_ZERORULEST) != 0) {
2248 2265 if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
2249 2266 if ((opts & OPT_DONOTHING) == 0) {
2250 2267 fprintf(stderr, "%d:", yylineNum);
2251 2268 perror("ioctl(SIOCZRLST)");
2252 2269 }
2253 2270 } else {
2254 2271 #ifdef USE_QUAD_T
2255 2272 printf("hits %qd bytes %qd ",
2256 2273 (long long)fr->fr_hits,
2257 2274 (long long)fr->fr_bytes);
2258 2275 #else
2259 2276 printf("hits %ld bytes %ld ",
2260 2277 fr->fr_hits, fr->fr_bytes);
2261 2278 #endif
2262 2279 printfr(fr, ioctlfunc);
2263 2280 }
2264 2281 } else if ((opts & OPT_REMOVE) != 0) {
2265 2282 if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
2266 2283 if ((opts & OPT_DONOTHING) != 0) {
2267 2284 fprintf(stderr, "%d:", yylineNum);
2268 2285 perror("ioctl(delete rule)");
2269 2286 }
2270 2287 }
2271 2288 } else {
2272 2289 if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
2273 2290 if (!(opts & OPT_DONOTHING)) {
2274 2291 fprintf(stderr, "%d:", yylineNum);
2275 2292 perror("ioctl(add/insert rule)");
2276 2293 }
2277 2294 }
2278 2295 }
2279 2296 }
2280 2297
2281 2298 static void setsyslog()
2282 2299 {
2283 2300 yysetdict(logwords);
2284 2301 yybreakondot = 1;
2285 2302 }
2286 2303
2287 2304
2288 2305 static void unsetsyslog()
2289 2306 {
2290 2307 yyresetdict();
2291 2308 yybreakondot = 0;
2292 2309 }
2293 2310
2294 2311
2295 2312 static void fillgroup(fr)
2296 2313 frentry_t *fr;
2297 2314 {
2298 2315 frentry_t *f;
2299 2316
2300 2317 for (f = frold; f != NULL; f = f->fr_next)
2301 2318 if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0)
2302 2319 break;
2303 2320 if (f == NULL)
2304 2321 return;
2305 2322
2306 2323 /*
2307 2324 * Only copy down matching fields if the rules are of the same type
2308 2325 * and are of ipf type. The only fields that are copied are those
2309 2326 * that impact the rule parsing itself, eg. need for knowing what the
2310 2327 * protocol should be for rules with port comparisons in them.
2311 2328 */
2312 2329 if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF)
2313 2330 return;
2314 2331
2315 2332 if (fr->fr_v == 0 && f->fr_v != 0)
2316 2333 fr->fr_v = f->fr_v;
2317 2334
2318 2335 if (fr->fr_mproto == 0 && f->fr_mproto != 0)
2319 2336 fr->fr_mproto = f->fr_mproto;
2320 2337 if (fr->fr_proto == 0 && f->fr_proto != 0)
2321 2338 fr->fr_proto = f->fr_proto;
2322 2339
2323 2340 if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) &&
2324 2341 ((f->fr_flx & FI_TCPUDP) != 0))
2325 2342 fr->fr_flx |= FI_TCPUDP;
2326 2343 }
|
↓ open down ↓ |
673 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX