xref: /onnv-gate/usr/src/cmd/ipf/tools/ipmon_y.y (revision 2393:76e0289ce525)
1*2393Syz155240 /*
2*2393Syz155240  * Copyright (C) 1993-2005  by Darren Reed.
3*2393Syz155240  * See the IPFILTER.LICENCE file for details on licencing.
4*2393Syz155240  */
5*2393Syz155240 
60Sstevel@tonic-gate %{
70Sstevel@tonic-gate #include "ipf.h"
8*2393Syz155240 #include <syslog.h>
90Sstevel@tonic-gate #undef	OPT_NAT
100Sstevel@tonic-gate #undef	OPT_VERBOSE
110Sstevel@tonic-gate #include "ipmon_l.h"
120Sstevel@tonic-gate #include "ipmon.h"
130Sstevel@tonic-gate 
140Sstevel@tonic-gate #define	YYDEBUG	1
150Sstevel@tonic-gate 
160Sstevel@tonic-gate extern	void	yyerror __P((char *));
170Sstevel@tonic-gate extern	int	yyparse __P((void));
180Sstevel@tonic-gate extern	int	yylex __P((void));
190Sstevel@tonic-gate extern	int	yydebug;
200Sstevel@tonic-gate extern	FILE	*yyin;
210Sstevel@tonic-gate extern	int	yylineNum;
220Sstevel@tonic-gate 
230Sstevel@tonic-gate typedef	struct	opt	{
240Sstevel@tonic-gate 	struct	opt	*o_next;
250Sstevel@tonic-gate 	int		o_line;
260Sstevel@tonic-gate 	int		o_type;
270Sstevel@tonic-gate 	int		o_num;
280Sstevel@tonic-gate 	char		*o_str;
290Sstevel@tonic-gate 	struct in_addr	o_ip;
300Sstevel@tonic-gate } opt_t;
310Sstevel@tonic-gate 
320Sstevel@tonic-gate static	void	build_action __P((struct opt *));
330Sstevel@tonic-gate static	opt_t	*new_opt __P((int));
34*2393Syz155240 static	void	free_action __P((ipmon_action_t *));
350Sstevel@tonic-gate 
36*2393Syz155240 static	ipmon_action_t	*alist = NULL;
370Sstevel@tonic-gate %}
380Sstevel@tonic-gate 
390Sstevel@tonic-gate %union	{
400Sstevel@tonic-gate 	char	*str;
410Sstevel@tonic-gate 	u_32_t	num;
420Sstevel@tonic-gate 	struct in_addr	addr;
430Sstevel@tonic-gate 	struct opt	*opt;
440Sstevel@tonic-gate 	union	i6addr	ip6;
450Sstevel@tonic-gate }
460Sstevel@tonic-gate 
47*2393Syz155240 %token	<num>	YY_NUMBER YY_HEX
48*2393Syz155240 %token	<str>	YY_STR
49*2393Syz155240 %token	<ip6>	YY_IPV6
50*2393Syz155240 %token	YY_COMMENT
51*2393Syz155240 %token	YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
52*2393Syz155240 %token	YY_RANGE_OUT YY_RANGE_IN
530Sstevel@tonic-gate 
54*2393Syz155240 %token	IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
550Sstevel@tonic-gate %token	IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT
560Sstevel@tonic-gate %token	IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
57*2393Syz155240 %token	IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
58*2393Syz155240 %token	IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT
59*2393Syz155240 %token	IPM_STATE IPM_NATTAG IPM_IPF
600Sstevel@tonic-gate %type	<addr> ipv4
61*2393Syz155240 %type	<opt> direction dstip dstport every execute group interface
62*2393Syz155240 %type	<opt> protocol result rule srcip srcport logtag matching
63*2393Syz155240 %type	<opt> matchopt nattag type doopt doing save syslog nothing
64*2393Syz155240 %type	<num> saveopts saveopt typeopt
650Sstevel@tonic-gate 
660Sstevel@tonic-gate %%
670Sstevel@tonic-gate file:	line
680Sstevel@tonic-gate 	| assign
690Sstevel@tonic-gate 	| file line
700Sstevel@tonic-gate 	| file assign
710Sstevel@tonic-gate 	;
720Sstevel@tonic-gate 
73*2393Syz155240 line:	IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';'
74*2393Syz155240 					{ build_action($3); resetlexer(); }
750Sstevel@tonic-gate 	| IPM_COMMENT
76*2393Syz155240 	| YY_COMMENT
770Sstevel@tonic-gate 	;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate assign:	YY_STR assigning YY_STR ';'		{ set_variable($1, $3);
800Sstevel@tonic-gate 						  resetlexer();
810Sstevel@tonic-gate 						  free($1);
820Sstevel@tonic-gate 						  free($3);
830Sstevel@tonic-gate 						}
840Sstevel@tonic-gate 	;
850Sstevel@tonic-gate 
860Sstevel@tonic-gate assigning:
870Sstevel@tonic-gate 	'='					{ yyvarnext = 1; }
880Sstevel@tonic-gate 	;
890Sstevel@tonic-gate 
90*2393Syz155240 matching:
91*2393Syz155240 	matchopt				{ $$ = $1; }
92*2393Syz155240 	| matchopt ',' matching			{ $1->o_next = $3; $$ = $1; }
930Sstevel@tonic-gate 	;
940Sstevel@tonic-gate 
95*2393Syz155240 matchopt:
96*2393Syz155240 	direction				{ $$ = $1; }
970Sstevel@tonic-gate 	| dstip					{ $$ = $1; }
980Sstevel@tonic-gate 	| dstport				{ $$ = $1; }
990Sstevel@tonic-gate 	| every					{ $$ = $1; }
1000Sstevel@tonic-gate 	| group					{ $$ = $1; }
1010Sstevel@tonic-gate 	| interface				{ $$ = $1; }
1020Sstevel@tonic-gate 	| protocol				{ $$ = $1; }
1030Sstevel@tonic-gate 	| result				{ $$ = $1; }
1040Sstevel@tonic-gate 	| rule					{ $$ = $1; }
1050Sstevel@tonic-gate 	| srcip					{ $$ = $1; }
1060Sstevel@tonic-gate 	| srcport				{ $$ = $1; }
107*2393Syz155240 	| logtag				{ $$ = $1; }
108*2393Syz155240 	| nattag				{ $$ = $1; }
109*2393Syz155240 	| type					{ $$ = $1; }
110*2393Syz155240 	;
111*2393Syz155240 
112*2393Syz155240 doing:
113*2393Syz155240 	doopt					{ $$ = $1; }
114*2393Syz155240 	| doopt ',' doing			{ $1->o_next = $3; $$ = $1; }
115*2393Syz155240 	;
116*2393Syz155240 
117*2393Syz155240 doopt:
118*2393Syz155240 	execute					{ $$ = $1; }
119*2393Syz155240 	| save					{ $$ = $1; }
120*2393Syz155240 	| syslog				{ $$ = $1; }
121*2393Syz155240 	| nothing				{ $$ = $1; }
1220Sstevel@tonic-gate 	;
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate direction:
1250Sstevel@tonic-gate 	IPM_DIRECTION '=' IPM_IN		{ $$ = new_opt(IPM_DIRECTION);
1260Sstevel@tonic-gate 						  $$->o_num = IPM_IN; }
1270Sstevel@tonic-gate 	| IPM_DIRECTION '=' IPM_OUT		{ $$ = new_opt(IPM_DIRECTION);
1280Sstevel@tonic-gate 						  $$->o_num = IPM_OUT; }
1290Sstevel@tonic-gate 	;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate dstip:	IPM_DSTIP '=' ipv4 '/' YY_NUMBER	{ $$ = new_opt(IPM_DSTIP);
1320Sstevel@tonic-gate 						  $$->o_ip = $3;
1330Sstevel@tonic-gate 						  $$->o_num = $5; }
1340Sstevel@tonic-gate 	;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate dstport:
1370Sstevel@tonic-gate 	IPM_DSTPORT '=' YY_NUMBER		{ $$ = new_opt(IPM_DSTPORT);
1380Sstevel@tonic-gate 						  $$->o_num = $3; }
1390Sstevel@tonic-gate 	| IPM_DSTPORT '=' YY_STR		{ $$ = new_opt(IPM_DSTPORT);
1400Sstevel@tonic-gate 						  $$->o_str = $3; }
1410Sstevel@tonic-gate 	;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate every:	IPM_EVERY IPM_SECOND			{ $$ = new_opt(IPM_SECOND);
1440Sstevel@tonic-gate 						  $$->o_num = 1; }
1450Sstevel@tonic-gate 	| IPM_EVERY YY_NUMBER IPM_SECONDS	{ $$ = new_opt(IPM_SECOND);
1460Sstevel@tonic-gate 						  $$->o_num = $2; }
1470Sstevel@tonic-gate 	| IPM_EVERY IPM_PACKET			{ $$ = new_opt(IPM_PACKET);
1480Sstevel@tonic-gate 						  $$->o_num = 1; }
1490Sstevel@tonic-gate 	| IPM_EVERY YY_NUMBER IPM_PACKETS	{ $$ = new_opt(IPM_PACKET);
1500Sstevel@tonic-gate 						  $$->o_num = $2; }
1510Sstevel@tonic-gate 	;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate group:	IPM_GROUP '=' YY_NUMBER			{ $$ = new_opt(IPM_GROUP);
1540Sstevel@tonic-gate 						  $$->o_num = $3; }
1550Sstevel@tonic-gate 	| IPM_GROUP '=' YY_STR			{ $$ = new_opt(IPM_GROUP);
1560Sstevel@tonic-gate 						  $$->o_str = $3; }
1570Sstevel@tonic-gate 	;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate interface:
1600Sstevel@tonic-gate 	IPM_INTERFACE '=' YY_STR		{ $$ = new_opt(IPM_INTERFACE);
1610Sstevel@tonic-gate 						  $$->o_str = $3; }
1620Sstevel@tonic-gate 	;
1630Sstevel@tonic-gate 
164*2393Syz155240 logtag:	IPM_LOGTAG '=' YY_NUMBER		{ $$ = new_opt(IPM_LOGTAG);
165*2393Syz155240 						  $$->o_num = $3; }
166*2393Syz155240 	;
167*2393Syz155240 
168*2393Syz155240 nattag:	IPM_NATTAG '=' YY_STR			{ $$ = new_opt(IPM_NATTAG);
169*2393Syz155240 						  $$->o_str = $3; }
170*2393Syz155240 	;
171*2393Syz155240 
1720Sstevel@tonic-gate protocol:
1730Sstevel@tonic-gate 	IPM_PROTOCOL '=' YY_NUMBER		{ $$ = new_opt(IPM_PROTOCOL);
1740Sstevel@tonic-gate 						  $$->o_num = $3; }
1750Sstevel@tonic-gate 	| IPM_PROTOCOL '=' YY_STR		{ $$ = new_opt(IPM_PROTOCOL);
1760Sstevel@tonic-gate 						  $$->o_num = getproto($3);
1770Sstevel@tonic-gate 						  free($3);
1780Sstevel@tonic-gate 						}
1790Sstevel@tonic-gate 	;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate result:	IPM_RESULT '=' YY_STR			{ $$ = new_opt(IPM_RESULT);
1820Sstevel@tonic-gate 						  $$->o_str = $3; }
1830Sstevel@tonic-gate 	;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate rule:	IPM_RULE '=' YY_NUMBER			{ $$ = new_opt(IPM_RULE);
1860Sstevel@tonic-gate 						  $$->o_num = YY_NUMBER; }
1870Sstevel@tonic-gate 	;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate srcip:	IPM_SRCIP '=' ipv4 '/' YY_NUMBER	{ $$ = new_opt(IPM_SRCIP);
1900Sstevel@tonic-gate 						  $$->o_ip = $3;
1910Sstevel@tonic-gate 						  $$->o_num = $5; }
1920Sstevel@tonic-gate 	;
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate srcport:
1950Sstevel@tonic-gate 	IPM_SRCPORT '=' YY_NUMBER		{ $$ = new_opt(IPM_SRCPORT);
1960Sstevel@tonic-gate 						  $$->o_num = $3; }
1970Sstevel@tonic-gate 	| IPM_SRCPORT '=' YY_STR		{ $$ = new_opt(IPM_SRCPORT);
1980Sstevel@tonic-gate 						  $$->o_str = $3; }
1990Sstevel@tonic-gate 	;
2000Sstevel@tonic-gate 
201*2393Syz155240 type:	IPM_TYPE '=' typeopt			{ $$ = new_opt(IPM_TYPE);
2020Sstevel@tonic-gate 						  $$->o_num = $3; }
2030Sstevel@tonic-gate 	;
2040Sstevel@tonic-gate 
205*2393Syz155240 typeopt:
206*2393Syz155240 	IPM_IPF					{ $$ = IPL_MAGIC; }
207*2393Syz155240 	| IPM_NAT				{ $$ = IPL_MAGIC_NAT; }
208*2393Syz155240 	| IPM_STATE				{ $$ = IPL_MAGIC_STATE; }
209*2393Syz155240 	;
210*2393Syz155240 
211*2393Syz155240 execute:
212*2393Syz155240 	IPM_EXECUTE YY_STR			{ $$ = new_opt(IPM_EXECUTE);
213*2393Syz155240 						  $$->o_str = $2; }
214*2393Syz155240 	;
215*2393Syz155240 
216*2393Syz155240 save:	IPM_SAVE saveopts YY_STR		{ $$ = new_opt(IPM_SAVE);
217*2393Syz155240 						  $$->o_num = $2;
218*2393Syz155240 						  $$->o_str = $3; }
219*2393Syz155240 	;
220*2393Syz155240 
221*2393Syz155240 saveopts:					{ $$ = 0; }
222*2393Syz155240 	| saveopt				{ $$ = $1; }
223*2393Syz155240 	| saveopt ',' saveopts			{ $$ = $1 | $3; }
224*2393Syz155240 	;
225*2393Syz155240 
226*2393Syz155240 saveopt:
227*2393Syz155240 	IPM_RAW					{ $$ = IPMDO_SAVERAW; }
228*2393Syz155240 	;
229*2393Syz155240 
230*2393Syz155240 syslog:	IPM_SYSLOG				{ $$ = new_opt(IPM_SYSLOG); }
231*2393Syz155240 	;
232*2393Syz155240 
233*2393Syz155240 nothing:
234*2393Syz155240 	IPM_NOTHING				{ $$ = 0; }
235*2393Syz155240 	;
236*2393Syz155240 
2370Sstevel@tonic-gate ipv4:   YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
2380Sstevel@tonic-gate 		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
2390Sstevel@tonic-gate 			yyerror("Invalid octet string for IP address");
2400Sstevel@tonic-gate 			return 0;
2410Sstevel@tonic-gate 		  }
2420Sstevel@tonic-gate 		  $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
2430Sstevel@tonic-gate 		  $$.s_addr = htonl($$.s_addr);
2440Sstevel@tonic-gate 		}
2450Sstevel@tonic-gate %%
2460Sstevel@tonic-gate static	struct	wordtab	yywords[] = {
2470Sstevel@tonic-gate 	{ "body",	IPM_BODY },
2480Sstevel@tonic-gate 	{ "direction",	IPM_DIRECTION },
249*2393Syz155240 	{ "do",		IPM_DO },
2500Sstevel@tonic-gate 	{ "dstip",	IPM_DSTIP },
2510Sstevel@tonic-gate 	{ "dstport",	IPM_DSTPORT },
2520Sstevel@tonic-gate 	{ "every",	IPM_EVERY },
2530Sstevel@tonic-gate 	{ "execute",	IPM_EXECUTE },
2540Sstevel@tonic-gate 	{ "group",	IPM_GROUP },
2550Sstevel@tonic-gate 	{ "in",		IPM_IN },
2560Sstevel@tonic-gate 	{ "interface",	IPM_INTERFACE },
257*2393Syz155240 	{ "ipf",	IPM_IPF },
258*2393Syz155240 	{ "logtag",	IPM_LOGTAG },
259*2393Syz155240 	{ "match",	IPM_MATCH },
260*2393Syz155240 	{ "nat",	IPM_NAT },
261*2393Syz155240 	{ "nattag",	IPM_NATTAG },
2620Sstevel@tonic-gate 	{ "no",		IPM_NO },
263*2393Syz155240 	{ "nothing",	IPM_NOTHING },
2640Sstevel@tonic-gate 	{ "out",	IPM_OUT },
2650Sstevel@tonic-gate 	{ "packet",	IPM_PACKET },
2660Sstevel@tonic-gate 	{ "packets",	IPM_PACKETS },
2670Sstevel@tonic-gate 	{ "protocol",	IPM_PROTOCOL },
2680Sstevel@tonic-gate 	{ "result",	IPM_RESULT },
2690Sstevel@tonic-gate 	{ "rule",	IPM_RULE },
270*2393Syz155240 	{ "save",	IPM_SAVE },
271*2393Syz155240 	{ "raw",	IPM_RAW },
2720Sstevel@tonic-gate 	{ "second",	IPM_SECOND },
2730Sstevel@tonic-gate 	{ "seconds",	IPM_SECONDS },
2740Sstevel@tonic-gate 	{ "srcip",	IPM_SRCIP },
2750Sstevel@tonic-gate 	{ "srcport",	IPM_SRCPORT },
276*2393Syz155240 	{ "state",	IPM_STATE },
277*2393Syz155240 	{ "syslog",	IPM_SYSLOG },
278*2393Syz155240 	{ "with",	IPM_WITH },
2790Sstevel@tonic-gate 	{ NULL,		0 }
2800Sstevel@tonic-gate };
2810Sstevel@tonic-gate 
282*2393Syz155240 static int macflags[17][2] = {
2830Sstevel@tonic-gate 	{ IPM_DIRECTION,	IPMAC_DIRECTION	},
2840Sstevel@tonic-gate 	{ IPM_DSTIP,		IPMAC_DSTIP	},
2850Sstevel@tonic-gate 	{ IPM_DSTPORT,		IPMAC_DSTPORT	},
2860Sstevel@tonic-gate 	{ IPM_GROUP,		IPMAC_GROUP	},
2870Sstevel@tonic-gate 	{ IPM_INTERFACE,	IPMAC_INTERFACE	},
288*2393Syz155240 	{ IPM_LOGTAG,		IPMAC_LOGTAG 	},
289*2393Syz155240 	{ IPM_NATTAG,		IPMAC_NATTAG 	},
2900Sstevel@tonic-gate 	{ IPM_PACKET,		IPMAC_EVERY	},
2910Sstevel@tonic-gate 	{ IPM_PROTOCOL,		IPMAC_PROTOCOL	},
2920Sstevel@tonic-gate 	{ IPM_RESULT,		IPMAC_RESULT	},
2930Sstevel@tonic-gate 	{ IPM_RULE,		IPMAC_RULE	},
2940Sstevel@tonic-gate 	{ IPM_SECOND,		IPMAC_EVERY	},
2950Sstevel@tonic-gate 	{ IPM_SRCIP,		IPMAC_SRCIP	},
2960Sstevel@tonic-gate 	{ IPM_SRCPORT,		IPMAC_SRCPORT	},
297*2393Syz155240 	{ IPM_TYPE,		IPMAC_TYPE 	},
298*2393Syz155240 	{ IPM_WITH,		IPMAC_WITH 	},
2990Sstevel@tonic-gate 	{ 0, 0 }
3000Sstevel@tonic-gate };
3010Sstevel@tonic-gate 
new_opt(type)3020Sstevel@tonic-gate static opt_t *new_opt(type)
3030Sstevel@tonic-gate int type;
3040Sstevel@tonic-gate {
3050Sstevel@tonic-gate 	opt_t *o;
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	o = (opt_t *)malloc(sizeof(*o));
3081448Sschuster 	if (o == NULL)
3091448Sschuster 		yyerror("sorry, out of memory");
3100Sstevel@tonic-gate 	o->o_type = type;
3110Sstevel@tonic-gate 	o->o_line = yylineNum;
3120Sstevel@tonic-gate 	o->o_num = 0;
3130Sstevel@tonic-gate 	o->o_str = (char *)0;
314*2393Syz155240 	o->o_next = NULL;
3150Sstevel@tonic-gate 	return o;
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate 
build_action(olist)3180Sstevel@tonic-gate static void build_action(olist)
3190Sstevel@tonic-gate opt_t *olist;
3200Sstevel@tonic-gate {
321*2393Syz155240 	ipmon_action_t *a;
3220Sstevel@tonic-gate 	opt_t *o;
3230Sstevel@tonic-gate 	char c;
3240Sstevel@tonic-gate 	int i;
3250Sstevel@tonic-gate 
326*2393Syz155240 	a = (ipmon_action_t *)calloc(1, sizeof(*a));
327*2393Syz155240 	if (a == NULL)
3280Sstevel@tonic-gate 		return;
329*2393Syz155240 	while ((o = olist) != NULL) {
330*2393Syz155240 		/*
331*2393Syz155240 		 * Check to see if the same comparator is being used more than
332*2393Syz155240 		 * once per matching statement.
333*2393Syz155240 		 */
3340Sstevel@tonic-gate 		for (i = 0; macflags[i][0]; i++)
3350Sstevel@tonic-gate 			if (macflags[i][0] == o->o_type)
3360Sstevel@tonic-gate 				break;
3370Sstevel@tonic-gate 		if (macflags[i][1] & a->ac_mflag) {
3380Sstevel@tonic-gate 			fprintf(stderr, "%s redfined on line %d\n",
3390Sstevel@tonic-gate 				yykeytostr(o->o_type), yylineNum);
3400Sstevel@tonic-gate 			if (o->o_str != NULL)
3410Sstevel@tonic-gate 				free(o->o_str);
3420Sstevel@tonic-gate 			olist = o->o_next;
3430Sstevel@tonic-gate 			free(o);
3440Sstevel@tonic-gate 			continue;
3450Sstevel@tonic-gate 		}
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 		a->ac_mflag |= macflags[i][1];
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 		switch (o->o_type)
3500Sstevel@tonic-gate 		{
3510Sstevel@tonic-gate 		case IPM_DIRECTION :
3520Sstevel@tonic-gate 			a->ac_direction = o->o_num;
3530Sstevel@tonic-gate 			break;
3540Sstevel@tonic-gate 		case IPM_DSTIP :
3550Sstevel@tonic-gate 			a->ac_dip = o->o_ip.s_addr;
356*2393Syz155240 			a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num));
3570Sstevel@tonic-gate 			break;
3580Sstevel@tonic-gate 		case IPM_DSTPORT :
3590Sstevel@tonic-gate 			a->ac_dport = htons(o->o_num);
3600Sstevel@tonic-gate 			break;
3610Sstevel@tonic-gate 		case IPM_EXECUTE :
3620Sstevel@tonic-gate 			a->ac_exec = o->o_str;
3630Sstevel@tonic-gate 			c = *o->o_str;
3640Sstevel@tonic-gate 			if (c== '"'|| c == '\'') {
3650Sstevel@tonic-gate 				if (o->o_str[strlen(o->o_str) - 1] == c) {
3660Sstevel@tonic-gate 					a->ac_run = strdup(o->o_str + 1);
3670Sstevel@tonic-gate 					a->ac_run[strlen(a->ac_run) - 1] ='\0';
3680Sstevel@tonic-gate 				} else
3690Sstevel@tonic-gate 					a->ac_run = o->o_str;
3700Sstevel@tonic-gate 			} else
3710Sstevel@tonic-gate 				a->ac_run = o->o_str;
3720Sstevel@tonic-gate 			o->o_str = NULL;
3730Sstevel@tonic-gate 			break;
3740Sstevel@tonic-gate 		case IPM_INTERFACE :
3750Sstevel@tonic-gate 			a->ac_iface = o->o_str;
3760Sstevel@tonic-gate 			o->o_str = NULL;
3770Sstevel@tonic-gate 			break;
3780Sstevel@tonic-gate 		case IPM_GROUP :
3790Sstevel@tonic-gate 			if (o->o_str != NULL)
3800Sstevel@tonic-gate 				strncpy(a->ac_group, o->o_str, FR_GROUPLEN);
3810Sstevel@tonic-gate 			else
3820Sstevel@tonic-gate 				sprintf(a->ac_group, "%d", o->o_num);
3830Sstevel@tonic-gate 			break;
384*2393Syz155240 		case IPM_LOGTAG :
385*2393Syz155240 			a->ac_logtag = o->o_num;
386*2393Syz155240 			break;
387*2393Syz155240 		case IPM_NATTAG :
388*2393Syz155240 			strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag));
389*2393Syz155240 			break;
3900Sstevel@tonic-gate 		case IPM_PACKET :
3910Sstevel@tonic-gate 			a->ac_packet = o->o_num;
3920Sstevel@tonic-gate 			break;
3930Sstevel@tonic-gate 		case IPM_PROTOCOL :
3940Sstevel@tonic-gate 			a->ac_proto = o->o_num;
3950Sstevel@tonic-gate 			break;
3960Sstevel@tonic-gate 		case IPM_RULE :
3970Sstevel@tonic-gate 			a->ac_rule = o->o_num;
3980Sstevel@tonic-gate 			break;
3990Sstevel@tonic-gate 		case IPM_RESULT :
4000Sstevel@tonic-gate 			if (!strcasecmp(o->o_str, "pass"))
4010Sstevel@tonic-gate 				a->ac_result = IPMR_PASS;
4020Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "block"))
4030Sstevel@tonic-gate 				a->ac_result = IPMR_BLOCK;
4040Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "nomatch"))
4050Sstevel@tonic-gate 				a->ac_result = IPMR_NOMATCH;
4060Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "log"))
4070Sstevel@tonic-gate 				a->ac_result = IPMR_LOG;
4080Sstevel@tonic-gate 			break;
4090Sstevel@tonic-gate 		case IPM_SECOND :
4100Sstevel@tonic-gate 			a->ac_second = o->o_num;
4110Sstevel@tonic-gate 			break;
4120Sstevel@tonic-gate 		case IPM_SRCIP :
4130Sstevel@tonic-gate 			a->ac_sip = o->o_ip.s_addr;
414*2393Syz155240 			a->ac_smsk = htonl(0xffffffff << (32 - o->o_num));
4150Sstevel@tonic-gate 			break;
4160Sstevel@tonic-gate 		case IPM_SRCPORT :
4170Sstevel@tonic-gate 			a->ac_sport = htons(o->o_num);
4180Sstevel@tonic-gate 			break;
419*2393Syz155240 		case IPM_SAVE :
420*2393Syz155240 			if (a->ac_savefile != NULL) {
421*2393Syz155240 				fprintf(stderr, "%s redfined on line %d\n",
422*2393Syz155240 					yykeytostr(o->o_type), yylineNum);
423*2393Syz155240 				break;
424*2393Syz155240 			}
425*2393Syz155240 			a->ac_savefile = strdup(o->o_str);
426*2393Syz155240 			a->ac_savefp = fopen(o->o_str, "a");
427*2393Syz155240 			a->ac_dflag |= o->o_num & IPMDO_SAVERAW;
428*2393Syz155240 			break;
429*2393Syz155240 		case IPM_SYSLOG :
430*2393Syz155240 			if (a->ac_syslog != 0) {
431*2393Syz155240 				fprintf(stderr, "%s redfined on line %d\n",
432*2393Syz155240 					yykeytostr(o->o_type), yylineNum);
433*2393Syz155240 				break;
434*2393Syz155240 			}
435*2393Syz155240 			a->ac_syslog = 1;
436*2393Syz155240 			break;
437*2393Syz155240 		case IPM_TYPE :
438*2393Syz155240 			a->ac_type = o->o_num;
439*2393Syz155240 			break;
440*2393Syz155240 		case IPM_WITH :
4410Sstevel@tonic-gate 			break;
4420Sstevel@tonic-gate 		default :
4430Sstevel@tonic-gate 			break;
4440Sstevel@tonic-gate 		}
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate 		olist = o->o_next;
4470Sstevel@tonic-gate 		if (o->o_str != NULL)
4480Sstevel@tonic-gate 			free(o->o_str);
4490Sstevel@tonic-gate 		free(o);
4500Sstevel@tonic-gate 	}
451*2393Syz155240 	a->ac_next = alist;
4520Sstevel@tonic-gate 	alist = a;
4530Sstevel@tonic-gate }
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 
check_action(buf,log,opts,lvl)456*2393Syz155240 int check_action(buf, log, opts, lvl)
457*2393Syz155240 char *buf, *log;
458*2393Syz155240 int opts, lvl;
4590Sstevel@tonic-gate {
460*2393Syz155240 	ipmon_action_t *a;
4610Sstevel@tonic-gate 	struct timeval tv;
4620Sstevel@tonic-gate 	ipflog_t *ipf;
4630Sstevel@tonic-gate 	tcphdr_t *tcp;
4640Sstevel@tonic-gate 	iplog_t *ipl;
465*2393Syz155240 	int matched;
4660Sstevel@tonic-gate 	u_long t1;
4670Sstevel@tonic-gate 	ip_t *ip;
4680Sstevel@tonic-gate 
469*2393Syz155240 	matched = 0;
4700Sstevel@tonic-gate 	ipl = (iplog_t *)buf;
4710Sstevel@tonic-gate 	ipf = (ipflog_t *)(ipl +1);
4720Sstevel@tonic-gate 	ip = (ip_t *)(ipf + 1);
4730Sstevel@tonic-gate 	tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
4740Sstevel@tonic-gate 
475*2393Syz155240 	for (a = alist; a != NULL; a = a->ac_next) {
476*2393Syz155240 		if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
4770Sstevel@tonic-gate 			if (a->ac_direction == IPM_IN) {
478*2393Syz155240 				if ((ipf->fl_flags & FR_INQUE) == 0)
4790Sstevel@tonic-gate 					continue;
4800Sstevel@tonic-gate 			} else if (a->ac_direction == IPM_OUT) {
481*2393Syz155240 				if ((ipf->fl_flags & FR_OUTQUE) == 0)
4820Sstevel@tonic-gate 					continue;
4830Sstevel@tonic-gate 			}
4840Sstevel@tonic-gate 		}
4850Sstevel@tonic-gate 
486*2393Syz155240 		if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic))
487*2393Syz155240 			continue;
488*2393Syz155240 
489*2393Syz155240 		if ((a->ac_mflag & IPMAC_EVERY) != 0) {
4900Sstevel@tonic-gate 			gettimeofday(&tv, NULL);
4910Sstevel@tonic-gate 			t1 = tv.tv_sec - a->ac_lastsec;
4920Sstevel@tonic-gate 			if (tv.tv_usec <= a->ac_lastusec)
4930Sstevel@tonic-gate 				t1--;
494*2393Syz155240 			if (a->ac_second != 0) {
4950Sstevel@tonic-gate 				if (t1 < a->ac_second)
4960Sstevel@tonic-gate 					continue;
4970Sstevel@tonic-gate 				a->ac_lastsec = tv.tv_sec;
4980Sstevel@tonic-gate 				a->ac_lastusec = tv.tv_usec;
4990Sstevel@tonic-gate 			}
5000Sstevel@tonic-gate 
501*2393Syz155240 			if (a->ac_packet != 0) {
502*2393Syz155240 				if (a->ac_pktcnt == 0)
5030Sstevel@tonic-gate 					a->ac_pktcnt++;
5040Sstevel@tonic-gate 				else if (a->ac_pktcnt == a->ac_packet) {
5050Sstevel@tonic-gate 					a->ac_pktcnt = 0;
5060Sstevel@tonic-gate 					continue;
5070Sstevel@tonic-gate 				} else {
5080Sstevel@tonic-gate 					a->ac_pktcnt++;
5090Sstevel@tonic-gate 					continue;
5100Sstevel@tonic-gate 				}
5110Sstevel@tonic-gate 			}
5120Sstevel@tonic-gate 		}
5130Sstevel@tonic-gate 
514*2393Syz155240 		if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
5150Sstevel@tonic-gate 			if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip)
5160Sstevel@tonic-gate 				continue;
5170Sstevel@tonic-gate 		}
5180Sstevel@tonic-gate 
519*2393Syz155240 		if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
5200Sstevel@tonic-gate 			if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
5210Sstevel@tonic-gate 				continue;
5220Sstevel@tonic-gate 			if (tcp->th_dport != a->ac_dport)
5230Sstevel@tonic-gate 				continue;
5240Sstevel@tonic-gate 		}
5250Sstevel@tonic-gate 
526*2393Syz155240 		if ((a->ac_mflag & IPMAC_GROUP) != 0) {
5270Sstevel@tonic-gate 			if (strncmp(a->ac_group, ipf->fl_group,
5280Sstevel@tonic-gate 				    FR_GROUPLEN) != 0)
5290Sstevel@tonic-gate 				continue;
5300Sstevel@tonic-gate 		}
5310Sstevel@tonic-gate 
532*2393Syz155240 		if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
5330Sstevel@tonic-gate 			if (strcmp(a->ac_iface, ipf->fl_ifname))
5340Sstevel@tonic-gate 				continue;
5350Sstevel@tonic-gate 		}
5360Sstevel@tonic-gate 
537*2393Syz155240 		if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
5380Sstevel@tonic-gate 			if (a->ac_proto != ip->ip_p)
5390Sstevel@tonic-gate 				continue;
5400Sstevel@tonic-gate 		}
5410Sstevel@tonic-gate 
542*2393Syz155240 		if ((a->ac_mflag & IPMAC_RESULT) != 0) {
543*2393Syz155240 			if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
544*2393Syz155240 				if (a->ac_result != IPMR_NOMATCH)
5450Sstevel@tonic-gate 					continue;
5460Sstevel@tonic-gate 			} else if (FR_ISPASS(ipf->fl_flags)) {
5470Sstevel@tonic-gate 				if (a->ac_result != IPMR_PASS)
5480Sstevel@tonic-gate 					continue;
5490Sstevel@tonic-gate 			} else if (FR_ISBLOCK(ipf->fl_flags)) {
5500Sstevel@tonic-gate 				if (a->ac_result != IPMR_BLOCK)
5510Sstevel@tonic-gate 					continue;
5520Sstevel@tonic-gate 			} else {	/* Log only */
5530Sstevel@tonic-gate 				if (a->ac_result != IPMR_LOG)
5540Sstevel@tonic-gate 					continue;
5550Sstevel@tonic-gate 			}
5560Sstevel@tonic-gate 		}
5570Sstevel@tonic-gate 
558*2393Syz155240 		if ((a->ac_mflag & IPMAC_RULE) != 0) {
5590Sstevel@tonic-gate 			if (a->ac_rule != ipf->fl_rule)
5600Sstevel@tonic-gate 				continue;
5610Sstevel@tonic-gate 		}
5620Sstevel@tonic-gate 
563*2393Syz155240 		if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
5640Sstevel@tonic-gate 			if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip)
5650Sstevel@tonic-gate 				continue;
5660Sstevel@tonic-gate 		}
5670Sstevel@tonic-gate 
568*2393Syz155240 		if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
5690Sstevel@tonic-gate 			if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
5700Sstevel@tonic-gate 				continue;
5710Sstevel@tonic-gate 			if (tcp->th_sport != a->ac_sport)
5720Sstevel@tonic-gate 				continue;
5730Sstevel@tonic-gate 		}
5740Sstevel@tonic-gate 
575*2393Syz155240 		if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
576*2393Syz155240 			if (a->ac_logtag != ipf->fl_logtag)
5770Sstevel@tonic-gate 				continue;
5780Sstevel@tonic-gate 		}
5790Sstevel@tonic-gate 
580*2393Syz155240 		if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
581*2393Syz155240 			if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
582*2393Syz155240 				    IPFTAG_LEN) != 0)
583*2393Syz155240 				continue;
584*2393Syz155240 		}
585*2393Syz155240 
586*2393Syz155240 		matched = 1;
587*2393Syz155240 
5880Sstevel@tonic-gate 		/*
5890Sstevel@tonic-gate 		 * It matched so now execute the command
5900Sstevel@tonic-gate 		 */
591*2393Syz155240 		if (a->ac_syslog != 0) {
592*2393Syz155240 			syslog(lvl, "%s", log);
593*2393Syz155240 		}
594*2393Syz155240 
595*2393Syz155240 		if (a->ac_savefp != NULL) {
596*2393Syz155240 			if (a->ac_dflag & IPMDO_SAVERAW)
597*2393Syz155240 				fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp);
598*2393Syz155240 			else
599*2393Syz155240 				fputs(log, a->ac_savefp);
600*2393Syz155240 		}
601*2393Syz155240 
602*2393Syz155240 		if (a->ac_exec != NULL) {
6030Sstevel@tonic-gate 			switch (fork())
6040Sstevel@tonic-gate 			{
6050Sstevel@tonic-gate 			case 0 :
6060Sstevel@tonic-gate 			{
6070Sstevel@tonic-gate 				FILE *pi;
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate 				pi = popen(a->ac_run, "w");
610*2393Syz155240 				if (pi != NULL) {
6110Sstevel@tonic-gate 					fprintf(pi, "%s\n", log);
612*2393Syz155240 					if ((opts & OPT_HEXHDR) != 0) {
6130Sstevel@tonic-gate 						dumphex(pi, 0, buf,
6140Sstevel@tonic-gate 							sizeof(*ipl) +
6150Sstevel@tonic-gate 							sizeof(*ipf));
6160Sstevel@tonic-gate 					}
617*2393Syz155240 					if ((opts & OPT_HEXBODY) != 0) {
6180Sstevel@tonic-gate 						dumphex(pi, 0, (char *)ip,
6190Sstevel@tonic-gate 							ipf->fl_hlen +
6200Sstevel@tonic-gate 							ipf->fl_plen);
6210Sstevel@tonic-gate 					}
6220Sstevel@tonic-gate 					pclose(pi);
6230Sstevel@tonic-gate 				}
6240Sstevel@tonic-gate 				exit(1);
6250Sstevel@tonic-gate 			}
6260Sstevel@tonic-gate 			case -1 :
6270Sstevel@tonic-gate 				break;
6280Sstevel@tonic-gate 			default :
6290Sstevel@tonic-gate 				break;
6300Sstevel@tonic-gate 			}
6310Sstevel@tonic-gate 		}
6320Sstevel@tonic-gate 	}
633*2393Syz155240 
634*2393Syz155240 	return matched;
635*2393Syz155240 }
636*2393Syz155240 
637*2393Syz155240 
free_action(a)638*2393Syz155240 static void free_action(a)
639*2393Syz155240 ipmon_action_t *a;
640*2393Syz155240 {
641*2393Syz155240 	if (a->ac_savefile != NULL) {
642*2393Syz155240 		free(a->ac_savefile);
643*2393Syz155240 		a->ac_savefile = NULL;
644*2393Syz155240 	}
645*2393Syz155240 	if (a->ac_savefp != NULL) {
646*2393Syz155240 		fclose(a->ac_savefp);
647*2393Syz155240 		a->ac_savefp = NULL;
648*2393Syz155240 	}
649*2393Syz155240 	if (a->ac_exec != NULL) {
650*2393Syz155240 		free(a->ac_exec);
651*2393Syz155240 		if (a->ac_run == a->ac_exec)
652*2393Syz155240 			a->ac_run = NULL;
653*2393Syz155240 		a->ac_exec = NULL;
654*2393Syz155240 	}
655*2393Syz155240 	if (a->ac_run != NULL) {
656*2393Syz155240 		free(a->ac_run);
657*2393Syz155240 		a->ac_run = NULL;
658*2393Syz155240 	}
659*2393Syz155240 	if (a->ac_iface != NULL) {
660*2393Syz155240 		free(a->ac_iface);
661*2393Syz155240 		a->ac_iface = NULL;
662*2393Syz155240 	}
663*2393Syz155240 	a->ac_next = NULL;
664*2393Syz155240 	free(a);
6650Sstevel@tonic-gate }
6660Sstevel@tonic-gate 
6670Sstevel@tonic-gate 
load_config(file)6680Sstevel@tonic-gate int load_config(file)
6690Sstevel@tonic-gate char *file;
6700Sstevel@tonic-gate {
671*2393Syz155240 	ipmon_action_t *a;
6720Sstevel@tonic-gate 	FILE *fp;
673*2393Syz155240 	char *s;
6740Sstevel@tonic-gate 
675*2393Syz155240 	s = getenv("YYDEBUG");
676*2393Syz155240 	if (s != NULL)
677*2393Syz155240 		yydebug = atoi(s);
678*2393Syz155240 	else
679*2393Syz155240 		yydebug = 0;
680*2393Syz155240 
681*2393Syz155240 	while ((a = alist) != NULL) {
682*2393Syz155240 		alist = a->ac_next;
683*2393Syz155240 		free_action(a);
684*2393Syz155240 	}
685*2393Syz155240 
686*2393Syz155240 	yylineNum = 1;
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 	(void) yysettab(yywords);
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 	fp = fopen(file, "r");
6910Sstevel@tonic-gate 	if (!fp) {
6920Sstevel@tonic-gate 		perror("load_config:fopen:");
6930Sstevel@tonic-gate 		return -1;
6940Sstevel@tonic-gate 	}
6950Sstevel@tonic-gate 	yyin = fp;
6960Sstevel@tonic-gate 	while (!feof(fp))
6970Sstevel@tonic-gate 		yyparse();
6980Sstevel@tonic-gate 	fclose(fp);
6990Sstevel@tonic-gate 	return 0;
7000Sstevel@tonic-gate }
701