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/ipmon_y.y
          +++ new/usr/src/cmd/ipf/tools/ipmon_y.y
   1    1  /*
   2    2   * Copyright (C) 1993-2005  by Darren Reed.
   3    3   * See the IPFILTER.LICENCE file for details on licencing.
        4 + *
        5 + * Copyright 2019 Joyent, Inc.
   4    6   */ 
   5    7  
   6    8  %{
   7    9  #include "ipf.h"
   8   10  #include <syslog.h>
       11 +#include <uuid/uuid.h>
   9   12  #undef  OPT_NAT
  10   13  #undef  OPT_VERBOSE
  11   14  #include "ipmon_l.h"
  12   15  #include "ipmon.h"
  13   16  
  14   17  #define YYDEBUG 1
  15   18  
  16   19  extern  void    yyerror __P((char *));
  17   20  extern  int     yyparse __P((void));
  18   21  extern  int     yylex __P((void));
  19   22  extern  int     yydebug;
  20   23  extern  FILE    *yyin;
  21   24  extern  int     yylineNum;
  22   25  
  23   26  typedef struct  opt     {
  24   27          struct  opt     *o_next;
  25   28          int             o_line;
  26   29          int             o_type;
  27   30          int             o_num;
  28   31          char            *o_str;
  29   32          struct in_addr  o_ip;
  30   33  } opt_t;
  31   34  
  32   35  static  void    build_action __P((struct opt *));
  33   36  static  opt_t   *new_opt __P((int));
  34   37  static  void    free_action __P((ipmon_action_t *));
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
  35   38  
  36   39  static  ipmon_action_t  *alist = NULL;
  37   40  %}
  38   41  
  39   42  %union  {
  40   43          char    *str;
  41   44          u_32_t  num;
  42   45          struct in_addr  addr;
  43   46          struct opt      *opt;
  44   47          union   i6addr  ip6;
       48 +        uuid_t  uuid;
  45   49  }
  46   50  
  47   51  %token  <num>   YY_NUMBER YY_HEX
  48   52  %token  <str>   YY_STR
  49   53  %token  <ip6>   YY_IPV6
       54 +%token  <uuid>  YY_UUID
  50   55  %token  YY_COMMENT 
  51   56  %token  YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
  52   57  %token  YY_RANGE_OUT YY_RANGE_IN
  53   58  
  54   59  %token  IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
  55   60  %token  IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT
  56   61  %token  IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
  57   62  %token  IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
  58   63  %token  IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT
  59   64  %token  IPM_STATE IPM_NATTAG IPM_IPF
  60   65  %type   <addr> ipv4
  61   66  %type   <opt> direction dstip dstport every execute group interface
  62   67  %type   <opt> protocol result rule srcip srcport logtag matching
  63   68  %type   <opt> matchopt nattag type doopt doing save syslog nothing
  64   69  %type   <num> saveopts saveopt typeopt
  65   70  
  66   71  %%
  67   72  file:   line
  68   73          | assign
  69   74          | file line
  70   75          | file assign
  71   76          ;
  72   77  
  73   78  line:   IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';'
  74   79                                          { build_action($3); resetlexer(); }
  75   80          | IPM_COMMENT
  76   81          | YY_COMMENT
  77   82          ;
  78   83  
  79   84  assign: YY_STR assigning YY_STR ';'             { set_variable($1, $3);
  80   85                                                    resetlexer();
  81   86                                                    free($1);
  82   87                                                    free($3);
  83   88                                                  } 
  84   89          ;
  85   90  
  86   91  assigning:
  87   92          '='                                     { yyvarnext = 1; }
  88   93          ;
  89   94  
  90   95  matching:
  91   96          matchopt                                { $$ = $1; }
  92   97          | matchopt ',' matching                 { $1->o_next = $3; $$ = $1; }
  93   98          ;
  94   99  
  95  100  matchopt:
  96  101          direction                               { $$ = $1; }
  97  102          | dstip                                 { $$ = $1; }
  98  103          | dstport                               { $$ = $1; }
  99  104          | every                                 { $$ = $1; }
 100  105          | group                                 { $$ = $1; }
 101  106          | interface                             { $$ = $1; }
 102  107          | protocol                              { $$ = $1; }
 103  108          | result                                { $$ = $1; }
 104  109          | rule                                  { $$ = $1; }
 105  110          | srcip                                 { $$ = $1; }
 106  111          | srcport                               { $$ = $1; }
 107  112          | logtag                                { $$ = $1; }
 108  113          | nattag                                { $$ = $1; }
 109  114          | type                                  { $$ = $1; }
 110  115          ;
 111  116  
 112  117  doing:
 113  118          doopt                                   { $$ = $1; }
 114  119          | doopt ',' doing                       { $1->o_next = $3; $$ = $1; }
 115  120          ;
 116  121  
 117  122  doopt:
 118  123          execute                                 { $$ = $1; }
 119  124          | save                                  { $$ = $1; }
 120  125          | syslog                                { $$ = $1; }
 121  126          | nothing                               { $$ = $1; }
 122  127          ;
 123  128  
 124  129  direction:
 125  130          IPM_DIRECTION '=' IPM_IN                { $$ = new_opt(IPM_DIRECTION);
 126  131                                                    $$->o_num = IPM_IN; }
 127  132          | IPM_DIRECTION '=' IPM_OUT             { $$ = new_opt(IPM_DIRECTION);
 128  133                                                    $$->o_num = IPM_OUT; }
 129  134          ;
 130  135  
 131  136  dstip:  IPM_DSTIP '=' ipv4 '/' YY_NUMBER        { $$ = new_opt(IPM_DSTIP);
 132  137                                                    $$->o_ip = $3;
 133  138                                                    $$->o_num = $5; }
 134  139          ;
 135  140  
 136  141  dstport:
 137  142          IPM_DSTPORT '=' YY_NUMBER               { $$ = new_opt(IPM_DSTPORT);
 138  143                                                    $$->o_num = $3; }
 139  144          | IPM_DSTPORT '=' YY_STR                { $$ = new_opt(IPM_DSTPORT);
 140  145                                                    $$->o_str = $3; }
 141  146          ;
 142  147  
 143  148  every:  IPM_EVERY IPM_SECOND                    { $$ = new_opt(IPM_SECOND);
 144  149                                                    $$->o_num = 1; }
 145  150          | IPM_EVERY YY_NUMBER IPM_SECONDS       { $$ = new_opt(IPM_SECOND);
 146  151                                                    $$->o_num = $2; }
 147  152          | IPM_EVERY IPM_PACKET                  { $$ = new_opt(IPM_PACKET);
 148  153                                                    $$->o_num = 1; }
 149  154          | IPM_EVERY YY_NUMBER IPM_PACKETS       { $$ = new_opt(IPM_PACKET);
 150  155                                                    $$->o_num = $2; }
 151  156          ;
 152  157  
 153  158  group:  IPM_GROUP '=' YY_NUMBER                 { $$ = new_opt(IPM_GROUP);
 154  159                                                    $$->o_num = $3; }
 155  160          | IPM_GROUP '=' YY_STR                  { $$ = new_opt(IPM_GROUP);
 156  161                                                    $$->o_str = $3; }
 157  162          ;
 158  163  
 159  164  interface:
 160  165          IPM_INTERFACE '=' YY_STR                { $$ = new_opt(IPM_INTERFACE);
 161  166                                                    $$->o_str = $3; }
 162  167          ;
 163  168  
 164  169  logtag: IPM_LOGTAG '=' YY_NUMBER                { $$ = new_opt(IPM_LOGTAG);
 165  170                                                    $$->o_num = $3; }
 166  171          ;
 167  172  
 168  173  nattag: IPM_NATTAG '=' YY_STR                   { $$ = new_opt(IPM_NATTAG);
 169  174                                                    $$->o_str = $3; }
 170  175          ;
 171  176  
 172  177  protocol:
 173  178          IPM_PROTOCOL '=' YY_NUMBER              { $$ = new_opt(IPM_PROTOCOL);
 174  179                                                    $$->o_num = $3; }
 175  180          | IPM_PROTOCOL '=' YY_STR               { $$ = new_opt(IPM_PROTOCOL);
 176  181                                                    $$->o_num = getproto($3);
 177  182                                                    free($3);
 178  183                                                  }
 179  184          ;
 180  185  
 181  186  result: IPM_RESULT '=' YY_STR                   { $$ = new_opt(IPM_RESULT);
 182  187                                                    $$->o_str = $3; }
 183  188          ;
 184  189  
 185  190  rule:   IPM_RULE '=' YY_NUMBER                  { $$ = new_opt(IPM_RULE);
 186  191                                                    $$->o_num = YY_NUMBER; }
 187  192          ;
 188  193  
 189  194  srcip:  IPM_SRCIP '=' ipv4 '/' YY_NUMBER        { $$ = new_opt(IPM_SRCIP);
 190  195                                                    $$->o_ip = $3;
 191  196                                                    $$->o_num = $5; }
 192  197          ;
 193  198  
 194  199  srcport:
 195  200          IPM_SRCPORT '=' YY_NUMBER               { $$ = new_opt(IPM_SRCPORT);
 196  201                                                    $$->o_num = $3; }
 197  202          | IPM_SRCPORT '=' YY_STR                { $$ = new_opt(IPM_SRCPORT);
 198  203                                                    $$->o_str = $3; }
 199  204          ;
 200  205  
 201  206  type:   IPM_TYPE '=' typeopt                    { $$ = new_opt(IPM_TYPE);
 202  207                                                    $$->o_num = $3; }
 203  208          ;
 204  209  
 205  210  typeopt:
 206  211          IPM_IPF                                 { $$ = IPL_MAGIC; }
 207  212          | IPM_NAT                               { $$ = IPL_MAGIC_NAT; }
 208  213          | IPM_STATE                             { $$ = IPL_MAGIC_STATE; }
 209  214          ;
 210  215  
 211  216  execute:
 212  217          IPM_EXECUTE YY_STR                      { $$ = new_opt(IPM_EXECUTE);
 213  218                                                    $$->o_str = $2; }
 214  219          ;
 215  220  
 216  221  save:   IPM_SAVE saveopts YY_STR                { $$ = new_opt(IPM_SAVE);
 217  222                                                    $$->o_num = $2;
 218  223                                                    $$->o_str = $3; }
 219  224          ;
 220  225  
 221  226  saveopts:                                       { $$ = 0; }
 222  227          | saveopt                               { $$ = $1; }
 223  228          | saveopt ',' saveopts                  { $$ = $1 | $3; }
 224  229          ;
 225  230  
 226  231  saveopt:
 227  232          IPM_RAW                                 { $$ = IPMDO_SAVERAW; }
 228  233          ;
 229  234  
 230  235  syslog: IPM_SYSLOG                              { $$ = new_opt(IPM_SYSLOG); }
 231  236          ;
 232  237  
 233  238  nothing:
 234  239          IPM_NOTHING                             { $$ = 0; }
 235  240          ;
 236  241  
 237  242  ipv4:   YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
 238  243                  { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
 239  244                          yyerror("Invalid octet string for IP address");
 240  245                          return 0;
 241  246                    }
 242  247                    $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
 243  248                    $$.s_addr = htonl($$.s_addr);
 244  249                  }
 245  250  %%
 246  251  static  struct  wordtab yywords[] = {
 247  252          { "body",       IPM_BODY },
 248  253          { "direction",  IPM_DIRECTION },
 249  254          { "do",         IPM_DO },
 250  255          { "dstip",      IPM_DSTIP },
 251  256          { "dstport",    IPM_DSTPORT },
 252  257          { "every",      IPM_EVERY },
 253  258          { "execute",    IPM_EXECUTE },
 254  259          { "group",      IPM_GROUP },
 255  260          { "in",         IPM_IN },
 256  261          { "interface",  IPM_INTERFACE },
 257  262          { "ipf",        IPM_IPF },
 258  263          { "logtag",     IPM_LOGTAG },
 259  264          { "match",      IPM_MATCH },
 260  265          { "nat",        IPM_NAT },
 261  266          { "nattag",     IPM_NATTAG },
 262  267          { "no",         IPM_NO },
 263  268          { "nothing",    IPM_NOTHING },
 264  269          { "out",        IPM_OUT },
 265  270          { "packet",     IPM_PACKET },
 266  271          { "packets",    IPM_PACKETS },
 267  272          { "protocol",   IPM_PROTOCOL },
 268  273          { "result",     IPM_RESULT },
 269  274          { "rule",       IPM_RULE },
 270  275          { "save",       IPM_SAVE },
 271  276          { "raw",        IPM_RAW },
 272  277          { "second",     IPM_SECOND },
 273  278          { "seconds",    IPM_SECONDS },
 274  279          { "srcip",      IPM_SRCIP },
 275  280          { "srcport",    IPM_SRCPORT },
 276  281          { "state",      IPM_STATE },
 277  282          { "syslog",     IPM_SYSLOG },
 278  283          { "with",       IPM_WITH },
 279  284          { NULL,         0 }
 280  285  };
 281  286  
 282  287  static int macflags[17][2] = {
 283  288          { IPM_DIRECTION,        IPMAC_DIRECTION },
 284  289          { IPM_DSTIP,            IPMAC_DSTIP     },
 285  290          { IPM_DSTPORT,          IPMAC_DSTPORT   },
 286  291          { IPM_GROUP,            IPMAC_GROUP     },
 287  292          { IPM_INTERFACE,        IPMAC_INTERFACE },
 288  293          { IPM_LOGTAG,           IPMAC_LOGTAG    },
 289  294          { IPM_NATTAG,           IPMAC_NATTAG    },
 290  295          { IPM_PACKET,           IPMAC_EVERY     },
 291  296          { IPM_PROTOCOL,         IPMAC_PROTOCOL  },
 292  297          { IPM_RESULT,           IPMAC_RESULT    },
 293  298          { IPM_RULE,             IPMAC_RULE      },
 294  299          { IPM_SECOND,           IPMAC_EVERY     },
 295  300          { IPM_SRCIP,            IPMAC_SRCIP     },
 296  301          { IPM_SRCPORT,          IPMAC_SRCPORT   },
 297  302          { IPM_TYPE,             IPMAC_TYPE      },
 298  303          { IPM_WITH,             IPMAC_WITH      },
 299  304          { 0, 0 }
 300  305  };
 301  306  
 302  307  static opt_t *new_opt(type)
 303  308  int type;
 304  309  {
 305  310          opt_t *o;
 306  311  
 307  312          o = (opt_t *)malloc(sizeof(*o));
 308  313          if (o == NULL)
 309  314                  yyerror("sorry, out of memory");
 310  315          o->o_type = type;
 311  316          o->o_line = yylineNum;
 312  317          o->o_num = 0;
 313  318          o->o_str = (char *)0;
 314  319          o->o_next = NULL;
 315  320          return o;
 316  321  }
 317  322  
 318  323  static void build_action(olist)
 319  324  opt_t *olist;
 320  325  {
 321  326          ipmon_action_t *a;
 322  327          opt_t *o;
 323  328          char c;
 324  329          int i;
 325  330  
 326  331          a = (ipmon_action_t *)calloc(1, sizeof(*a));
 327  332          if (a == NULL)
 328  333                  return;
 329  334          while ((o = olist) != NULL) {
 330  335                  /*
 331  336                   * Check to see if the same comparator is being used more than
 332  337                   * once per matching statement.
 333  338                   */
 334  339                  for (i = 0; macflags[i][0]; i++)
 335  340                          if (macflags[i][0] == o->o_type)
 336  341                                  break;
 337  342                  if (macflags[i][1] & a->ac_mflag) {
 338  343                          fprintf(stderr, "%s redfined on line %d\n",
 339  344                                  yykeytostr(o->o_type), yylineNum);
 340  345                          if (o->o_str != NULL)
 341  346                                  free(o->o_str);
 342  347                          olist = o->o_next;
 343  348                          free(o);
 344  349                          continue;
 345  350                  }
 346  351  
 347  352                  a->ac_mflag |= macflags[i][1];
 348  353  
 349  354                  switch (o->o_type)
 350  355                  {
 351  356                  case IPM_DIRECTION :
 352  357                          a->ac_direction = o->o_num;
 353  358                          break;
 354  359                  case IPM_DSTIP :
 355  360                          a->ac_dip = o->o_ip.s_addr;
 356  361                          a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num));
 357  362                          break;
 358  363                  case IPM_DSTPORT :
 359  364                          a->ac_dport = htons(o->o_num);
 360  365                          break;
 361  366                  case IPM_EXECUTE :
 362  367                          a->ac_exec = o->o_str;
 363  368                          c = *o->o_str;
 364  369                          if (c== '"'|| c == '\'') {
 365  370                                  if (o->o_str[strlen(o->o_str) - 1] == c) {
 366  371                                          a->ac_run = strdup(o->o_str + 1);
 367  372                                          a->ac_run[strlen(a->ac_run) - 1] ='\0';
 368  373                                  } else
 369  374                                          a->ac_run = o->o_str;
 370  375                          } else
 371  376                                  a->ac_run = o->o_str;
 372  377                          o->o_str = NULL;
 373  378                          break;
 374  379                  case IPM_INTERFACE :
 375  380                          a->ac_iface = o->o_str;
 376  381                          o->o_str = NULL;
 377  382                          break;
 378  383                  case IPM_GROUP : 
 379  384                          if (o->o_str != NULL)
 380  385                                  strncpy(a->ac_group, o->o_str, FR_GROUPLEN);
 381  386                          else
 382  387                                  sprintf(a->ac_group, "%d", o->o_num);
 383  388                          break;
 384  389                  case IPM_LOGTAG :
 385  390                          a->ac_logtag = o->o_num;
 386  391                          break;
 387  392                  case IPM_NATTAG :
 388  393                          strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag));
 389  394                          break;
 390  395                  case IPM_PACKET :
 391  396                          a->ac_packet = o->o_num;
 392  397                          break;
 393  398                  case IPM_PROTOCOL :
 394  399                          a->ac_proto = o->o_num;
 395  400                          break;
 396  401                  case IPM_RULE :
 397  402                          a->ac_rule = o->o_num;
 398  403                          break;
 399  404                  case IPM_RESULT :
 400  405                          if (!strcasecmp(o->o_str, "pass"))
 401  406                                  a->ac_result = IPMR_PASS;
 402  407                          else if (!strcasecmp(o->o_str, "block"))
 403  408                                  a->ac_result = IPMR_BLOCK;
 404  409                          else if (!strcasecmp(o->o_str, "nomatch"))
 405  410                                  a->ac_result = IPMR_NOMATCH;
 406  411                          else if (!strcasecmp(o->o_str, "log"))
 407  412                                  a->ac_result = IPMR_LOG;
 408  413                          break;
 409  414                  case IPM_SECOND :
 410  415                          a->ac_second = o->o_num;
 411  416                          break;
 412  417                  case IPM_SRCIP :
 413  418                          a->ac_sip = o->o_ip.s_addr;
 414  419                          a->ac_smsk = htonl(0xffffffff << (32 - o->o_num));
 415  420                          break;
 416  421                  case IPM_SRCPORT :
 417  422                          a->ac_sport = htons(o->o_num);
 418  423                          break;
 419  424                  case IPM_SAVE :
 420  425                          if (a->ac_savefile != NULL) {
 421  426                                  fprintf(stderr, "%s redfined on line %d\n",
 422  427                                          yykeytostr(o->o_type), yylineNum);
 423  428                                  break;
 424  429                          }
 425  430                          a->ac_savefile = strdup(o->o_str);
 426  431                          a->ac_savefp = fopen(o->o_str, "a");
 427  432                          a->ac_dflag |= o->o_num & IPMDO_SAVERAW;
 428  433                          break;
 429  434                  case IPM_SYSLOG :
 430  435                          if (a->ac_syslog != 0) {
 431  436                                  fprintf(stderr, "%s redfined on line %d\n",
 432  437                                          yykeytostr(o->o_type), yylineNum);
 433  438                                  break;
 434  439                          }
 435  440                          a->ac_syslog = 1;
 436  441                          break;
 437  442                  case IPM_TYPE :
 438  443                          a->ac_type = o->o_num;
 439  444                          break;
 440  445                  case IPM_WITH :
 441  446                          break;
 442  447                  default :
 443  448                          break;
 444  449                  }
 445  450  
 446  451                  olist = o->o_next;
 447  452                  if (o->o_str != NULL)
 448  453                          free(o->o_str);
 449  454                  free(o);
 450  455          }
 451  456          a->ac_next = alist;
 452  457          alist = a;
 453  458  }
 454  459  
 455  460  
 456  461  int check_action(buf, log, opts, lvl)
 457  462  char *buf, *log;
 458  463  int opts, lvl;
 459  464  {
 460  465          ipmon_action_t *a;
 461  466          struct timeval tv;
 462  467          ipflog_t *ipf;
 463  468          tcphdr_t *tcp;
 464  469          iplog_t *ipl;
 465  470          int matched;
 466  471          u_long t1;
 467  472          ip_t *ip;
 468  473  
 469  474          matched = 0;
 470  475          ipl = (iplog_t *)buf;
 471  476          ipf = (ipflog_t *)(ipl +1);
 472  477          ip = (ip_t *)(ipf + 1);
 473  478          tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
 474  479  
 475  480          for (a = alist; a != NULL; a = a->ac_next) {
 476  481                  if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
 477  482                          if (a->ac_direction == IPM_IN) {
 478  483                                  if ((ipf->fl_flags & FR_INQUE) == 0)
 479  484                                          continue;
 480  485                          } else if (a->ac_direction == IPM_OUT) {
 481  486                                  if ((ipf->fl_flags & FR_OUTQUE) == 0)
 482  487                                          continue;
 483  488                          }
 484  489                  }
 485  490  
 486  491                  if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic))
 487  492                          continue;
 488  493  
 489  494                  if ((a->ac_mflag & IPMAC_EVERY) != 0) {
 490  495                          gettimeofday(&tv, NULL);
 491  496                          t1 = tv.tv_sec - a->ac_lastsec;
 492  497                          if (tv.tv_usec <= a->ac_lastusec)
 493  498                                  t1--;
 494  499                          if (a->ac_second != 0) {
 495  500                                  if (t1 < a->ac_second)
 496  501                                          continue;
 497  502                                  a->ac_lastsec = tv.tv_sec;
 498  503                                  a->ac_lastusec = tv.tv_usec;
 499  504                          }
 500  505  
 501  506                          if (a->ac_packet != 0) {
 502  507                                  if (a->ac_pktcnt == 0)
 503  508                                          a->ac_pktcnt++;
 504  509                                  else if (a->ac_pktcnt == a->ac_packet) {
 505  510                                          a->ac_pktcnt = 0;
 506  511                                          continue;
 507  512                                  } else {
 508  513                                          a->ac_pktcnt++;
 509  514                                          continue;
 510  515                                  }
 511  516                          }
 512  517                  }
 513  518  
 514  519                  if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
 515  520                          if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip)
 516  521                                  continue;
 517  522                  }
 518  523  
 519  524                  if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
 520  525                          if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
 521  526                                  continue;
 522  527                          if (tcp->th_dport != a->ac_dport)
 523  528                                  continue;
 524  529                  }
 525  530  
 526  531                  if ((a->ac_mflag & IPMAC_GROUP) != 0) {
 527  532                          if (strncmp(a->ac_group, ipf->fl_group,
 528  533                                      FR_GROUPLEN) != 0)
 529  534                                  continue;
 530  535                  }
 531  536  
 532  537                  if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
 533  538                          if (strcmp(a->ac_iface, ipf->fl_ifname))
 534  539                                  continue;
 535  540                  }
 536  541  
 537  542                  if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
 538  543                          if (a->ac_proto != ip->ip_p)
 539  544                                  continue;
 540  545                  }
 541  546  
 542  547                  if ((a->ac_mflag & IPMAC_RESULT) != 0) {
 543  548                          if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
 544  549                                  if (a->ac_result != IPMR_NOMATCH)
 545  550                                          continue;
 546  551                          } else if (FR_ISPASS(ipf->fl_flags)) {
 547  552                                  if (a->ac_result != IPMR_PASS)
 548  553                                          continue;
 549  554                          } else if (FR_ISBLOCK(ipf->fl_flags)) {
 550  555                                  if (a->ac_result != IPMR_BLOCK)
 551  556                                          continue;
 552  557                          } else {        /* Log only */
 553  558                                  if (a->ac_result != IPMR_LOG)
 554  559                                          continue;
 555  560                          }
 556  561                  }
 557  562  
 558  563                  if ((a->ac_mflag & IPMAC_RULE) != 0) {
 559  564                          if (a->ac_rule != ipf->fl_rule)
 560  565                                  continue;
 561  566                  }
 562  567  
 563  568                  if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
 564  569                          if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip)
 565  570                                  continue;
 566  571                  }
 567  572  
 568  573                  if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
 569  574                          if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
 570  575                                  continue;
 571  576                          if (tcp->th_sport != a->ac_sport)
 572  577                                  continue;
 573  578                  }
 574  579  
 575  580                  if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
 576  581                          if (a->ac_logtag != ipf->fl_logtag)
 577  582                                  continue;
 578  583                  }
 579  584  
 580  585                  if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
 581  586                          if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
 582  587                                      IPFTAG_LEN) != 0)
 583  588                                  continue;
 584  589                  }
 585  590  
 586  591                  matched = 1;
 587  592  
 588  593                  /*
 589  594                   * It matched so now execute the command
 590  595                   */
 591  596                  if (a->ac_syslog != 0) {
 592  597                          syslog(lvl, "%s", log);
 593  598                  }
 594  599  
 595  600                  if (a->ac_savefp != NULL) {
 596  601                          if (a->ac_dflag & IPMDO_SAVERAW)
 597  602                                  fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp);
 598  603                          else
 599  604                                  fputs(log, a->ac_savefp);
 600  605                  }
 601  606  
 602  607                  if (a->ac_exec != NULL) {
 603  608                          switch (fork())
 604  609                          {
 605  610                          case 0 :
 606  611                          {
 607  612                                  FILE *pi;
 608  613  
 609  614                                  pi = popen(a->ac_run, "w");
 610  615                                  if (pi != NULL) {
 611  616                                          fprintf(pi, "%s\n", log);
 612  617                                          if ((opts & OPT_HEXHDR) != 0) {
 613  618                                                  dumphex(pi, 0, buf,
 614  619                                                          sizeof(*ipl) +
 615  620                                                          sizeof(*ipf));
 616  621                                          }
 617  622                                          if ((opts & OPT_HEXBODY) != 0) {
 618  623                                                  dumphex(pi, 0, (char *)ip,
 619  624                                                          ipf->fl_hlen +
 620  625                                                          ipf->fl_plen);
 621  626                                          }
 622  627                                          pclose(pi);
 623  628                                  }
 624  629                                  exit(1);
 625  630                          }
 626  631                          case -1 :
 627  632                                  break;
 628  633                          default :
 629  634                                  break;
 630  635                          }
 631  636                  }
 632  637          }
 633  638  
 634  639          return matched;
 635  640  }
 636  641  
 637  642  
 638  643  static void free_action(a)
 639  644  ipmon_action_t *a;
 640  645  {
 641  646          if (a->ac_savefile != NULL) {
 642  647                  free(a->ac_savefile);
 643  648                  a->ac_savefile = NULL;
 644  649          }
 645  650          if (a->ac_savefp != NULL) {
 646  651                  fclose(a->ac_savefp);
 647  652                  a->ac_savefp = NULL;
 648  653          }
 649  654          if (a->ac_exec != NULL) {
 650  655                  free(a->ac_exec);
 651  656                  if (a->ac_run == a->ac_exec)
 652  657                          a->ac_run = NULL;
 653  658                  a->ac_exec = NULL;
 654  659          }
 655  660          if (a->ac_run != NULL) {
 656  661                  free(a->ac_run);
 657  662                  a->ac_run = NULL;
 658  663          }
 659  664          if (a->ac_iface != NULL) {
 660  665                  free(a->ac_iface);
 661  666                  a->ac_iface = NULL;
 662  667          }
 663  668          a->ac_next = NULL;
 664  669          free(a);
 665  670  }
 666  671  
 667  672  
 668  673  int load_config(file)
 669  674  char *file;
 670  675  {
 671  676          ipmon_action_t *a;
 672  677          FILE *fp;
 673  678          char *s;
 674  679  
 675  680          s = getenv("YYDEBUG");
 676  681          if (s != NULL)
 677  682                  yydebug = atoi(s);
 678  683          else
 679  684                  yydebug = 0;
 680  685  
 681  686          while ((a = alist) != NULL) {
 682  687                  alist = a->ac_next;
 683  688                  free_action(a);
 684  689          }
 685  690  
 686  691          yylineNum = 1;
 687  692  
 688  693          (void) yysettab(yywords);
 689  694  
 690  695          fp = fopen(file, "r");
 691  696          if (!fp) {
 692  697                  perror("load_config:fopen:");
 693  698                  return -1;
 694  699          }
 695  700          yyin = fp;
 696  701          while (!feof(fp))
 697  702                  yyparse();
 698  703          fclose(fp);
 699  704          return 0;
 700  705  }
  
    | 
      ↓ open down ↓ | 
    641 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX