141edb306SCy Schubert
241edb306SCy Schubert /*
341edb306SCy Schubert * Copyright (C) 2012 by Darren Reed.
441edb306SCy Schubert *
541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert */
741edb306SCy Schubert %{
841edb306SCy Schubert #include "ipf.h"
941edb306SCy Schubert #include <syslog.h>
1041edb306SCy Schubert #undef OPT_NAT
1141edb306SCy Schubert #undef OPT_VERBOSE
1241edb306SCy Schubert #include "ipmon_l.h"
1341edb306SCy Schubert #include "ipmon.h"
1441edb306SCy Schubert
1541edb306SCy Schubert #include <dlfcn.h>
1641edb306SCy Schubert
1741edb306SCy Schubert #define YYDEBUG 1
1841edb306SCy Schubert
1941edb306SCy Schubert extern void yyerror(char *);
2041edb306SCy Schubert extern int yyparse(void);
2141edb306SCy Schubert extern int yylex(void);
2241edb306SCy Schubert extern int yydebug;
2341edb306SCy Schubert extern FILE *yyin;
2441edb306SCy Schubert extern int yylineNum;
2541edb306SCy Schubert extern int ipmonopts;
2641edb306SCy Schubert
2741edb306SCy Schubert typedef struct opt_s {
2841edb306SCy Schubert struct opt_s *o_next;
2941edb306SCy Schubert int o_line;
3041edb306SCy Schubert int o_type;
3141edb306SCy Schubert int o_num;
3241edb306SCy Schubert char *o_str;
3341edb306SCy Schubert struct in_addr o_ip;
3441edb306SCy Schubert int o_logfac;
3541edb306SCy Schubert int o_logpri;
3641edb306SCy Schubert } opt_t;
3741edb306SCy Schubert
3841edb306SCy Schubert static void build_action(opt_t *, ipmon_doing_t *);
3941edb306SCy Schubert static opt_t *new_opt(int);
4041edb306SCy Schubert static void free_action(ipmon_action_t *);
4141edb306SCy Schubert static void print_action(ipmon_action_t *);
4241edb306SCy Schubert static int find_doing(char *);
4341edb306SCy Schubert static ipmon_doing_t *build_doing(char *, char *);
4441edb306SCy Schubert static void print_match(ipmon_action_t *);
4541edb306SCy Schubert static int install_saver(char *, char *);
4641edb306SCy Schubert
4741edb306SCy Schubert static ipmon_action_t *alist = NULL;
4841edb306SCy Schubert
4941edb306SCy Schubert ipmon_saver_int_t *saverlist = NULL;
5041edb306SCy Schubert %}
5141edb306SCy Schubert
5241edb306SCy Schubert %union {
5341edb306SCy Schubert char *str;
5441edb306SCy Schubert u_32_t num;
5541edb306SCy Schubert struct in_addr addr;
5641edb306SCy Schubert struct opt_s *opt;
5741edb306SCy Schubert union i6addr ip6;
5841edb306SCy Schubert struct ipmon_doing_s *ipmd;
5941edb306SCy Schubert }
6041edb306SCy Schubert
6141edb306SCy Schubert %token <num> YY_NUMBER YY_HEX
6241edb306SCy Schubert %token <str> YY_STR
6341edb306SCy Schubert %token <ip6> YY_IPV6
6441edb306SCy Schubert %token YY_COMMENT
6541edb306SCy Schubert %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
6641edb306SCy Schubert %token YY_RANGE_OUT YY_RANGE_IN
6741edb306SCy Schubert
6841edb306SCy Schubert %token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
6941edb306SCy Schubert %token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION
7041edb306SCy Schubert %token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
7141edb306SCy Schubert %token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
7241edb306SCy Schubert %token IPM_DO IPM_DOING IPM_TYPE IPM_NAT
7341edb306SCy Schubert %token IPM_STATE IPM_NATTAG IPM_IPF
7441edb306SCy Schubert %type <addr> ipv4
7541edb306SCy Schubert %type <opt> direction dstip dstport every group interface
7641edb306SCy Schubert %type <opt> protocol result rule srcip srcport logtag matching
7741edb306SCy Schubert %type <opt> matchopt nattag type
7841edb306SCy Schubert %type <num> typeopt
7941edb306SCy Schubert %type <ipmd> doopt doing
8041edb306SCy Schubert
8141edb306SCy Schubert %%
8241edb306SCy Schubert file: action
8341edb306SCy Schubert | file action
8441edb306SCy Schubert ;
8541edb306SCy Schubert
8641edb306SCy Schubert action: line ';'
8741edb306SCy Schubert | assign ';'
8841edb306SCy Schubert | IPM_COMMENT
8941edb306SCy Schubert | YY_COMMENT
9041edb306SCy Schubert ;
9141edb306SCy Schubert
9241edb306SCy Schubert line: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}'
9341edb306SCy Schubert { build_action($3, $8);
9441edb306SCy Schubert resetlexer();
9541edb306SCy Schubert }
9641edb306SCy Schubert | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3))
9741edb306SCy Schubert yyerror("install saver");
9841edb306SCy Schubert }
9941edb306SCy Schubert ;
10041edb306SCy Schubert
10141edb306SCy Schubert assign: YY_STR assigning YY_STR { set_variable($1, $3);
10241edb306SCy Schubert resetlexer();
10341edb306SCy Schubert free($1);
10441edb306SCy Schubert free($3);
10541edb306SCy Schubert yyvarnext = 0;
10641edb306SCy Schubert }
10741edb306SCy Schubert ;
10841edb306SCy Schubert
10941edb306SCy Schubert assigning:
11041edb306SCy Schubert '=' { yyvarnext = 1; }
11141edb306SCy Schubert ;
11241edb306SCy Schubert
11341edb306SCy Schubert matching:
11441edb306SCy Schubert matchopt { $$ = $1; }
11541edb306SCy Schubert | matchopt ',' matching { $1->o_next = $3; $$ = $1; }
11641edb306SCy Schubert ;
11741edb306SCy Schubert
11841edb306SCy Schubert matchopt:
11941edb306SCy Schubert direction { $$ = $1; }
12041edb306SCy Schubert | dstip { $$ = $1; }
12141edb306SCy Schubert | dstport { $$ = $1; }
12241edb306SCy Schubert | every { $$ = $1; }
12341edb306SCy Schubert | group { $$ = $1; }
12441edb306SCy Schubert | interface { $$ = $1; }
12541edb306SCy Schubert | protocol { $$ = $1; }
12641edb306SCy Schubert | result { $$ = $1; }
12741edb306SCy Schubert | rule { $$ = $1; }
12841edb306SCy Schubert | srcip { $$ = $1; }
12941edb306SCy Schubert | srcport { $$ = $1; }
13041edb306SCy Schubert | logtag { $$ = $1; }
13141edb306SCy Schubert | nattag { $$ = $1; }
13241edb306SCy Schubert | type { $$ = $1; }
13341edb306SCy Schubert ;
13441edb306SCy Schubert
13541edb306SCy Schubert doing:
13641edb306SCy Schubert doopt { $$ = $1; }
13741edb306SCy Schubert | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; }
13841edb306SCy Schubert ;
13941edb306SCy Schubert
14041edb306SCy Schubert doopt:
14141edb306SCy Schubert YY_STR { if (find_doing($1) != IPM_DOING)
14241edb306SCy Schubert yyerror("unknown action");
14341edb306SCy Schubert }
14441edb306SCy Schubert '(' YY_STR ')' { $$ = build_doing($1, $4);
14541edb306SCy Schubert if ($$ == NULL)
14641edb306SCy Schubert yyerror("action building");
14741edb306SCy Schubert }
14841edb306SCy Schubert | YY_STR { if (find_doing($1) == IPM_DOING)
14941edb306SCy Schubert $$ = build_doing($1, NULL);
15041edb306SCy Schubert }
15141edb306SCy Schubert ;
15241edb306SCy Schubert
15341edb306SCy Schubert direction:
15441edb306SCy Schubert IPM_DIRECTION '=' IPM_IN { $$ = new_opt(IPM_DIRECTION);
15541edb306SCy Schubert $$->o_num = IPM_IN; }
15641edb306SCy Schubert | IPM_DIRECTION '=' IPM_OUT { $$ = new_opt(IPM_DIRECTION);
15741edb306SCy Schubert $$->o_num = IPM_OUT; }
15841edb306SCy Schubert ;
15941edb306SCy Schubert
16041edb306SCy Schubert dstip: IPM_DSTIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_DSTIP);
16141edb306SCy Schubert $$->o_ip = $3;
16241edb306SCy Schubert $$->o_num = $5; }
16341edb306SCy Schubert ;
16441edb306SCy Schubert
16541edb306SCy Schubert dstport:
16641edb306SCy Schubert IPM_DSTPORT '=' YY_NUMBER { $$ = new_opt(IPM_DSTPORT);
16741edb306SCy Schubert $$->o_num = $3; }
16841edb306SCy Schubert | IPM_DSTPORT '=' YY_STR { $$ = new_opt(IPM_DSTPORT);
16941edb306SCy Schubert $$->o_str = $3; }
17041edb306SCy Schubert ;
17141edb306SCy Schubert
17241edb306SCy Schubert every: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND);
17341edb306SCy Schubert $$->o_num = 1; }
17441edb306SCy Schubert | IPM_EVERY YY_NUMBER IPM_SECONDS { $$ = new_opt(IPM_SECOND);
17541edb306SCy Schubert $$->o_num = $2; }
17641edb306SCy Schubert | IPM_EVERY IPM_PACKET { $$ = new_opt(IPM_PACKET);
17741edb306SCy Schubert $$->o_num = 1; }
17841edb306SCy Schubert | IPM_EVERY YY_NUMBER IPM_PACKETS { $$ = new_opt(IPM_PACKET);
17941edb306SCy Schubert $$->o_num = $2; }
18041edb306SCy Schubert ;
18141edb306SCy Schubert
18241edb306SCy Schubert group: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP);
18341edb306SCy Schubert $$->o_num = $3; }
18441edb306SCy Schubert | IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP);
18541edb306SCy Schubert $$->o_str = $3; }
18641edb306SCy Schubert ;
18741edb306SCy Schubert
18841edb306SCy Schubert interface:
18941edb306SCy Schubert IPM_INTERFACE '=' YY_STR { $$ = new_opt(IPM_INTERFACE);
19041edb306SCy Schubert $$->o_str = $3; }
19141edb306SCy Schubert ;
19241edb306SCy Schubert
19341edb306SCy Schubert logtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG);
19441edb306SCy Schubert $$->o_num = $3; }
19541edb306SCy Schubert ;
19641edb306SCy Schubert
19741edb306SCy Schubert nattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG);
19841edb306SCy Schubert $$->o_str = $3; }
19941edb306SCy Schubert ;
20041edb306SCy Schubert
20141edb306SCy Schubert protocol:
20241edb306SCy Schubert IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL);
20341edb306SCy Schubert $$->o_num = $3; }
20441edb306SCy Schubert | IPM_PROTOCOL '=' YY_STR { $$ = new_opt(IPM_PROTOCOL);
20541edb306SCy Schubert $$->o_num = getproto($3);
20641edb306SCy Schubert free($3);
20741edb306SCy Schubert }
20841edb306SCy Schubert ;
20941edb306SCy Schubert
21041edb306SCy Schubert result: IPM_RESULT '=' YY_STR { $$ = new_opt(IPM_RESULT);
21141edb306SCy Schubert $$->o_str = $3; }
21241edb306SCy Schubert ;
21341edb306SCy Schubert
21441edb306SCy Schubert rule: IPM_RULE '=' YY_NUMBER { $$ = new_opt(IPM_RULE);
21541edb306SCy Schubert $$->o_num = YY_NUMBER; }
21641edb306SCy Schubert ;
21741edb306SCy Schubert
21841edb306SCy Schubert srcip: IPM_SRCIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_SRCIP);
21941edb306SCy Schubert $$->o_ip = $3;
22041edb306SCy Schubert $$->o_num = $5; }
22141edb306SCy Schubert ;
22241edb306SCy Schubert
22341edb306SCy Schubert srcport:
22441edb306SCy Schubert IPM_SRCPORT '=' YY_NUMBER { $$ = new_opt(IPM_SRCPORT);
22541edb306SCy Schubert $$->o_num = $3; }
22641edb306SCy Schubert | IPM_SRCPORT '=' YY_STR { $$ = new_opt(IPM_SRCPORT);
22741edb306SCy Schubert $$->o_str = $3; }
22841edb306SCy Schubert ;
22941edb306SCy Schubert
23041edb306SCy Schubert type: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE);
23141edb306SCy Schubert $$->o_num = $3; }
23241edb306SCy Schubert ;
23341edb306SCy Schubert
23441edb306SCy Schubert typeopt:
23541edb306SCy Schubert IPM_IPF { $$ = IPL_MAGIC; }
23641edb306SCy Schubert | IPM_NAT { $$ = IPL_MAGIC_NAT; }
23741edb306SCy Schubert | IPM_STATE { $$ = IPL_MAGIC_STATE; }
23841edb306SCy Schubert ;
23941edb306SCy Schubert
24041edb306SCy Schubert
24141edb306SCy Schubert
24241edb306SCy Schubert ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
24341edb306SCy Schubert { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
24441edb306SCy Schubert yyerror("Invalid octet string for IP address");
245*2582ae57SCy Schubert return(0);
24641edb306SCy Schubert }
24741edb306SCy Schubert $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
24841edb306SCy Schubert $$.s_addr = htonl($$.s_addr);
24941edb306SCy Schubert }
25041edb306SCy Schubert %%
25141edb306SCy Schubert static struct wordtab yywords[] = {
25241edb306SCy Schubert { "body", IPM_BODY },
25341edb306SCy Schubert { "direction", IPM_DIRECTION },
25441edb306SCy Schubert { "do", IPM_DO },
25541edb306SCy Schubert { "dstip", IPM_DSTIP },
25641edb306SCy Schubert { "dstport", IPM_DSTPORT },
25741edb306SCy Schubert { "every", IPM_EVERY },
25841edb306SCy Schubert { "group", IPM_GROUP },
25941edb306SCy Schubert { "in", IPM_IN },
26041edb306SCy Schubert { "interface", IPM_INTERFACE },
26141edb306SCy Schubert { "ipf", IPM_IPF },
26241edb306SCy Schubert { "load_action",IPM_LOADACTION },
26341edb306SCy Schubert { "logtag", IPM_LOGTAG },
26441edb306SCy Schubert { "match", IPM_MATCH },
26541edb306SCy Schubert { "nat", IPM_NAT },
26641edb306SCy Schubert { "nattag", IPM_NATTAG },
26741edb306SCy Schubert { "no", IPM_NO },
26841edb306SCy Schubert { "out", IPM_OUT },
26941edb306SCy Schubert { "packet", IPM_PACKET },
27041edb306SCy Schubert { "packets", IPM_PACKETS },
27141edb306SCy Schubert { "protocol", IPM_PROTOCOL },
27241edb306SCy Schubert { "result", IPM_RESULT },
27341edb306SCy Schubert { "rule", IPM_RULE },
27441edb306SCy Schubert { "second", IPM_SECOND },
27541edb306SCy Schubert { "seconds", IPM_SECONDS },
27641edb306SCy Schubert { "srcip", IPM_SRCIP },
27741edb306SCy Schubert { "srcport", IPM_SRCPORT },
27841edb306SCy Schubert { "state", IPM_STATE },
27941edb306SCy Schubert { "with", IPM_WITH },
28041edb306SCy Schubert { NULL, 0 }
28141edb306SCy Schubert };
28241edb306SCy Schubert
28341edb306SCy Schubert static int macflags[17][2] = {
28441edb306SCy Schubert { IPM_DIRECTION, IPMAC_DIRECTION },
28541edb306SCy Schubert { IPM_DSTIP, IPMAC_DSTIP },
28641edb306SCy Schubert { IPM_DSTPORT, IPMAC_DSTPORT },
28741edb306SCy Schubert { IPM_GROUP, IPMAC_GROUP },
28841edb306SCy Schubert { IPM_INTERFACE, IPMAC_INTERFACE },
28941edb306SCy Schubert { IPM_LOGTAG, IPMAC_LOGTAG },
29041edb306SCy Schubert { IPM_NATTAG, IPMAC_NATTAG },
29141edb306SCy Schubert { IPM_PACKET, IPMAC_EVERY },
29241edb306SCy Schubert { IPM_PROTOCOL, IPMAC_PROTOCOL },
29341edb306SCy Schubert { IPM_RESULT, IPMAC_RESULT },
29441edb306SCy Schubert { IPM_RULE, IPMAC_RULE },
29541edb306SCy Schubert { IPM_SECOND, IPMAC_EVERY },
29641edb306SCy Schubert { IPM_SRCIP, IPMAC_SRCIP },
29741edb306SCy Schubert { IPM_SRCPORT, IPMAC_SRCPORT },
29841edb306SCy Schubert { IPM_TYPE, IPMAC_TYPE },
29941edb306SCy Schubert { IPM_WITH, IPMAC_WITH },
30041edb306SCy Schubert { 0, 0 }
30141edb306SCy Schubert };
30241edb306SCy Schubert
30341edb306SCy Schubert static opt_t *
new_opt(int type)304efeb8bffSCy Schubert new_opt(int type)
30541edb306SCy Schubert {
30641edb306SCy Schubert opt_t *o;
30741edb306SCy Schubert
30841edb306SCy Schubert o = (opt_t *)calloc(1, sizeof(*o));
30941edb306SCy Schubert o->o_type = type;
31041edb306SCy Schubert o->o_line = yylineNum;
31141edb306SCy Schubert o->o_logfac = -1;
31241edb306SCy Schubert o->o_logpri = -1;
313*2582ae57SCy Schubert return(o);
31441edb306SCy Schubert }
31541edb306SCy Schubert
31641edb306SCy Schubert static void
build_action(opt_t * olist,ipmon_doing_t * todo)317efeb8bffSCy Schubert build_action(opt_t *olist, ipmon_doing_t *todo)
31841edb306SCy Schubert {
31941edb306SCy Schubert ipmon_action_t *a;
32041edb306SCy Schubert opt_t *o;
32141edb306SCy Schubert int i;
32241edb306SCy Schubert
32341edb306SCy Schubert a = (ipmon_action_t *)calloc(1, sizeof(*a));
32441edb306SCy Schubert if (a == NULL)
32541edb306SCy Schubert return;
32641edb306SCy Schubert
32741edb306SCy Schubert while ((o = olist) != NULL) {
32841edb306SCy Schubert /*
32941edb306SCy Schubert * Check to see if the same comparator is being used more than
33041edb306SCy Schubert * once per matching statement.
33141edb306SCy Schubert */
33241edb306SCy Schubert for (i = 0; macflags[i][0]; i++)
33341edb306SCy Schubert if (macflags[i][0] == o->o_type)
33441edb306SCy Schubert break;
33541edb306SCy Schubert if (macflags[i][1] & a->ac_mflag) {
33641edb306SCy Schubert fprintf(stderr, "%s redfined on line %d\n",
33741edb306SCy Schubert yykeytostr(o->o_type), yylineNum);
33841edb306SCy Schubert if (o->o_str != NULL)
33941edb306SCy Schubert free(o->o_str);
34041edb306SCy Schubert olist = o->o_next;
34141edb306SCy Schubert free(o);
34241edb306SCy Schubert continue;
34341edb306SCy Schubert }
34441edb306SCy Schubert
34541edb306SCy Schubert a->ac_mflag |= macflags[i][1];
34641edb306SCy Schubert
34741edb306SCy Schubert switch (o->o_type)
34841edb306SCy Schubert {
34941edb306SCy Schubert case IPM_DIRECTION :
35041edb306SCy Schubert a->ac_direction = o->o_num;
35141edb306SCy Schubert break;
35241edb306SCy Schubert case IPM_DSTIP :
35341edb306SCy Schubert a->ac_dip = o->o_ip.s_addr;
35441edb306SCy Schubert a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num));
35541edb306SCy Schubert break;
35641edb306SCy Schubert case IPM_DSTPORT :
35741edb306SCy Schubert a->ac_dport = htons(o->o_num);
35841edb306SCy Schubert break;
35941edb306SCy Schubert case IPM_INTERFACE :
36041edb306SCy Schubert a->ac_iface = o->o_str;
36141edb306SCy Schubert o->o_str = NULL;
36241edb306SCy Schubert break;
36341edb306SCy Schubert case IPM_GROUP :
36441edb306SCy Schubert if (o->o_str != NULL)
36541edb306SCy Schubert strncpy(a->ac_group, o->o_str, FR_GROUPLEN);
36641edb306SCy Schubert else
367d740faa3SCy Schubert sprintf(a->ac_group, "%d", o->o_num);
36841edb306SCy Schubert break;
36941edb306SCy Schubert case IPM_LOGTAG :
37041edb306SCy Schubert a->ac_logtag = o->o_num;
37141edb306SCy Schubert break;
37241edb306SCy Schubert case IPM_NATTAG :
37341edb306SCy Schubert strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag));
37441edb306SCy Schubert break;
37541edb306SCy Schubert case IPM_PACKET :
37641edb306SCy Schubert a->ac_packet = o->o_num;
37741edb306SCy Schubert break;
37841edb306SCy Schubert case IPM_PROTOCOL :
37941edb306SCy Schubert a->ac_proto = o->o_num;
38041edb306SCy Schubert break;
38141edb306SCy Schubert case IPM_RULE :
38241edb306SCy Schubert a->ac_rule = o->o_num;
38341edb306SCy Schubert break;
38441edb306SCy Schubert case IPM_RESULT :
38541edb306SCy Schubert if (!strcasecmp(o->o_str, "pass"))
38641edb306SCy Schubert a->ac_result = IPMR_PASS;
38741edb306SCy Schubert else if (!strcasecmp(o->o_str, "block"))
38841edb306SCy Schubert a->ac_result = IPMR_BLOCK;
38941edb306SCy Schubert else if (!strcasecmp(o->o_str, "nomatch"))
39041edb306SCy Schubert a->ac_result = IPMR_NOMATCH;
39141edb306SCy Schubert else if (!strcasecmp(o->o_str, "log"))
39241edb306SCy Schubert a->ac_result = IPMR_LOG;
39341edb306SCy Schubert break;
39441edb306SCy Schubert case IPM_SECOND :
39541edb306SCy Schubert a->ac_second = o->o_num;
39641edb306SCy Schubert break;
39741edb306SCy Schubert case IPM_SRCIP :
39841edb306SCy Schubert a->ac_sip = o->o_ip.s_addr;
39941edb306SCy Schubert a->ac_smsk = htonl(0xffffffff << (32 - o->o_num));
40041edb306SCy Schubert break;
40141edb306SCy Schubert case IPM_SRCPORT :
40241edb306SCy Schubert a->ac_sport = htons(o->o_num);
40341edb306SCy Schubert break;
40441edb306SCy Schubert case IPM_TYPE :
40541edb306SCy Schubert a->ac_type = o->o_num;
40641edb306SCy Schubert break;
40741edb306SCy Schubert case IPM_WITH :
40841edb306SCy Schubert break;
40941edb306SCy Schubert default :
41041edb306SCy Schubert break;
41141edb306SCy Schubert }
41241edb306SCy Schubert
41341edb306SCy Schubert olist = o->o_next;
41441edb306SCy Schubert if (o->o_str != NULL)
41541edb306SCy Schubert free(o->o_str);
41641edb306SCy Schubert free(o);
41741edb306SCy Schubert }
41841edb306SCy Schubert
41941edb306SCy Schubert a->ac_doing = todo;
42041edb306SCy Schubert a->ac_next = alist;
42141edb306SCy Schubert alist = a;
42241edb306SCy Schubert
42341edb306SCy Schubert if (ipmonopts & IPMON_VERBOSE)
42441edb306SCy Schubert print_action(a);
42541edb306SCy Schubert }
42641edb306SCy Schubert
42741edb306SCy Schubert
42841edb306SCy Schubert int
check_action(char * buf,char * log,int opts,int lvl)429efeb8bffSCy Schubert check_action(char *buf, char *log, int opts, int lvl)
43041edb306SCy Schubert {
43141edb306SCy Schubert ipmon_action_t *a;
43241edb306SCy Schubert struct timeval tv;
43341edb306SCy Schubert ipmon_doing_t *d;
43441edb306SCy Schubert ipmon_msg_t msg;
43541edb306SCy Schubert ipflog_t *ipf;
43641edb306SCy Schubert tcphdr_t *tcp;
43741edb306SCy Schubert iplog_t *ipl;
43841edb306SCy Schubert int matched;
43941edb306SCy Schubert u_long t1;
44041edb306SCy Schubert ip_t *ip;
44141edb306SCy Schubert
44241edb306SCy Schubert matched = 0;
44341edb306SCy Schubert ipl = (iplog_t *)buf;
44441edb306SCy Schubert ipf = (ipflog_t *)(ipl +1);
44541edb306SCy Schubert ip = (ip_t *)(ipf + 1);
44641edb306SCy Schubert tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
44741edb306SCy Schubert
44841edb306SCy Schubert msg.imm_data = ipl;
44941edb306SCy Schubert msg.imm_dsize = ipl->ipl_dsize;
45041edb306SCy Schubert msg.imm_when = ipl->ipl_time.tv_sec;
45141edb306SCy Schubert msg.imm_msg = log;
45241edb306SCy Schubert msg.imm_msglen = strlen(log);
45341edb306SCy Schubert msg.imm_loglevel = lvl;
45441edb306SCy Schubert
45541edb306SCy Schubert for (a = alist; a != NULL; a = a->ac_next) {
45641edb306SCy Schubert verbose(0, "== checking config rule\n");
45741edb306SCy Schubert if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
45841edb306SCy Schubert if (a->ac_direction == IPM_IN) {
45941edb306SCy Schubert if ((ipf->fl_flags & FR_INQUE) == 0) {
46041edb306SCy Schubert verbose(8, "-- direction not in\n");
46141edb306SCy Schubert continue;
46241edb306SCy Schubert }
46341edb306SCy Schubert } else if (a->ac_direction == IPM_OUT) {
46441edb306SCy Schubert if ((ipf->fl_flags & FR_OUTQUE) == 0) {
46541edb306SCy Schubert verbose(8, "-- direction not out\n");
46641edb306SCy Schubert continue;
46741edb306SCy Schubert }
46841edb306SCy Schubert }
46941edb306SCy Schubert }
47041edb306SCy Schubert
47141edb306SCy Schubert if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) {
47241edb306SCy Schubert verbose(8, "-- type mismatch\n");
47341edb306SCy Schubert continue;
47441edb306SCy Schubert }
47541edb306SCy Schubert
47641edb306SCy Schubert if ((a->ac_mflag & IPMAC_EVERY) != 0) {
47741edb306SCy Schubert gettimeofday(&tv, NULL);
47841edb306SCy Schubert t1 = tv.tv_sec - a->ac_lastsec;
47941edb306SCy Schubert if (tv.tv_usec <= a->ac_lastusec)
48041edb306SCy Schubert t1--;
48141edb306SCy Schubert if (a->ac_second != 0) {
48241edb306SCy Schubert if (t1 < a->ac_second) {
48341edb306SCy Schubert verbose(8, "-- too soon\n");
48441edb306SCy Schubert continue;
48541edb306SCy Schubert }
48641edb306SCy Schubert a->ac_lastsec = tv.tv_sec;
48741edb306SCy Schubert a->ac_lastusec = tv.tv_usec;
48841edb306SCy Schubert }
48941edb306SCy Schubert
49041edb306SCy Schubert if (a->ac_packet != 0) {
49141edb306SCy Schubert if (a->ac_pktcnt == 0)
49241edb306SCy Schubert a->ac_pktcnt++;
49341edb306SCy Schubert else if (a->ac_pktcnt == a->ac_packet) {
49441edb306SCy Schubert a->ac_pktcnt = 0;
49541edb306SCy Schubert verbose(8, "-- packet count\n");
49641edb306SCy Schubert continue;
49741edb306SCy Schubert } else {
49841edb306SCy Schubert a->ac_pktcnt++;
49941edb306SCy Schubert verbose(8, "-- packet count\n");
50041edb306SCy Schubert continue;
50141edb306SCy Schubert }
50241edb306SCy Schubert }
50341edb306SCy Schubert }
50441edb306SCy Schubert
50541edb306SCy Schubert if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
50641edb306SCy Schubert if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) {
50741edb306SCy Schubert verbose(8, "-- dstip wrong\n");
50841edb306SCy Schubert continue;
50941edb306SCy Schubert }
51041edb306SCy Schubert }
51141edb306SCy Schubert
51241edb306SCy Schubert if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
51341edb306SCy Schubert if (ip->ip_p != IPPROTO_UDP &&
51441edb306SCy Schubert ip->ip_p != IPPROTO_TCP) {
51541edb306SCy Schubert verbose(8, "-- not port protocol\n");
51641edb306SCy Schubert continue;
51741edb306SCy Schubert }
51841edb306SCy Schubert if (tcp->th_dport != a->ac_dport) {
51941edb306SCy Schubert verbose(8, "-- dport mismatch\n");
52041edb306SCy Schubert continue;
52141edb306SCy Schubert }
52241edb306SCy Schubert }
52341edb306SCy Schubert
52441edb306SCy Schubert if ((a->ac_mflag & IPMAC_GROUP) != 0) {
52541edb306SCy Schubert if (strncmp(a->ac_group, ipf->fl_group,
52641edb306SCy Schubert FR_GROUPLEN) != 0) {
52741edb306SCy Schubert verbose(8, "-- group mismatch\n");
52841edb306SCy Schubert continue;
52941edb306SCy Schubert }
53041edb306SCy Schubert }
53141edb306SCy Schubert
53241edb306SCy Schubert if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
53341edb306SCy Schubert if (strcmp(a->ac_iface, ipf->fl_ifname)) {
53441edb306SCy Schubert verbose(8, "-- ifname mismatch\n");
53541edb306SCy Schubert continue;
53641edb306SCy Schubert }
53741edb306SCy Schubert }
53841edb306SCy Schubert
53941edb306SCy Schubert if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
54041edb306SCy Schubert if (a->ac_proto != ip->ip_p) {
54141edb306SCy Schubert verbose(8, "-- protocol mismatch\n");
54241edb306SCy Schubert continue;
54341edb306SCy Schubert }
54441edb306SCy Schubert }
54541edb306SCy Schubert
54641edb306SCy Schubert if ((a->ac_mflag & IPMAC_RESULT) != 0) {
54741edb306SCy Schubert if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
54841edb306SCy Schubert if (a->ac_result != IPMR_NOMATCH) {
54941edb306SCy Schubert verbose(8, "-- ff-flags mismatch\n");
55041edb306SCy Schubert continue;
55141edb306SCy Schubert }
55241edb306SCy Schubert } else if (FR_ISPASS(ipf->fl_flags)) {
55341edb306SCy Schubert if (a->ac_result != IPMR_PASS) {
55441edb306SCy Schubert verbose(8, "-- pass mismatch\n");
55541edb306SCy Schubert continue;
55641edb306SCy Schubert }
55741edb306SCy Schubert } else if (FR_ISBLOCK(ipf->fl_flags)) {
55841edb306SCy Schubert if (a->ac_result != IPMR_BLOCK) {
55941edb306SCy Schubert verbose(8, "-- block mismatch\n");
56041edb306SCy Schubert continue;
56141edb306SCy Schubert }
56241edb306SCy Schubert } else { /* Log only */
56341edb306SCy Schubert if (a->ac_result != IPMR_LOG) {
56441edb306SCy Schubert verbose(8, "-- log mismatch\n");
56541edb306SCy Schubert continue;
56641edb306SCy Schubert }
56741edb306SCy Schubert }
56841edb306SCy Schubert }
56941edb306SCy Schubert
57041edb306SCy Schubert if ((a->ac_mflag & IPMAC_RULE) != 0) {
57141edb306SCy Schubert if (a->ac_rule != ipf->fl_rule) {
57241edb306SCy Schubert verbose(8, "-- rule mismatch\n");
57341edb306SCy Schubert continue;
57441edb306SCy Schubert }
57541edb306SCy Schubert }
57641edb306SCy Schubert
57741edb306SCy Schubert if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
57841edb306SCy Schubert if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) {
57941edb306SCy Schubert verbose(8, "-- srcip mismatch\n");
58041edb306SCy Schubert continue;
58141edb306SCy Schubert }
58241edb306SCy Schubert }
58341edb306SCy Schubert
58441edb306SCy Schubert if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
58541edb306SCy Schubert if (ip->ip_p != IPPROTO_UDP &&
58641edb306SCy Schubert ip->ip_p != IPPROTO_TCP) {
58741edb306SCy Schubert verbose(8, "-- port protocol mismatch\n");
58841edb306SCy Schubert continue;
58941edb306SCy Schubert }
59041edb306SCy Schubert if (tcp->th_sport != a->ac_sport) {
59141edb306SCy Schubert verbose(8, "-- sport mismatch\n");
59241edb306SCy Schubert continue;
59341edb306SCy Schubert }
59441edb306SCy Schubert }
59541edb306SCy Schubert
59641edb306SCy Schubert if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
59741edb306SCy Schubert if (a->ac_logtag != ipf->fl_logtag) {
59841edb306SCy Schubert verbose(8, "-- logtag %d != %d\n",
59941edb306SCy Schubert a->ac_logtag, ipf->fl_logtag);
60041edb306SCy Schubert continue;
60141edb306SCy Schubert }
60241edb306SCy Schubert }
60341edb306SCy Schubert
60441edb306SCy Schubert if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
60541edb306SCy Schubert if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
60641edb306SCy Schubert IPFTAG_LEN) != 0) {
60741edb306SCy Schubert verbose(8, "-- nattag mismatch\n");
60841edb306SCy Schubert continue;
60941edb306SCy Schubert }
61041edb306SCy Schubert }
61141edb306SCy Schubert
61241edb306SCy Schubert matched = 1;
61341edb306SCy Schubert verbose(8, "++ matched\n");
61441edb306SCy Schubert
61541edb306SCy Schubert /*
61641edb306SCy Schubert * It matched so now perform the saves
61741edb306SCy Schubert */
61841edb306SCy Schubert for (d = a->ac_doing; d != NULL; d = d->ipmd_next)
61941edb306SCy Schubert (*d->ipmd_store)(d->ipmd_token, &msg);
62041edb306SCy Schubert }
62141edb306SCy Schubert
622*2582ae57SCy Schubert return(matched);
62341edb306SCy Schubert }
62441edb306SCy Schubert
62541edb306SCy Schubert
62641edb306SCy Schubert static void
free_action(ipmon_action_t * a)627efeb8bffSCy Schubert free_action(ipmon_action_t *a)
62841edb306SCy Schubert {
62941edb306SCy Schubert ipmon_doing_t *d;
63041edb306SCy Schubert
63141edb306SCy Schubert while ((d = a->ac_doing) != NULL) {
63241edb306SCy Schubert a->ac_doing = d->ipmd_next;
63341edb306SCy Schubert (*d->ipmd_saver->ims_destroy)(d->ipmd_token);
63441edb306SCy Schubert free(d);
63541edb306SCy Schubert }
63641edb306SCy Schubert
63741edb306SCy Schubert if (a->ac_iface != NULL) {
63841edb306SCy Schubert free(a->ac_iface);
63941edb306SCy Schubert a->ac_iface = NULL;
64041edb306SCy Schubert }
64141edb306SCy Schubert a->ac_next = NULL;
64241edb306SCy Schubert free(a);
64341edb306SCy Schubert }
64441edb306SCy Schubert
64541edb306SCy Schubert
64641edb306SCy Schubert int
load_config(char * file)647efeb8bffSCy Schubert load_config(char *file)
64841edb306SCy Schubert {
64941edb306SCy Schubert FILE *fp;
65041edb306SCy Schubert char *s;
65141edb306SCy Schubert
65241edb306SCy Schubert unload_config();
65341edb306SCy Schubert
65441edb306SCy Schubert s = getenv("YYDEBUG");
65541edb306SCy Schubert if (s != NULL)
65641edb306SCy Schubert yydebug = atoi(s);
65741edb306SCy Schubert else
65841edb306SCy Schubert yydebug = 0;
65941edb306SCy Schubert
66041edb306SCy Schubert yylineNum = 1;
66141edb306SCy Schubert
66241edb306SCy Schubert (void) yysettab(yywords);
66341edb306SCy Schubert
66441edb306SCy Schubert fp = fopen(file, "r");
66541edb306SCy Schubert if (!fp) {
66641edb306SCy Schubert perror("load_config:fopen:");
667*2582ae57SCy Schubert return(-1);
66841edb306SCy Schubert }
66941edb306SCy Schubert yyin = fp;
67041edb306SCy Schubert while (!feof(fp))
67141edb306SCy Schubert yyparse();
67241edb306SCy Schubert fclose(fp);
673*2582ae57SCy Schubert return(0);
67441edb306SCy Schubert }
67541edb306SCy Schubert
67641edb306SCy Schubert
67741edb306SCy Schubert void
unload_config(void)678efeb8bffSCy Schubert unload_config(void)
67941edb306SCy Schubert {
68041edb306SCy Schubert ipmon_saver_int_t *sav, **imsip;
68141edb306SCy Schubert ipmon_saver_t *is;
68241edb306SCy Schubert ipmon_action_t *a;
68341edb306SCy Schubert
68441edb306SCy Schubert while ((a = alist) != NULL) {
68541edb306SCy Schubert alist = a->ac_next;
68641edb306SCy Schubert free_action(a);
68741edb306SCy Schubert }
68841edb306SCy Schubert
68941edb306SCy Schubert /*
69041edb306SCy Schubert * Look for savers that have been added in dynamically from the
69141edb306SCy Schubert * configuration file.
69241edb306SCy Schubert */
69341edb306SCy Schubert for (imsip = &saverlist; (sav = *imsip) != NULL; ) {
69441edb306SCy Schubert if (sav->imsi_handle == NULL)
69541edb306SCy Schubert imsip = &sav->imsi_next;
69641edb306SCy Schubert else {
69741edb306SCy Schubert dlclose(sav->imsi_handle);
69841edb306SCy Schubert
69941edb306SCy Schubert *imsip = sav->imsi_next;
70041edb306SCy Schubert is = sav->imsi_stor;
70141edb306SCy Schubert free(sav);
70241edb306SCy Schubert
70341edb306SCy Schubert free(is->ims_name);
70441edb306SCy Schubert free(is);
70541edb306SCy Schubert }
70641edb306SCy Schubert }
70741edb306SCy Schubert }
70841edb306SCy Schubert
70941edb306SCy Schubert
71041edb306SCy Schubert void
dump_config(void)711efeb8bffSCy Schubert dump_config(void)
71241edb306SCy Schubert {
71341edb306SCy Schubert ipmon_action_t *a;
71441edb306SCy Schubert
71541edb306SCy Schubert for (a = alist; a != NULL; a = a->ac_next) {
71641edb306SCy Schubert print_action(a);
71741edb306SCy Schubert
71841edb306SCy Schubert printf("#\n");
71941edb306SCy Schubert }
72041edb306SCy Schubert }
72141edb306SCy Schubert
72241edb306SCy Schubert
72341edb306SCy Schubert static void
print_action(ipmon_action_t * a)724efeb8bffSCy Schubert print_action(ipmon_action_t *a)
72541edb306SCy Schubert {
72641edb306SCy Schubert ipmon_doing_t *d;
72741edb306SCy Schubert
72841edb306SCy Schubert printf("match { ");
72941edb306SCy Schubert print_match(a);
73041edb306SCy Schubert printf("; }\n");
73141edb306SCy Schubert printf("do {");
73241edb306SCy Schubert for (d = a->ac_doing; d != NULL; d = d->ipmd_next) {
73341edb306SCy Schubert printf("%s", d->ipmd_saver->ims_name);
73441edb306SCy Schubert if (d->ipmd_saver->ims_print != NULL) {
73541edb306SCy Schubert printf("(\"");
73641edb306SCy Schubert (*d->ipmd_saver->ims_print)(d->ipmd_token);
73741edb306SCy Schubert printf("\")");
73841edb306SCy Schubert }
73941edb306SCy Schubert printf(";");
74041edb306SCy Schubert }
74141edb306SCy Schubert printf("};\n");
74241edb306SCy Schubert }
74341edb306SCy Schubert
74441edb306SCy Schubert
74541edb306SCy Schubert void *
add_doing(ipmon_saver_t * saver)746efeb8bffSCy Schubert add_doing(ipmon_saver_t *saver)
74741edb306SCy Schubert {
74841edb306SCy Schubert ipmon_saver_int_t *it;
74941edb306SCy Schubert
75041edb306SCy Schubert if (find_doing(saver->ims_name) == IPM_DOING)
751*2582ae57SCy Schubert return(NULL);
75241edb306SCy Schubert
75341edb306SCy Schubert it = calloc(1, sizeof(*it));
75441edb306SCy Schubert if (it == NULL)
755*2582ae57SCy Schubert return(NULL);
75641edb306SCy Schubert it->imsi_stor = saver;
75741edb306SCy Schubert it->imsi_next = saverlist;
75841edb306SCy Schubert saverlist = it;
759*2582ae57SCy Schubert return(it);
76041edb306SCy Schubert }
76141edb306SCy Schubert
76241edb306SCy Schubert
76341edb306SCy Schubert static int
find_doing(char * string)764efeb8bffSCy Schubert find_doing(char *string)
76541edb306SCy Schubert {
76641edb306SCy Schubert ipmon_saver_int_t *it;
76741edb306SCy Schubert
76841edb306SCy Schubert for (it = saverlist; it != NULL; it = it->imsi_next) {
76941edb306SCy Schubert if (!strcmp(it->imsi_stor->ims_name, string))
770*2582ae57SCy Schubert return(IPM_DOING);
77141edb306SCy Schubert }
772*2582ae57SCy Schubert return(0);
77341edb306SCy Schubert }
77441edb306SCy Schubert
77541edb306SCy Schubert
77641edb306SCy Schubert static ipmon_doing_t *
build_doing(char * target,char * options)777efeb8bffSCy Schubert build_doing(char *target, char *options)
77841edb306SCy Schubert {
77941edb306SCy Schubert ipmon_saver_int_t *it;
78041edb306SCy Schubert char *strarray[2];
78141edb306SCy Schubert ipmon_doing_t *d, *d1;
78241edb306SCy Schubert ipmon_action_t *a;
78341edb306SCy Schubert ipmon_saver_t *save;
78441edb306SCy Schubert
78541edb306SCy Schubert d = calloc(1, sizeof(*d));
78641edb306SCy Schubert if (d == NULL)
787*2582ae57SCy Schubert return(NULL);
78841edb306SCy Schubert
78941edb306SCy Schubert for (it = saverlist; it != NULL; it = it->imsi_next) {
79041edb306SCy Schubert if (!strcmp(it->imsi_stor->ims_name, target))
79141edb306SCy Schubert break;
79241edb306SCy Schubert }
79341edb306SCy Schubert if (it == NULL) {
79441edb306SCy Schubert free(d);
795*2582ae57SCy Schubert return(NULL);
79641edb306SCy Schubert }
79741edb306SCy Schubert
79841edb306SCy Schubert strarray[0] = options;
79941edb306SCy Schubert strarray[1] = NULL;
80041edb306SCy Schubert
80141edb306SCy Schubert d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray);
80241edb306SCy Schubert if (d->ipmd_token == NULL) {
80341edb306SCy Schubert free(d);
804*2582ae57SCy Schubert return(NULL);
80541edb306SCy Schubert }
80641edb306SCy Schubert
80741edb306SCy Schubert save = it->imsi_stor;
80841edb306SCy Schubert d->ipmd_saver = save;
80941edb306SCy Schubert d->ipmd_store = it->imsi_stor->ims_store;
81041edb306SCy Schubert
81141edb306SCy Schubert /*
81241edb306SCy Schubert * Look for duplicate do-things that need to be dup'd
81341edb306SCy Schubert */
81441edb306SCy Schubert for (a = alist; a != NULL; a = a->ac_next) {
81541edb306SCy Schubert for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) {
81641edb306SCy Schubert if (save != d1->ipmd_saver)
81741edb306SCy Schubert continue;
81841edb306SCy Schubert if (save->ims_match == NULL || save->ims_dup == NULL)
81941edb306SCy Schubert continue;
82041edb306SCy Schubert if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token))
82141edb306SCy Schubert continue;
82241edb306SCy Schubert
82341edb306SCy Schubert (*d->ipmd_saver->ims_destroy)(d->ipmd_token);
82441edb306SCy Schubert d->ipmd_token = (*save->ims_dup)(d1->ipmd_token);
82541edb306SCy Schubert break;
82641edb306SCy Schubert }
82741edb306SCy Schubert }
82841edb306SCy Schubert
829*2582ae57SCy Schubert return(d);
83041edb306SCy Schubert }
83141edb306SCy Schubert
83241edb306SCy Schubert
83341edb306SCy Schubert static void
print_match(ipmon_action_t * a)834efeb8bffSCy Schubert print_match(ipmon_action_t *a)
83541edb306SCy Schubert {
83641edb306SCy Schubert char *coma = "";
83741edb306SCy Schubert
83841edb306SCy Schubert if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
83941edb306SCy Schubert printf("direction = ");
84041edb306SCy Schubert if (a->ac_direction == IPM_IN)
84141edb306SCy Schubert printf("in");
84241edb306SCy Schubert else if (a->ac_direction == IPM_OUT)
84341edb306SCy Schubert printf("out");
84441edb306SCy Schubert coma = ", ";
84541edb306SCy Schubert }
84641edb306SCy Schubert
84741edb306SCy Schubert if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
84841edb306SCy Schubert printf("%sdstip = ", coma);
84941edb306SCy Schubert printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk);
85041edb306SCy Schubert coma = ", ";
85141edb306SCy Schubert }
85241edb306SCy Schubert
85341edb306SCy Schubert if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
85441edb306SCy Schubert printf("%sdstport = %hu", coma, ntohs(a->ac_dport));
85541edb306SCy Schubert coma = ", ";
85641edb306SCy Schubert }
85741edb306SCy Schubert
85841edb306SCy Schubert if ((a->ac_mflag & IPMAC_GROUP) != 0) {
85941edb306SCy Schubert char group[FR_GROUPLEN+1];
86041edb306SCy Schubert
86141edb306SCy Schubert strncpy(group, a->ac_group, FR_GROUPLEN);
86241edb306SCy Schubert group[FR_GROUPLEN] = '\0';
86341edb306SCy Schubert printf("%sgroup = %s", coma, group);
86441edb306SCy Schubert coma = ", ";
86541edb306SCy Schubert }
86641edb306SCy Schubert
86741edb306SCy Schubert if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
86841edb306SCy Schubert printf("%siface = %s", coma, a->ac_iface);
86941edb306SCy Schubert coma = ", ";
87041edb306SCy Schubert }
87141edb306SCy Schubert
87241edb306SCy Schubert if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
87341edb306SCy Schubert printf("%slogtag = %u", coma, a->ac_logtag);
87441edb306SCy Schubert coma = ", ";
87541edb306SCy Schubert }
87641edb306SCy Schubert
87741edb306SCy Schubert if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
87841edb306SCy Schubert char tag[17];
87941edb306SCy Schubert
88041edb306SCy Schubert strncpy(tag, a->ac_nattag, 16);
88141edb306SCy Schubert tag[16] = '\0';
88241edb306SCy Schubert printf("%snattag = %s", coma, tag);
88341edb306SCy Schubert coma = ", ";
88441edb306SCy Schubert }
88541edb306SCy Schubert
88641edb306SCy Schubert if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
88741edb306SCy Schubert printf("%sprotocol = %u", coma, a->ac_proto);
88841edb306SCy Schubert coma = ", ";
88941edb306SCy Schubert }
89041edb306SCy Schubert
89141edb306SCy Schubert if ((a->ac_mflag & IPMAC_RESULT) != 0) {
89241edb306SCy Schubert printf("%sresult = ", coma);
89341edb306SCy Schubert switch (a->ac_result)
89441edb306SCy Schubert {
89541edb306SCy Schubert case IPMR_LOG :
89641edb306SCy Schubert printf("log");
89741edb306SCy Schubert break;
89841edb306SCy Schubert case IPMR_PASS :
89941edb306SCy Schubert printf("pass");
90041edb306SCy Schubert break;
90141edb306SCy Schubert case IPMR_BLOCK :
90241edb306SCy Schubert printf("block");
90341edb306SCy Schubert break;
90441edb306SCy Schubert case IPMR_NOMATCH :
90541edb306SCy Schubert printf("nomatch");
90641edb306SCy Schubert break;
90741edb306SCy Schubert }
90841edb306SCy Schubert coma = ", ";
90941edb306SCy Schubert }
91041edb306SCy Schubert
91141edb306SCy Schubert if ((a->ac_mflag & IPMAC_RULE) != 0) {
91241edb306SCy Schubert printf("%srule = %u", coma, a->ac_rule);
91341edb306SCy Schubert coma = ", ";
91441edb306SCy Schubert }
91541edb306SCy Schubert
91641edb306SCy Schubert if ((a->ac_mflag & IPMAC_EVERY) != 0) {
91741edb306SCy Schubert if (a->ac_packet > 1) {
91841edb306SCy Schubert printf("%severy %d packets", coma, a->ac_packet);
91941edb306SCy Schubert coma = ", ";
92041edb306SCy Schubert } else if (a->ac_packet == 1) {
92141edb306SCy Schubert printf("%severy packet", coma);
92241edb306SCy Schubert coma = ", ";
92341edb306SCy Schubert }
92441edb306SCy Schubert if (a->ac_second > 1) {
92541edb306SCy Schubert printf("%severy %d seconds", coma, a->ac_second);
92641edb306SCy Schubert coma = ", ";
92741edb306SCy Schubert } else if (a->ac_second == 1) {
92841edb306SCy Schubert printf("%severy second", coma);
92941edb306SCy Schubert coma = ", ";
93041edb306SCy Schubert }
93141edb306SCy Schubert }
93241edb306SCy Schubert
93341edb306SCy Schubert if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
93441edb306SCy Schubert printf("%ssrcip = ", coma);
93541edb306SCy Schubert printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk);
93641edb306SCy Schubert coma = ", ";
93741edb306SCy Schubert }
93841edb306SCy Schubert
93941edb306SCy Schubert if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
94041edb306SCy Schubert printf("%ssrcport = %hu", coma, ntohs(a->ac_sport));
94141edb306SCy Schubert coma = ", ";
94241edb306SCy Schubert }
94341edb306SCy Schubert
94441edb306SCy Schubert if ((a->ac_mflag & IPMAC_TYPE) != 0) {
94541edb306SCy Schubert printf("%stype = ", coma);
94641edb306SCy Schubert switch (a->ac_type)
94741edb306SCy Schubert {
94841edb306SCy Schubert case IPL_LOGIPF :
94941edb306SCy Schubert printf("ipf");
95041edb306SCy Schubert break;
95141edb306SCy Schubert case IPL_LOGSTATE :
95241edb306SCy Schubert printf("state");
95341edb306SCy Schubert break;
95441edb306SCy Schubert case IPL_LOGNAT :
95541edb306SCy Schubert printf("nat");
95641edb306SCy Schubert break;
95741edb306SCy Schubert }
95841edb306SCy Schubert coma = ", ";
95941edb306SCy Schubert }
96041edb306SCy Schubert
96141edb306SCy Schubert if ((a->ac_mflag & IPMAC_WITH) != 0) {
96241edb306SCy Schubert printf("%swith ", coma);
96341edb306SCy Schubert coma = ", ";
96441edb306SCy Schubert }
96541edb306SCy Schubert }
96641edb306SCy Schubert
96741edb306SCy Schubert
96841edb306SCy Schubert static int
install_saver(char * name,char * path)969efeb8bffSCy Schubert install_saver(char *name, char *path)
97041edb306SCy Schubert {
97141edb306SCy Schubert ipmon_saver_int_t *isi;
97241edb306SCy Schubert ipmon_saver_t *is;
97341edb306SCy Schubert char nbuf[80];
97441edb306SCy Schubert
97541edb306SCy Schubert if (find_doing(name) == IPM_DOING)
976*2582ae57SCy Schubert return(-1);
97741edb306SCy Schubert
97841edb306SCy Schubert isi = calloc(1, sizeof(*isi));
97941edb306SCy Schubert if (isi == NULL)
980*2582ae57SCy Schubert return(-1);
98141edb306SCy Schubert
98241edb306SCy Schubert is = calloc(1, sizeof(*is));
98341edb306SCy Schubert if (is == NULL)
98441edb306SCy Schubert goto loaderror;
98541edb306SCy Schubert
98641edb306SCy Schubert is->ims_name = name;
98741edb306SCy Schubert
98841edb306SCy Schubert #ifdef RTLD_LAZY
98941edb306SCy Schubert isi->imsi_handle = dlopen(path, RTLD_LAZY);
99041edb306SCy Schubert #endif
99141edb306SCy Schubert #ifdef DL_LAZY
99241edb306SCy Schubert isi->imsi_handle = dlopen(path, DL_LAZY);
99341edb306SCy Schubert #endif
99441edb306SCy Schubert
99541edb306SCy Schubert if (isi->imsi_handle == NULL)
99641edb306SCy Schubert goto loaderror;
99741edb306SCy Schubert
99841edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%sdup", name);
99941edb306SCy Schubert is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf);
100041edb306SCy Schubert
100141edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%sdestroy", name);
100241edb306SCy Schubert is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf);
100341edb306SCy Schubert if (is->ims_destroy == NULL)
100441edb306SCy Schubert goto loaderror;
100541edb306SCy Schubert
100641edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%smatch", name);
100741edb306SCy Schubert is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf);
100841edb306SCy Schubert
100941edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%sparse", name);
101041edb306SCy Schubert is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf);
101141edb306SCy Schubert if (is->ims_parse == NULL)
101241edb306SCy Schubert goto loaderror;
101341edb306SCy Schubert
101441edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%sprint", name);
101541edb306SCy Schubert is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf);
101641edb306SCy Schubert if (is->ims_print == NULL)
101741edb306SCy Schubert goto loaderror;
101841edb306SCy Schubert
101941edb306SCy Schubert snprintf(nbuf, sizeof(nbuf), "%sstore", name);
102041edb306SCy Schubert is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf);
102141edb306SCy Schubert if (is->ims_store == NULL)
102241edb306SCy Schubert goto loaderror;
102341edb306SCy Schubert
102441edb306SCy Schubert isi->imsi_stor = is;
102541edb306SCy Schubert isi->imsi_next = saverlist;
102641edb306SCy Schubert saverlist = isi;
102741edb306SCy Schubert
1028*2582ae57SCy Schubert return(0);
102941edb306SCy Schubert
103041edb306SCy Schubert loaderror:
103141edb306SCy Schubert if (isi->imsi_handle != NULL)
103241edb306SCy Schubert dlclose(isi->imsi_handle);
103341edb306SCy Schubert free(isi);
103441edb306SCy Schubert if (is != NULL)
103541edb306SCy Schubert free(is);
1036*2582ae57SCy Schubert return(-1);
103741edb306SCy Schubert }
1038