1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 3170268Sdarrenr/* 4170268Sdarrenr * Copyright (C) 2001-2004 by Darren Reed. 5170268Sdarrenr * 6170268Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7170268Sdarrenr */ 8145510Sdarrenr%{ 9145510Sdarrenr#include "ipf.h" 10145510Sdarrenr#include <syslog.h> 11145510Sdarrenr#undef OPT_NAT 12145510Sdarrenr#undef OPT_VERBOSE 13145510Sdarrenr#include "ipmon_l.h" 14145510Sdarrenr#include "ipmon.h" 15145510Sdarrenr 16145510Sdarrenr#define YYDEBUG 1 17145510Sdarrenr 18145510Sdarrenrextern void yyerror __P((char *)); 19145510Sdarrenrextern int yyparse __P((void)); 20145510Sdarrenrextern int yylex __P((void)); 21145510Sdarrenrextern int yydebug; 22145510Sdarrenrextern FILE *yyin; 23145510Sdarrenrextern int yylineNum; 24145510Sdarrenr 25145510Sdarrenrtypedef struct opt { 26145510Sdarrenr struct opt *o_next; 27145510Sdarrenr int o_line; 28145510Sdarrenr int o_type; 29145510Sdarrenr int o_num; 30145510Sdarrenr char *o_str; 31145510Sdarrenr struct in_addr o_ip; 32145510Sdarrenr} opt_t; 33145510Sdarrenr 34145510Sdarrenrstatic void build_action __P((struct opt *)); 35145510Sdarrenrstatic opt_t *new_opt __P((int)); 36145510Sdarrenrstatic void free_action __P((ipmon_action_t *)); 37145510Sdarrenr 38145510Sdarrenrstatic ipmon_action_t *alist = NULL; 39145510Sdarrenr%} 40145510Sdarrenr 41145510Sdarrenr%union { 42145510Sdarrenr char *str; 43145510Sdarrenr u_32_t num; 44145510Sdarrenr struct in_addr addr; 45145510Sdarrenr struct opt *opt; 46145510Sdarrenr union i6addr ip6; 47145510Sdarrenr} 48145510Sdarrenr 49145510Sdarrenr%token <num> YY_NUMBER YY_HEX 50145510Sdarrenr%token <str> YY_STR 51145510Sdarrenr%token <ip6> YY_IPV6 52145510Sdarrenr%token YY_COMMENT 53145510Sdarrenr%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 54145510Sdarrenr%token YY_RANGE_OUT YY_RANGE_IN 55145510Sdarrenr 56145510Sdarrenr%token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT 57145510Sdarrenr%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT 58145510Sdarrenr%token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE 59145510Sdarrenr%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH 60145510Sdarrenr%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT 61145510Sdarrenr%token IPM_STATE IPM_NATTAG IPM_IPF 62145510Sdarrenr%type <addr> ipv4 63145510Sdarrenr%type <opt> direction dstip dstport every execute group interface 64145510Sdarrenr%type <opt> protocol result rule srcip srcport logtag matching 65145510Sdarrenr%type <opt> matchopt nattag type doopt doing save syslog nothing 66145510Sdarrenr%type <num> saveopts saveopt typeopt 67145510Sdarrenr 68145510Sdarrenr%% 69145510Sdarrenrfile: line 70145510Sdarrenr | assign 71145510Sdarrenr | file line 72145510Sdarrenr | file assign 73145510Sdarrenr ; 74145510Sdarrenr 75145510Sdarrenrline: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';' 76145510Sdarrenr { build_action($3); resetlexer(); } 77145510Sdarrenr | IPM_COMMENT 78145510Sdarrenr | YY_COMMENT 79145510Sdarrenr ; 80145510Sdarrenr 81145510Sdarrenrassign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 82145510Sdarrenr resetlexer(); 83145510Sdarrenr free($1); 84145510Sdarrenr free($3); 85170268Sdarrenr yyvarnext = 0; 86145510Sdarrenr } 87145510Sdarrenr ; 88145510Sdarrenr 89145510Sdarrenrassigning: 90145510Sdarrenr '=' { yyvarnext = 1; } 91145510Sdarrenr ; 92145510Sdarrenr 93145510Sdarrenrmatching: 94145510Sdarrenr matchopt { $$ = $1; } 95145510Sdarrenr | matchopt ',' matching { $1->o_next = $3; $$ = $1; } 96145510Sdarrenr ; 97145510Sdarrenr 98145510Sdarrenrmatchopt: 99145510Sdarrenr direction { $$ = $1; } 100145510Sdarrenr | dstip { $$ = $1; } 101145510Sdarrenr | dstport { $$ = $1; } 102145510Sdarrenr | every { $$ = $1; } 103145510Sdarrenr | group { $$ = $1; } 104145510Sdarrenr | interface { $$ = $1; } 105145510Sdarrenr | protocol { $$ = $1; } 106145510Sdarrenr | result { $$ = $1; } 107145510Sdarrenr | rule { $$ = $1; } 108145510Sdarrenr | srcip { $$ = $1; } 109145510Sdarrenr | srcport { $$ = $1; } 110145510Sdarrenr | logtag { $$ = $1; } 111145510Sdarrenr | nattag { $$ = $1; } 112145510Sdarrenr | type { $$ = $1; } 113145510Sdarrenr ; 114145510Sdarrenr 115145510Sdarrenrdoing: 116145510Sdarrenr doopt { $$ = $1; } 117145510Sdarrenr | doopt ',' doing { $1->o_next = $3; $$ = $1; } 118145510Sdarrenr ; 119145510Sdarrenr 120145510Sdarrenrdoopt: 121145510Sdarrenr execute { $$ = $1; } 122145510Sdarrenr | save { $$ = $1; } 123145510Sdarrenr | syslog { $$ = $1; } 124145510Sdarrenr | nothing { $$ = $1; } 125145510Sdarrenr ; 126145510Sdarrenr 127145510Sdarrenrdirection: 128145510Sdarrenr IPM_DIRECTION '=' IPM_IN { $$ = new_opt(IPM_DIRECTION); 129145510Sdarrenr $$->o_num = IPM_IN; } 130145510Sdarrenr | IPM_DIRECTION '=' IPM_OUT { $$ = new_opt(IPM_DIRECTION); 131145510Sdarrenr $$->o_num = IPM_OUT; } 132145510Sdarrenr ; 133145510Sdarrenr 134145510Sdarrenrdstip: IPM_DSTIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_DSTIP); 135145510Sdarrenr $$->o_ip = $3; 136145510Sdarrenr $$->o_num = $5; } 137145510Sdarrenr ; 138145510Sdarrenr 139145510Sdarrenrdstport: 140145510Sdarrenr IPM_DSTPORT '=' YY_NUMBER { $$ = new_opt(IPM_DSTPORT); 141145510Sdarrenr $$->o_num = $3; } 142145510Sdarrenr | IPM_DSTPORT '=' YY_STR { $$ = new_opt(IPM_DSTPORT); 143145510Sdarrenr $$->o_str = $3; } 144145510Sdarrenr ; 145145510Sdarrenr 146145510Sdarrenrevery: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND); 147145510Sdarrenr $$->o_num = 1; } 148145510Sdarrenr | IPM_EVERY YY_NUMBER IPM_SECONDS { $$ = new_opt(IPM_SECOND); 149145510Sdarrenr $$->o_num = $2; } 150145510Sdarrenr | IPM_EVERY IPM_PACKET { $$ = new_opt(IPM_PACKET); 151145510Sdarrenr $$->o_num = 1; } 152145510Sdarrenr | IPM_EVERY YY_NUMBER IPM_PACKETS { $$ = new_opt(IPM_PACKET); 153145510Sdarrenr $$->o_num = $2; } 154145510Sdarrenr ; 155145510Sdarrenr 156145510Sdarrenrgroup: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP); 157145510Sdarrenr $$->o_num = $3; } 158145510Sdarrenr | IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP); 159145510Sdarrenr $$->o_str = $3; } 160145510Sdarrenr ; 161145510Sdarrenr 162145510Sdarrenrinterface: 163145510Sdarrenr IPM_INTERFACE '=' YY_STR { $$ = new_opt(IPM_INTERFACE); 164145510Sdarrenr $$->o_str = $3; } 165145510Sdarrenr ; 166145510Sdarrenr 167145510Sdarrenrlogtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG); 168145510Sdarrenr $$->o_num = $3; } 169145510Sdarrenr ; 170145510Sdarrenr 171145510Sdarrenrnattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG); 172145510Sdarrenr $$->o_str = $3; } 173145510Sdarrenr ; 174145510Sdarrenr 175145510Sdarrenrprotocol: 176145510Sdarrenr IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL); 177145510Sdarrenr $$->o_num = $3; } 178145510Sdarrenr | IPM_PROTOCOL '=' YY_STR { $$ = new_opt(IPM_PROTOCOL); 179145510Sdarrenr $$->o_num = getproto($3); 180145510Sdarrenr free($3); 181145510Sdarrenr } 182145510Sdarrenr ; 183145510Sdarrenr 184145510Sdarrenrresult: IPM_RESULT '=' YY_STR { $$ = new_opt(IPM_RESULT); 185145510Sdarrenr $$->o_str = $3; } 186145510Sdarrenr ; 187145510Sdarrenr 188145510Sdarrenrrule: IPM_RULE '=' YY_NUMBER { $$ = new_opt(IPM_RULE); 189145510Sdarrenr $$->o_num = YY_NUMBER; } 190145510Sdarrenr ; 191145510Sdarrenr 192145510Sdarrenrsrcip: IPM_SRCIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_SRCIP); 193145510Sdarrenr $$->o_ip = $3; 194145510Sdarrenr $$->o_num = $5; } 195145510Sdarrenr ; 196145510Sdarrenr 197145510Sdarrenrsrcport: 198145510Sdarrenr IPM_SRCPORT '=' YY_NUMBER { $$ = new_opt(IPM_SRCPORT); 199145510Sdarrenr $$->o_num = $3; } 200145510Sdarrenr | IPM_SRCPORT '=' YY_STR { $$ = new_opt(IPM_SRCPORT); 201145510Sdarrenr $$->o_str = $3; } 202145510Sdarrenr ; 203145510Sdarrenr 204145510Sdarrenrtype: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE); 205145510Sdarrenr $$->o_num = $3; } 206145510Sdarrenr ; 207145510Sdarrenr 208145510Sdarrenrtypeopt: 209145510Sdarrenr IPM_IPF { $$ = IPL_MAGIC; } 210145510Sdarrenr | IPM_NAT { $$ = IPL_MAGIC_NAT; } 211145510Sdarrenr | IPM_STATE { $$ = IPL_MAGIC_STATE; } 212145510Sdarrenr ; 213145510Sdarrenr 214145510Sdarrenrexecute: 215145510Sdarrenr IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE); 216145510Sdarrenr $$->o_str = $2; } 217145510Sdarrenr ; 218145510Sdarrenr 219145510Sdarrenrsave: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE); 220145510Sdarrenr $$->o_num = $2; 221145510Sdarrenr $$->o_str = $3; } 222145510Sdarrenr ; 223145510Sdarrenr 224145510Sdarrenrsaveopts: { $$ = 0; } 225145510Sdarrenr | saveopt { $$ = $1; } 226145510Sdarrenr | saveopt ',' saveopts { $$ = $1 | $3; } 227145510Sdarrenr ; 228145510Sdarrenr 229145510Sdarrenrsaveopt: 230145510Sdarrenr IPM_RAW { $$ = IPMDO_SAVERAW; } 231145510Sdarrenr ; 232145510Sdarrenr 233145510Sdarrenrsyslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); } 234145510Sdarrenr ; 235145510Sdarrenr 236145510Sdarrenrnothing: 237145510Sdarrenr IPM_NOTHING { $$ = 0; } 238145510Sdarrenr ; 239145510Sdarrenr 240145510Sdarrenripv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 241145510Sdarrenr { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 242145510Sdarrenr yyerror("Invalid octet string for IP address"); 243145510Sdarrenr return 0; 244145510Sdarrenr } 245145510Sdarrenr $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 246145510Sdarrenr $$.s_addr = htonl($$.s_addr); 247145510Sdarrenr } 248145510Sdarrenr%% 249145510Sdarrenrstatic struct wordtab yywords[] = { 250145510Sdarrenr { "body", IPM_BODY }, 251145510Sdarrenr { "direction", IPM_DIRECTION }, 252145510Sdarrenr { "do", IPM_DO }, 253145510Sdarrenr { "dstip", IPM_DSTIP }, 254145510Sdarrenr { "dstport", IPM_DSTPORT }, 255145510Sdarrenr { "every", IPM_EVERY }, 256145510Sdarrenr { "execute", IPM_EXECUTE }, 257145510Sdarrenr { "group", IPM_GROUP }, 258145510Sdarrenr { "in", IPM_IN }, 259145510Sdarrenr { "interface", IPM_INTERFACE }, 260145510Sdarrenr { "ipf", IPM_IPF }, 261145510Sdarrenr { "logtag", IPM_LOGTAG }, 262145510Sdarrenr { "match", IPM_MATCH }, 263145510Sdarrenr { "nat", IPM_NAT }, 264145510Sdarrenr { "nattag", IPM_NATTAG }, 265145510Sdarrenr { "no", IPM_NO }, 266145510Sdarrenr { "nothing", IPM_NOTHING }, 267145510Sdarrenr { "out", IPM_OUT }, 268145510Sdarrenr { "packet", IPM_PACKET }, 269145510Sdarrenr { "packets", IPM_PACKETS }, 270145510Sdarrenr { "protocol", IPM_PROTOCOL }, 271145510Sdarrenr { "result", IPM_RESULT }, 272145510Sdarrenr { "rule", IPM_RULE }, 273145510Sdarrenr { "save", IPM_SAVE }, 274145510Sdarrenr { "second", IPM_SECOND }, 275145510Sdarrenr { "seconds", IPM_SECONDS }, 276145510Sdarrenr { "srcip", IPM_SRCIP }, 277145510Sdarrenr { "srcport", IPM_SRCPORT }, 278145510Sdarrenr { "state", IPM_STATE }, 279145510Sdarrenr { "syslog", IPM_SYSLOG }, 280145510Sdarrenr { "with", IPM_WITH }, 281145510Sdarrenr { NULL, 0 } 282145510Sdarrenr}; 283145510Sdarrenr 284145510Sdarrenrstatic int macflags[17][2] = { 285145510Sdarrenr { IPM_DIRECTION, IPMAC_DIRECTION }, 286145510Sdarrenr { IPM_DSTIP, IPMAC_DSTIP }, 287145510Sdarrenr { IPM_DSTPORT, IPMAC_DSTPORT }, 288145510Sdarrenr { IPM_GROUP, IPMAC_GROUP }, 289145510Sdarrenr { IPM_INTERFACE, IPMAC_INTERFACE }, 290145510Sdarrenr { IPM_LOGTAG, IPMAC_LOGTAG }, 291145510Sdarrenr { IPM_NATTAG, IPMAC_NATTAG }, 292145510Sdarrenr { IPM_PACKET, IPMAC_EVERY }, 293145510Sdarrenr { IPM_PROTOCOL, IPMAC_PROTOCOL }, 294145510Sdarrenr { IPM_RESULT, IPMAC_RESULT }, 295145510Sdarrenr { IPM_RULE, IPMAC_RULE }, 296145510Sdarrenr { IPM_SECOND, IPMAC_EVERY }, 297145510Sdarrenr { IPM_SRCIP, IPMAC_SRCIP }, 298145510Sdarrenr { IPM_SRCPORT, IPMAC_SRCPORT }, 299145510Sdarrenr { IPM_TYPE, IPMAC_TYPE }, 300145510Sdarrenr { IPM_WITH, IPMAC_WITH }, 301145510Sdarrenr { 0, 0 } 302145510Sdarrenr}; 303145510Sdarrenr 304145510Sdarrenrstatic opt_t *new_opt(type) 305145510Sdarrenrint type; 306145510Sdarrenr{ 307145510Sdarrenr opt_t *o; 308145510Sdarrenr 309145510Sdarrenr o = (opt_t *)malloc(sizeof(*o)); 310145510Sdarrenr o->o_type = type; 311145510Sdarrenr o->o_line = yylineNum; 312145510Sdarrenr o->o_num = 0; 313145510Sdarrenr o->o_str = (char *)0; 314145510Sdarrenr o->o_next = NULL; 315145510Sdarrenr return o; 316145510Sdarrenr} 317145510Sdarrenr 318145510Sdarrenrstatic void build_action(olist) 319145510Sdarrenropt_t *olist; 320145510Sdarrenr{ 321145510Sdarrenr ipmon_action_t *a; 322145510Sdarrenr opt_t *o; 323145510Sdarrenr char c; 324145510Sdarrenr int i; 325145510Sdarrenr 326145510Sdarrenr a = (ipmon_action_t *)calloc(1, sizeof(*a)); 327145510Sdarrenr if (a == NULL) 328145510Sdarrenr return; 329145510Sdarrenr while ((o = olist) != NULL) { 330145510Sdarrenr /* 331145510Sdarrenr * Check to see if the same comparator is being used more than 332145510Sdarrenr * once per matching statement. 333145510Sdarrenr */ 334145510Sdarrenr for (i = 0; macflags[i][0]; i++) 335145510Sdarrenr if (macflags[i][0] == o->o_type) 336145510Sdarrenr break; 337145510Sdarrenr if (macflags[i][1] & a->ac_mflag) { 338145510Sdarrenr fprintf(stderr, "%s redfined on line %d\n", 339145510Sdarrenr yykeytostr(o->o_type), yylineNum); 340145510Sdarrenr if (o->o_str != NULL) 341145510Sdarrenr free(o->o_str); 342145510Sdarrenr olist = o->o_next; 343145510Sdarrenr free(o); 344145510Sdarrenr continue; 345145510Sdarrenr } 346145510Sdarrenr 347145510Sdarrenr a->ac_mflag |= macflags[i][1]; 348145510Sdarrenr 349145510Sdarrenr switch (o->o_type) 350145510Sdarrenr { 351145510Sdarrenr case IPM_DIRECTION : 352145510Sdarrenr a->ac_direction = o->o_num; 353145510Sdarrenr break; 354145510Sdarrenr case IPM_DSTIP : 355145510Sdarrenr a->ac_dip = o->o_ip.s_addr; 356145510Sdarrenr a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num)); 357145510Sdarrenr break; 358145510Sdarrenr case IPM_DSTPORT : 359145510Sdarrenr a->ac_dport = htons(o->o_num); 360145510Sdarrenr break; 361145510Sdarrenr case IPM_EXECUTE : 362145510Sdarrenr a->ac_exec = o->o_str; 363145510Sdarrenr c = *o->o_str; 364145510Sdarrenr if (c== '"'|| c == '\'') { 365145510Sdarrenr if (o->o_str[strlen(o->o_str) - 1] == c) { 366145510Sdarrenr a->ac_run = strdup(o->o_str + 1); 367145510Sdarrenr a->ac_run[strlen(a->ac_run) - 1] ='\0'; 368145510Sdarrenr } else 369145510Sdarrenr a->ac_run = o->o_str; 370145510Sdarrenr } else 371145510Sdarrenr a->ac_run = o->o_str; 372145510Sdarrenr o->o_str = NULL; 373145510Sdarrenr break; 374145510Sdarrenr case IPM_INTERFACE : 375145510Sdarrenr a->ac_iface = o->o_str; 376145510Sdarrenr o->o_str = NULL; 377145510Sdarrenr break; 378145510Sdarrenr case IPM_GROUP : 379145510Sdarrenr if (o->o_str != NULL) 380145510Sdarrenr strncpy(a->ac_group, o->o_str, FR_GROUPLEN); 381145510Sdarrenr else 382145510Sdarrenr sprintf(a->ac_group, "%d", o->o_num); 383145510Sdarrenr break; 384145510Sdarrenr case IPM_LOGTAG : 385145510Sdarrenr a->ac_logtag = o->o_num; 386145510Sdarrenr break; 387145510Sdarrenr case IPM_NATTAG : 388145510Sdarrenr strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag)); 389145510Sdarrenr break; 390145510Sdarrenr case IPM_PACKET : 391145510Sdarrenr a->ac_packet = o->o_num; 392145510Sdarrenr break; 393145510Sdarrenr case IPM_PROTOCOL : 394145510Sdarrenr a->ac_proto = o->o_num; 395145510Sdarrenr break; 396145510Sdarrenr case IPM_RULE : 397145510Sdarrenr a->ac_rule = o->o_num; 398145510Sdarrenr break; 399145510Sdarrenr case IPM_RESULT : 400145510Sdarrenr if (!strcasecmp(o->o_str, "pass")) 401145510Sdarrenr a->ac_result = IPMR_PASS; 402145510Sdarrenr else if (!strcasecmp(o->o_str, "block")) 403145510Sdarrenr a->ac_result = IPMR_BLOCK; 404145510Sdarrenr else if (!strcasecmp(o->o_str, "nomatch")) 405145510Sdarrenr a->ac_result = IPMR_NOMATCH; 406145510Sdarrenr else if (!strcasecmp(o->o_str, "log")) 407145510Sdarrenr a->ac_result = IPMR_LOG; 408145510Sdarrenr break; 409145510Sdarrenr case IPM_SECOND : 410145510Sdarrenr a->ac_second = o->o_num; 411145510Sdarrenr break; 412145510Sdarrenr case IPM_SRCIP : 413145510Sdarrenr a->ac_sip = o->o_ip.s_addr; 414145510Sdarrenr a->ac_smsk = htonl(0xffffffff << (32 - o->o_num)); 415145510Sdarrenr break; 416145510Sdarrenr case IPM_SRCPORT : 417145510Sdarrenr a->ac_sport = htons(o->o_num); 418145510Sdarrenr break; 419145510Sdarrenr case IPM_SAVE : 420145510Sdarrenr if (a->ac_savefile != NULL) { 421145510Sdarrenr fprintf(stderr, "%s redfined on line %d\n", 422145510Sdarrenr yykeytostr(o->o_type), yylineNum); 423145510Sdarrenr break; 424145510Sdarrenr } 425145510Sdarrenr a->ac_savefile = strdup(o->o_str); 426145510Sdarrenr a->ac_savefp = fopen(o->o_str, "a"); 427145510Sdarrenr a->ac_dflag |= o->o_num & IPMDO_SAVERAW; 428145510Sdarrenr break; 429145510Sdarrenr case IPM_SYSLOG : 430145510Sdarrenr if (a->ac_syslog != 0) { 431145510Sdarrenr fprintf(stderr, "%s redfined on line %d\n", 432145510Sdarrenr yykeytostr(o->o_type), yylineNum); 433145510Sdarrenr break; 434145510Sdarrenr } 435145510Sdarrenr a->ac_syslog = 1; 436145510Sdarrenr break; 437145510Sdarrenr case IPM_TYPE : 438145510Sdarrenr a->ac_type = o->o_num; 439145510Sdarrenr break; 440145510Sdarrenr case IPM_WITH : 441145510Sdarrenr break; 442145510Sdarrenr default : 443145510Sdarrenr break; 444145510Sdarrenr } 445145510Sdarrenr 446145510Sdarrenr olist = o->o_next; 447145510Sdarrenr if (o->o_str != NULL) 448145510Sdarrenr free(o->o_str); 449145510Sdarrenr free(o); 450145510Sdarrenr } 451145510Sdarrenr a->ac_next = alist; 452145510Sdarrenr alist = a; 453145510Sdarrenr} 454145510Sdarrenr 455145510Sdarrenr 456145510Sdarrenrint check_action(buf, log, opts, lvl) 457145510Sdarrenrchar *buf, *log; 458145510Sdarrenrint opts, lvl; 459145510Sdarrenr{ 460145510Sdarrenr ipmon_action_t *a; 461145510Sdarrenr struct timeval tv; 462145510Sdarrenr ipflog_t *ipf; 463145510Sdarrenr tcphdr_t *tcp; 464145510Sdarrenr iplog_t *ipl; 465145510Sdarrenr int matched; 466145510Sdarrenr u_long t1; 467145510Sdarrenr ip_t *ip; 468145510Sdarrenr 469145510Sdarrenr matched = 0; 470145510Sdarrenr ipl = (iplog_t *)buf; 471145510Sdarrenr ipf = (ipflog_t *)(ipl +1); 472145510Sdarrenr ip = (ip_t *)(ipf + 1); 473145510Sdarrenr tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); 474145510Sdarrenr 475145510Sdarrenr for (a = alist; a != NULL; a = a->ac_next) { 476145510Sdarrenr if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { 477145510Sdarrenr if (a->ac_direction == IPM_IN) { 478145510Sdarrenr if ((ipf->fl_flags & FR_INQUE) == 0) 479145510Sdarrenr continue; 480145510Sdarrenr } else if (a->ac_direction == IPM_OUT) { 481145510Sdarrenr if ((ipf->fl_flags & FR_OUTQUE) == 0) 482145510Sdarrenr continue; 483145510Sdarrenr } 484145510Sdarrenr } 485145510Sdarrenr 486145510Sdarrenr if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) 487145510Sdarrenr continue; 488145510Sdarrenr 489145510Sdarrenr if ((a->ac_mflag & IPMAC_EVERY) != 0) { 490145510Sdarrenr gettimeofday(&tv, NULL); 491145510Sdarrenr t1 = tv.tv_sec - a->ac_lastsec; 492145510Sdarrenr if (tv.tv_usec <= a->ac_lastusec) 493145510Sdarrenr t1--; 494145510Sdarrenr if (a->ac_second != 0) { 495145510Sdarrenr if (t1 < a->ac_second) 496145510Sdarrenr continue; 497145510Sdarrenr a->ac_lastsec = tv.tv_sec; 498145510Sdarrenr a->ac_lastusec = tv.tv_usec; 499145510Sdarrenr } 500145510Sdarrenr 501145510Sdarrenr if (a->ac_packet != 0) { 502145510Sdarrenr if (a->ac_pktcnt == 0) 503145510Sdarrenr a->ac_pktcnt++; 504145510Sdarrenr else if (a->ac_pktcnt == a->ac_packet) { 505145510Sdarrenr a->ac_pktcnt = 0; 506145510Sdarrenr continue; 507145510Sdarrenr } else { 508145510Sdarrenr a->ac_pktcnt++; 509145510Sdarrenr continue; 510145510Sdarrenr } 511145510Sdarrenr } 512145510Sdarrenr } 513145510Sdarrenr 514145510Sdarrenr if ((a->ac_mflag & IPMAC_DSTIP) != 0) { 515145510Sdarrenr if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) 516145510Sdarrenr continue; 517145510Sdarrenr } 518145510Sdarrenr 519145510Sdarrenr if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { 520145510Sdarrenr if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) 521145510Sdarrenr continue; 522145510Sdarrenr if (tcp->th_dport != a->ac_dport) 523145510Sdarrenr continue; 524145510Sdarrenr } 525145510Sdarrenr 526145510Sdarrenr if ((a->ac_mflag & IPMAC_GROUP) != 0) { 527145510Sdarrenr if (strncmp(a->ac_group, ipf->fl_group, 528145510Sdarrenr FR_GROUPLEN) != 0) 529145510Sdarrenr continue; 530145510Sdarrenr } 531145510Sdarrenr 532145510Sdarrenr if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { 533145510Sdarrenr if (strcmp(a->ac_iface, ipf->fl_ifname)) 534145510Sdarrenr continue; 535145510Sdarrenr } 536145510Sdarrenr 537145510Sdarrenr if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { 538145510Sdarrenr if (a->ac_proto != ip->ip_p) 539145510Sdarrenr continue; 540145510Sdarrenr } 541145510Sdarrenr 542145510Sdarrenr if ((a->ac_mflag & IPMAC_RESULT) != 0) { 543145510Sdarrenr if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { 544145510Sdarrenr if (a->ac_result != IPMR_NOMATCH) 545145510Sdarrenr continue; 546145510Sdarrenr } else if (FR_ISPASS(ipf->fl_flags)) { 547145510Sdarrenr if (a->ac_result != IPMR_PASS) 548145510Sdarrenr continue; 549145510Sdarrenr } else if (FR_ISBLOCK(ipf->fl_flags)) { 550145510Sdarrenr if (a->ac_result != IPMR_BLOCK) 551145510Sdarrenr continue; 552145510Sdarrenr } else { /* Log only */ 553145510Sdarrenr if (a->ac_result != IPMR_LOG) 554145510Sdarrenr continue; 555145510Sdarrenr } 556145510Sdarrenr } 557145510Sdarrenr 558145510Sdarrenr if ((a->ac_mflag & IPMAC_RULE) != 0) { 559145510Sdarrenr if (a->ac_rule != ipf->fl_rule) 560145510Sdarrenr continue; 561145510Sdarrenr } 562145510Sdarrenr 563145510Sdarrenr if ((a->ac_mflag & IPMAC_SRCIP) != 0) { 564145510Sdarrenr if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) 565145510Sdarrenr continue; 566145510Sdarrenr } 567145510Sdarrenr 568145510Sdarrenr if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { 569145510Sdarrenr if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) 570145510Sdarrenr continue; 571145510Sdarrenr if (tcp->th_sport != a->ac_sport) 572145510Sdarrenr continue; 573145510Sdarrenr } 574145510Sdarrenr 575145510Sdarrenr if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { 576145510Sdarrenr if (a->ac_logtag != ipf->fl_logtag) 577145510Sdarrenr continue; 578145510Sdarrenr } 579145510Sdarrenr 580145510Sdarrenr if ((a->ac_mflag & IPMAC_NATTAG) != 0) { 581145510Sdarrenr if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, 582145510Sdarrenr IPFTAG_LEN) != 0) 583145510Sdarrenr continue; 584145510Sdarrenr } 585145510Sdarrenr 586145510Sdarrenr matched = 1; 587145510Sdarrenr 588145510Sdarrenr /* 589145510Sdarrenr * It matched so now execute the command 590145510Sdarrenr */ 591145510Sdarrenr if (a->ac_syslog != 0) { 592145510Sdarrenr syslog(lvl, "%s", log); 593145510Sdarrenr } 594145510Sdarrenr 595145510Sdarrenr if (a->ac_savefp != NULL) { 596145510Sdarrenr if (a->ac_dflag & IPMDO_SAVERAW) 597145510Sdarrenr fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp); 598145510Sdarrenr else 599145510Sdarrenr fputs(log, a->ac_savefp); 600145510Sdarrenr } 601145510Sdarrenr 602145510Sdarrenr if (a->ac_exec != NULL) { 603145510Sdarrenr switch (fork()) 604145510Sdarrenr { 605145510Sdarrenr case 0 : 606145510Sdarrenr { 607145510Sdarrenr FILE *pi; 608145510Sdarrenr 609145510Sdarrenr pi = popen(a->ac_run, "w"); 610145510Sdarrenr if (pi != NULL) { 611145510Sdarrenr fprintf(pi, "%s\n", log); 612145510Sdarrenr if ((opts & OPT_HEXHDR) != 0) { 613145510Sdarrenr dumphex(pi, 0, buf, 614145510Sdarrenr sizeof(*ipl) + 615145510Sdarrenr sizeof(*ipf)); 616145510Sdarrenr } 617145510Sdarrenr if ((opts & OPT_HEXBODY) != 0) { 618145510Sdarrenr dumphex(pi, 0, (char *)ip, 619145510Sdarrenr ipf->fl_hlen + 620145510Sdarrenr ipf->fl_plen); 621145510Sdarrenr } 622145510Sdarrenr pclose(pi); 623145510Sdarrenr } 624145510Sdarrenr exit(1); 625145510Sdarrenr } 626145510Sdarrenr case -1 : 627145510Sdarrenr break; 628145510Sdarrenr default : 629145510Sdarrenr break; 630145510Sdarrenr } 631145510Sdarrenr } 632145510Sdarrenr } 633145510Sdarrenr 634145510Sdarrenr return matched; 635145510Sdarrenr} 636145510Sdarrenr 637145510Sdarrenr 638145510Sdarrenrstatic void free_action(a) 639145510Sdarrenripmon_action_t *a; 640145510Sdarrenr{ 641145510Sdarrenr if (a->ac_savefile != NULL) { 642145510Sdarrenr free(a->ac_savefile); 643145510Sdarrenr a->ac_savefile = NULL; 644145510Sdarrenr } 645145510Sdarrenr if (a->ac_savefp != NULL) { 646145510Sdarrenr fclose(a->ac_savefp); 647145510Sdarrenr a->ac_savefp = NULL; 648145510Sdarrenr } 649145510Sdarrenr if (a->ac_exec != NULL) { 650145510Sdarrenr free(a->ac_exec); 651145510Sdarrenr if (a->ac_run == a->ac_exec) 652145510Sdarrenr a->ac_run = NULL; 653145510Sdarrenr a->ac_exec = NULL; 654145510Sdarrenr } 655145510Sdarrenr if (a->ac_run != NULL) { 656145510Sdarrenr free(a->ac_run); 657145510Sdarrenr a->ac_run = NULL; 658145510Sdarrenr } 659145510Sdarrenr if (a->ac_iface != NULL) { 660145510Sdarrenr free(a->ac_iface); 661145510Sdarrenr a->ac_iface = NULL; 662145510Sdarrenr } 663145510Sdarrenr a->ac_next = NULL; 664145510Sdarrenr free(a); 665145510Sdarrenr} 666145510Sdarrenr 667145510Sdarrenr 668145510Sdarrenrint load_config(file) 669145510Sdarrenrchar *file; 670145510Sdarrenr{ 671145510Sdarrenr ipmon_action_t *a; 672145510Sdarrenr FILE *fp; 673145510Sdarrenr char *s; 674145510Sdarrenr 675145510Sdarrenr s = getenv("YYDEBUG"); 676145510Sdarrenr if (s != NULL) 677145510Sdarrenr yydebug = atoi(s); 678145510Sdarrenr else 679145510Sdarrenr yydebug = 0; 680145510Sdarrenr 681145510Sdarrenr while ((a = alist) != NULL) { 682145510Sdarrenr alist = a->ac_next; 683145510Sdarrenr free_action(a); 684145510Sdarrenr } 685145510Sdarrenr 686145510Sdarrenr yylineNum = 1; 687145510Sdarrenr 688145510Sdarrenr (void) yysettab(yywords); 689145510Sdarrenr 690145510Sdarrenr fp = fopen(file, "r"); 691145510Sdarrenr if (!fp) { 692145510Sdarrenr perror("load_config:fopen:"); 693145510Sdarrenr return -1; 694145510Sdarrenr } 695145510Sdarrenr yyin = fp; 696145510Sdarrenr while (!feof(fp)) 697145510Sdarrenr yyparse(); 698145510Sdarrenr fclose(fp); 699145510Sdarrenr return 0; 700145510Sdarrenr} 701