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