summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/tools/ipmon_y.y
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/tools/ipmon_y.y')
-rw-r--r--contrib/ipfilter/tools/ipmon_y.y722
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;
+}
OpenPOWER on IntegriCloud