diff options
Diffstat (limited to 'contrib/ipfilter/tools/ipmon_y.y')
-rw-r--r-- | contrib/ipfilter/tools/ipmon_y.y | 722 |
1 files changed, 537 insertions, 185 deletions
diff --git a/contrib/ipfilter/tools/ipmon_y.y b/contrib/ipfilter/tools/ipmon_y.y index 98042d8..f14180d 100644 --- a/contrib/ipfilter/tools/ipmon_y.y +++ b/contrib/ipfilter/tools/ipmon_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -13,6 +13,8 @@ #include "ipmon_l.h" #include "ipmon.h" +#include <dlfcn.h> + #define YYDEBUG 1 extern void yyerror __P((char *)); @@ -21,69 +23,88 @@ extern int yylex __P((void)); extern int yydebug; extern FILE *yyin; extern int yylineNum; +extern int ipmonopts; -typedef struct opt { - struct opt *o_next; +typedef struct opt_s { + struct opt_s *o_next; int o_line; int o_type; int o_num; char *o_str; struct in_addr o_ip; + int o_logfac; + int o_logpri; } opt_t; -static void build_action __P((struct opt *)); +static void build_action __P((opt_t *, ipmon_doing_t *)); static opt_t *new_opt __P((int)); static void free_action __P((ipmon_action_t *)); +static void print_action __P((ipmon_action_t *)); +static int find_doing __P((char *)); +static ipmon_doing_t *build_doing __P((char *, char *)); +static void print_match __P((ipmon_action_t *)); +static int install_saver __P((char *, char *)); static ipmon_action_t *alist = NULL; + +ipmon_saver_int_t *saverlist = NULL; %} %union { char *str; u_32_t num; struct in_addr addr; - struct opt *opt; + struct opt_s *opt; union i6addr ip6; + struct ipmon_doing_s *ipmd; } %token <num> YY_NUMBER YY_HEX %token <str> YY_STR %token <ip6> YY_IPV6 -%token YY_COMMENT +%token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT -%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT +%token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION %token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE %token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH -%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT +%token IPM_DO IPM_DOING IPM_TYPE IPM_NAT %token IPM_STATE IPM_NATTAG IPM_IPF %type <addr> ipv4 -%type <opt> direction dstip dstport every execute group interface +%type <opt> direction dstip dstport every group interface %type <opt> protocol result rule srcip srcport logtag matching -%type <opt> matchopt nattag type doopt doing save syslog nothing -%type <num> saveopts saveopt typeopt +%type <opt> matchopt nattag type +%type <num> typeopt +%type <ipmd> doopt doing %% -file: line - | assign - | file line - | file assign +file: action + | file action ; -line: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';' - { build_action($3); resetlexer(); } +action: line ';' + | assign ';' | IPM_COMMENT | YY_COMMENT ; -assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); +line: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}' + { build_action($3, $8); + resetlexer(); + } + | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3)) + yyerror("install saver"); + } + ; + +assign: YY_STR assigning YY_STR { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; - } + } ; assigning: @@ -114,14 +135,20 @@ matchopt: doing: doopt { $$ = $1; } - | doopt ',' doing { $1->o_next = $3; $$ = $1; } + | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; } ; doopt: - execute { $$ = $1; } - | save { $$ = $1; } - | syslog { $$ = $1; } - | nothing { $$ = $1; } + YY_STR { if (find_doing($1) != IPM_DOING) + yyerror("unknown action"); + } + '(' YY_STR ')' { $$ = build_doing($1, $4); + if ($$ == NULL) + yyerror("action building"); + } + | YY_STR { if (find_doing($1) == IPM_DOING) + $$ = build_doing($1, NULL); + } ; direction: @@ -211,31 +238,7 @@ typeopt: | IPM_STATE { $$ = IPL_MAGIC_STATE; } ; -execute: - IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE); - $$->o_str = $2; } - ; -save: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE); - $$->o_num = $2; - $$->o_str = $3; } - ; - -saveopts: { $$ = 0; } - | saveopt { $$ = $1; } - | saveopt ',' saveopts { $$ = $1 | $3; } - ; - -saveopt: - IPM_RAW { $$ = IPMDO_SAVERAW; } - ; - -syslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); } - ; - -nothing: - IPM_NOTHING { $$ = 0; } - ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { @@ -253,30 +256,27 @@ static struct wordtab yywords[] = { { "dstip", IPM_DSTIP }, { "dstport", IPM_DSTPORT }, { "every", IPM_EVERY }, - { "execute", IPM_EXECUTE }, { "group", IPM_GROUP }, { "in", IPM_IN }, { "interface", IPM_INTERFACE }, { "ipf", IPM_IPF }, + { "load_action",IPM_LOADACTION }, { "logtag", IPM_LOGTAG }, { "match", IPM_MATCH }, { "nat", IPM_NAT }, { "nattag", IPM_NATTAG }, { "no", IPM_NO }, - { "nothing", IPM_NOTHING }, { "out", IPM_OUT }, { "packet", IPM_PACKET }, { "packets", IPM_PACKETS }, { "protocol", IPM_PROTOCOL }, { "result", IPM_RESULT }, { "rule", IPM_RULE }, - { "save", IPM_SAVE }, { "second", IPM_SECOND }, { "seconds", IPM_SECONDS }, { "srcip", IPM_SRCIP }, { "srcport", IPM_SRCPORT }, { "state", IPM_STATE }, - { "syslog", IPM_SYSLOG }, { "with", IPM_WITH }, { NULL, 0 } }; @@ -301,31 +301,33 @@ static int macflags[17][2] = { { 0, 0 } }; -static opt_t *new_opt(type) -int type; +static opt_t * +new_opt(type) + int type; { opt_t *o; - o = (opt_t *)malloc(sizeof(*o)); + o = (opt_t *)calloc(1, sizeof(*o)); o->o_type = type; o->o_line = yylineNum; - o->o_num = 0; - o->o_str = (char *)0; - o->o_next = NULL; + o->o_logfac = -1; + o->o_logpri = -1; return o; } -static void build_action(olist) -opt_t *olist; +static void +build_action(olist, todo) + opt_t *olist; + ipmon_doing_t *todo; { ipmon_action_t *a; opt_t *o; - char c; int i; a = (ipmon_action_t *)calloc(1, sizeof(*a)); if (a == NULL) return; + while ((o = olist) != NULL) { /* * Check to see if the same comparator is being used more than @@ -358,24 +360,11 @@ opt_t *olist; case IPM_DSTPORT : a->ac_dport = htons(o->o_num); break; - case IPM_EXECUTE : - a->ac_exec = o->o_str; - c = *o->o_str; - if (c== '"'|| c == '\'') { - if (o->o_str[strlen(o->o_str) - 1] == c) { - a->ac_run = strdup(o->o_str + 1); - a->ac_run[strlen(a->ac_run) - 1] ='\0'; - } else - a->ac_run = o->o_str; - } else - a->ac_run = o->o_str; - o->o_str = NULL; - break; case IPM_INTERFACE : a->ac_iface = o->o_str; o->o_str = NULL; break; - case IPM_GROUP : + case IPM_GROUP : if (o->o_str != NULL) strncpy(a->ac_group, o->o_str, FR_GROUPLEN); else @@ -416,24 +405,6 @@ opt_t *olist; case IPM_SRCPORT : a->ac_sport = htons(o->o_num); break; - case IPM_SAVE : - if (a->ac_savefile != NULL) { - fprintf(stderr, "%s redfined on line %d\n", - yykeytostr(o->o_type), yylineNum); - break; - } - a->ac_savefile = strdup(o->o_str); - a->ac_savefp = fopen(o->o_str, "a"); - a->ac_dflag |= o->o_num & IPMDO_SAVERAW; - break; - case IPM_SYSLOG : - if (a->ac_syslog != 0) { - fprintf(stderr, "%s redfined on line %d\n", - yykeytostr(o->o_type), yylineNum); - break; - } - a->ac_syslog = 1; - break; case IPM_TYPE : a->ac_type = o->o_num; break; @@ -448,17 +419,25 @@ opt_t *olist; free(o->o_str); free(o); } + + a->ac_doing = todo; a->ac_next = alist; alist = a; + + if (ipmonopts & IPMON_VERBOSE) + print_action(a); } -int check_action(buf, log, opts, lvl) -char *buf, *log; -int opts, lvl; +int +check_action(buf, log, opts, lvl) + char *buf, *log; + int opts, lvl; { ipmon_action_t *a; struct timeval tv; + ipmon_doing_t *d; + ipmon_msg_t msg; ipflog_t *ipf; tcphdr_t *tcp; iplog_t *ipl; @@ -472,19 +451,33 @@ int opts, lvl; ip = (ip_t *)(ipf + 1); tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); + msg.imm_data = ipl; + msg.imm_dsize = ipl->ipl_dsize; + msg.imm_when = ipl->ipl_time.tv_sec; + msg.imm_msg = log; + msg.imm_msglen = strlen(log); + msg.imm_loglevel = lvl; + for (a = alist; a != NULL; a = a->ac_next) { + verbose(0, "== checking config rule\n"); if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { if (a->ac_direction == IPM_IN) { - if ((ipf->fl_flags & FR_INQUE) == 0) + if ((ipf->fl_flags & FR_INQUE) == 0) { + verbose(8, "-- direction not in\n"); continue; + } } else if (a->ac_direction == IPM_OUT) { - if ((ipf->fl_flags & FR_OUTQUE) == 0) + if ((ipf->fl_flags & FR_OUTQUE) == 0) { + verbose(8, "-- direction not out\n"); continue; + } } } - if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) + if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) { + verbose(8, "-- type mismatch\n"); continue; + } if ((a->ac_mflag & IPMAC_EVERY) != 0) { gettimeofday(&tv, NULL); @@ -492,8 +485,10 @@ int opts, lvl; if (tv.tv_usec <= a->ac_lastusec) t1--; if (a->ac_second != 0) { - if (t1 < a->ac_second) + if (t1 < a->ac_second) { + verbose(8, "-- too soon\n"); continue; + } a->ac_lastsec = tv.tv_sec; a->ac_lastusec = tv.tv_usec; } @@ -503,159 +498,149 @@ int opts, lvl; a->ac_pktcnt++; else if (a->ac_pktcnt == a->ac_packet) { a->ac_pktcnt = 0; + verbose(8, "-- packet count\n"); continue; } else { a->ac_pktcnt++; + verbose(8, "-- packet count\n"); continue; } } } if ((a->ac_mflag & IPMAC_DSTIP) != 0) { - if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) + if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) { + verbose(8, "-- dstip wrong\n"); continue; + } } if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { - if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + if (ip->ip_p != IPPROTO_UDP && + ip->ip_p != IPPROTO_TCP) { + verbose(8, "-- not port protocol\n"); continue; - if (tcp->th_dport != a->ac_dport) + } + if (tcp->th_dport != a->ac_dport) { + verbose(8, "-- dport mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_GROUP) != 0) { if (strncmp(a->ac_group, ipf->fl_group, - FR_GROUPLEN) != 0) + FR_GROUPLEN) != 0) { + verbose(8, "-- group mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { - if (strcmp(a->ac_iface, ipf->fl_ifname)) + if (strcmp(a->ac_iface, ipf->fl_ifname)) { + verbose(8, "-- ifname mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { - if (a->ac_proto != ip->ip_p) + if (a->ac_proto != ip->ip_p) { + verbose(8, "-- protocol mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_RESULT) != 0) { if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { - if (a->ac_result != IPMR_NOMATCH) + if (a->ac_result != IPMR_NOMATCH) { + verbose(8, "-- ff-flags mismatch\n"); continue; + } } else if (FR_ISPASS(ipf->fl_flags)) { - if (a->ac_result != IPMR_PASS) + if (a->ac_result != IPMR_PASS) { + verbose(8, "-- pass mismatch\n"); continue; + } } else if (FR_ISBLOCK(ipf->fl_flags)) { - if (a->ac_result != IPMR_BLOCK) + if (a->ac_result != IPMR_BLOCK) { + verbose(8, "-- block mismatch\n"); continue; + } } else { /* Log only */ - if (a->ac_result != IPMR_LOG) + if (a->ac_result != IPMR_LOG) { + verbose(8, "-- log mismatch\n"); continue; + } } } if ((a->ac_mflag & IPMAC_RULE) != 0) { - if (a->ac_rule != ipf->fl_rule) + if (a->ac_rule != ipf->fl_rule) { + verbose(8, "-- rule mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_SRCIP) != 0) { - if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) + if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) { + verbose(8, "-- srcip mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { - if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + if (ip->ip_p != IPPROTO_UDP && + ip->ip_p != IPPROTO_TCP) { + verbose(8, "-- port protocol mismatch\n"); continue; - if (tcp->th_sport != a->ac_sport) + } + if (tcp->th_sport != a->ac_sport) { + verbose(8, "-- sport mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { - if (a->ac_logtag != ipf->fl_logtag) + if (a->ac_logtag != ipf->fl_logtag) { + verbose(8, "-- logtag %d != %d\n", + a->ac_logtag, ipf->fl_logtag); continue; + } } if ((a->ac_mflag & IPMAC_NATTAG) != 0) { if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, - IPFTAG_LEN) != 0) + IPFTAG_LEN) != 0) { + verbose(8, "-- nattag mismatch\n"); continue; + } } matched = 1; + verbose(8, "++ matched\n"); /* - * It matched so now execute the command + * It matched so now perform the saves */ - if (a->ac_syslog != 0) { - syslog(lvl, "%s", log); - } - - if (a->ac_savefp != NULL) { - if (a->ac_dflag & IPMDO_SAVERAW) - fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp); - else - fputs(log, a->ac_savefp); - } - - if (a->ac_exec != NULL) { - switch (fork()) - { - case 0 : - { - FILE *pi; - - pi = popen(a->ac_run, "w"); - if (pi != NULL) { - fprintf(pi, "%s\n", log); - if ((opts & OPT_HEXHDR) != 0) { - dumphex(pi, 0, buf, - sizeof(*ipl) + - sizeof(*ipf)); - } - if ((opts & OPT_HEXBODY) != 0) { - dumphex(pi, 0, (char *)ip, - ipf->fl_hlen + - ipf->fl_plen); - } - pclose(pi); - } - exit(1); - } - case -1 : - break; - default : - break; - } - } + for (d = a->ac_doing; d != NULL; d = d->ipmd_next) + (*d->ipmd_store)(d->ipmd_token, &msg); } return matched; } -static void free_action(a) -ipmon_action_t *a; +static void +free_action(a) + ipmon_action_t *a; { - if (a->ac_savefile != NULL) { - free(a->ac_savefile); - a->ac_savefile = NULL; - } - if (a->ac_savefp != NULL) { - fclose(a->ac_savefp); - a->ac_savefp = NULL; - } - if (a->ac_exec != NULL) { - free(a->ac_exec); - if (a->ac_run == a->ac_exec) - a->ac_run = NULL; - a->ac_exec = NULL; - } - if (a->ac_run != NULL) { - free(a->ac_run); - a->ac_run = NULL; + ipmon_doing_t *d; + + while ((d = a->ac_doing) != NULL) { + a->ac_doing = d->ipmd_next; + (*d->ipmd_saver->ims_destroy)(d->ipmd_token); + free(d); } + if (a->ac_iface != NULL) { free(a->ac_iface); a->ac_iface = NULL; @@ -665,24 +650,21 @@ ipmon_action_t *a; } -int load_config(file) -char *file; +int +load_config(file) + char *file; { - ipmon_action_t *a; FILE *fp; char *s; + unload_config(); + s = getenv("YYDEBUG"); if (s != NULL) yydebug = atoi(s); else yydebug = 0; - while ((a = alist) != NULL) { - alist = a->ac_next; - free_action(a); - } - yylineNum = 1; (void) yysettab(yywords); @@ -698,3 +680,373 @@ char *file; fclose(fp); return 0; } + + +void +unload_config() +{ + ipmon_saver_int_t *sav, **imsip; + ipmon_saver_t *is; + ipmon_action_t *a; + + while ((a = alist) != NULL) { + alist = a->ac_next; + free_action(a); + } + + /* + * Look for savers that have been added in dynamically from the + * configuration file. + */ + for (imsip = &saverlist; (sav = *imsip) != NULL; ) { + if (sav->imsi_handle == NULL) + imsip = &sav->imsi_next; + else { + dlclose(sav->imsi_handle); + + *imsip = sav->imsi_next; + is = sav->imsi_stor; + free(sav); + + free(is->ims_name); + free(is); + } + } +} + + +void +dump_config() +{ + ipmon_action_t *a; + + for (a = alist; a != NULL; a = a->ac_next) { + print_action(a); + + printf("#\n"); + } +} + + +static void +print_action(a) + ipmon_action_t *a; +{ + ipmon_doing_t *d; + + printf("match { "); + print_match(a); + printf("; }\n"); + printf("do {"); + for (d = a->ac_doing; d != NULL; d = d->ipmd_next) { + printf("%s", d->ipmd_saver->ims_name); + if (d->ipmd_saver->ims_print != NULL) { + printf("(\""); + (*d->ipmd_saver->ims_print)(d->ipmd_token); + printf("\")"); + } + printf(";"); + } + printf("};\n"); +} + + +void * +add_doing(saver) + ipmon_saver_t *saver; +{ + ipmon_saver_int_t *it; + + if (find_doing(saver->ims_name) == IPM_DOING) + return NULL; + + it = calloc(1, sizeof(*it)); + if (it == NULL) + return NULL; + it->imsi_stor = saver; + it->imsi_next = saverlist; + saverlist = it; + return it; +} + + +static int +find_doing(string) + char *string; +{ + ipmon_saver_int_t *it; + + for (it = saverlist; it != NULL; it = it->imsi_next) { + if (!strcmp(it->imsi_stor->ims_name, string)) + return IPM_DOING; + } + return 0; +} + + +static ipmon_doing_t * +build_doing(target, options) + char *target; + char *options; +{ + ipmon_saver_int_t *it; + char *strarray[2]; + ipmon_doing_t *d, *d1; + ipmon_action_t *a; + ipmon_saver_t *save; + + d = calloc(1, sizeof(*d)); + if (d == NULL) + return NULL; + + for (it = saverlist; it != NULL; it = it->imsi_next) { + if (!strcmp(it->imsi_stor->ims_name, target)) + break; + } + if (it == NULL) { + free(d); + return NULL; + } + + strarray[0] = options; + strarray[1] = NULL; + + d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray); + if (d->ipmd_token == NULL) { + free(d); + return NULL; + } + + save = it->imsi_stor; + d->ipmd_saver = save; + d->ipmd_store = it->imsi_stor->ims_store; + + /* + * Look for duplicate do-things that need to be dup'd + */ + for (a = alist; a != NULL; a = a->ac_next) { + for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) { + if (save != d1->ipmd_saver) + continue; + if (save->ims_match == NULL || save->ims_dup == NULL) + continue; + if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token)) + continue; + + (*d->ipmd_saver->ims_destroy)(d->ipmd_token); + d->ipmd_token = (*save->ims_dup)(d1->ipmd_token); + break; + } + } + + return d; +} + + +static void +print_match(a) + ipmon_action_t *a; +{ + char *coma = ""; + + if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { + printf("direction = "); + if (a->ac_direction == IPM_IN) + printf("in"); + else if (a->ac_direction == IPM_OUT) + printf("out"); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_DSTIP) != 0) { + printf("%sdstip = ", coma); + printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { + printf("%sdstport = %hu", coma, ntohs(a->ac_dport)); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_GROUP) != 0) { + char group[FR_GROUPLEN+1]; + + strncpy(group, a->ac_group, FR_GROUPLEN); + group[FR_GROUPLEN] = '\0'; + printf("%sgroup = %s", coma, group); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { + printf("%siface = %s", coma, a->ac_iface); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { + printf("%slogtag = %u", coma, a->ac_logtag); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_NATTAG) != 0) { + char tag[17]; + + strncpy(tag, a->ac_nattag, 16); + tag[16] = '\0'; + printf("%snattag = %s", coma, tag); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { + printf("%sprotocol = %u", coma, a->ac_proto); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_RESULT) != 0) { + printf("%sresult = ", coma); + switch (a->ac_result) + { + case IPMR_LOG : + printf("log"); + break; + case IPMR_PASS : + printf("pass"); + break; + case IPMR_BLOCK : + printf("block"); + break; + case IPMR_NOMATCH : + printf("nomatch"); + break; + } + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_RULE) != 0) { + printf("%srule = %u", coma, a->ac_rule); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_EVERY) != 0) { + if (a->ac_packet > 1) { + printf("%severy %d packets", coma, a->ac_packet); + coma = ", "; + } else if (a->ac_packet == 1) { + printf("%severy packet", coma); + coma = ", "; + } + if (a->ac_second > 1) { + printf("%severy %d seconds", coma, a->ac_second); + coma = ", "; + } else if (a->ac_second == 1) { + printf("%severy second", coma); + coma = ", "; + } + } + + if ((a->ac_mflag & IPMAC_SRCIP) != 0) { + printf("%ssrcip = ", coma); + printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { + printf("%ssrcport = %hu", coma, ntohs(a->ac_sport)); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_TYPE) != 0) { + printf("%stype = ", coma); + switch (a->ac_type) + { + case IPL_LOGIPF : + printf("ipf"); + break; + case IPL_LOGSTATE : + printf("state"); + break; + case IPL_LOGNAT : + printf("nat"); + break; + } + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_WITH) != 0) { + printf("%swith ", coma); + coma = ", "; + } +} + + +static int +install_saver(name, path) + char *name, *path; +{ + ipmon_saver_int_t *isi; + ipmon_saver_t *is; + char nbuf[80]; + + if (find_doing(name) == IPM_DOING) + return -1; + + isi = calloc(1, sizeof(*isi)); + if (isi == NULL) + return -1; + + is = calloc(1, sizeof(*is)); + if (is == NULL) + goto loaderror; + + is->ims_name = name; + +#ifdef RTLD_LAZY + isi->imsi_handle = dlopen(path, RTLD_LAZY); +#endif +#ifdef DL_LAZY + isi->imsi_handle = dlopen(path, DL_LAZY); +#endif + + if (isi->imsi_handle == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sdup", name); + is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf); + + snprintf(nbuf, sizeof(nbuf), "%sdestroy", name); + is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_destroy == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%smatch", name); + is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf); + + snprintf(nbuf, sizeof(nbuf), "%sparse", name); + is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_parse == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sprint", name); + is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_print == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sstore", name); + is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_store == NULL) + goto loaderror; + + isi->imsi_stor = is; + isi->imsi_next = saverlist; + saverlist = isi; + + return 0; + +loaderror: + if (isi->imsi_handle != NULL) + dlclose(isi->imsi_handle); + free(isi); + if (is != NULL) + free(is); + return -1; +} |