ippool_y.y revision 145519
1145519Sdarrenr/*	$FreeBSD: head/contrib/ipfilter/tools/ippool_y.y 145519 2005-04-25 18:20:15Z darrenr $	*/
2145510Sdarrenr
3145510Sdarrenr%{
4145510Sdarrenr#include <sys/types.h>
5145510Sdarrenr#include <sys/time.h>
6145510Sdarrenr#include <sys/param.h>
7145510Sdarrenr#include <sys/socket.h>
8145510Sdarrenr#if defined(BSD) && (BSD >= 199306)
9145510Sdarrenr# include <sys/cdefs.h>
10145510Sdarrenr#endif
11145510Sdarrenr#include <sys/ioctl.h>
12145510Sdarrenr
13145510Sdarrenr#include <net/if.h>
14145510Sdarrenr#if __FreeBSD_version >= 300000
15145510Sdarrenr# include <net/if_var.h>
16145510Sdarrenr#endif
17145510Sdarrenr#include <netinet/in.h>
18145510Sdarrenr
19145510Sdarrenr#include <arpa/inet.h>
20145510Sdarrenr
21145510Sdarrenr#include <stdio.h>
22145510Sdarrenr#include <fcntl.h>
23145510Sdarrenr#include <stdlib.h>
24145510Sdarrenr#include <string.h>
25145510Sdarrenr#include <netdb.h>
26145510Sdarrenr#include <ctype.h>
27145510Sdarrenr#include <unistd.h>
28145510Sdarrenr
29145510Sdarrenr#include "ipf.h"
30145510Sdarrenr#include "netinet/ip_lookup.h"
31145510Sdarrenr#include "netinet/ip_pool.h"
32145510Sdarrenr#include "netinet/ip_htable.h"
33145510Sdarrenr#include "ippool_l.h"
34145510Sdarrenr#include "kmem.h"
35145510Sdarrenr
36145510Sdarrenr#define	YYDEBUG	1
37145510Sdarrenr
38145510Sdarrenrextern	int	yyparse __P((void));
39145510Sdarrenrextern	int	yydebug;
40145510Sdarrenrextern	FILE	*yyin;
41145510Sdarrenr
42145510Sdarrenrstatic	iphtable_t	ipht;
43145510Sdarrenrstatic	iphtent_t	iphte;
44145510Sdarrenrstatic	ip_pool_t	iplo;
45145510Sdarrenrstatic	ioctlfunc_t	poolioctl = NULL;
46145510Sdarrenrstatic	char		poolname[FR_GROUPLEN];
47145510Sdarrenr
48145510Sdarrenr%}
49145510Sdarrenr
50145510Sdarrenr%union	{
51145510Sdarrenr	char	*str;
52145510Sdarrenr	u_32_t	num;
53145510Sdarrenr	struct	in_addr	addr;
54145510Sdarrenr	struct	alist_s	*alist;
55145510Sdarrenr	struct	in_addr	adrmsk[2];
56145510Sdarrenr	iphtent_t	*ipe;
57145510Sdarrenr	ip_pool_node_t	*ipp;
58145510Sdarrenr	union	i6addr	ip6;
59145510Sdarrenr}
60145510Sdarrenr
61145510Sdarrenr%token  <num>   YY_NUMBER YY_HEX
62145510Sdarrenr%token  <str>   YY_STR
63145510Sdarrenr%token	  YY_COMMENT
64145510Sdarrenr%token	  YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
65145510Sdarrenr%token	  YY_RANGE_OUT YY_RANGE_IN
66145510Sdarrenr%token  <ip6>   YY_IPV6
67145510Sdarrenr
68145510Sdarrenr%token	IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
69145510Sdarrenr%token	IPT_TABLE IPT_GROUPMAP IPT_HASH
70145510Sdarrenr%token	IPT_ROLE IPT_TYPE IPT_TREE
71145510Sdarrenr%token	IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
72145510Sdarrenr%type	<num> role table inout
73145510Sdarrenr%type	<ipp> ipftree range addrlist
74145510Sdarrenr%type	<adrmsk> addrmask
75145510Sdarrenr%type	<ipe> ipfgroup ipfhash hashlist hashentry
76145510Sdarrenr%type	<ipe> groupentry setgrouplist grouplist
77145510Sdarrenr%type	<addr> ipaddr mask ipv4
78145510Sdarrenr%type	<str> number setgroup
79145510Sdarrenr
80145510Sdarrenr%%
81145510Sdarrenrfile:	line
82145510Sdarrenr	| assign
83145510Sdarrenr	| file line
84145510Sdarrenr	| file assign
85145510Sdarrenr	;
86145510Sdarrenr
87145510Sdarrenrline:	table role ipftree eol		{ iplo.ipo_unit = $2;
88145510Sdarrenr					  iplo.ipo_list = $3;
89145510Sdarrenr					  load_pool(&iplo, poolioctl);
90145510Sdarrenr					  resetlexer();
91145510Sdarrenr					}
92145510Sdarrenr	| table role ipfhash eol	{ ipht.iph_unit = $2;
93145510Sdarrenr					  ipht.iph_type = IPHASH_LOOKUP;
94145510Sdarrenr					  load_hash(&ipht, $3, poolioctl);
95145510Sdarrenr					  resetlexer();
96145510Sdarrenr					}
97145510Sdarrenr	| groupmap role number ipfgroup eol
98145510Sdarrenr					{ ipht.iph_unit = $2;
99145510Sdarrenr					  strncpy(ipht.iph_name, $3,
100145510Sdarrenr						  sizeof(ipht.iph_name));
101145510Sdarrenr					  ipht.iph_type = IPHASH_GROUPMAP;
102145510Sdarrenr					  load_hash(&ipht, $4, poolioctl);
103145510Sdarrenr					  resetlexer();
104145510Sdarrenr					}
105145510Sdarrenr	| YY_COMMENT
106145510Sdarrenr	;
107145510Sdarrenr
108145510Sdarrenreol:	';'
109145510Sdarrenr	;
110145510Sdarrenr
111145510Sdarrenrassign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
112145510Sdarrenr					  resetlexer();
113145510Sdarrenr					  free($1);
114145510Sdarrenr					  free($3);
115145510Sdarrenr					}
116145510Sdarrenr	;
117145510Sdarrenr
118145510Sdarrenrassigning:
119145510Sdarrenr	'='				{ yyvarnext = 1; }
120145510Sdarrenr	;
121145510Sdarrenr
122145510Sdarrenrtable:	IPT_TABLE		{ bzero((char *)&ipht, sizeof(ipht));
123145510Sdarrenr				  bzero((char *)&iphte, sizeof(iphte));
124145510Sdarrenr				  bzero((char *)&iplo, sizeof(iplo));
125145510Sdarrenr				  *ipht.iph_name = '\0';
126145510Sdarrenr				  iplo.ipo_flags = IPHASH_ANON;
127145510Sdarrenr				  iplo.ipo_name[0] = '\0';
128145510Sdarrenr				}
129145510Sdarrenr	;
130145510Sdarrenr
131145510Sdarrenrgroupmap:
132145510Sdarrenr	IPT_GROUPMAP inout	{ bzero((char *)&ipht, sizeof(ipht));
133145510Sdarrenr				  bzero((char *)&iphte, sizeof(iphte));
134145510Sdarrenr				  *ipht.iph_name = '\0';
135145510Sdarrenr				  ipht.iph_unit = IPHASH_GROUPMAP;
136145510Sdarrenr				  ipht.iph_flags = $2;
137145510Sdarrenr				}
138145510Sdarrenr	;
139145510Sdarrenr
140145510Sdarrenrinout:	IPT_IN				{ $$ = FR_INQUE; }
141145510Sdarrenr	| IPT_OUT			{ $$ = FR_OUTQUE; }
142145510Sdarrenr	;
143145510Sdarrenrrole:
144145510Sdarrenr	IPT_ROLE '=' IPT_IPF		{ $$ = IPL_LOGIPF; }
145145510Sdarrenr	| IPT_ROLE '=' IPT_NAT		{ $$ = IPL_LOGNAT; }
146145510Sdarrenr	| IPT_ROLE '=' IPT_AUTH		{ $$ = IPL_LOGAUTH; }
147145510Sdarrenr	| IPT_ROLE '=' IPT_COUNT	{ $$ = IPL_LOGCOUNT; }
148145510Sdarrenr	;
149145510Sdarrenr
150145510Sdarrenripftree:
151145510Sdarrenr	IPT_TYPE '=' IPT_TREE number start addrlist end
152145510Sdarrenr					{ strncpy(iplo.ipo_name, $4,
153145510Sdarrenr						  sizeof(iplo.ipo_name));
154145510Sdarrenr					  $$ = $6;
155145510Sdarrenr					}
156145510Sdarrenr	;
157145510Sdarrenr
158145510Sdarrenripfhash:
159145510Sdarrenr	IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
160145510Sdarrenr					{ strncpy(ipht.iph_name, $4,
161145510Sdarrenr						  sizeof(ipht.iph_name));
162145510Sdarrenr					  $$ = $7;
163145510Sdarrenr					}
164145510Sdarrenr	;
165145510Sdarrenr
166145510Sdarrenripfgroup:
167145510Sdarrenr	setgroup hashopts start grouplist end
168145510Sdarrenr					{ iphtent_t *e;
169145510Sdarrenr					  for (e = $4; e != NULL;
170145510Sdarrenr					       e = e->ipe_next)
171145510Sdarrenr						if (e->ipe_group[0] == '\0')
172145510Sdarrenr							strncpy(e->ipe_group,
173145510Sdarrenr								$1,
174145510Sdarrenr								FR_GROUPLEN);
175145510Sdarrenr					  $$ = $4;
176145510Sdarrenr					}
177145510Sdarrenr	| hashopts start setgrouplist end		{ $$ = $3; }
178145510Sdarrenr	;
179145510Sdarrenr
180145510Sdarrenrnumber:	IPT_NUM '=' YY_NUMBER			{ sprintf(poolname, "%u", $3);
181145510Sdarrenr						  $$ = poolname;
182145510Sdarrenr						}
183145510Sdarrenr	| IPT_NAME '=' YY_STR			{ $$ = $3; }
184145510Sdarrenr	|					{ $$ = ""; }
185145510Sdarrenr	;
186145510Sdarrenr
187145510Sdarrenrsetgroup:
188145510Sdarrenr	IPT_GROUP '=' YY_STR		{ char tmp[FR_GROUPLEN+1];
189145510Sdarrenr					  strncpy(tmp, $3, FR_GROUPLEN);
190145510Sdarrenr					  $$ = strdup(tmp);
191145510Sdarrenr					}
192145510Sdarrenr	| IPT_GROUP '=' YY_NUMBER	{ char tmp[FR_GROUPLEN+1];
193145510Sdarrenr					  sprintf(tmp, "%u", $3);
194145510Sdarrenr					  $$ = strdup(tmp);
195145510Sdarrenr					}
196145510Sdarrenr	;
197145510Sdarrenr
198145510Sdarrenrhashopts:
199145510Sdarrenr	| size
200145510Sdarrenr	| seed
201145510Sdarrenr	| size seed
202145510Sdarrenr	;
203145510Sdarrenr
204145510Sdarrenraddrlist:
205145510Sdarrenr	next				{ $$ = NULL; }
206145510Sdarrenr	| range next addrlist		{ $1->ipn_next = $3; $$ = $1; }
207145510Sdarrenr	| range next			{ $$ = $1; }
208145510Sdarrenr	;
209145510Sdarrenr
210145510Sdarrenrgrouplist:
211145510Sdarrenr	next				{ $$ = NULL; }
212145510Sdarrenr	| groupentry next grouplist	{ $$ = $1; $1->ipe_next = $3; }
213145510Sdarrenr	| addrmask next grouplist	{ $$ = calloc(1, sizeof(iphtent_t));
214145510Sdarrenr					  bcopy((char *)&($1[0]),
215145510Sdarrenr						(char *)&($$->ipe_addr),
216145510Sdarrenr						sizeof($$->ipe_addr));
217145510Sdarrenr					  bcopy((char *)&($1[1]),
218145510Sdarrenr						(char *)&($$->ipe_mask),
219145510Sdarrenr						sizeof($$->ipe_mask));
220145510Sdarrenr					  $$->ipe_next = $3;
221145510Sdarrenr					}
222145510Sdarrenr	| groupentry next		{ $$ = $1; }
223145510Sdarrenr	| addrmask next			{ $$ = calloc(1, sizeof(iphtent_t));
224145510Sdarrenr					  bcopy((char *)&($1[0]),
225145510Sdarrenr						(char *)&($$->ipe_addr),
226145510Sdarrenr						sizeof($$->ipe_addr));
227145510Sdarrenr					  bcopy((char *)&($1[1]),
228145510Sdarrenr						(char *)&($$->ipe_mask),
229145510Sdarrenr						sizeof($$->ipe_mask));
230145510Sdarrenr					}
231145510Sdarrenr	;
232145510Sdarrenr
233145510Sdarrenrsetgrouplist:
234145510Sdarrenr	next				{ $$ = NULL; }
235145510Sdarrenr	| groupentry next		{ $$ = $1; }
236145510Sdarrenr	| groupentry next setgrouplist	{ $1->ipe_next = $3; $$ = $1; }
237145510Sdarrenr	;
238145510Sdarrenr
239145510Sdarrenrgroupentry:
240145510Sdarrenr	addrmask ',' setgroup		{ $$ = calloc(1, sizeof(iphtent_t));
241145510Sdarrenr					  bcopy((char *)&($1[0]),
242145510Sdarrenr						(char *)&($$->ipe_addr),
243145510Sdarrenr						sizeof($$->ipe_addr));
244145510Sdarrenr					  bcopy((char *)&($1[1]),
245145510Sdarrenr						(char *)&($$->ipe_mask),
246145510Sdarrenr						sizeof($$->ipe_mask));
247145510Sdarrenr					  strncpy($$->ipe_group, $3,
248145510Sdarrenr						  FR_GROUPLEN);
249145510Sdarrenr					  free($3);
250145510Sdarrenr					}
251145510Sdarrenr	;
252145510Sdarrenr
253145510Sdarrenrrange:	addrmask	{ $$ = calloc(1, sizeof(*$$));
254145510Sdarrenr			  $$->ipn_info = 0;
255145510Sdarrenr			  $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
256145510Sdarrenr			  $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr;
257145510Sdarrenr			  $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
258145510Sdarrenr			  $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr;
259145510Sdarrenr			}
260145510Sdarrenr	| '!' addrmask	{ $$ = calloc(1, sizeof(*$$));
261145510Sdarrenr			  $$->ipn_info = 1;
262145510Sdarrenr			  $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
263145510Sdarrenr			  $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr;
264145510Sdarrenr			  $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
265145510Sdarrenr			  $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr;
266145510Sdarrenr			}
267145510Sdarrenr
268145510Sdarrenrhashlist:
269145510Sdarrenr	next				{ $$ = NULL; }
270145510Sdarrenr	| hashentry next		{ $$ = $1; }
271145510Sdarrenr	| hashentry next hashlist	{ $1->ipe_next = $3; $$ = $1; }
272145510Sdarrenr	;
273145510Sdarrenr
274145510Sdarrenrhashentry:
275145510Sdarrenr	addrmask 			{ $$ = calloc(1, sizeof(iphtent_t));
276145510Sdarrenr					  bcopy((char *)&($1[0]),
277145510Sdarrenr						(char *)&($$->ipe_addr),
278145510Sdarrenr						sizeof($$->ipe_addr));
279145510Sdarrenr					  bcopy((char *)&($1[1]),
280145510Sdarrenr						(char *)&($$->ipe_mask),
281145510Sdarrenr						sizeof($$->ipe_mask));
282145510Sdarrenr					}
283145510Sdarrenr	;
284145510Sdarrenr
285145510Sdarrenraddrmask:
286145510Sdarrenr	ipaddr '/' mask		{ $$[0] = $1; $$[1].s_addr = $3.s_addr;
287145510Sdarrenr				  yyexpectaddr = 0;
288145510Sdarrenr				}
289145510Sdarrenr	| ipaddr		{ $$[0] = $1; $$[1].s_addr = 0xffffffff;
290145510Sdarrenr				  yyexpectaddr = 0;
291145510Sdarrenr				}
292145510Sdarrenr	;
293145510Sdarrenr
294145510Sdarrenripaddr:	ipv4			{ $$ = $1; }
295145510Sdarrenr	| YY_NUMBER		{ $$.s_addr = htonl($1); }
296145510Sdarrenr	| YY_STR		{ if (gethost($1, &($$.s_addr)) == -1)
297145510Sdarrenr					yyerror("Unknown hostname");
298145510Sdarrenr				}
299145510Sdarrenr	;
300145510Sdarrenr
301145510Sdarrenrmask:	YY_NUMBER		{ ntomask(4, $1, (u_32_t *)&$$.s_addr); }
302145510Sdarrenr	| ipv4			{ $$ = $1; }
303145510Sdarrenr	;
304145510Sdarrenr
305145510Sdarrenrstart:	'{'			{ yyexpectaddr = 1; }
306145510Sdarrenr	;
307145510Sdarrenr
308145510Sdarrenrend:	'}'			{ yyexpectaddr = 0; }
309145510Sdarrenr	;
310145510Sdarrenr
311145510Sdarrenrnext:	';'			{ yyexpectaddr = 1; }
312145510Sdarrenr	;
313145510Sdarrenr
314145510Sdarrenrsize:	IPT_SIZE '=' YY_NUMBER	{ ipht.iph_size = $3; }
315145510Sdarrenr	;
316145510Sdarrenr
317145510Sdarrenrseed:	IPT_SEED '=' YY_NUMBER	{ ipht.iph_seed = $3; }
318145510Sdarrenr	;
319145510Sdarrenr
320145510Sdarrenripv4:	YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
321145510Sdarrenr		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
322145510Sdarrenr			yyerror("Invalid octet string for IP address");
323145510Sdarrenr			return 0;
324145510Sdarrenr		  }
325145510Sdarrenr		  $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
326145510Sdarrenr		  $$.s_addr = htonl($$.s_addr);
327145510Sdarrenr		}
328145510Sdarrenr	;
329145510Sdarrenr%%
330145510Sdarrenrstatic	wordtab_t	yywords[] = {
331145510Sdarrenr	{ "auth",	IPT_AUTH },
332145510Sdarrenr	{ "count",	IPT_COUNT },
333145510Sdarrenr	{ "group",	IPT_GROUP },
334145510Sdarrenr	{ "group-map",	IPT_GROUPMAP },
335145510Sdarrenr	{ "hash",	IPT_HASH },
336145510Sdarrenr	{ "in",		IPT_IN },
337145510Sdarrenr	{ "ipf",	IPT_IPF },
338145510Sdarrenr	{ "name",	IPT_NAME },
339145510Sdarrenr	{ "nat",	IPT_NAT },
340145510Sdarrenr	{ "number",	IPT_NUM },
341145510Sdarrenr	{ "out",	IPT_OUT },
342145510Sdarrenr	{ "role",	IPT_ROLE },
343145510Sdarrenr	{ "seed",	IPT_SEED },
344145510Sdarrenr	{ "size",	IPT_SIZE },
345145510Sdarrenr	{ "table",	IPT_TABLE },
346145510Sdarrenr	{ "tree",	IPT_TREE },
347145510Sdarrenr	{ "type",	IPT_TYPE },
348145510Sdarrenr	{ NULL,		0 }
349145510Sdarrenr};
350145510Sdarrenr
351145510Sdarrenr
352145510Sdarrenrint ippool_parsefile(fd, filename, iocfunc)
353145510Sdarrenrint fd;
354145510Sdarrenrchar *filename;
355145510Sdarrenrioctlfunc_t iocfunc;
356145510Sdarrenr{
357145510Sdarrenr	FILE *fp = NULL;
358145510Sdarrenr	char *s;
359145510Sdarrenr
360145510Sdarrenr	yylineNum = 1;
361145510Sdarrenr	(void) yysettab(yywords);
362145510Sdarrenr
363145510Sdarrenr	s = getenv("YYDEBUG");
364145510Sdarrenr	if (s)
365145510Sdarrenr		yydebug = atoi(s);
366145510Sdarrenr	else
367145510Sdarrenr		yydebug = 0;
368145510Sdarrenr
369145510Sdarrenr	if (strcmp(filename, "-")) {
370145510Sdarrenr		fp = fopen(filename, "r");
371145510Sdarrenr		if (!fp) {
372145510Sdarrenr			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
373145510Sdarrenr				STRERROR(errno));
374145510Sdarrenr			return -1;
375145510Sdarrenr		}
376145510Sdarrenr	} else
377145510Sdarrenr		fp = stdin;
378145510Sdarrenr
379145510Sdarrenr	while (ippool_parsesome(fd, fp, iocfunc) == 1)
380145510Sdarrenr		;
381145510Sdarrenr	if (fp != NULL)
382145510Sdarrenr		fclose(fp);
383145510Sdarrenr	return 0;
384145510Sdarrenr}
385145510Sdarrenr
386145510Sdarrenr
387145510Sdarrenrint ippool_parsesome(fd, fp, iocfunc)
388145510Sdarrenrint fd;
389145510SdarrenrFILE *fp;
390145510Sdarrenrioctlfunc_t iocfunc;
391145510Sdarrenr{
392145510Sdarrenr	char *s;
393145510Sdarrenr	int i;
394145510Sdarrenr
395145510Sdarrenr	poolioctl = iocfunc;
396145510Sdarrenr
397145510Sdarrenr	if (feof(fp))
398145510Sdarrenr		return 0;
399145510Sdarrenr	i = fgetc(fp);
400145510Sdarrenr	if (i == EOF)
401145510Sdarrenr		return 0;
402145510Sdarrenr	if (ungetc(i, fp) == EOF)
403145510Sdarrenr		return 0;
404145510Sdarrenr	if (feof(fp))
405145510Sdarrenr		return 0;
406145510Sdarrenr	s = getenv("YYDEBUG");
407145510Sdarrenr	if (s)
408145510Sdarrenr		yydebug = atoi(s);
409145510Sdarrenr	else
410145510Sdarrenr		yydebug = 0;
411145510Sdarrenr
412145510Sdarrenr	yyin = fp;
413145510Sdarrenr	yyparse();
414145510Sdarrenr	return 1;
415145510Sdarrenr}
416