ipmon_y.y revision 255332
12061Sjkh/* $FreeBSD: head/contrib/ipfilter/tools/ipmon_y.y 255332 2013-09-06 23:11:19Z cy $ */ 212483Speter 32061Sjkh/* 42061Sjkh * Copyright (C) 2012 by Darren Reed. 58854Srgrimes * 62061Sjkh * See the IPFILTER.LICENCE file for details on licencing. 72061Sjkh */ 83197Scsgr%{ 93197Scsgr#include "ipf.h" 102061Sjkh#include <syslog.h> 1112483Speter#undef OPT_NAT 122160Scsgr#undef OPT_VERBOSE 132834Swollman#include "ipmon_l.h" 142061Sjkh#include "ipmon.h" 152061Sjkh 162160Scsgr#include <dlfcn.h> 171594Srgrimes 182061Sjkh#define YYDEBUG 1 192061Sjkh 201594Srgrimesextern void yyerror __P((char *)); 217407Srgrimesextern int yyparse __P((void)); 227407Srgrimesextern int yylex __P((void)); 237108Sphkextern int yydebug; 247108Sphkextern FILE *yyin; 257108Sphkextern int yylineNum; 267407Srgrimesextern int ipmonopts; 277407Srgrimes 287407Srgrimestypedef struct opt_s { 297108Sphk struct opt_s *o_next; 302061Sjkh int o_line; 312061Sjkh int o_type; 322061Sjkh int o_num; 332061Sjkh char *o_str; 342061Sjkh struct in_addr o_ip; 352061Sjkh int o_logfac; 362061Sjkh int o_logpri; 372061Sjkh} opt_t; 382061Sjkh 392061Sjkhstatic void build_action __P((opt_t *, ipmon_doing_t *)); 402061Sjkhstatic opt_t *new_opt __P((int)); 412061Sjkhstatic void free_action __P((ipmon_action_t *)); 423197Scsgrstatic void print_action __P((ipmon_action_t *)); 432626Scsgrstatic int find_doing __P((char *)); 442626Scsgrstatic ipmon_doing_t *build_doing __P((char *, char *)); 452061Sjkhstatic void print_match __P((ipmon_action_t *)); 462061Sjkhstatic int install_saver __P((char *, char *)); 472061Sjkh 482061Sjkhstatic ipmon_action_t *alist = NULL; 492061Sjkh 502061Sjkhipmon_saver_int_t *saverlist = NULL; 512061Sjkh%} 522061Sjkh 532061Sjkh%union { 542061Sjkh char *str; 552061Sjkh u_32_t num; 562061Sjkh struct in_addr addr; 572061Sjkh struct opt_s *opt; 582061Sjkh union i6addr ip6; 592061Sjkh struct ipmon_doing_s *ipmd; 602061Sjkh} 612061Sjkh 622061Sjkh%token <num> YY_NUMBER YY_HEX 632834Swollman%token <str> YY_STR 642834Swollman%token <ip6> YY_IPV6 652834Swollman%token YY_COMMENT 662834Swollman%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 672834Swollman%token YY_RANGE_OUT YY_RANGE_IN 682834Swollman 691594Srgrimes%token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT 704486Sphk%token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION 714486Sphk%token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE 724486Sphk%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH 734486Sphk%token IPM_DO IPM_DOING IPM_TYPE IPM_NAT 744486Sphk%token IPM_STATE IPM_NATTAG IPM_IPF 752061Sjkh%type <addr> ipv4 762061Sjkh%type <opt> direction dstip dstport every group interface 772061Sjkh%type <opt> protocol result rule srcip srcport logtag matching 782061Sjkh%type <opt> matchopt nattag type 792061Sjkh%type <num> typeopt 802061Sjkh%type <ipmd> doopt doing 812061Sjkh 822061Sjkh%% 832061Sjkhfile: action 842061Sjkh | file action 852061Sjkh ; 862061Sjkh 872061Sjkhaction: line ';' 882061Sjkh | assign ';' 892061Sjkh | IPM_COMMENT 9012483Speter | YY_COMMENT 9112483Speter ; 9212483Speter 9312483Speterline: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}' 9412483Speter { build_action($3, $8); 9512483Speter resetlexer(); 962061Sjkh } 972061Sjkh | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3)) 988854Srgrimes yyerror("install saver"); 992061Sjkh } 1002061Sjkh ; 10112483Speter 1022061Sjkhassign: YY_STR assigning YY_STR { set_variable($1, $3); 10312483Speter resetlexer(); 1042061Sjkh free($1); 1052061Sjkh free($3); 1062061Sjkh yyvarnext = 0; 1072061Sjkh } 1082061Sjkh ; 1092061Sjkh 1102061Sjkhassigning: 11112483Speter '=' { yyvarnext = 1; } 11212483Speter ; 11312483Speter 11412483Spetermatching: 11512483Speter matchopt { $$ = $1; } 11612483Speter | matchopt ',' matching { $1->o_next = $3; $$ = $1; } 11712483Speter ; 11812483Speter 1193030Srgrimesmatchopt: 1202061Sjkh direction { $$ = $1; } 1213030Srgrimes | dstip { $$ = $1; } 1222061Sjkh | dstport { $$ = $1; } 1236722Sphk | every { $$ = $1; } 1242061Sjkh | group { $$ = $1; } 1252302Spaul | interface { $$ = $1; } 1262302Spaul | protocol { $$ = $1; } 1272302Spaul | result { $$ = $1; } 1282302Spaul | rule { $$ = $1; } 1292302Spaul | srcip { $$ = $1; } 1302302Spaul | srcport { $$ = $1; } 13110760Sache | logtag { $$ = $1; } 13210760Sache | nattag { $$ = $1; } 1332302Spaul | type { $$ = $1; } 13410760Sache ; 13510760Sache 13610760Sachedoing: 13710760Sache doopt { $$ = $1; } 1382302Spaul | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; } 1392302Spaul ; 1402302Spaul 1412302Spauldoopt: 1422302Spaul YY_STR { if (find_doing($1) != IPM_DOING) 1432302Spaul yyerror("unknown action"); 1442302Spaul } 1452061Sjkh '(' YY_STR ')' { $$ = build_doing($1, $4); 1462061Sjkh if ($$ == NULL) 1472061Sjkh yyerror("action building"); 1482061Sjkh } 1492061Sjkh | YY_STR { if (find_doing($1) == IPM_DOING) 1502061Sjkh $$ = build_doing($1, NULL); 1512061Sjkh } 1522061Sjkh ; 1532061Sjkh 1542061Sjkhdirection: 1552061Sjkh IPM_DIRECTION '=' IPM_IN { $$ = new_opt(IPM_DIRECTION); 1562061Sjkh $$->o_num = IPM_IN; } 1572061Sjkh | IPM_DIRECTION '=' IPM_OUT { $$ = new_opt(IPM_DIRECTION); 1582061Sjkh $$->o_num = IPM_OUT; } 1592061Sjkh ; 1602061Sjkh 1612061Sjkhdstip: IPM_DSTIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_DSTIP); 1622061Sjkh $$->o_ip = $3; 1632061Sjkh $$->o_num = $5; } 1642061Sjkh ; 1652061Sjkh 1662061Sjkhdstport: 1672061Sjkh IPM_DSTPORT '=' YY_NUMBER { $$ = new_opt(IPM_DSTPORT); 1682061Sjkh $$->o_num = $3; } 1692061Sjkh | IPM_DSTPORT '=' YY_STR { $$ = new_opt(IPM_DSTPORT); 1702061Sjkh $$->o_str = $3; } 1713626Swollman ; 1723626Swollman 1733626Swollmanevery: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND); 1743626Swollman $$->o_num = 1; } 1753626Swollman | IPM_EVERY YY_NUMBER IPM_SECONDS { $$ = new_opt(IPM_SECOND); 1763626Swollman $$->o_num = $2; } 1773626Swollman | IPM_EVERY IPM_PACKET { $$ = new_opt(IPM_PACKET); 1783626Swollman $$->o_num = 1; } 1793626Swollman | IPM_EVERY YY_NUMBER IPM_PACKETS { $$ = new_opt(IPM_PACKET); 1803626Swollman $$->o_num = $2; } 1813626Swollman ; 1827059Sroberto 1833626Swollmangroup: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP); 1843626Swollman $$->o_num = $3; } 1853626Swollman | IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP); 1863626Swollman $$->o_str = $3; } 1873626Swollman ; 1883626Swollman 1893626Swollmaninterface: 1903626Swollman IPM_INTERFACE '=' YY_STR { $$ = new_opt(IPM_INTERFACE); 1913626Swollman $$->o_str = $3; } 1923626Swollman ; 1933626Swollman 1943626Swollmanlogtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG); 1953626Swollman $$->o_num = $3; } 1963626Swollman ; 1973626Swollman 1983626Swollmannattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG); 1993626Swollman $$->o_str = $3; } 2003626Swollman ; 2017446Ssos 2023626Swollmanprotocol: 2033626Swollman IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL); 2043626Swollman $$->o_num = $3; } 2053626Swollman | IPM_PROTOCOL '=' YY_STR { $$ = new_opt(IPM_PROTOCOL); 2063626Swollman $$->o_num = getproto($3); 2073626Swollman free($3); 2083626Swollman } 2092061Sjkh ; 2102061Sjkh 2112061Sjkhresult: IPM_RESULT '=' YY_STR { $$ = new_opt(IPM_RESULT); 2122061Sjkh $$->o_str = $3; } 2132061Sjkh ; 2142061Sjkh 2152061Sjkhrule: IPM_RULE '=' YY_NUMBER { $$ = new_opt(IPM_RULE); 2162061Sjkh $$->o_num = YY_NUMBER; } 2172061Sjkh ; 2182061Sjkh 2192061Sjkhsrcip: IPM_SRCIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_SRCIP); 2202061Sjkh $$->o_ip = $3; 2217130Srgrimes $$->o_num = $5; } 2227130Srgrimes ; 2237130Srgrimes 2242061Sjkhsrcport: 2252061Sjkh IPM_SRCPORT '=' YY_NUMBER { $$ = new_opt(IPM_SRCPORT); 2264249Sache $$->o_num = $3; } 2272685Srgrimes | IPM_SRCPORT '=' YY_STR { $$ = new_opt(IPM_SRCPORT); 2286927Snate $$->o_str = $3; } 2292685Srgrimes ; 2303518Sache 2313197Scsgrtype: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE); 2323197Scsgr $$->o_num = $3; } 23312166Sjkh ; 2343197Scsgr 2352061Sjkhtypeopt: 2362061Sjkh IPM_IPF { $$ = IPL_MAGIC; } 2372061Sjkh | IPM_NAT { $$ = IPL_MAGIC_NAT; } 2382883Sphk | IPM_STATE { $$ = IPL_MAGIC_STATE; } 2393429Sache ; 2403429Sache 2417281Srgrimes 2423242Spaul 2433242Spaulipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 2447171Sats { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 2452061Sjkh yyerror("Invalid octet string for IP address"); 2463213Spst return 0; 2474942Sache } 2485749Swollman $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 2495772Swollman $$.s_addr = htonl($$.s_addr); 2505865Sache } 2515866Sache%% 2522061Sjkhstatic struct wordtab yywords[] = { 2535366Snate { "body", IPM_BODY }, 2545366Snate { "direction", IPM_DIRECTION }, 2556934Sse { "do", IPM_DO }, 2565366Snate { "dstip", IPM_DSTIP }, 2575366Snate { "dstport", IPM_DSTPORT }, 2587292Srgrimes { "every", IPM_EVERY }, 2597292Srgrimes { "group", IPM_GROUP }, 2605366Snate { "in", IPM_IN }, 2615366Snate { "interface", IPM_INTERFACE }, 2625366Snate { "ipf", IPM_IPF }, 2635366Snate { "load_action",IPM_LOADACTION }, 2645366Snate { "logtag", IPM_LOGTAG }, 2655366Snate { "match", IPM_MATCH }, 2665772Swollman { "nat", IPM_NAT }, 2675772Swollman { "nattag", IPM_NATTAG }, 2685728Swollman { "no", IPM_NO }, 2695728Swollman { "out", IPM_OUT }, 2705728Swollman { "packet", IPM_PACKET }, 2715728Swollman { "packets", IPM_PACKETS }, 2725728Swollman { "protocol", IPM_PROTOCOL }, 2735366Snate { "result", IPM_RESULT }, 2742061Sjkh { "rule", IPM_RULE }, 2752061Sjkh { "second", IPM_SECOND }, 2762061Sjkh { "seconds", IPM_SECONDS }, 2772061Sjkh { "srcip", IPM_SRCIP }, 2782061Sjkh { "srcport", IPM_SRCPORT }, 2792061Sjkh { "state", IPM_STATE }, 2802061Sjkh { "with", IPM_WITH }, 2812061Sjkh { NULL, 0 } 2822061Sjkh}; 2838295Srgrimes 2848295Srgrimesstatic int macflags[17][2] = { 28511772Snate { IPM_DIRECTION, IPMAC_DIRECTION }, 2868295Srgrimes { IPM_DSTIP, IPMAC_DSTIP }, 2878489Srgrimes { IPM_DSTPORT, IPMAC_DSTPORT }, 2888489Srgrimes { IPM_GROUP, IPMAC_GROUP }, 28911772Snate { IPM_INTERFACE, IPMAC_INTERFACE }, 2908489Srgrimes { IPM_LOGTAG, IPMAC_LOGTAG }, 2918489Srgrimes { IPM_NATTAG, IPMAC_NATTAG }, 2928489Srgrimes { IPM_PACKET, IPMAC_EVERY }, 29311772Snate { IPM_PROTOCOL, IPMAC_PROTOCOL }, 2948489Srgrimes { IPM_RESULT, IPMAC_RESULT }, 2958295Srgrimes { IPM_RULE, IPMAC_RULE }, 2962468Spaul { IPM_SECOND, IPMAC_EVERY }, 2972061Sjkh { IPM_SRCIP, IPMAC_SRCIP }, 2982273Spaul { IPM_SRCPORT, IPMAC_SRCPORT }, 2992061Sjkh { IPM_TYPE, IPMAC_TYPE }, 3008295Srgrimes { IPM_WITH, IPMAC_WITH }, 3012160Scsgr { 0, 0 } 3022160Scsgr}; 3032160Scsgr 3042160Scsgrstatic opt_t * 3052279Spaulnew_opt(type) 3064054Spst int type; 3074054Spst{ 3082061Sjkh opt_t *o; 3092061Sjkh 3102279Spaul o = (opt_t *)calloc(1, sizeof(*o)); 31111772Snate o->o_type = type; 3122468Spaul o->o_line = yylineNum; 3132468Spaul o->o_logfac = -1; 31411772Snate o->o_logpri = -1; 3153197Scsgr return o; 3162626Scsgr} 3172626Scsgr 31810838Sjkhstatic void 3192626Scsgrbuild_action(olist, todo) 3202626Scsgr opt_t *olist; 3218304Srgrimes ipmon_doing_t *todo; 3228304Srgrimes{ 32311772Snate ipmon_action_t *a; 3248304Srgrimes opt_t *o; 3252061Sjkh int i; 32611806Sphk 3272061Sjkh a = (ipmon_action_t *)calloc(1, sizeof(*a)); 32812106Sjfieber if (a == NULL) 3292061Sjkh return; 3302061Sjkh 3312273Spaul while ((o = olist) != NULL) { 3322061Sjkh /* 3332061Sjkh * Check to see if the same comparator is being used more than 3342061Sjkh * once per matching statement. 33511769Sphk */ 33611769Sphk for (i = 0; macflags[i][0]; i++) 33712106Sjfieber if (macflags[i][0] == o->o_type) 33812106Sjfieber break; 33912106Sjfieber if (macflags[i][1] & a->ac_mflag) { 34012106Sjfieber fprintf(stderr, "%s redfined on line %d\n", 34110479Sdg yykeytostr(o->o_type), yylineNum); 34210479Sdg if (o->o_str != NULL) 3432061Sjkh free(o->o_str); 3441594Srgrimes olist = o->o_next; 345 free(o); 346 continue; 347 } 348 349 a->ac_mflag |= macflags[i][1]; 350 351 switch (o->o_type) 352 { 353 case IPM_DIRECTION : 354 a->ac_direction = o->o_num; 355 break; 356 case IPM_DSTIP : 357 a->ac_dip = o->o_ip.s_addr; 358 a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num)); 359 break; 360 case IPM_DSTPORT : 361 a->ac_dport = htons(o->o_num); 362 break; 363 case IPM_INTERFACE : 364 a->ac_iface = o->o_str; 365 o->o_str = NULL; 366 break; 367 case IPM_GROUP : 368 if (o->o_str != NULL) 369 strncpy(a->ac_group, o->o_str, FR_GROUPLEN); 370 else 371 sprintf(a->ac_group, "%d", o->o_num); 372 break; 373 case IPM_LOGTAG : 374 a->ac_logtag = o->o_num; 375 break; 376 case IPM_NATTAG : 377 strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag)); 378 break; 379 case IPM_PACKET : 380 a->ac_packet = o->o_num; 381 break; 382 case IPM_PROTOCOL : 383 a->ac_proto = o->o_num; 384 break; 385 case IPM_RULE : 386 a->ac_rule = o->o_num; 387 break; 388 case IPM_RESULT : 389 if (!strcasecmp(o->o_str, "pass")) 390 a->ac_result = IPMR_PASS; 391 else if (!strcasecmp(o->o_str, "block")) 392 a->ac_result = IPMR_BLOCK; 393 else if (!strcasecmp(o->o_str, "nomatch")) 394 a->ac_result = IPMR_NOMATCH; 395 else if (!strcasecmp(o->o_str, "log")) 396 a->ac_result = IPMR_LOG; 397 break; 398 case IPM_SECOND : 399 a->ac_second = o->o_num; 400 break; 401 case IPM_SRCIP : 402 a->ac_sip = o->o_ip.s_addr; 403 a->ac_smsk = htonl(0xffffffff << (32 - o->o_num)); 404 break; 405 case IPM_SRCPORT : 406 a->ac_sport = htons(o->o_num); 407 break; 408 case IPM_TYPE : 409 a->ac_type = o->o_num; 410 break; 411 case IPM_WITH : 412 break; 413 default : 414 break; 415 } 416 417 olist = o->o_next; 418 if (o->o_str != NULL) 419 free(o->o_str); 420 free(o); 421 } 422 423 a->ac_doing = todo; 424 a->ac_next = alist; 425 alist = a; 426 427 if (ipmonopts & IPMON_VERBOSE) 428 print_action(a); 429} 430 431 432int 433check_action(buf, log, opts, lvl) 434 char *buf, *log; 435 int opts, lvl; 436{ 437 ipmon_action_t *a; 438 struct timeval tv; 439 ipmon_doing_t *d; 440 ipmon_msg_t msg; 441 ipflog_t *ipf; 442 tcphdr_t *tcp; 443 iplog_t *ipl; 444 int matched; 445 u_long t1; 446 ip_t *ip; 447 448 matched = 0; 449 ipl = (iplog_t *)buf; 450 ipf = (ipflog_t *)(ipl +1); 451 ip = (ip_t *)(ipf + 1); 452 tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); 453 454 msg.imm_data = ipl; 455 msg.imm_dsize = ipl->ipl_dsize; 456 msg.imm_when = ipl->ipl_time.tv_sec; 457 msg.imm_msg = log; 458 msg.imm_msglen = strlen(log); 459 msg.imm_loglevel = lvl; 460 461 for (a = alist; a != NULL; a = a->ac_next) { 462 verbose(0, "== checking config rule\n"); 463 if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { 464 if (a->ac_direction == IPM_IN) { 465 if ((ipf->fl_flags & FR_INQUE) == 0) { 466 verbose(8, "-- direction not in\n"); 467 continue; 468 } 469 } else if (a->ac_direction == IPM_OUT) { 470 if ((ipf->fl_flags & FR_OUTQUE) == 0) { 471 verbose(8, "-- direction not out\n"); 472 continue; 473 } 474 } 475 } 476 477 if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) { 478 verbose(8, "-- type mismatch\n"); 479 continue; 480 } 481 482 if ((a->ac_mflag & IPMAC_EVERY) != 0) { 483 gettimeofday(&tv, NULL); 484 t1 = tv.tv_sec - a->ac_lastsec; 485 if (tv.tv_usec <= a->ac_lastusec) 486 t1--; 487 if (a->ac_second != 0) { 488 if (t1 < a->ac_second) { 489 verbose(8, "-- too soon\n"); 490 continue; 491 } 492 a->ac_lastsec = tv.tv_sec; 493 a->ac_lastusec = tv.tv_usec; 494 } 495 496 if (a->ac_packet != 0) { 497 if (a->ac_pktcnt == 0) 498 a->ac_pktcnt++; 499 else if (a->ac_pktcnt == a->ac_packet) { 500 a->ac_pktcnt = 0; 501 verbose(8, "-- packet count\n"); 502 continue; 503 } else { 504 a->ac_pktcnt++; 505 verbose(8, "-- packet count\n"); 506 continue; 507 } 508 } 509 } 510 511 if ((a->ac_mflag & IPMAC_DSTIP) != 0) { 512 if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) { 513 verbose(8, "-- dstip wrong\n"); 514 continue; 515 } 516 } 517 518 if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { 519 if (ip->ip_p != IPPROTO_UDP && 520 ip->ip_p != IPPROTO_TCP) { 521 verbose(8, "-- not port protocol\n"); 522 continue; 523 } 524 if (tcp->th_dport != a->ac_dport) { 525 verbose(8, "-- dport mismatch\n"); 526 continue; 527 } 528 } 529 530 if ((a->ac_mflag & IPMAC_GROUP) != 0) { 531 if (strncmp(a->ac_group, ipf->fl_group, 532 FR_GROUPLEN) != 0) { 533 verbose(8, "-- group mismatch\n"); 534 continue; 535 } 536 } 537 538 if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { 539 if (strcmp(a->ac_iface, ipf->fl_ifname)) { 540 verbose(8, "-- ifname mismatch\n"); 541 continue; 542 } 543 } 544 545 if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { 546 if (a->ac_proto != ip->ip_p) { 547 verbose(8, "-- protocol mismatch\n"); 548 continue; 549 } 550 } 551 552 if ((a->ac_mflag & IPMAC_RESULT) != 0) { 553 if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { 554 if (a->ac_result != IPMR_NOMATCH) { 555 verbose(8, "-- ff-flags mismatch\n"); 556 continue; 557 } 558 } else if (FR_ISPASS(ipf->fl_flags)) { 559 if (a->ac_result != IPMR_PASS) { 560 verbose(8, "-- pass mismatch\n"); 561 continue; 562 } 563 } else if (FR_ISBLOCK(ipf->fl_flags)) { 564 if (a->ac_result != IPMR_BLOCK) { 565 verbose(8, "-- block mismatch\n"); 566 continue; 567 } 568 } else { /* Log only */ 569 if (a->ac_result != IPMR_LOG) { 570 verbose(8, "-- log mismatch\n"); 571 continue; 572 } 573 } 574 } 575 576 if ((a->ac_mflag & IPMAC_RULE) != 0) { 577 if (a->ac_rule != ipf->fl_rule) { 578 verbose(8, "-- rule mismatch\n"); 579 continue; 580 } 581 } 582 583 if ((a->ac_mflag & IPMAC_SRCIP) != 0) { 584 if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) { 585 verbose(8, "-- srcip mismatch\n"); 586 continue; 587 } 588 } 589 590 if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { 591 if (ip->ip_p != IPPROTO_UDP && 592 ip->ip_p != IPPROTO_TCP) { 593 verbose(8, "-- port protocol mismatch\n"); 594 continue; 595 } 596 if (tcp->th_sport != a->ac_sport) { 597 verbose(8, "-- sport mismatch\n"); 598 continue; 599 } 600 } 601 602 if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { 603 if (a->ac_logtag != ipf->fl_logtag) { 604 verbose(8, "-- logtag %d != %d\n", 605 a->ac_logtag, ipf->fl_logtag); 606 continue; 607 } 608 } 609 610 if ((a->ac_mflag & IPMAC_NATTAG) != 0) { 611 if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, 612 IPFTAG_LEN) != 0) { 613 verbose(8, "-- nattag mismatch\n"); 614 continue; 615 } 616 } 617 618 matched = 1; 619 verbose(8, "++ matched\n"); 620 621 /* 622 * It matched so now perform the saves 623 */ 624 for (d = a->ac_doing; d != NULL; d = d->ipmd_next) 625 (*d->ipmd_store)(d->ipmd_token, &msg); 626 } 627 628 return matched; 629} 630 631 632static void 633free_action(a) 634 ipmon_action_t *a; 635{ 636 ipmon_doing_t *d; 637 638 while ((d = a->ac_doing) != NULL) { 639 a->ac_doing = d->ipmd_next; 640 (*d->ipmd_saver->ims_destroy)(d->ipmd_token); 641 free(d); 642 } 643 644 if (a->ac_iface != NULL) { 645 free(a->ac_iface); 646 a->ac_iface = NULL; 647 } 648 a->ac_next = NULL; 649 free(a); 650} 651 652 653int 654load_config(file) 655 char *file; 656{ 657 FILE *fp; 658 char *s; 659 660 unload_config(); 661 662 s = getenv("YYDEBUG"); 663 if (s != NULL) 664 yydebug = atoi(s); 665 else 666 yydebug = 0; 667 668 yylineNum = 1; 669 670 (void) yysettab(yywords); 671 672 fp = fopen(file, "r"); 673 if (!fp) { 674 perror("load_config:fopen:"); 675 return -1; 676 } 677 yyin = fp; 678 while (!feof(fp)) 679 yyparse(); 680 fclose(fp); 681 return 0; 682} 683 684 685void 686unload_config() 687{ 688 ipmon_saver_int_t *sav, **imsip; 689 ipmon_saver_t *is; 690 ipmon_action_t *a; 691 692 while ((a = alist) != NULL) { 693 alist = a->ac_next; 694 free_action(a); 695 } 696 697 /* 698 * Look for savers that have been added in dynamically from the 699 * configuration file. 700 */ 701 for (imsip = &saverlist; (sav = *imsip) != NULL; ) { 702 if (sav->imsi_handle == NULL) 703 imsip = &sav->imsi_next; 704 else { 705 dlclose(sav->imsi_handle); 706 707 *imsip = sav->imsi_next; 708 is = sav->imsi_stor; 709 free(sav); 710 711 free(is->ims_name); 712 free(is); 713 } 714 } 715} 716 717 718void 719dump_config() 720{ 721 ipmon_action_t *a; 722 723 for (a = alist; a != NULL; a = a->ac_next) { 724 print_action(a); 725 726 printf("#\n"); 727 } 728} 729 730 731static void 732print_action(a) 733 ipmon_action_t *a; 734{ 735 ipmon_doing_t *d; 736 737 printf("match { "); 738 print_match(a); 739 printf("; }\n"); 740 printf("do {"); 741 for (d = a->ac_doing; d != NULL; d = d->ipmd_next) { 742 printf("%s", d->ipmd_saver->ims_name); 743 if (d->ipmd_saver->ims_print != NULL) { 744 printf("(\""); 745 (*d->ipmd_saver->ims_print)(d->ipmd_token); 746 printf("\")"); 747 } 748 printf(";"); 749 } 750 printf("};\n"); 751} 752 753 754void * 755add_doing(saver) 756 ipmon_saver_t *saver; 757{ 758 ipmon_saver_int_t *it; 759 760 if (find_doing(saver->ims_name) == IPM_DOING) 761 return NULL; 762 763 it = calloc(1, sizeof(*it)); 764 if (it == NULL) 765 return NULL; 766 it->imsi_stor = saver; 767 it->imsi_next = saverlist; 768 saverlist = it; 769 return it; 770} 771 772 773static int 774find_doing(string) 775 char *string; 776{ 777 ipmon_saver_int_t *it; 778 779 for (it = saverlist; it != NULL; it = it->imsi_next) { 780 if (!strcmp(it->imsi_stor->ims_name, string)) 781 return IPM_DOING; 782 } 783 return 0; 784} 785 786 787static ipmon_doing_t * 788build_doing(target, options) 789 char *target; 790 char *options; 791{ 792 ipmon_saver_int_t *it; 793 char *strarray[2]; 794 ipmon_doing_t *d, *d1; 795 ipmon_action_t *a; 796 ipmon_saver_t *save; 797 798 d = calloc(1, sizeof(*d)); 799 if (d == NULL) 800 return NULL; 801 802 for (it = saverlist; it != NULL; it = it->imsi_next) { 803 if (!strcmp(it->imsi_stor->ims_name, target)) 804 break; 805 } 806 if (it == NULL) { 807 free(d); 808 return NULL; 809 } 810 811 strarray[0] = options; 812 strarray[1] = NULL; 813 814 d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray); 815 if (d->ipmd_token == NULL) { 816 free(d); 817 return NULL; 818 } 819 820 save = it->imsi_stor; 821 d->ipmd_saver = save; 822 d->ipmd_store = it->imsi_stor->ims_store; 823 824 /* 825 * Look for duplicate do-things that need to be dup'd 826 */ 827 for (a = alist; a != NULL; a = a->ac_next) { 828 for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) { 829 if (save != d1->ipmd_saver) 830 continue; 831 if (save->ims_match == NULL || save->ims_dup == NULL) 832 continue; 833 if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token)) 834 continue; 835 836 (*d->ipmd_saver->ims_destroy)(d->ipmd_token); 837 d->ipmd_token = (*save->ims_dup)(d1->ipmd_token); 838 break; 839 } 840 } 841 842 return d; 843} 844 845 846static void 847print_match(a) 848 ipmon_action_t *a; 849{ 850 char *coma = ""; 851 852 if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { 853 printf("direction = "); 854 if (a->ac_direction == IPM_IN) 855 printf("in"); 856 else if (a->ac_direction == IPM_OUT) 857 printf("out"); 858 coma = ", "; 859 } 860 861 if ((a->ac_mflag & IPMAC_DSTIP) != 0) { 862 printf("%sdstip = ", coma); 863 printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk); 864 coma = ", "; 865 } 866 867 if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { 868 printf("%sdstport = %hu", coma, ntohs(a->ac_dport)); 869 coma = ", "; 870 } 871 872 if ((a->ac_mflag & IPMAC_GROUP) != 0) { 873 char group[FR_GROUPLEN+1]; 874 875 strncpy(group, a->ac_group, FR_GROUPLEN); 876 group[FR_GROUPLEN] = '\0'; 877 printf("%sgroup = %s", coma, group); 878 coma = ", "; 879 } 880 881 if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { 882 printf("%siface = %s", coma, a->ac_iface); 883 coma = ", "; 884 } 885 886 if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { 887 printf("%slogtag = %u", coma, a->ac_logtag); 888 coma = ", "; 889 } 890 891 if ((a->ac_mflag & IPMAC_NATTAG) != 0) { 892 char tag[17]; 893 894 strncpy(tag, a->ac_nattag, 16); 895 tag[16] = '\0'; 896 printf("%snattag = %s", coma, tag); 897 coma = ", "; 898 } 899 900 if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { 901 printf("%sprotocol = %u", coma, a->ac_proto); 902 coma = ", "; 903 } 904 905 if ((a->ac_mflag & IPMAC_RESULT) != 0) { 906 printf("%sresult = ", coma); 907 switch (a->ac_result) 908 { 909 case IPMR_LOG : 910 printf("log"); 911 break; 912 case IPMR_PASS : 913 printf("pass"); 914 break; 915 case IPMR_BLOCK : 916 printf("block"); 917 break; 918 case IPMR_NOMATCH : 919 printf("nomatch"); 920 break; 921 } 922 coma = ", "; 923 } 924 925 if ((a->ac_mflag & IPMAC_RULE) != 0) { 926 printf("%srule = %u", coma, a->ac_rule); 927 coma = ", "; 928 } 929 930 if ((a->ac_mflag & IPMAC_EVERY) != 0) { 931 if (a->ac_packet > 1) { 932 printf("%severy %d packets", coma, a->ac_packet); 933 coma = ", "; 934 } else if (a->ac_packet == 1) { 935 printf("%severy packet", coma); 936 coma = ", "; 937 } 938 if (a->ac_second > 1) { 939 printf("%severy %d seconds", coma, a->ac_second); 940 coma = ", "; 941 } else if (a->ac_second == 1) { 942 printf("%severy second", coma); 943 coma = ", "; 944 } 945 } 946 947 if ((a->ac_mflag & IPMAC_SRCIP) != 0) { 948 printf("%ssrcip = ", coma); 949 printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk); 950 coma = ", "; 951 } 952 953 if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { 954 printf("%ssrcport = %hu", coma, ntohs(a->ac_sport)); 955 coma = ", "; 956 } 957 958 if ((a->ac_mflag & IPMAC_TYPE) != 0) { 959 printf("%stype = ", coma); 960 switch (a->ac_type) 961 { 962 case IPL_LOGIPF : 963 printf("ipf"); 964 break; 965 case IPL_LOGSTATE : 966 printf("state"); 967 break; 968 case IPL_LOGNAT : 969 printf("nat"); 970 break; 971 } 972 coma = ", "; 973 } 974 975 if ((a->ac_mflag & IPMAC_WITH) != 0) { 976 printf("%swith ", coma); 977 coma = ", "; 978 } 979} 980 981 982static int 983install_saver(name, path) 984 char *name, *path; 985{ 986 ipmon_saver_int_t *isi; 987 ipmon_saver_t *is; 988 char nbuf[80]; 989 990 if (find_doing(name) == IPM_DOING) 991 return -1; 992 993 isi = calloc(1, sizeof(*isi)); 994 if (isi == NULL) 995 return -1; 996 997 is = calloc(1, sizeof(*is)); 998 if (is == NULL) 999 goto loaderror; 1000 1001 is->ims_name = name; 1002 1003#ifdef RTLD_LAZY 1004 isi->imsi_handle = dlopen(path, RTLD_LAZY); 1005#endif 1006#ifdef DL_LAZY 1007 isi->imsi_handle = dlopen(path, DL_LAZY); 1008#endif 1009 1010 if (isi->imsi_handle == NULL) 1011 goto loaderror; 1012 1013 snprintf(nbuf, sizeof(nbuf), "%sdup", name); 1014 is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf); 1015 1016 snprintf(nbuf, sizeof(nbuf), "%sdestroy", name); 1017 is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf); 1018 if (is->ims_destroy == NULL) 1019 goto loaderror; 1020 1021 snprintf(nbuf, sizeof(nbuf), "%smatch", name); 1022 is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf); 1023 1024 snprintf(nbuf, sizeof(nbuf), "%sparse", name); 1025 is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf); 1026 if (is->ims_parse == NULL) 1027 goto loaderror; 1028 1029 snprintf(nbuf, sizeof(nbuf), "%sprint", name); 1030 is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf); 1031 if (is->ims_print == NULL) 1032 goto loaderror; 1033 1034 snprintf(nbuf, sizeof(nbuf), "%sstore", name); 1035 is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf); 1036 if (is->ims_store == NULL) 1037 goto loaderror; 1038 1039 isi->imsi_stor = is; 1040 isi->imsi_next = saverlist; 1041 saverlist = isi; 1042 1043 return 0; 1044 1045loaderror: 1046 if (isi->imsi_handle != NULL) 1047 dlclose(isi->imsi_handle); 1048 free(isi); 1049 if (is != NULL) 1050 free(is); 1051 return -1; 1052} 1053