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