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/ipnat_y.y
          +++ new/usr/src/cmd/ipf/tools/ipnat_y.y
   1    1  %{
   2    2  /*
   3    3   * Copyright (C) 2001-2008 by Darren Reed.
   4    4   *
   5    5   * See the IPFILTER.LICENCE file for details on licencing.
   6    6   *
   7    7   * Copyright 2008 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  #pragma ident   "%Z%%M% %I%     %E% SMI"
  12   13  
  13   14  #ifdef  __FreeBSD__
  14   15  # ifndef __FreeBSD_cc_version
  15   16  #  include <osreldate.h>
  16   17  # else
  17   18  #  if __FreeBSD_cc_version < 430000
  18   19  #   include <osreldate.h>
  19   20  #  endif
  20   21  # endif
  21   22  #endif
  22   23  #include <stdio.h>
  23   24  #include <unistd.h>
  24   25  #include <string.h>
  25   26  #include <fcntl.h>
  26   27  #include <errno.h>
  27   28  #if !defined(__SVR4) && !defined(__GNUC__)
  28   29  #include <strings.h>
  29   30  #endif
  30   31  #include <sys/types.h>
  31   32  #include <sys/param.h>
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  32   33  #include <sys/file.h>
  33   34  #include <stdlib.h>
  34   35  #include <stddef.h>
  35   36  #include <sys/socket.h>
  36   37  #include <sys/ioctl.h>
  37   38  #include <netinet/in.h>
  38   39  #include <netinet/in_systm.h>
  39   40  #include <sys/time.h>
  40   41  #include <syslog.h>
  41   42  #include <net/if.h>
       43 +#include <uuid/uuid.h>
  42   44  #if __FreeBSD_version >= 300000
  43   45  # include <net/if_var.h>
  44   46  #endif
  45   47  #include <netdb.h>
  46   48  #include <arpa/nameser.h>
  47   49  #include <resolv.h>
  48   50  #include "ipf.h"
  49   51  #include "netinet/ipl.h"
  50   52  #include "ipnat_l.h"
  51   53  
  52   54  #define YYDEBUG 1
  53   55  
  54   56  extern  void    yyerror __P((char *));
  55   57  extern  int     yyparse __P((void));
  56   58  extern  int     yylex __P((void));
  57   59  extern  int     yydebug;
  58   60  extern  FILE    *yyin;
  59   61  extern  int     yylineNum;
  60   62  
  61   63  static  ipnat_t         *nattop = NULL;
  62   64  static  ipnat_t         *nat = NULL;
  63   65  static  int             natfd = -1;
  64   66  static  ioctlfunc_t     natioctlfunc = NULL;
  65   67  static  addfunc_t       nataddfunc = NULL;
  66   68  
  67   69  static  void    newnatrule __P((void));
  68   70  static  void    setnatproto __P((int));
  69   71  
  70   72  %}
  71   73  %union  {
  72   74          char    *str;
  73   75          u_32_t  num;
  74   76          struct  {
  75   77                  i6addr_t        a;
  76   78                  int             v;
  77   79          } ipa;
  78   80          frentry_t       fr;
  79   81          frtuc_t *frt;
  80   82          u_short port;
  81   83          struct  {
  
    | 
      ↓ open down ↓ | 
    30 lines elided | 
    
      ↑ open up ↑ | 
  
  82   84                  u_short p1;
  83   85                  u_short p2;
  84   86                  int     pc;
  85   87          } pc;
  86   88          struct  {
  87   89                  i6addr_t        a;
  88   90                  i6addr_t        m;
  89   91                  int     v;
  90   92          } ipp;
  91   93          union   i6addr  ip6;
       94 +        uuid_t  uuid;
  92   95  };
  93   96  
  94   97  %token  <num>   YY_NUMBER YY_HEX
  95   98  %token  <str>   YY_STR
  96   99  %token    YY_COMMENT 
  97  100  %token    YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
  98  101  %token    YY_RANGE_OUT YY_RANGE_IN
  99  102  %token  <ip6>   YY_IPV6
      103 +%token  <uuid>  YY_UUID
 100  104  
 101  105  %token  IPNY_MAPBLOCK IPNY_RDR IPNY_PORT IPNY_PORTS IPNY_AUTO IPNY_RANGE
 102  106  %token  IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY
 103  107  %token  IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY
 104  108  %token  IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG
 105  109  %token  IPNY_TLATE IPNY_SEQUENTIAL
 106  110  %type   <port> portspec
 107  111  %type   <num> hexnumber compare range proto
 108  112  %type   <num> saddr daddr sobject dobject mapfrom rdrfrom dip
 109  113  %type   <ipa> hostname ipv4 ipaddr
 110  114  %type   <ipp> addr rhaddr
 111  115  %type   <pc> portstuff
 112  116  %%
 113  117  file:   line
 114  118          | assign
 115  119          | file line
 116  120          | file assign
 117  121          ;
 118  122  
 119  123  line:   xx rule         { while ((nat = nattop) != NULL) {
 120  124                                  if (nat->in_v == 0)
 121  125                                          nat->in_v = 4;
 122  126                                  nattop = nat->in_next;
 123  127                                  (*nataddfunc)(natfd, natioctlfunc, nat);
 124  128                                  free(nat);
 125  129                            }
 126  130                            resetlexer();
 127  131                          }
 128  132          | YY_COMMENT
 129  133          ;
 130  134  
 131  135  assign: YY_STR assigning YY_STR ';'     { set_variable($1, $3);
 132  136                                            resetlexer();
 133  137                                            free($1);
 134  138                                            free($3);
 135  139                                          }
 136  140          ;
 137  141  
 138  142  assigning:
 139  143          '='                             { yyvarnext = 1; }
 140  144          ;
 141  145  
 142  146  xx:                                     { newnatrule(); }
 143  147          ;
 144  148  
 145  149  rule:   map eol
 146  150          | mapblock eol
 147  151          | redir eol
 148  152          ;
 149  153  
 150  154  eol:    | ';'
 151  155          ;
 152  156  
 153  157  map:    mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
 154  158                                  { if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
 155  159                                          yyerror("1.address family mismatch");
 156  160                                    bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
 157  161                                    bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
 158  162                                    bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
 159  163                                    bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
 160  164                                    if (nat->in_ifnames[1][0] == '\0')
 161  165                                          strncpy(nat->in_ifnames[1],
 162  166                                                  nat->in_ifnames[0],
 163  167                                                  sizeof(nat->in_ifnames[0]));
 164  168                                    if ((nat->in_flags & IPN_TCPUDP) == 0)
 165  169                                          setnatproto(nat->in_p);
 166  170                                    if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 167  171                                        ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
 168  172                                          nat_setgroupmap(nat);
 169  173                                  }
 170  174          | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions
 171  175                                  { if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
 172  176                                          yyerror("2.address family mismatch");
 173  177                                    bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
 174  178                                    bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
 175  179                                    bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
 176  180                                    bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
 177  181                                    if (nat->in_ifnames[1][0] == '\0')
 178  182                                          strncpy(nat->in_ifnames[1],
 179  183                                                  nat->in_ifnames[0],
 180  184                                                  sizeof(nat->in_ifnames[0]));
 181  185                                    if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
 182  186                                          setnatproto(nat->in_p);
 183  187                                    if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 184  188                                        ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
 185  189                                          nat_setgroupmap(nat);
 186  190                                  }
 187  191          | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions
 188  192                                  { if ($3 != 0 && $3 != $5.v && $5.v != 0)
 189  193                                          yyerror("3.address family mismatch");
 190  194                                    bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
 191  195                                    bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
 192  196                                    if (nat->in_ifnames[1][0] == '\0')
 193  197                                          strncpy(nat->in_ifnames[1],
 194  198                                                  nat->in_ifnames[0],
 195  199                                                  sizeof(nat->in_ifnames[0]));
 196  200                                    if ((nat->in_flags & IPN_TCPUDP) == 0)
 197  201                                          setnatproto(nat->in_p);
 198  202                                    if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 199  203                                        ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
 200  204                                          nat_setgroupmap(nat);
 201  205                                  }
 202  206          | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions
 203  207                                  { if ($3 != 0 && $3 != $5.v && $5.v != 0)
 204  208                                          yyerror("4.address family mismatch");
 205  209                                    bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
 206  210                                    bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
 207  211                                    if (nat->in_ifnames[1][0] == '\0')
 208  212                                          strncpy(nat->in_ifnames[1],
 209  213                                                  nat->in_ifnames[0],
 210  214                                                  sizeof(nat->in_ifnames[0]));
 211  215                                    if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
 212  216                                          setnatproto(nat->in_p);
 213  217                                    if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 214  218                                        ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
 215  219                                          nat_setgroupmap(nat);
 216  220                                  }
 217  221          ;
 218  222  
 219  223  mapblock:
 220  224          mapblockit ifnames addr IPNY_TLATE addr ports mapoptions
 221  225                                  { if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
 222  226                                          yyerror("5.address family mismatch");
 223  227                                    bcopy(&$3.a, &nat->in_in[0], sizeof($3.a));
 224  228                                    bcopy(&$3.m, &nat->in_in[1], sizeof($3.a));
 225  229                                    bcopy(&$5.a, &nat->in_out[0], sizeof($5.a));
 226  230                                    bcopy(&$5.m, &nat->in_out[1], sizeof($5.a));
 227  231                                    if (nat->in_ifnames[1][0] == '\0')
 228  232                                          strncpy(nat->in_ifnames[1],
 229  233                                                  nat->in_ifnames[0],
 230  234                                                  sizeof(nat->in_ifnames[0]));
 231  235                                    if ((nat->in_flags & IPN_TCPUDP) == 0)
 232  236                                          setnatproto(nat->in_p);
 233  237                                    if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 234  238                                        ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
 235  239                                          nat_setgroupmap(nat);
 236  240                                  }
 237  241          ;
 238  242  
 239  243  redir:  rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions
 240  244                                  { if ($6 != 0 && $3.v != 0 && $6 != $3.v)
 241  245                                          yyerror("6.address family mismatch");
 242  246                                    bcopy(&$3.a, &nat->in_out[0], sizeof($3.a));
 243  247                                    bcopy(&$3.m, &nat->in_out[1], sizeof($3.a));
 244  248                                    if (nat->in_ifnames[1][0] == '\0')
 245  249                                          strncpy(nat->in_ifnames[1],
 246  250                                                  nat->in_ifnames[0],
 247  251                                                  sizeof(nat->in_ifnames[0]));
 248  252                                    if ((nat->in_p == 0) &&
 249  253                                        ((nat->in_flags & IPN_TCPUDP) == 0) &&
 250  254                                        (nat->in_pmin != 0 ||
 251  255                                         nat->in_pmax != 0 ||
 252  256                                         nat->in_pnext != 0))
 253  257                                                  setnatproto(IPPROTO_TCP);
 254  258                                  }
 255  259          | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
 256  260                                  { if ($5 != 0 && $3 != 0 && $5 != $3)
 257  261                                          yyerror("7.address family mismatch");
 258  262                                    if ((nat->in_p == 0) &&
 259  263                                        ((nat->in_flags & IPN_TCPUDP) == 0) &&
 260  264                                        (nat->in_pmin != 0 ||
 261  265                                         nat->in_pmax != 0 ||
 262  266                                         nat->in_pnext != 0))
 263  267                                          setnatproto(IPPROTO_TCP);
 264  268                                    if (nat->in_ifnames[1][0] == '\0')
 265  269                                          strncpy(nat->in_ifnames[1],
 266  270                                                  nat->in_ifnames[0],
 267  271                                                  sizeof(nat->in_ifnames[0]));
 268  272                                  }
 269  273          | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions
 270  274                                  { if ($5 != 0 && $3.v != 0 && $5 != $3.v)
 271  275                                          yyerror("8.address family mismatch");
 272  276                                    bcopy(&$3.a, &nat->in_out[0], sizeof($3.a));
 273  277                                    bcopy(&$3.m, &nat->in_out[1], sizeof($3.a));
 274  278                                    if (nat->in_ifnames[1][0] == '\0')
 275  279                                          strncpy(nat->in_ifnames[1],
 276  280                                                  nat->in_ifnames[0],
 277  281                                                  sizeof(nat->in_ifnames[0]));
 278  282                                  }
 279  283          ;
 280  284  
 281  285  proxy:  | IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto
 282  286                          { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
 283  287                            if (nat->in_dcmp == 0) {
 284  288                                  nat->in_dport = htons($3);
 285  289                            } else if ($3 != nat->in_dport) {
 286  290                                  yyerror("proxy port numbers not consistant");
 287  291                            }
 288  292                            setnatproto($6);
 289  293                            free($4);
 290  294                          }
 291  295          | IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto
 292  296                          { int pnum;
 293  297                            strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
 294  298                            pnum = getportproto($3, $6);
 295  299                            if (pnum == -1)
 296  300                                  yyerror("invalid port number");
 297  301                            nat->in_dport = pnum;
 298  302                            setnatproto($6);
 299  303                            free($3);
 300  304                            free($4);
 301  305                          }
 302  306          ;
 303  307  
 304  308  setproto:
 305  309          | proto                         { if (nat->in_p != 0 ||
 306  310                                                nat->in_flags & IPN_TCPUDP)
 307  311                                                  yyerror("protocol set twice");
 308  312                                            setnatproto($1);
 309  313                                          }
 310  314          | IPNY_TCPUDP                   { if (nat->in_p != 0 ||
 311  315                                                nat->in_flags & IPN_TCPUDP)
 312  316                                                  yyerror("protocol set twice");
 313  317                                            nat->in_flags |= IPN_TCPUDP;
 314  318                                            nat->in_p = 0;
 315  319                                          }
 316  320          | IPNY_TCP '/' IPNY_UDP         { if (nat->in_p != 0 ||
 317  321                                                nat->in_flags & IPN_TCPUDP)
 318  322                                                  yyerror("protocol set twice");
 319  323                                            nat->in_flags |= IPN_TCPUDP;
 320  324                                            nat->in_p = 0;
 321  325                                          }
 322  326          ;
 323  327  
 324  328  rhaddr: addr                            { $$.a = $1.a;
 325  329                                            $$.m = $1.m;
 326  330                                            $$.v = $1.v;
 327  331                                            if ($$.v == 0)
 328  332                                                  $$.v = nat->in_v;
 329  333                                            yyexpectaddr = 0; }
 330  334          | IPNY_RANGE hostname '-' hostname
 331  335                                          { if ($2.v != 0 && $4.v != 0 && $4.v != $2.v)
 332  336                                                  yyerror("9.address family "
 333  337                                                          "mismatch");
 334  338                                            $$.v = $2.v;
 335  339                                            $$.a = $2.a;
 336  340                                            $$.m = $4.a;
 337  341                                            nat->in_flags |= IPN_IPRANGE;
 338  342                                            yyexpectaddr = 0; }
 339  343          ;
 340  344  
 341  345  dip:
 342  346          hostname                        { bcopy(&$1.a, &nat->in_in[0],
 343  347                                                  sizeof($1.a));
 344  348                                            if ($1.v == 0)
 345  349                                                  $1.v = nat->in_v;
 346  350                                            if ($1.v == 4) {
 347  351                                                  nat->in_inmsk = 0xffffffff;
 348  352                                            } else {
 349  353                                                  nat->in_in[1].i6[0] = 0xffffffff;
 350  354                                                  nat->in_in[1].i6[1] = 0xffffffff;
 351  355                                                  nat->in_in[1].i6[2] = 0xffffffff;
 352  356                                                  nat->in_in[1].i6[3] = 0xffffffff;
 353  357                                            }
 354  358                                            $$ = $1.v;
 355  359                                          }
 356  360          | hostname '/' YY_NUMBER        { if ($1.v == 0)
 357  361                                                  $1.v = nat->in_v;
 358  362                                            if ($1.v == 4 &&
 359  363                                                ($1.a.in4.s_addr != 0 ||
 360  364                                                ($3 != 0 && $3 != 32)))
 361  365                                                  yyerror("Invalid mask for dip");
 362  366                                            else if ($1.v == 6 &&
 363  367                                                ($1.a.in4.s_addr != 0 ||
 364  368                                                ($3 != 0 && $3 != 128)))
 365  369                                                  yyerror("Invalid mask for dip");
 366  370                                            else if ($1.v == 0 ) {
 367  371                                                  if ($1.a.in4.s_addr == 0 &&
 368  372                                                      ($3 == 32 || $3 == 0))
 369  373                                                          $1.v = 4;
 370  374                                                  else if ($3 == 128)
 371  375                                                          $1.v = 6;
 372  376                                            }
 373  377                                            bcopy(&$1.a, &nat->in_in[0],
 374  378                                                  sizeof($1.a));
 375  379                                            ntomask($1.v, $3,
 376  380                                                  (u_32_t *)&nat->in_in[1]);
 377  381                                            nat->in_in[0].i6[0] &= nat->in_in[1].i6[0];
 378  382                                            nat->in_in[0].i6[0] &= nat->in_in[1].i6[1];
 379  383                                            nat->in_in[0].i6[0] &= nat->in_in[1].i6[2];
 380  384                                            nat->in_in[0].i6[0] &= nat->in_in[1].i6[3];
 381  385                                            nat->in_v = $1.v;
 382  386                                            $$ = $1.v;
 383  387                                          }
 384  388          | hostname ',' { yyexpectaddr = 1; } hostname
 385  389                                          { if ($1.v != $4.v)
 386  390                                                  yyerror("10.address family "
 387  391                                                          "mismatch");
 388  392                                            $$ = $1.v;
 389  393                                            nat->in_flags |= IPN_SPLIT;
 390  394                                            bcopy(&$1.a, &nat->in_in[0],
 391  395                                                  sizeof($1.a));
 392  396                                            bcopy(&$4.a, &nat->in_in[1],
 393  397                                                  sizeof($4.a));
 394  398                                            yyexpectaddr = 0; }
 395  399          ;
 396  400  
 397  401  portspec:
 398  402          YY_NUMBER                       { if ($1 > 65535)       /* Unsigned */
 399  403                                                  yyerror("invalid port number");
 400  404                                            else
 401  405                                                  $$ = $1;
 402  406                                          }
 403  407          | YY_STR                        { if (getport(NULL, $1, &($$)) == -1)
 404  408                                                  yyerror("invalid port number");
 405  409                                            $$ = ntohs($$);
 406  410                                          }
 407  411          ;
 408  412  
 409  413  dport:  | IPNY_PORT portspec                    { nat->in_pmin = htons($2);
 410  414                                                    nat->in_pmax = htons($2); }
 411  415          | IPNY_PORT portspec '-' portspec       { nat->in_pmin = htons($2);
 412  416                                                    nat->in_pmax = htons($4); }
 413  417          | IPNY_PORT portspec ':' portspec       { nat->in_pmin = htons($2);
 414  418                                                    nat->in_pmax = htons($4); }
 415  419          ;
 416  420  
 417  421  nport:  IPNY_PORT portspec              { nat->in_pnext = htons($2); }
 418  422          | IPNY_PORT '=' portspec        { nat->in_pnext = htons($3);
 419  423                                            nat->in_flags |= IPN_FIXEDDPORT;
 420  424                                          }
 421  425          ;
 422  426  
 423  427  ports:  | IPNY_PORTS YY_NUMBER          { nat->in_pmin = $2; }
 424  428          | IPNY_PORTS IPNY_AUTO          { nat->in_flags |= IPN_AUTOPORTMAP; }
 425  429          ;
 426  430  
 427  431  mapit:  IPNY_MAP                        { nat->in_redir = NAT_MAP; }
 428  432          | IPNY_BIMAP                    { nat->in_redir = NAT_BIMAP; }
 429  433          ;
 430  434  
 431  435  rdrit:  IPNY_RDR                        { nat->in_redir = NAT_REDIRECT; }
 432  436          ;
 433  437  
 434  438  mapblockit:
 435  439          IPNY_MAPBLOCK                   { nat->in_redir = NAT_MAPBLK; }
 436  440          ;
 437  441  
 438  442  mapfrom:
 439  443          from sobject IPNY_TO dobject    { if ($2 != 0 && $4 != 0 && $2 != $4)
 440  444                                                  yyerror("11.address family "
 441  445                                                          "mismatch");
 442  446                                            $$ = $2;
 443  447                                          }
 444  448          | from sobject '!' IPNY_TO dobject
 445  449                                          { if ($2 != 0 && $5 != 0 && $2 != $5)
 446  450                                                  yyerror("12.address family "
 447  451                                                          "mismatch");
 448  452                                            nat->in_flags |= IPN_NOTDST;
 449  453                                            $$ = $2;
 450  454                                          }
 451  455          ;
 452  456  
 453  457  rdrfrom:
 454  458          from sobject IPNY_TO dobject    { if ($2 != 0 && $4 != 0 && $2 != $4)
 455  459                                                  yyerror("13.address family "
 456  460                                                          "mismatch");
 457  461                                            $$ = $2;
 458  462                                          }
 459  463          | '!' from sobject IPNY_TO dobject
 460  464                                          { if ($3 != 0 && $5 != 0 && $3 != $5)
 461  465                                                  yyerror("14.address family "
 462  466                                                          "mismatch");
 463  467                                            nat->in_flags |= IPN_NOTSRC;
 464  468                                            $$ = $3;
 465  469                                          }
 466  470          ;
 467  471  
 468  472  from:   IPNY_FROM                       { nat->in_flags |= IPN_FILTER;
 469  473                                            yyexpectaddr = 1; }
 470  474          ;
 471  475  
 472  476  ifnames:
 473  477          ifname                          { yyexpectaddr = 1; }
 474  478          | ifname ',' otherifname        { yyexpectaddr = 1; }
 475  479          ;
 476  480  
 477  481  ifname: YY_STR                  { strncpy(nat->in_ifnames[0], $1,
 478  482                                            sizeof(nat->in_ifnames[0]));
 479  483                                    nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
 480  484                                    free($1);
 481  485                                  }
 482  486          ;
 483  487  
 484  488  otherifname:
 485  489          YY_STR                  { strncpy(nat->in_ifnames[1], $1,
 486  490                                            sizeof(nat->in_ifnames[1]));
 487  491                                    nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
 488  492                                    free($1);
 489  493                                  }
 490  494          ;
 491  495  
 492  496  mapport:
 493  497          IPNY_PORTMAP tcpudp portspec ':' portspec randport
 494  498                          { nat->in_pmin = htons($3);
 495  499                            nat->in_pmax = htons($5);
 496  500                          }
 497  501          | IPNY_PORTMAP tcpudp IPNY_AUTO randport
 498  502                          { nat->in_flags |= IPN_AUTOPORTMAP;
 499  503                            nat->in_pmin = htons(1024);
 500  504                            nat->in_pmax = htons(65535);
 501  505                          }
 502  506          | IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER
 503  507                          { if (strcmp($2, "icmp") != 0) {
 504  508                                  yyerror("icmpidmap not followed by icmp");
 505  509                            }
 506  510                            free($2);
 507  511                            if ($3 < 0 || $3 > 65535)
 508  512                                  yyerror("invalid ICMP Id number");
 509  513                            if ($5 < 0 || $5 > 65535)
 510  514                                  yyerror("invalid ICMP Id number");
 511  515                            nat->in_flags = IPN_ICMPQUERY;
 512  516                            nat->in_pmin = htons($3);
 513  517                            nat->in_pmax = htons($5);
 514  518                          }
 515  519          ;
 516  520  
 517  521  randport:
 518  522          | IPNY_SEQUENTIAL       { nat->in_flags |= IPN_SEQUENTIAL; }
 519  523          ;
 520  524  
 521  525  sobject:
 522  526          saddr                           { $$ = $1; }
 523  527          | saddr IPNY_PORT portstuff     { nat->in_sport = $3.p1;
 524  528                                            nat->in_stop = $3.p2;
 525  529                                            nat->in_scmp = $3.pc;
 526  530                                            $$ = $1;
 527  531                                          }
 528  532          ;
 529  533  
 530  534  saddr:  addr                            { if (nat->in_redir == NAT_REDIRECT) {
 531  535                                                  bcopy(&$1.a, &nat->in_src[0],
 532  536                                                          sizeof($1.a));
 533  537                                                  bcopy(&$1.m, &nat->in_src[1],
 534  538                                                          sizeof($1.a));
 535  539                                            } else {
 536  540                                                  bcopy(&$1.a, &nat->in_in[0],
 537  541                                                          sizeof($1.a));
 538  542                                                  bcopy(&$1.m, &nat->in_in[1],
 539  543                                                          sizeof($1.a));
 540  544                                            }
 541  545                                            $$ = $1.v;
 542  546                                          }
 543  547          ;
 544  548  
 545  549  dobject:
 546  550          daddr                           { $$ = $1; }
 547  551          | daddr IPNY_PORT portstuff     { nat->in_dport = $3.p1;
 548  552                                            nat->in_dtop = $3.p2;
 549  553                                            nat->in_dcmp = $3.pc;
 550  554                                            if (nat->in_redir == NAT_REDIRECT)
 551  555                                                  nat->in_pmin = htons($3.p1);
 552  556                                          }
 553  557          ;
 554  558  
 555  559  daddr:  addr                            { if (nat->in_redir == NAT_REDIRECT) {
 556  560                                                  bcopy(&$1.a, &nat->in_out[0],
 557  561                                                          sizeof($1.a));
 558  562                                                  bcopy(&$1.m, &nat->in_out[1],
 559  563                                                          sizeof($1.a));
 560  564                                            } else {
 561  565                                                  bcopy(&$1.a, &nat->in_src[0],
 562  566                                                          sizeof($1.a));
 563  567                                                  bcopy(&$1.m, &nat->in_src[1],
 564  568                                                          sizeof($1.a));
 565  569                                            }
 566  570                                            $$ = $1.v;
 567  571                                          }
 568  572          ;
 569  573  
 570  574  addr:   IPNY_ANY                        { yyexpectaddr = 0;
 571  575                                            bzero(&$$.a, sizeof($$.a));
 572  576                                            bzero(&$$.m, sizeof($$.a));
 573  577                                            $$.v = nat->in_v;
 574  578                                          }
 575  579          | hostname                      { $$.a = $1.a;
 576  580                                            $$.v = $1.v;
 577  581                                            if ($$.v == 4) {
 578  582                                                  $$.m.in4.s_addr = 0xffffffff;
 579  583                                            } else {
 580  584                                                  $$.m.i6[0] = 0xffffffff;
 581  585                                                  $$.m.i6[1] = 0xffffffff;
 582  586                                                  $$.m.i6[2] = 0xffffffff;
 583  587                                                  $$.m.i6[3] = 0xffffffff;
 584  588                                            }
 585  589                                            yyexpectaddr = 0;
 586  590                                          }
 587  591          | hostname '/' YY_NUMBER        { $$.a = $1.a;
 588  592                                            if ($1.v == 0) {
 589  593                                                  if ($1.a.in4.s_addr != 0)
 590  594                                                          yyerror("invalid addr");
 591  595                                                  if ($3 == 0 || $3 == 32)
 592  596                                                          $1.v = 4;
 593  597                                                  else if ($3 == 128)
 594  598                                                          $1.v = 6;
 595  599                                                  else
 596  600                                                          yyerror("invalid mask");
 597  601                                                  nat->in_v = $1.v;
 598  602                                            }
 599  603                                            ntomask($1.v, $3, (u_32_t *)&$$.m);
 600  604                                            $$.a.i6[0] &= $$.m.i6[0];
 601  605                                            $$.a.i6[1] &= $$.m.i6[1];
 602  606                                            $$.a.i6[2] &= $$.m.i6[2];
 603  607                                            $$.a.i6[3] &= $$.m.i6[3];
 604  608                                            $$.v = $1.v;
 605  609                                            yyexpectaddr = 0;
 606  610                                          }
 607  611          | hostname '/' ipaddr           { if ($1.v != $3.v) {
 608  612                                                  yyerror("1.address family "
 609  613                                                          "mismatch");
 610  614                                            }
 611  615                                            $$.a = $1.a;
 612  616                                            $$.m = $3.a;
 613  617                                            $$.a.i6[0] &= $$.m.i6[0];
 614  618                                            $$.a.i6[1] &= $$.m.i6[1];
 615  619                                            $$.a.i6[2] &= $$.m.i6[2];
 616  620                                            $$.a.i6[3] &= $$.m.i6[3];
 617  621                                            $$.v = $1.v;
 618  622                                            yyexpectaddr = 0;
 619  623                                          }
 620  624          | hostname '/' hexnumber        { $$.a = $1.a;
 621  625                                            $$.m.in4.s_addr = htonl($3);
 622  626                                            $$.a.in4.s_addr &= $$.m.in4.s_addr;
 623  627                                            $$.v = 4;
 624  628                                          }
 625  629          | hostname IPNY_MASK ipaddr     { if ($1.v != $3.v) {
 626  630                                                  yyerror("2.address family "
 627  631                                                          "mismatch");
 628  632                                            }
 629  633                                            $$.a = $1.a;
 630  634                                            $$.m = $3.a;
 631  635                                            $$.a.i6[0] &= $$.m.i6[0];
 632  636                                            $$.a.i6[1] &= $$.m.i6[1];
 633  637                                            $$.a.i6[2] &= $$.m.i6[2];
 634  638                                            $$.a.i6[3] &= $$.m.i6[3];
 635  639                                            $$.v = $1.v;
 636  640                                            yyexpectaddr = 0;
 637  641                                          }
 638  642          | hostname IPNY_MASK hexnumber  { $$.a = $1.a;
 639  643                                            $$.m.in4.s_addr = htonl($3);
 640  644                                            $$.a.in4.s_addr &= $$.m.in4.s_addr;
 641  645                                            $$.v = 4;
 642  646                                          }
 643  647          ;
 644  648  
 645  649  portstuff:
 646  650          compare portspec                { $$.pc = $1; $$.p1 = $2; }
 647  651          | portspec range portspec       { $$.pc = $2; $$.p1 = $1; $$.p2 = $3; }
 648  652          ;
 649  653  
 650  654  mapoptions:
 651  655          rr frag age mssclamp nattag setproto
 652  656          ;
 653  657  
 654  658  rdroptions:
 655  659          rr frag age sticky mssclamp rdrproxy nattag
 656  660          ;
 657  661  
 658  662  nattag: | IPNY_TAG YY_STR               { strncpy(nat->in_tag.ipt_tag, $2,
 659  663                                                    sizeof(nat->in_tag.ipt_tag));
 660  664                                          }
 661  665  
 662  666  rr:     | IPNY_ROUNDROBIN               { nat->in_flags |= IPN_ROUNDR; }
 663  667          ;
 664  668  
 665  669  frag:   | IPNY_FRAG                     { nat->in_flags |= IPN_FRAG; }
 666  670          ;
 667  671  
 668  672  age:    | IPNY_AGE YY_NUMBER                    { nat->in_age[0] = $2;
 669  673                                                    nat->in_age[1] = $2; }
 670  674          | IPNY_AGE YY_NUMBER '/' YY_NUMBER      { nat->in_age[0] = $2;
 671  675                                                    nat->in_age[1] = $4; }
 672  676          ;
 673  677  
 674  678  sticky: | IPNY_STICKY                   { if (!(nat->in_flags & IPN_ROUNDR) &&
 675  679                                                !(nat->in_flags & IPN_SPLIT)) {
 676  680                                                  fprintf(stderr,
 677  681                  "'sticky' for use with round-robin/IP splitting only\n");
 678  682                                            } else
 679  683                                                  nat->in_flags |= IPN_STICKY;
 680  684                                          }
 681  685          ;
 682  686  
 683  687  mssclamp:
 684  688          | IPNY_MSSCLAMP YY_NUMBER               { nat->in_mssclamp = $2; }
 685  689          ;
 686  690  
 687  691  tcpudp: | IPNY_TCP                      { setnatproto(IPPROTO_TCP); }
 688  692          | IPNY_UDP                      { setnatproto(IPPROTO_UDP); }
 689  693          | IPNY_TCPUDP                   { nat->in_flags |= IPN_TCPUDP;
 690  694                                            nat->in_p = 0;
 691  695                                          }
 692  696          | IPNY_TCP '/' IPNY_UDP         { nat->in_flags |= IPN_TCPUDP;
 693  697                                            nat->in_p = 0;
 694  698                                          }
 695  699          ;
 696  700  
 697  701  rdrproxy:
 698  702          IPNY_PROXY YY_STR
 699  703                                          { strncpy(nat->in_plabel, $2,
 700  704                                                    sizeof(nat->in_plabel));
 701  705                                            nat->in_dport = nat->in_pnext;
 702  706                                            nat->in_dport = htons(nat->in_dport);
 703  707                                            free($2);
 704  708                                          }
 705  709          | proxy                         { if (nat->in_plabel[0] != '\0') {
 706  710                                                    nat->in_pmin = nat->in_dport;
 707  711                                                    nat->in_pmax = nat->in_pmin;
 708  712                                                    nat->in_pnext = nat->in_pmin;
 709  713                                            }
 710  714                                          }
 711  715          ;
 712  716  
 713  717  proto:  YY_NUMBER                       { $$ = $1; }
 714  718          | IPNY_TCP                      { $$ = IPPROTO_TCP; }
 715  719          | IPNY_UDP                      { $$ = IPPROTO_UDP; }
 716  720          | YY_STR                        { $$ = getproto($1); free($1); }
 717  721          ;
 718  722  
 719  723  hexnumber:
 720  724          YY_HEX                          { $$ = $1; }
 721  725          ;
 722  726  
 723  727  hostname:
 724  728          YY_STR                          { i6addr_t addr;
 725  729                                            if (gethost($1, &addr, 0) == 0) {
 726  730                                                  $$.a = addr;
 727  731                                                  $$.v = 4;
 728  732                                            } else
 729  733                                            if (gethost($1, &addr, 1) == 0) {
 730  734                                                  $$.a = addr;
 731  735                                                  $$.v = 6;
 732  736                                            } else {
 733  737                                                  yyerror("Unknown hostname");
 734  738                                            }
 735  739                                            if ($$.v != 0)
 736  740                                                  nat->in_v = $$.v;
 737  741                                            free($1);
 738  742                                          }
 739  743          | YY_NUMBER                     { bzero(&$$.a, sizeof($$.a));
 740  744                                            $$.a.in4.s_addr = htonl($1);
 741  745                                            if ($$.a.in4.s_addr != 0)
 742  746                                                  $$.v = 4;
 743  747                                            else
 744  748                                                  $$.v = nat->in_v;
 745  749                                            if ($$.v != 0)
 746  750                                                  nat->in_v = $$.v;
 747  751                                          }
 748  752          | ipv4                          { $$ = $1; 
 749  753                                            nat->in_v = 4;
 750  754                                          }
 751  755          | YY_IPV6                       { $$.a = $1;
 752  756                                            $$.v = 6;
 753  757                                            nat->in_v = 6;
 754  758                                          }
 755  759          | YY_NUMBER YY_IPV6             { $$.a = $2;
 756  760                                            $$.v = 6;
 757  761                                          }
 758  762          ;
 759  763  
 760  764  compare:
 761  765          '='                             { $$ = FR_EQUAL; }
 762  766          | YY_CMP_EQ                     { $$ = FR_EQUAL; }
 763  767          | YY_CMP_NE                     { $$ = FR_NEQUAL; }
 764  768          | YY_CMP_LT                     { $$ = FR_LESST; }
 765  769          | YY_CMP_LE                     { $$ = FR_LESSTE; }
 766  770          | YY_CMP_GT                     { $$ = FR_GREATERT; }
 767  771          | YY_CMP_GE                     { $$ = FR_GREATERTE; }
 768  772  
 769  773  range:
 770  774          YY_RANGE_OUT                    { $$ = FR_OUTRANGE; }
 771  775          | YY_RANGE_IN                   { $$ = FR_INRANGE; }
 772  776          ;
 773  777  
 774  778  ipaddr: ipv4                            { $$ = $1; }
 775  779          | YY_IPV6                       { $$.a = $1;
 776  780                                            $$.v = 6;
 777  781                                          }
 778  782          ;
 779  783  
 780  784  ipv4:   YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
 781  785                  { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
 782  786                          yyerror("Invalid octet string for IP address");
 783  787                          return 0;
 784  788                    }
 785  789                    $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
 786  790                    $$.a.in4.s_addr = htonl($$.a.in4.s_addr);
 787  791                    $$.v = 4;
 788  792                  }
 789  793          ;
 790  794  
 791  795  %%
 792  796  
 793  797  
 794  798  static  wordtab_t       yywords[] = {
 795  799          { "age",        IPNY_AGE },
 796  800          { "any",        IPNY_ANY },
 797  801          { "auto",       IPNY_AUTO },
 798  802          { "bimap",      IPNY_BIMAP },
 799  803          { "frag",       IPNY_FRAG },
 800  804          { "from",       IPNY_FROM },
 801  805          { "icmpidmap",  IPNY_ICMPIDMAP },
 802  806          { "mask",       IPNY_MASK },
 803  807          { "map",        IPNY_MAP },
 804  808          { "map-block",  IPNY_MAPBLOCK },
 805  809          { "mssclamp",   IPNY_MSSCLAMP },
 806  810          { "netmask",    IPNY_MASK },
 807  811          { "port",       IPNY_PORT },
 808  812          { "portmap",    IPNY_PORTMAP },
 809  813          { "ports",      IPNY_PORTS },
 810  814          { "proxy",      IPNY_PROXY },
 811  815          { "range",      IPNY_RANGE },
 812  816          { "rdr",        IPNY_RDR },
 813  817          { "round-robin",IPNY_ROUNDROBIN },
 814  818          { "sequential", IPNY_SEQUENTIAL },
 815  819          { "sticky",     IPNY_STICKY },
 816  820          { "tag",        IPNY_TAG },
 817  821          { "tcp",        IPNY_TCP },
 818  822          { "tcpudp",     IPNY_TCPUDP },
 819  823          { "to",         IPNY_TO },
 820  824          { "udp",        IPNY_UDP },
 821  825          { "-",          '-' },
 822  826          { "->",         IPNY_TLATE },
 823  827          { "eq",         YY_CMP_EQ },
 824  828          { "ne",         YY_CMP_NE },
 825  829          { "lt",         YY_CMP_LT },
 826  830          { "gt",         YY_CMP_GT },
 827  831          { "le",         YY_CMP_LE },
 828  832          { "ge",         YY_CMP_GE },
 829  833          { NULL,         0 }
 830  834  };
 831  835  
 832  836  
 833  837  int ipnat_parsefile(fd, addfunc, ioctlfunc, filename)
 834  838  int fd;
 835  839  addfunc_t addfunc;
 836  840  ioctlfunc_t ioctlfunc;
 837  841  char *filename;
 838  842  {
 839  843          FILE *fp = NULL;
 840  844          char *s;
 841  845  
 842  846          (void) yysettab(yywords);
 843  847  
 844  848          s = getenv("YYDEBUG");
 845  849          if (s)
 846  850                  yydebug = atoi(s);
 847  851          else
 848  852                  yydebug = 0;
 849  853  
 850  854          if (strcmp(filename, "-")) {
 851  855                  fp = fopen(filename, "r");
 852  856                  if (!fp) {
 853  857                          fprintf(stderr, "fopen(%s) failed: %s\n", filename,
 854  858                                  STRERROR(errno));
 855  859                          return -1;
 856  860                  }
 857  861          } else
 858  862                  fp = stdin;
 859  863  
 860  864          while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1)
 861  865                  ;
 862  866          if (fp != NULL)
 863  867                  fclose(fp);
 864  868          return 0;
 865  869  }
 866  870  
 867  871  
 868  872  int ipnat_parsesome(fd, addfunc, ioctlfunc, fp)
 869  873  int fd;
 870  874  addfunc_t addfunc;
 871  875  ioctlfunc_t ioctlfunc;
 872  876  FILE *fp;
 873  877  {
 874  878          char *s;
 875  879          int i;
 876  880  
 877  881          yylineNum = 1;
 878  882  
 879  883          natfd = fd;
 880  884          nataddfunc = addfunc;
 881  885          natioctlfunc = ioctlfunc;
 882  886  
 883  887          if (feof(fp))
 884  888                  return 0;
 885  889          i = fgetc(fp);
 886  890          if (i == EOF)
 887  891                  return 0;
 888  892          if (ungetc(i, fp) == EOF)
 889  893                  return 0;
 890  894          if (feof(fp))
 891  895                  return 0;
 892  896          s = getenv("YYDEBUG");
 893  897          if (s)
 894  898                  yydebug = atoi(s);
 895  899          else
 896  900                  yydebug = 0;
 897  901  
 898  902          yyin = fp;
 899  903          yyparse();
 900  904          return 1;
 901  905  }
 902  906  
 903  907  
 904  908  static void newnatrule()
 905  909  {
 906  910          ipnat_t *n;
 907  911  
 908  912          n = calloc(1, sizeof(*n));
 909  913          if (n == NULL)
 910  914                  return;
 911  915  
 912  916          if (nat == NULL)
 913  917                  nattop = nat = n;
 914  918          else {
 915  919                  nat->in_next = n;
 916  920                  nat = n;
 917  921          }
 918  922  }
 919  923  
 920  924  
 921  925  static void setnatproto(p)
 922  926  int p;
 923  927  {
 924  928          nat->in_p = p;
 925  929  
 926  930          switch (p)
 927  931          {
 928  932          case IPPROTO_TCP :
 929  933                  nat->in_flags |= IPN_TCP;
 930  934                  nat->in_flags &= ~IPN_UDP;
 931  935                  break;
 932  936          case IPPROTO_UDP :
 933  937                  nat->in_flags |= IPN_UDP;
 934  938                  nat->in_flags &= ~IPN_TCP;
 935  939                  break;
 936  940          case IPPROTO_ICMP :
 937  941                  nat->in_flags &= ~IPN_TCPUDP;
 938  942                  if (!(nat->in_flags & IPN_ICMPQUERY)) {
 939  943                          nat->in_dcmp = 0;
 940  944                          nat->in_scmp = 0;
 941  945                          nat->in_pmin = 0;
 942  946                          nat->in_pmax = 0;
 943  947                          nat->in_pnext = 0;
 944  948                  }
 945  949                  break;
 946  950          default :
 947  951                  if ((nat->in_redir & NAT_MAPBLK) == 0) {
 948  952                          /* Only reset dcmp/scmp in case dport/sport not set */
 949  953                          if (0 == nat->in_tuc.ftu_dport)
 950  954                                  nat->in_dcmp = 0;
 951  955                          if (0 == nat->in_tuc.ftu_sport)
 952  956                                  nat->in_scmp = 0;
 953  957                          nat->in_pmin = 0;
 954  958                          nat->in_pmax = 0;
 955  959                          nat->in_pnext = 0;
 956  960                          nat->in_flags &= ~IPN_TCPUDP;
 957  961                  }
 958  962                  break;
 959  963          }
 960  964  
 961  965          if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT)
 962  966                  nat->in_flags &= ~IPN_FIXEDDPORT;
 963  967  }
 964  968  
 965  969  
 966  970  void ipnat_addrule(fd, ioctlfunc, ptr)
 967  971  int fd;
 968  972  ioctlfunc_t ioctlfunc;
 969  973  void *ptr;
 970  974  {
 971  975          ioctlcmd_t add, del;
 972  976          ipfobj_t obj;
 973  977          ipnat_t *ipn;
 974  978  
 975  979          ipn = ptr;
 976  980          bzero((char *)&obj, sizeof(obj));
 977  981          obj.ipfo_rev = IPFILTER_VERSION;
 978  982          obj.ipfo_size = sizeof(ipnat_t);
 979  983          obj.ipfo_type = IPFOBJ_IPNAT;
 980  984          obj.ipfo_ptr = ptr;
 981  985          add = 0;
 982  986          del = 0;
 983  987  
 984  988          if ((opts & OPT_DONOTHING) != 0)
 985  989                  fd = -1;
 986  990  
 987  991          if (opts & OPT_ZERORULEST) {
 988  992                  add = SIOCZRLST;
 989  993          } else if (opts & OPT_INACTIVE) {
 990  994                  add = SIOCADNAT;
 991  995                  del = SIOCRMNAT;
 992  996          } else {
 993  997                  add = SIOCADNAT;
 994  998                  del = SIOCRMNAT;
 995  999          }
 996 1000  
 997 1001          if (ipn && (opts & OPT_VERBOSE))
 998 1002                  printnat(ipn, opts);
 999 1003  
1000 1004          if (opts & OPT_DEBUG)
1001 1005                  binprint(ipn, sizeof(*ipn));
1002 1006  
1003 1007          if ((opts & OPT_ZERORULEST) != 0) {
1004 1008                  if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
1005 1009                          if ((opts & OPT_DONOTHING) == 0) {
1006 1010                                  fprintf(stderr, "%d:", yylineNum);
1007 1011                                  perror("ioctl(SIOCZRLST)");
1008 1012                          }
1009 1013                  } else {
1010 1014  #ifdef  USE_QUAD_T
1011 1015  /*
1012 1016                          printf("hits %qd bytes %qd ",
1013 1017                                  (long long)fr->fr_hits,
1014 1018                                  (long long)fr->fr_bytes);
1015 1019  */
1016 1020  #else
1017 1021  /*
1018 1022                          printf("hits %ld bytes %ld ",
1019 1023                                  fr->fr_hits, fr->fr_bytes);
1020 1024  */
1021 1025  #endif
1022 1026                          printnat(ipn, opts);
1023 1027                  }
1024 1028          } else if ((opts & OPT_REMOVE) != 0) {
1025 1029                  if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
1026 1030                          if ((opts & OPT_DONOTHING) == 0) {
1027 1031                                  fprintf(stderr, "%d:", yylineNum);
1028 1032                                  perror("ioctl(delete nat rule)");
1029 1033                          }
1030 1034                  }
1031 1035          } else {
1032 1036                  if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
1033 1037                          if ((opts & OPT_DONOTHING) == 0) {
1034 1038                                  fprintf(stderr, "%d:", yylineNum);
1035 1039                                  perror("ioctl(add/insert nat rule)");
1036 1040                          }
1037 1041                  }
1038 1042          }
1039 1043  }
1040 1044  
  
    | 
      ↓ open down ↓ | 
    931 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX