xref: /titanic_51/usr/src/cmd/ipf/tools/ipmon_y.y (revision ab25eeb551a4be927a4b6ae2cf8aff7ed17decb4)
1*ab25eeb5Syz155240 /*
2*ab25eeb5Syz155240  * Copyright (C) 1993-2005  by Darren Reed.
3*ab25eeb5Syz155240  * See the IPFILTER.LICENCE file for details on licencing.
4*ab25eeb5Syz155240  */
5*ab25eeb5Syz155240 
67c478bd9Sstevel@tonic-gate %{
77c478bd9Sstevel@tonic-gate #include "ipf.h"
8*ab25eeb5Syz155240 #include <syslog.h>
97c478bd9Sstevel@tonic-gate #undef	OPT_NAT
107c478bd9Sstevel@tonic-gate #undef	OPT_VERBOSE
117c478bd9Sstevel@tonic-gate #include "ipmon_l.h"
127c478bd9Sstevel@tonic-gate #include "ipmon.h"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #define	YYDEBUG	1
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate extern	void	yyerror __P((char *));
177c478bd9Sstevel@tonic-gate extern	int	yyparse __P((void));
187c478bd9Sstevel@tonic-gate extern	int	yylex __P((void));
197c478bd9Sstevel@tonic-gate extern	int	yydebug;
207c478bd9Sstevel@tonic-gate extern	FILE	*yyin;
217c478bd9Sstevel@tonic-gate extern	int	yylineNum;
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate typedef	struct	opt	{
247c478bd9Sstevel@tonic-gate 	struct	opt	*o_next;
257c478bd9Sstevel@tonic-gate 	int		o_line;
267c478bd9Sstevel@tonic-gate 	int		o_type;
277c478bd9Sstevel@tonic-gate 	int		o_num;
287c478bd9Sstevel@tonic-gate 	char		*o_str;
297c478bd9Sstevel@tonic-gate 	struct in_addr	o_ip;
307c478bd9Sstevel@tonic-gate } opt_t;
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate static	void	build_action __P((struct opt *));
337c478bd9Sstevel@tonic-gate static	opt_t	*new_opt __P((int));
34*ab25eeb5Syz155240 static	void	free_action __P((ipmon_action_t *));
357c478bd9Sstevel@tonic-gate 
36*ab25eeb5Syz155240 static	ipmon_action_t	*alist = NULL;
377c478bd9Sstevel@tonic-gate %}
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate %union	{
407c478bd9Sstevel@tonic-gate 	char	*str;
417c478bd9Sstevel@tonic-gate 	u_32_t	num;
427c478bd9Sstevel@tonic-gate 	struct in_addr	addr;
437c478bd9Sstevel@tonic-gate 	struct opt	*opt;
447c478bd9Sstevel@tonic-gate 	union	i6addr	ip6;
457c478bd9Sstevel@tonic-gate }
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate %token	<num>	YY_NUMBER YY_HEX
487c478bd9Sstevel@tonic-gate %token	<str>	YY_STR
49*ab25eeb5Syz155240 %token	<ip6>	YY_IPV6
507c478bd9Sstevel@tonic-gate %token	YY_COMMENT
517c478bd9Sstevel@tonic-gate %token	YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
527c478bd9Sstevel@tonic-gate %token	YY_RANGE_OUT YY_RANGE_IN
537c478bd9Sstevel@tonic-gate 
54*ab25eeb5Syz155240 %token	IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
557c478bd9Sstevel@tonic-gate %token	IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT
567c478bd9Sstevel@tonic-gate %token	IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
57*ab25eeb5Syz155240 %token	IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
58*ab25eeb5Syz155240 %token	IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT
59*ab25eeb5Syz155240 %token	IPM_STATE IPM_NATTAG IPM_IPF
607c478bd9Sstevel@tonic-gate %type	<addr> ipv4
61*ab25eeb5Syz155240 %type	<opt> direction dstip dstport every execute group interface
62*ab25eeb5Syz155240 %type	<opt> protocol result rule srcip srcport logtag matching
63*ab25eeb5Syz155240 %type	<opt> matchopt nattag type doopt doing save syslog nothing
64*ab25eeb5Syz155240 %type	<num> saveopts saveopt typeopt
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate %%
677c478bd9Sstevel@tonic-gate file:	line
687c478bd9Sstevel@tonic-gate 	| assign
697c478bd9Sstevel@tonic-gate 	| file line
707c478bd9Sstevel@tonic-gate 	| file assign
717c478bd9Sstevel@tonic-gate 	;
727c478bd9Sstevel@tonic-gate 
73*ab25eeb5Syz155240 line:	IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';'
74*ab25eeb5Syz155240 					{ build_action($3); resetlexer(); }
757c478bd9Sstevel@tonic-gate 	| IPM_COMMENT
76*ab25eeb5Syz155240 	| YY_COMMENT
777c478bd9Sstevel@tonic-gate 	;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate assign:	YY_STR assigning YY_STR ';'		{ set_variable($1, $3);
807c478bd9Sstevel@tonic-gate 						  resetlexer();
817c478bd9Sstevel@tonic-gate 						  free($1);
827c478bd9Sstevel@tonic-gate 						  free($3);
837c478bd9Sstevel@tonic-gate 						}
847c478bd9Sstevel@tonic-gate 	;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate assigning:
877c478bd9Sstevel@tonic-gate 	'='					{ yyvarnext = 1; }
887c478bd9Sstevel@tonic-gate 	;
897c478bd9Sstevel@tonic-gate 
90*ab25eeb5Syz155240 matching:
91*ab25eeb5Syz155240 	matchopt				{ $$ = $1; }
92*ab25eeb5Syz155240 	| matchopt ',' matching			{ $1->o_next = $3; $$ = $1; }
937c478bd9Sstevel@tonic-gate 	;
947c478bd9Sstevel@tonic-gate 
95*ab25eeb5Syz155240 matchopt:
96*ab25eeb5Syz155240 	direction				{ $$ = $1; }
977c478bd9Sstevel@tonic-gate 	| dstip					{ $$ = $1; }
987c478bd9Sstevel@tonic-gate 	| dstport				{ $$ = $1; }
997c478bd9Sstevel@tonic-gate 	| every					{ $$ = $1; }
1007c478bd9Sstevel@tonic-gate 	| group					{ $$ = $1; }
1017c478bd9Sstevel@tonic-gate 	| interface				{ $$ = $1; }
1027c478bd9Sstevel@tonic-gate 	| protocol				{ $$ = $1; }
1037c478bd9Sstevel@tonic-gate 	| result				{ $$ = $1; }
1047c478bd9Sstevel@tonic-gate 	| rule					{ $$ = $1; }
1057c478bd9Sstevel@tonic-gate 	| srcip					{ $$ = $1; }
1067c478bd9Sstevel@tonic-gate 	| srcport				{ $$ = $1; }
107*ab25eeb5Syz155240 	| logtag				{ $$ = $1; }
108*ab25eeb5Syz155240 	| nattag				{ $$ = $1; }
109*ab25eeb5Syz155240 	| type					{ $$ = $1; }
110*ab25eeb5Syz155240 	;
111*ab25eeb5Syz155240 
112*ab25eeb5Syz155240 doing:
113*ab25eeb5Syz155240 	doopt					{ $$ = $1; }
114*ab25eeb5Syz155240 	| doopt ',' doing			{ $1->o_next = $3; $$ = $1; }
115*ab25eeb5Syz155240 	;
116*ab25eeb5Syz155240 
117*ab25eeb5Syz155240 doopt:
118*ab25eeb5Syz155240 	execute					{ $$ = $1; }
119*ab25eeb5Syz155240 	| save					{ $$ = $1; }
120*ab25eeb5Syz155240 	| syslog				{ $$ = $1; }
121*ab25eeb5Syz155240 	| nothing				{ $$ = $1; }
1227c478bd9Sstevel@tonic-gate 	;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate direction:
1257c478bd9Sstevel@tonic-gate 	IPM_DIRECTION '=' IPM_IN		{ $$ = new_opt(IPM_DIRECTION);
1267c478bd9Sstevel@tonic-gate 						  $$->o_num = IPM_IN; }
1277c478bd9Sstevel@tonic-gate 	| IPM_DIRECTION '=' IPM_OUT		{ $$ = new_opt(IPM_DIRECTION);
1287c478bd9Sstevel@tonic-gate 						  $$->o_num = IPM_OUT; }
1297c478bd9Sstevel@tonic-gate 	;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate dstip:	IPM_DSTIP '=' ipv4 '/' YY_NUMBER	{ $$ = new_opt(IPM_DSTIP);
1327c478bd9Sstevel@tonic-gate 						  $$->o_ip = $3;
1337c478bd9Sstevel@tonic-gate 						  $$->o_num = $5; }
1347c478bd9Sstevel@tonic-gate 	;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate dstport:
1377c478bd9Sstevel@tonic-gate 	IPM_DSTPORT '=' YY_NUMBER		{ $$ = new_opt(IPM_DSTPORT);
1387c478bd9Sstevel@tonic-gate 						  $$->o_num = $3; }
1397c478bd9Sstevel@tonic-gate 	| IPM_DSTPORT '=' YY_STR		{ $$ = new_opt(IPM_DSTPORT);
1407c478bd9Sstevel@tonic-gate 						  $$->o_str = $3; }
1417c478bd9Sstevel@tonic-gate 	;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate every:	IPM_EVERY IPM_SECOND			{ $$ = new_opt(IPM_SECOND);
1447c478bd9Sstevel@tonic-gate 						  $$->o_num = 1; }
1457c478bd9Sstevel@tonic-gate 	| IPM_EVERY YY_NUMBER IPM_SECONDS	{ $$ = new_opt(IPM_SECOND);
1467c478bd9Sstevel@tonic-gate 						  $$->o_num = $2; }
1477c478bd9Sstevel@tonic-gate 	| IPM_EVERY IPM_PACKET			{ $$ = new_opt(IPM_PACKET);
1487c478bd9Sstevel@tonic-gate 						  $$->o_num = 1; }
1497c478bd9Sstevel@tonic-gate 	| IPM_EVERY YY_NUMBER IPM_PACKETS	{ $$ = new_opt(IPM_PACKET);
1507c478bd9Sstevel@tonic-gate 						  $$->o_num = $2; }
1517c478bd9Sstevel@tonic-gate 	;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate group:	IPM_GROUP '=' YY_NUMBER			{ $$ = new_opt(IPM_GROUP);
1547c478bd9Sstevel@tonic-gate 						  $$->o_num = $3; }
1557c478bd9Sstevel@tonic-gate 	| IPM_GROUP '=' YY_STR			{ $$ = new_opt(IPM_GROUP);
1567c478bd9Sstevel@tonic-gate 						  $$->o_str = $3; }
1577c478bd9Sstevel@tonic-gate 	;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate interface:
1607c478bd9Sstevel@tonic-gate 	IPM_INTERFACE '=' YY_STR		{ $$ = new_opt(IPM_INTERFACE);
1617c478bd9Sstevel@tonic-gate 						  $$->o_str = $3; }
1627c478bd9Sstevel@tonic-gate 	;
1637c478bd9Sstevel@tonic-gate 
164*ab25eeb5Syz155240 logtag:	IPM_LOGTAG '=' YY_NUMBER		{ $$ = new_opt(IPM_LOGTAG);
165*ab25eeb5Syz155240 						  $$->o_num = $3; }
166*ab25eeb5Syz155240 	;
167*ab25eeb5Syz155240 
168*ab25eeb5Syz155240 nattag:	IPM_NATTAG '=' YY_STR			{ $$ = new_opt(IPM_NATTAG);
169*ab25eeb5Syz155240 						  $$->o_str = $3; }
170*ab25eeb5Syz155240 	;
171*ab25eeb5Syz155240 
1727c478bd9Sstevel@tonic-gate protocol:
1737c478bd9Sstevel@tonic-gate 	IPM_PROTOCOL '=' YY_NUMBER		{ $$ = new_opt(IPM_PROTOCOL);
1747c478bd9Sstevel@tonic-gate 						  $$->o_num = $3; }
1757c478bd9Sstevel@tonic-gate 	| IPM_PROTOCOL '=' YY_STR		{ $$ = new_opt(IPM_PROTOCOL);
1767c478bd9Sstevel@tonic-gate 						  $$->o_num = getproto($3);
1777c478bd9Sstevel@tonic-gate 						  free($3);
1787c478bd9Sstevel@tonic-gate 						}
1797c478bd9Sstevel@tonic-gate 	;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate result:	IPM_RESULT '=' YY_STR			{ $$ = new_opt(IPM_RESULT);
1827c478bd9Sstevel@tonic-gate 						  $$->o_str = $3; }
1837c478bd9Sstevel@tonic-gate 	;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate rule:	IPM_RULE '=' YY_NUMBER			{ $$ = new_opt(IPM_RULE);
1867c478bd9Sstevel@tonic-gate 						  $$->o_num = YY_NUMBER; }
1877c478bd9Sstevel@tonic-gate 	;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate srcip:	IPM_SRCIP '=' ipv4 '/' YY_NUMBER	{ $$ = new_opt(IPM_SRCIP);
1907c478bd9Sstevel@tonic-gate 						  $$->o_ip = $3;
1917c478bd9Sstevel@tonic-gate 						  $$->o_num = $5; }
1927c478bd9Sstevel@tonic-gate 	;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate srcport:
1957c478bd9Sstevel@tonic-gate 	IPM_SRCPORT '=' YY_NUMBER		{ $$ = new_opt(IPM_SRCPORT);
1967c478bd9Sstevel@tonic-gate 						  $$->o_num = $3; }
1977c478bd9Sstevel@tonic-gate 	| IPM_SRCPORT '=' YY_STR		{ $$ = new_opt(IPM_SRCPORT);
1987c478bd9Sstevel@tonic-gate 						  $$->o_str = $3; }
1997c478bd9Sstevel@tonic-gate 	;
2007c478bd9Sstevel@tonic-gate 
201*ab25eeb5Syz155240 type:	IPM_TYPE '=' typeopt			{ $$ = new_opt(IPM_TYPE);
2027c478bd9Sstevel@tonic-gate 						  $$->o_num = $3; }
2037c478bd9Sstevel@tonic-gate 	;
2047c478bd9Sstevel@tonic-gate 
205*ab25eeb5Syz155240 typeopt:
206*ab25eeb5Syz155240 	IPM_IPF					{ $$ = IPL_MAGIC; }
207*ab25eeb5Syz155240 	| IPM_NAT				{ $$ = IPL_MAGIC_NAT; }
208*ab25eeb5Syz155240 	| IPM_STATE				{ $$ = IPL_MAGIC_STATE; }
209*ab25eeb5Syz155240 	;
210*ab25eeb5Syz155240 
211*ab25eeb5Syz155240 execute:
212*ab25eeb5Syz155240 	IPM_EXECUTE YY_STR			{ $$ = new_opt(IPM_EXECUTE);
213*ab25eeb5Syz155240 						  $$->o_str = $2; }
214*ab25eeb5Syz155240 	;
215*ab25eeb5Syz155240 
216*ab25eeb5Syz155240 save:	IPM_SAVE saveopts YY_STR		{ $$ = new_opt(IPM_SAVE);
217*ab25eeb5Syz155240 						  $$->o_num = $2;
218*ab25eeb5Syz155240 						  $$->o_str = $3; }
219*ab25eeb5Syz155240 	;
220*ab25eeb5Syz155240 
221*ab25eeb5Syz155240 saveopts:					{ $$ = 0; }
222*ab25eeb5Syz155240 	| saveopt				{ $$ = $1; }
223*ab25eeb5Syz155240 	| saveopt ',' saveopts			{ $$ = $1 | $3; }
224*ab25eeb5Syz155240 	;
225*ab25eeb5Syz155240 
226*ab25eeb5Syz155240 saveopt:
227*ab25eeb5Syz155240 	IPM_RAW					{ $$ = IPMDO_SAVERAW; }
228*ab25eeb5Syz155240 	;
229*ab25eeb5Syz155240 
230*ab25eeb5Syz155240 syslog:	IPM_SYSLOG				{ $$ = new_opt(IPM_SYSLOG); }
231*ab25eeb5Syz155240 	;
232*ab25eeb5Syz155240 
233*ab25eeb5Syz155240 nothing:
234*ab25eeb5Syz155240 	IPM_NOTHING				{ $$ = 0; }
235*ab25eeb5Syz155240 	;
236*ab25eeb5Syz155240 
2377c478bd9Sstevel@tonic-gate ipv4:   YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
2387c478bd9Sstevel@tonic-gate 		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
2397c478bd9Sstevel@tonic-gate 			yyerror("Invalid octet string for IP address");
2407c478bd9Sstevel@tonic-gate 			return 0;
2417c478bd9Sstevel@tonic-gate 		  }
2427c478bd9Sstevel@tonic-gate 		  $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
2437c478bd9Sstevel@tonic-gate 		  $$.s_addr = htonl($$.s_addr);
2447c478bd9Sstevel@tonic-gate 		}
2457c478bd9Sstevel@tonic-gate %%
2467c478bd9Sstevel@tonic-gate static	struct	wordtab	yywords[] = {
2477c478bd9Sstevel@tonic-gate 	{ "body",	IPM_BODY },
2487c478bd9Sstevel@tonic-gate 	{ "direction",	IPM_DIRECTION },
249*ab25eeb5Syz155240 	{ "do",		IPM_DO },
2507c478bd9Sstevel@tonic-gate 	{ "dstip",	IPM_DSTIP },
2517c478bd9Sstevel@tonic-gate 	{ "dstport",	IPM_DSTPORT },
2527c478bd9Sstevel@tonic-gate 	{ "every",	IPM_EVERY },
2537c478bd9Sstevel@tonic-gate 	{ "execute",	IPM_EXECUTE },
2547c478bd9Sstevel@tonic-gate 	{ "group",	IPM_GROUP },
2557c478bd9Sstevel@tonic-gate 	{ "in",		IPM_IN },
2567c478bd9Sstevel@tonic-gate 	{ "interface",	IPM_INTERFACE },
257*ab25eeb5Syz155240 	{ "ipf",	IPM_IPF },
258*ab25eeb5Syz155240 	{ "logtag",	IPM_LOGTAG },
259*ab25eeb5Syz155240 	{ "match",	IPM_MATCH },
260*ab25eeb5Syz155240 	{ "nat",	IPM_NAT },
261*ab25eeb5Syz155240 	{ "nattag",	IPM_NATTAG },
2627c478bd9Sstevel@tonic-gate 	{ "no",		IPM_NO },
263*ab25eeb5Syz155240 	{ "nothing",	IPM_NOTHING },
2647c478bd9Sstevel@tonic-gate 	{ "out",	IPM_OUT },
2657c478bd9Sstevel@tonic-gate 	{ "packet",	IPM_PACKET },
2667c478bd9Sstevel@tonic-gate 	{ "packets",	IPM_PACKETS },
2677c478bd9Sstevel@tonic-gate 	{ "protocol",	IPM_PROTOCOL },
2687c478bd9Sstevel@tonic-gate 	{ "result",	IPM_RESULT },
2697c478bd9Sstevel@tonic-gate 	{ "rule",	IPM_RULE },
270*ab25eeb5Syz155240 	{ "save",	IPM_SAVE },
271*ab25eeb5Syz155240 	{ "raw",	IPM_RAW },
2727c478bd9Sstevel@tonic-gate 	{ "second",	IPM_SECOND },
2737c478bd9Sstevel@tonic-gate 	{ "seconds",	IPM_SECONDS },
2747c478bd9Sstevel@tonic-gate 	{ "srcip",	IPM_SRCIP },
2757c478bd9Sstevel@tonic-gate 	{ "srcport",	IPM_SRCPORT },
276*ab25eeb5Syz155240 	{ "state",	IPM_STATE },
277*ab25eeb5Syz155240 	{ "syslog",	IPM_SYSLOG },
278*ab25eeb5Syz155240 	{ "with",	IPM_WITH },
2797c478bd9Sstevel@tonic-gate 	{ NULL,		0 }
2807c478bd9Sstevel@tonic-gate };
2817c478bd9Sstevel@tonic-gate 
282*ab25eeb5Syz155240 static int macflags[17][2] = {
2837c478bd9Sstevel@tonic-gate 	{ IPM_DIRECTION,	IPMAC_DIRECTION	},
2847c478bd9Sstevel@tonic-gate 	{ IPM_DSTIP,		IPMAC_DSTIP	},
2857c478bd9Sstevel@tonic-gate 	{ IPM_DSTPORT,		IPMAC_DSTPORT	},
2867c478bd9Sstevel@tonic-gate 	{ IPM_GROUP,		IPMAC_GROUP	},
2877c478bd9Sstevel@tonic-gate 	{ IPM_INTERFACE,	IPMAC_INTERFACE	},
288*ab25eeb5Syz155240 	{ IPM_LOGTAG,		IPMAC_LOGTAG 	},
289*ab25eeb5Syz155240 	{ IPM_NATTAG,		IPMAC_NATTAG 	},
2907c478bd9Sstevel@tonic-gate 	{ IPM_PACKET,		IPMAC_EVERY	},
2917c478bd9Sstevel@tonic-gate 	{ IPM_PROTOCOL,		IPMAC_PROTOCOL	},
2927c478bd9Sstevel@tonic-gate 	{ IPM_RESULT,		IPMAC_RESULT	},
2937c478bd9Sstevel@tonic-gate 	{ IPM_RULE,		IPMAC_RULE	},
2947c478bd9Sstevel@tonic-gate 	{ IPM_SECOND,		IPMAC_EVERY	},
2957c478bd9Sstevel@tonic-gate 	{ IPM_SRCIP,		IPMAC_SRCIP	},
2967c478bd9Sstevel@tonic-gate 	{ IPM_SRCPORT,		IPMAC_SRCPORT	},
297*ab25eeb5Syz155240 	{ IPM_TYPE,		IPMAC_TYPE 	},
298*ab25eeb5Syz155240 	{ IPM_WITH,		IPMAC_WITH 	},
2997c478bd9Sstevel@tonic-gate 	{ 0, 0 }
3007c478bd9Sstevel@tonic-gate };
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate static opt_t *new_opt(type)
3037c478bd9Sstevel@tonic-gate int type;
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 	opt_t *o;
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	o = (opt_t *)malloc(sizeof(*o));
3085e985db5Sschuster 	if (o == NULL)
3095e985db5Sschuster 		yyerror("sorry, out of memory");
3107c478bd9Sstevel@tonic-gate 	o->o_type = type;
3117c478bd9Sstevel@tonic-gate 	o->o_line = yylineNum;
3127c478bd9Sstevel@tonic-gate 	o->o_num = 0;
3137c478bd9Sstevel@tonic-gate 	o->o_str = (char *)0;
314*ab25eeb5Syz155240 	o->o_next = NULL;
3157c478bd9Sstevel@tonic-gate 	return o;
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate static void build_action(olist)
3197c478bd9Sstevel@tonic-gate opt_t *olist;
3207c478bd9Sstevel@tonic-gate {
321*ab25eeb5Syz155240 	ipmon_action_t *a;
3227c478bd9Sstevel@tonic-gate 	opt_t *o;
3237c478bd9Sstevel@tonic-gate 	char c;
3247c478bd9Sstevel@tonic-gate 	int i;
3257c478bd9Sstevel@tonic-gate 
326*ab25eeb5Syz155240 	a = (ipmon_action_t *)calloc(1, sizeof(*a));
327*ab25eeb5Syz155240 	if (a == NULL)
3287c478bd9Sstevel@tonic-gate 		return;
329*ab25eeb5Syz155240 	while ((o = olist) != NULL) {
330*ab25eeb5Syz155240 		/*
331*ab25eeb5Syz155240 		 * Check to see if the same comparator is being used more than
332*ab25eeb5Syz155240 		 * once per matching statement.
333*ab25eeb5Syz155240 		 */
3347c478bd9Sstevel@tonic-gate 		for (i = 0; macflags[i][0]; i++)
3357c478bd9Sstevel@tonic-gate 			if (macflags[i][0] == o->o_type)
3367c478bd9Sstevel@tonic-gate 				break;
3377c478bd9Sstevel@tonic-gate 		if (macflags[i][1] & a->ac_mflag) {
3387c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s redfined on line %d\n",
3397c478bd9Sstevel@tonic-gate 				yykeytostr(o->o_type), yylineNum);
3407c478bd9Sstevel@tonic-gate 			if (o->o_str != NULL)
3417c478bd9Sstevel@tonic-gate 				free(o->o_str);
3427c478bd9Sstevel@tonic-gate 			olist = o->o_next;
3437c478bd9Sstevel@tonic-gate 			free(o);
3447c478bd9Sstevel@tonic-gate 			continue;
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 		a->ac_mflag |= macflags[i][1];
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 		switch (o->o_type)
3507c478bd9Sstevel@tonic-gate 		{
3517c478bd9Sstevel@tonic-gate 		case IPM_DIRECTION :
3527c478bd9Sstevel@tonic-gate 			a->ac_direction = o->o_num;
3537c478bd9Sstevel@tonic-gate 			break;
3547c478bd9Sstevel@tonic-gate 		case IPM_DSTIP :
3557c478bd9Sstevel@tonic-gate 			a->ac_dip = o->o_ip.s_addr;
356*ab25eeb5Syz155240 			a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num));
3577c478bd9Sstevel@tonic-gate 			break;
3587c478bd9Sstevel@tonic-gate 		case IPM_DSTPORT :
3597c478bd9Sstevel@tonic-gate 			a->ac_dport = htons(o->o_num);
3607c478bd9Sstevel@tonic-gate 			break;
3617c478bd9Sstevel@tonic-gate 		case IPM_EXECUTE :
3627c478bd9Sstevel@tonic-gate 			a->ac_exec = o->o_str;
3637c478bd9Sstevel@tonic-gate 			c = *o->o_str;
3647c478bd9Sstevel@tonic-gate 			if (c== '"'|| c == '\'') {
3657c478bd9Sstevel@tonic-gate 				if (o->o_str[strlen(o->o_str) - 1] == c) {
3667c478bd9Sstevel@tonic-gate 					a->ac_run = strdup(o->o_str + 1);
3677c478bd9Sstevel@tonic-gate 					a->ac_run[strlen(a->ac_run) - 1] ='\0';
3687c478bd9Sstevel@tonic-gate 				} else
3697c478bd9Sstevel@tonic-gate 					a->ac_run = o->o_str;
3707c478bd9Sstevel@tonic-gate 			} else
3717c478bd9Sstevel@tonic-gate 				a->ac_run = o->o_str;
3727c478bd9Sstevel@tonic-gate 			o->o_str = NULL;
3737c478bd9Sstevel@tonic-gate 			break;
3747c478bd9Sstevel@tonic-gate 		case IPM_INTERFACE :
3757c478bd9Sstevel@tonic-gate 			a->ac_iface = o->o_str;
3767c478bd9Sstevel@tonic-gate 			o->o_str = NULL;
3777c478bd9Sstevel@tonic-gate 			break;
3787c478bd9Sstevel@tonic-gate 		case IPM_GROUP :
3797c478bd9Sstevel@tonic-gate 			if (o->o_str != NULL)
3807c478bd9Sstevel@tonic-gate 				strncpy(a->ac_group, o->o_str, FR_GROUPLEN);
3817c478bd9Sstevel@tonic-gate 			else
3827c478bd9Sstevel@tonic-gate 				sprintf(a->ac_group, "%d", o->o_num);
3837c478bd9Sstevel@tonic-gate 			break;
384*ab25eeb5Syz155240 		case IPM_LOGTAG :
385*ab25eeb5Syz155240 			a->ac_logtag = o->o_num;
386*ab25eeb5Syz155240 			break;
387*ab25eeb5Syz155240 		case IPM_NATTAG :
388*ab25eeb5Syz155240 			strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag));
389*ab25eeb5Syz155240 			break;
3907c478bd9Sstevel@tonic-gate 		case IPM_PACKET :
3917c478bd9Sstevel@tonic-gate 			a->ac_packet = o->o_num;
3927c478bd9Sstevel@tonic-gate 			break;
3937c478bd9Sstevel@tonic-gate 		case IPM_PROTOCOL :
3947c478bd9Sstevel@tonic-gate 			a->ac_proto = o->o_num;
3957c478bd9Sstevel@tonic-gate 			break;
3967c478bd9Sstevel@tonic-gate 		case IPM_RULE :
3977c478bd9Sstevel@tonic-gate 			a->ac_rule = o->o_num;
3987c478bd9Sstevel@tonic-gate 			break;
3997c478bd9Sstevel@tonic-gate 		case IPM_RESULT :
4007c478bd9Sstevel@tonic-gate 			if (!strcasecmp(o->o_str, "pass"))
4017c478bd9Sstevel@tonic-gate 				a->ac_result = IPMR_PASS;
4027c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "block"))
4037c478bd9Sstevel@tonic-gate 				a->ac_result = IPMR_BLOCK;
4047c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "nomatch"))
4057c478bd9Sstevel@tonic-gate 				a->ac_result = IPMR_NOMATCH;
4067c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(o->o_str, "log"))
4077c478bd9Sstevel@tonic-gate 				a->ac_result = IPMR_LOG;
4087c478bd9Sstevel@tonic-gate 			break;
4097c478bd9Sstevel@tonic-gate 		case IPM_SECOND :
4107c478bd9Sstevel@tonic-gate 			a->ac_second = o->o_num;
4117c478bd9Sstevel@tonic-gate 			break;
4127c478bd9Sstevel@tonic-gate 		case IPM_SRCIP :
4137c478bd9Sstevel@tonic-gate 			a->ac_sip = o->o_ip.s_addr;
414*ab25eeb5Syz155240 			a->ac_smsk = htonl(0xffffffff << (32 - o->o_num));
4157c478bd9Sstevel@tonic-gate 			break;
4167c478bd9Sstevel@tonic-gate 		case IPM_SRCPORT :
4177c478bd9Sstevel@tonic-gate 			a->ac_sport = htons(o->o_num);
4187c478bd9Sstevel@tonic-gate 			break;
419*ab25eeb5Syz155240 		case IPM_SAVE :
420*ab25eeb5Syz155240 			if (a->ac_savefile != NULL) {
421*ab25eeb5Syz155240 				fprintf(stderr, "%s redfined on line %d\n",
422*ab25eeb5Syz155240 					yykeytostr(o->o_type), yylineNum);
423*ab25eeb5Syz155240 				break;
424*ab25eeb5Syz155240 			}
425*ab25eeb5Syz155240 			a->ac_savefile = strdup(o->o_str);
426*ab25eeb5Syz155240 			a->ac_savefp = fopen(o->o_str, "a");
427*ab25eeb5Syz155240 			a->ac_dflag |= o->o_num & IPMDO_SAVERAW;
428*ab25eeb5Syz155240 			break;
429*ab25eeb5Syz155240 		case IPM_SYSLOG :
430*ab25eeb5Syz155240 			if (a->ac_syslog != 0) {
431*ab25eeb5Syz155240 				fprintf(stderr, "%s redfined on line %d\n",
432*ab25eeb5Syz155240 					yykeytostr(o->o_type), yylineNum);
433*ab25eeb5Syz155240 				break;
434*ab25eeb5Syz155240 			}
435*ab25eeb5Syz155240 			a->ac_syslog = 1;
436*ab25eeb5Syz155240 			break;
437*ab25eeb5Syz155240 		case IPM_TYPE :
438*ab25eeb5Syz155240 			a->ac_type = o->o_num;
439*ab25eeb5Syz155240 			break;
440*ab25eeb5Syz155240 		case IPM_WITH :
4417c478bd9Sstevel@tonic-gate 			break;
4427c478bd9Sstevel@tonic-gate 		default :
4437c478bd9Sstevel@tonic-gate 			break;
4447c478bd9Sstevel@tonic-gate 		}
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 		olist = o->o_next;
4477c478bd9Sstevel@tonic-gate 		if (o->o_str != NULL)
4487c478bd9Sstevel@tonic-gate 			free(o->o_str);
4497c478bd9Sstevel@tonic-gate 		free(o);
4507c478bd9Sstevel@tonic-gate 	}
451*ab25eeb5Syz155240 	a->ac_next = alist;
4527c478bd9Sstevel@tonic-gate 	alist = a;
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 
456*ab25eeb5Syz155240 int check_action(buf, log, opts, lvl)
457*ab25eeb5Syz155240 char *buf, *log;
458*ab25eeb5Syz155240 int opts, lvl;
4597c478bd9Sstevel@tonic-gate {
460*ab25eeb5Syz155240 	ipmon_action_t *a;
4617c478bd9Sstevel@tonic-gate 	struct timeval tv;
4627c478bd9Sstevel@tonic-gate 	ipflog_t *ipf;
4637c478bd9Sstevel@tonic-gate 	tcphdr_t *tcp;
4647c478bd9Sstevel@tonic-gate 	iplog_t *ipl;
465*ab25eeb5Syz155240 	int matched;
4667c478bd9Sstevel@tonic-gate 	u_long t1;
4677c478bd9Sstevel@tonic-gate 	ip_t *ip;
4687c478bd9Sstevel@tonic-gate 
469*ab25eeb5Syz155240 	matched = 0;
4707c478bd9Sstevel@tonic-gate 	ipl = (iplog_t *)buf;
4717c478bd9Sstevel@tonic-gate 	ipf = (ipflog_t *)(ipl +1);
4727c478bd9Sstevel@tonic-gate 	ip = (ip_t *)(ipf + 1);
4737c478bd9Sstevel@tonic-gate 	tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
4747c478bd9Sstevel@tonic-gate 
475*ab25eeb5Syz155240 	for (a = alist; a != NULL; a = a->ac_next) {
476*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
4777c478bd9Sstevel@tonic-gate 			if (a->ac_direction == IPM_IN) {
478*ab25eeb5Syz155240 				if ((ipf->fl_flags & FR_INQUE) == 0)
4797c478bd9Sstevel@tonic-gate 					continue;
4807c478bd9Sstevel@tonic-gate 			} else if (a->ac_direction == IPM_OUT) {
481*ab25eeb5Syz155240 				if ((ipf->fl_flags & FR_OUTQUE) == 0)
4827c478bd9Sstevel@tonic-gate 					continue;
4837c478bd9Sstevel@tonic-gate 			}
4847c478bd9Sstevel@tonic-gate 		}
4857c478bd9Sstevel@tonic-gate 
486*ab25eeb5Syz155240 		if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic))
487*ab25eeb5Syz155240 			continue;
488*ab25eeb5Syz155240 
489*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_EVERY) != 0) {
4907c478bd9Sstevel@tonic-gate 			gettimeofday(&tv, NULL);
4917c478bd9Sstevel@tonic-gate 			t1 = tv.tv_sec - a->ac_lastsec;
4927c478bd9Sstevel@tonic-gate 			if (tv.tv_usec <= a->ac_lastusec)
4937c478bd9Sstevel@tonic-gate 				t1--;
494*ab25eeb5Syz155240 			if (a->ac_second != 0) {
4957c478bd9Sstevel@tonic-gate 				if (t1 < a->ac_second)
4967c478bd9Sstevel@tonic-gate 					continue;
4977c478bd9Sstevel@tonic-gate 				a->ac_lastsec = tv.tv_sec;
4987c478bd9Sstevel@tonic-gate 				a->ac_lastusec = tv.tv_usec;
4997c478bd9Sstevel@tonic-gate 			}
5007c478bd9Sstevel@tonic-gate 
501*ab25eeb5Syz155240 			if (a->ac_packet != 0) {
502*ab25eeb5Syz155240 				if (a->ac_pktcnt == 0)
5037c478bd9Sstevel@tonic-gate 					a->ac_pktcnt++;
5047c478bd9Sstevel@tonic-gate 				else if (a->ac_pktcnt == a->ac_packet) {
5057c478bd9Sstevel@tonic-gate 					a->ac_pktcnt = 0;
5067c478bd9Sstevel@tonic-gate 					continue;
5077c478bd9Sstevel@tonic-gate 				} else {
5087c478bd9Sstevel@tonic-gate 					a->ac_pktcnt++;
5097c478bd9Sstevel@tonic-gate 					continue;
5107c478bd9Sstevel@tonic-gate 				}
5117c478bd9Sstevel@tonic-gate 			}
5127c478bd9Sstevel@tonic-gate 		}
5137c478bd9Sstevel@tonic-gate 
514*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
5157c478bd9Sstevel@tonic-gate 			if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip)
5167c478bd9Sstevel@tonic-gate 				continue;
5177c478bd9Sstevel@tonic-gate 		}
5187c478bd9Sstevel@tonic-gate 
519*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
5207c478bd9Sstevel@tonic-gate 			if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
5217c478bd9Sstevel@tonic-gate 				continue;
5227c478bd9Sstevel@tonic-gate 			if (tcp->th_dport != a->ac_dport)
5237c478bd9Sstevel@tonic-gate 				continue;
5247c478bd9Sstevel@tonic-gate 		}
5257c478bd9Sstevel@tonic-gate 
526*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_GROUP) != 0) {
5277c478bd9Sstevel@tonic-gate 			if (strncmp(a->ac_group, ipf->fl_group,
5287c478bd9Sstevel@tonic-gate 				    FR_GROUPLEN) != 0)
5297c478bd9Sstevel@tonic-gate 				continue;
5307c478bd9Sstevel@tonic-gate 		}
5317c478bd9Sstevel@tonic-gate 
532*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
5337c478bd9Sstevel@tonic-gate 			if (strcmp(a->ac_iface, ipf->fl_ifname))
5347c478bd9Sstevel@tonic-gate 				continue;
5357c478bd9Sstevel@tonic-gate 		}
5367c478bd9Sstevel@tonic-gate 
537*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
5387c478bd9Sstevel@tonic-gate 			if (a->ac_proto != ip->ip_p)
5397c478bd9Sstevel@tonic-gate 				continue;
5407c478bd9Sstevel@tonic-gate 		}
5417c478bd9Sstevel@tonic-gate 
542*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_RESULT) != 0) {
543*ab25eeb5Syz155240 			if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
544*ab25eeb5Syz155240 				if (a->ac_result != IPMR_NOMATCH)
5457c478bd9Sstevel@tonic-gate 					continue;
5467c478bd9Sstevel@tonic-gate 			} else if (FR_ISPASS(ipf->fl_flags)) {
5477c478bd9Sstevel@tonic-gate 				if (a->ac_result != IPMR_PASS)
5487c478bd9Sstevel@tonic-gate 					continue;
5497c478bd9Sstevel@tonic-gate 			} else if (FR_ISBLOCK(ipf->fl_flags)) {
5507c478bd9Sstevel@tonic-gate 				if (a->ac_result != IPMR_BLOCK)
5517c478bd9Sstevel@tonic-gate 					continue;
5527c478bd9Sstevel@tonic-gate 			} else {	/* Log only */
5537c478bd9Sstevel@tonic-gate 				if (a->ac_result != IPMR_LOG)
5547c478bd9Sstevel@tonic-gate 					continue;
5557c478bd9Sstevel@tonic-gate 			}
5567c478bd9Sstevel@tonic-gate 		}
5577c478bd9Sstevel@tonic-gate 
558*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_RULE) != 0) {
5597c478bd9Sstevel@tonic-gate 			if (a->ac_rule != ipf->fl_rule)
5607c478bd9Sstevel@tonic-gate 				continue;
5617c478bd9Sstevel@tonic-gate 		}
5627c478bd9Sstevel@tonic-gate 
563*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
5647c478bd9Sstevel@tonic-gate 			if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip)
5657c478bd9Sstevel@tonic-gate 				continue;
5667c478bd9Sstevel@tonic-gate 		}
5677c478bd9Sstevel@tonic-gate 
568*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
5697c478bd9Sstevel@tonic-gate 			if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
5707c478bd9Sstevel@tonic-gate 				continue;
5717c478bd9Sstevel@tonic-gate 			if (tcp->th_sport != a->ac_sport)
5727c478bd9Sstevel@tonic-gate 				continue;
5737c478bd9Sstevel@tonic-gate 		}
5747c478bd9Sstevel@tonic-gate 
575*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
576*ab25eeb5Syz155240 			if (a->ac_logtag != ipf->fl_logtag)
5777c478bd9Sstevel@tonic-gate 				continue;
5787c478bd9Sstevel@tonic-gate 		}
5797c478bd9Sstevel@tonic-gate 
580*ab25eeb5Syz155240 		if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
581*ab25eeb5Syz155240 			if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
582*ab25eeb5Syz155240 				    IPFTAG_LEN) != 0)
583*ab25eeb5Syz155240 				continue;
584*ab25eeb5Syz155240 		}
585*ab25eeb5Syz155240 
586*ab25eeb5Syz155240 		matched = 1;
587*ab25eeb5Syz155240 
5887c478bd9Sstevel@tonic-gate 		/*
5897c478bd9Sstevel@tonic-gate 		 * It matched so now execute the command
5907c478bd9Sstevel@tonic-gate 		 */
591*ab25eeb5Syz155240 		if (a->ac_syslog != 0) {
592*ab25eeb5Syz155240 			syslog(lvl, "%s", log);
593*ab25eeb5Syz155240 		}
594*ab25eeb5Syz155240 
595*ab25eeb5Syz155240 		if (a->ac_savefp != NULL) {
596*ab25eeb5Syz155240 			if (a->ac_dflag & IPMDO_SAVERAW)
597*ab25eeb5Syz155240 				fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp);
598*ab25eeb5Syz155240 			else
599*ab25eeb5Syz155240 				fputs(log, a->ac_savefp);
600*ab25eeb5Syz155240 		}
601*ab25eeb5Syz155240 
602*ab25eeb5Syz155240 		if (a->ac_exec != NULL) {
6037c478bd9Sstevel@tonic-gate 			switch (fork())
6047c478bd9Sstevel@tonic-gate 			{
6057c478bd9Sstevel@tonic-gate 			case 0 :
6067c478bd9Sstevel@tonic-gate 			{
6077c478bd9Sstevel@tonic-gate 				FILE *pi;
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 				pi = popen(a->ac_run, "w");
610*ab25eeb5Syz155240 				if (pi != NULL) {
6117c478bd9Sstevel@tonic-gate 					fprintf(pi, "%s\n", log);
612*ab25eeb5Syz155240 					if ((opts & OPT_HEXHDR) != 0) {
6137c478bd9Sstevel@tonic-gate 						dumphex(pi, 0, buf,
6147c478bd9Sstevel@tonic-gate 							sizeof(*ipl) +
6157c478bd9Sstevel@tonic-gate 							sizeof(*ipf));
6167c478bd9Sstevel@tonic-gate 					}
617*ab25eeb5Syz155240 					if ((opts & OPT_HEXBODY) != 0) {
6187c478bd9Sstevel@tonic-gate 						dumphex(pi, 0, (char *)ip,
6197c478bd9Sstevel@tonic-gate 							ipf->fl_hlen +
6207c478bd9Sstevel@tonic-gate 							ipf->fl_plen);
6217c478bd9Sstevel@tonic-gate 					}
6227c478bd9Sstevel@tonic-gate 					pclose(pi);
6237c478bd9Sstevel@tonic-gate 				}
6247c478bd9Sstevel@tonic-gate 				exit(1);
6257c478bd9Sstevel@tonic-gate 			}
6267c478bd9Sstevel@tonic-gate 			case -1 :
6277c478bd9Sstevel@tonic-gate 				break;
6287c478bd9Sstevel@tonic-gate 			default :
6297c478bd9Sstevel@tonic-gate 				break;
6307c478bd9Sstevel@tonic-gate 			}
6317c478bd9Sstevel@tonic-gate 		}
6327c478bd9Sstevel@tonic-gate 	}
633*ab25eeb5Syz155240 
634*ab25eeb5Syz155240 	return matched;
635*ab25eeb5Syz155240 }
636*ab25eeb5Syz155240 
637*ab25eeb5Syz155240 
638*ab25eeb5Syz155240 static void free_action(a)
639*ab25eeb5Syz155240 ipmon_action_t *a;
640*ab25eeb5Syz155240 {
641*ab25eeb5Syz155240 	if (a->ac_savefile != NULL) {
642*ab25eeb5Syz155240 		free(a->ac_savefile);
643*ab25eeb5Syz155240 		a->ac_savefile = NULL;
644*ab25eeb5Syz155240 	}
645*ab25eeb5Syz155240 	if (a->ac_savefp != NULL) {
646*ab25eeb5Syz155240 		fclose(a->ac_savefp);
647*ab25eeb5Syz155240 		a->ac_savefp = NULL;
648*ab25eeb5Syz155240 	}
649*ab25eeb5Syz155240 	if (a->ac_exec != NULL) {
650*ab25eeb5Syz155240 		free(a->ac_exec);
651*ab25eeb5Syz155240 		if (a->ac_run == a->ac_exec)
652*ab25eeb5Syz155240 			a->ac_run = NULL;
653*ab25eeb5Syz155240 		a->ac_exec = NULL;
654*ab25eeb5Syz155240 	}
655*ab25eeb5Syz155240 	if (a->ac_run != NULL) {
656*ab25eeb5Syz155240 		free(a->ac_run);
657*ab25eeb5Syz155240 		a->ac_run = NULL;
658*ab25eeb5Syz155240 	}
659*ab25eeb5Syz155240 	if (a->ac_iface != NULL) {
660*ab25eeb5Syz155240 		free(a->ac_iface);
661*ab25eeb5Syz155240 		a->ac_iface = NULL;
662*ab25eeb5Syz155240 	}
663*ab25eeb5Syz155240 	a->ac_next = NULL;
664*ab25eeb5Syz155240 	free(a);
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate int load_config(file)
6697c478bd9Sstevel@tonic-gate char *file;
6707c478bd9Sstevel@tonic-gate {
671*ab25eeb5Syz155240 	ipmon_action_t *a;
6727c478bd9Sstevel@tonic-gate 	FILE *fp;
673*ab25eeb5Syz155240 	char *s;
6747c478bd9Sstevel@tonic-gate 
675*ab25eeb5Syz155240 	s = getenv("YYDEBUG");
676*ab25eeb5Syz155240 	if (s != NULL)
677*ab25eeb5Syz155240 		yydebug = atoi(s);
678*ab25eeb5Syz155240 	else
679*ab25eeb5Syz155240 		yydebug = 0;
680*ab25eeb5Syz155240 
681*ab25eeb5Syz155240 	while ((a = alist) != NULL) {
682*ab25eeb5Syz155240 		alist = a->ac_next;
683*ab25eeb5Syz155240 		free_action(a);
684*ab25eeb5Syz155240 	}
685*ab25eeb5Syz155240 
686*ab25eeb5Syz155240 	yylineNum = 1;
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	(void) yysettab(yywords);
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	fp = fopen(file, "r");
6917c478bd9Sstevel@tonic-gate 	if (!fp) {
6927c478bd9Sstevel@tonic-gate 		perror("load_config:fopen:");
6937c478bd9Sstevel@tonic-gate 		return -1;
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 	yyin = fp;
6967c478bd9Sstevel@tonic-gate 	while (!feof(fp))
6977c478bd9Sstevel@tonic-gate 		yyparse();
6987c478bd9Sstevel@tonic-gate 	fclose(fp);
6997c478bd9Sstevel@tonic-gate 	return 0;
7007c478bd9Sstevel@tonic-gate }
701