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