xref: /titanic_51/usr/src/cmd/ipf/tools/ippool_y.y (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 %{
2 #include <sys/types.h>
3 #include <sys/time.h>
4 #include <sys/param.h>
5 #include <sys/socket.h>
6 #if defined(BSD) && (BSD >= 199306)
7 # include <sys/cdefs.h>
8 #endif
9 #include <sys/ioctl.h>
10 
11 #include <net/if.h>
12 #if __FreeBSD_version >= 300000
13 # include <net/if_var.h>
14 #endif
15 #include <netinet/in.h>
16 
17 #include <arpa/inet.h>
18 
19 #include <stdio.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <netdb.h>
24 #include <ctype.h>
25 #include <unistd.h>
26 
27 #include "ipf.h"
28 #if SOLARIS2 >= 10
29 #include "ip_lookup.h"
30 #include "ip_pool.h"
31 #include "ip_htable.h"
32 #else
33 #include "netinet/ip_lookup.h"
34 #include "netinet/ip_pool.h"
35 #include "netinet/ip_htable.h"
36 #endif
37 #include "ippool_l.h"
38 #include "kmem.h"
39 
40 #define	YYDEBUG	1
41 
42 extern	int	yyparse __P((void));
43 extern	int	yydebug;
44 extern	FILE	*yyin;
45 
46 static	iphtable_t	ipht;
47 static	iphtent_t	iphte;
48 static	ip_pool_t	iplo;
49 static	ioctlfunc_t	poolioctl = NULL;
50 static	char		poolname[FR_GROUPLEN];
51 
52 %}
53 
54 %union	{
55 	char	*str;
56 	u_32_t	num;
57 	struct	in_addr	addr;
58 	struct	alist_s	*alist;
59 	struct	in_addr	adrmsk[2];
60 	iphtent_t	*ipe;
61 	ip_pool_node_t	*ipp;
62 	union	i6addr	ip6;
63 }
64 
65 %token  <num>   YY_NUMBER YY_HEX
66 %token  <str>   YY_STR
67 %token	  YY_COMMENT
68 %token	  YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
69 %token	  YY_RANGE_OUT YY_RANGE_IN
70 %token  <ip6>   YY_IPV6
71 
72 %token	IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
73 %token	IPT_TABLE IPT_GROUPMAP IPT_HASH
74 %token	IPT_ROLE IPT_TYPE IPT_TREE
75 %token	IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
76 %type	<num> role table inout
77 %type	<ipp> ipftree range addrlist
78 %type	<adrmsk> addrmask
79 %type	<ipe> ipfgroup ipfhash hashlist hashentry
80 %type	<ipe> groupentry setgrouplist grouplist
81 %type	<addr> ipaddr mask ipv4
82 %type	<str> number setgroup
83 
84 %%
85 file:	line
86 	| assign
87 	| file line
88 	| file assign
89 	;
90 
91 line:	table role ipftree eol		{ iplo.ipo_unit = $2;
92 					  iplo.ipo_list = $3;
93 					  load_pool(&iplo, poolioctl);
94 					  resetlexer();
95 					}
96 	| table role ipfhash eol	{ ipht.iph_unit = $2;
97 					  ipht.iph_type = IPHASH_LOOKUP;
98 					  load_hash(&ipht, $3, poolioctl);
99 					  resetlexer();
100 					}
101 	| groupmap role number ipfgroup eol
102 					{ ipht.iph_unit = $2;
103 					  strncpy(ipht.iph_name, $3,
104 						  sizeof(ipht.iph_name));
105 					  ipht.iph_type = IPHASH_GROUPMAP;
106 					  load_hash(&ipht, $4, poolioctl);
107 					  resetlexer();
108 					}
109 	| YY_COMMENT
110 	;
111 
112 eol:	';'
113 	;
114 
115 assign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
116 					  resetlexer();
117 					  free($1);
118 					  free($3);
119 					}
120 	;
121 
122 assigning:
123 	'='				{ yyvarnext = 1; }
124 	;
125 
126 table:	IPT_TABLE		{ bzero((char *)&ipht, sizeof(ipht));
127 				  bzero((char *)&iphte, sizeof(iphte));
128 				  bzero((char *)&iplo, sizeof(iplo));
129 				  *ipht.iph_name = '\0';
130 				  iplo.ipo_flags = IPHASH_ANON;
131 				  iplo.ipo_name[0] = '\0';
132 				}
133 	;
134 
135 groupmap:
136 	IPT_GROUPMAP inout	{ bzero((char *)&ipht, sizeof(ipht));
137 				  bzero((char *)&iphte, sizeof(iphte));
138 				  *ipht.iph_name = '\0';
139 				  ipht.iph_unit = IPHASH_GROUPMAP;
140 				  ipht.iph_flags = $2;
141 				}
142 	;
143 
144 inout:	IPT_IN				{ $$ = FR_INQUE; }
145 	| IPT_OUT			{ $$ = FR_OUTQUE; }
146 	;
147 role:
148 	IPT_ROLE '=' IPT_IPF		{ $$ = IPL_LOGIPF; }
149 	| IPT_ROLE '=' IPT_NAT		{ $$ = IPL_LOGNAT; }
150 	| IPT_ROLE '=' IPT_AUTH		{ $$ = IPL_LOGAUTH; }
151 	| IPT_ROLE '=' IPT_COUNT	{ $$ = IPL_LOGCOUNT; }
152 	;
153 
154 ipftree:
155 	IPT_TYPE '=' IPT_TREE number '{' addrlist '}'
156 					{ strncpy(iplo.ipo_name, $4,
157 						  sizeof(iplo.ipo_name));
158 					  $$ = $6;
159 					}
160 	;
161 
162 ipfhash:
163 	IPT_TYPE '=' IPT_HASH number hashopts '{' hashlist '}'
164 					{ strncpy(ipht.iph_name, $4,
165 						  sizeof(ipht.iph_name));
166 					  $$ = $7;
167 					}
168 	;
169 
170 ipfgroup:
171 	setgroup hashopts '{' grouplist '}'
172 					{ iphtent_t *e;
173 					  for (e = $4; e != NULL;
174 					       e = e->ipe_next)
175 						if (e->ipe_group[0] == '\0')
176 							strncpy(e->ipe_group,
177 								$1,
178 								FR_GROUPLEN);
179 					  $$ = $4;
180 					}
181 	| hashopts '{' setgrouplist '}'		{ $$ = $3; }
182 	;
183 
184 number:	IPT_NUM '=' YY_NUMBER			{ sprintf(poolname, "%u", $3);
185 						  $$ = poolname;
186 						}
187 	| IPT_NAME '=' YY_STR			{ $$ = $3; }
188 	|					{ $$ = ""; }
189 	;
190 
191 setgroup:
192 	IPT_GROUP '=' YY_STR		{ char tmp[FR_GROUPLEN+1];
193 					  strncpy(tmp, $3, FR_GROUPLEN);
194 					  $$ = strdup(tmp);
195 					}
196 	| IPT_GROUP '=' YY_NUMBER	{ char tmp[FR_GROUPLEN+1];
197 					  sprintf(tmp, "%u", $3);
198 					  $$ = strdup(tmp);
199 					}
200 	;
201 
202 hashopts:
203 	| size
204 	| seed
205 	| size seed
206 	;
207 
208 addrlist:
209 	range ',' addrlist		{ $1->ipn_next = $3; $$ = $1; }
210 	| range				{ $$ = $1; }
211 	;
212 
213 grouplist:
214 	groupentry ';' grouplist	{ $$ = $1; $1->ipe_next = $3; }
215 	| addrmask ';' grouplist	{ $$ = calloc(1, sizeof(iphtent_t));
216 					  bcopy((char *)&($1[0]),
217 						(char *)&($$->ipe_addr),
218 						sizeof($$->ipe_addr));
219 					  bcopy((char *)&($1[1]),
220 						(char *)&($$->ipe_mask),
221 						sizeof($$->ipe_mask));
222 					  $$->ipe_next = $3;
223 					}
224 	| groupentry ';'		{ $$ = $1; }
225 	| addrmask ';'			{ $$ = calloc(1, sizeof(iphtent_t));
226 					  bcopy((char *)&($1[0]),
227 						(char *)&($$->ipe_addr),
228 						sizeof($$->ipe_addr));
229 					  bcopy((char *)&($1[1]),
230 						(char *)&($$->ipe_mask),
231 						sizeof($$->ipe_mask));
232 					}
233 	;
234 
235 setgrouplist:
236 	groupentry ';'			{ $$ = $1; }
237 	| groupentry ';' setgrouplist	{ $1->ipe_next = $3; $$ = $1; }
238 	;
239 
240 groupentry:
241 	addrmask ',' setgroup		{ $$ = calloc(1, sizeof(iphtent_t));
242 					  bcopy((char *)&($1[0]),
243 						(char *)&($$->ipe_addr),
244 						sizeof($$->ipe_addr));
245 					  bcopy((char *)&($1[1]),
246 						(char *)&($$->ipe_mask),
247 						sizeof($$->ipe_mask));
248 					  strncpy($$->ipe_group, $3,
249 						  FR_GROUPLEN);
250 					  free($3);
251 					}
252 	;
253 
254 range:	addrmask	{ $$ = calloc(1, sizeof(*$$));
255 			  $$->ipn_info = 0;
256 			  $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr;
257 			  $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr;
258 			}
259 	| '!' addrmask	{ $$ = calloc(1, sizeof(*$$));
260 			  $$->ipn_info = 1;
261 			  $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr;
262 			  $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr;
263 			}
264 
265 hashlist:
266 	hashentry ';'			{ $$ = $1; }
267 	| hashentry ';' hashlist	{ $1->ipe_next = $3; $$ = $1; }
268 	;
269 
270 hashentry:
271 	addrmask 			{ $$ = calloc(1, sizeof(iphtent_t));
272 					  bcopy((char *)&($1[0]),
273 						(char *)&($$->ipe_addr),
274 						sizeof($$->ipe_addr));
275 					  bcopy((char *)&($1[1]),
276 						(char *)&($$->ipe_mask),
277 						sizeof($$->ipe_mask));
278 					}
279 	;
280 
281 addrmask:
282 	ipaddr '/' mask		{ $$[0] = $1; $$[1].s_addr = $3.s_addr; }
283 	| ipaddr		{ $$[0] = $1; $$[1].s_addr = 0xffffffff; }
284 	;
285 
286 ipaddr:	ipv4			{ $$ = $1; }
287 	| YY_NUMBER		{ $$.s_addr = htonl($1); }
288 	;
289 
290 mask:	YY_NUMBER		{ ntomask(4, $1, (u_32_t *)&$$.s_addr); }
291 	| ipv4			{ $$ = $1; }
292 	;
293 
294 size:	IPT_SIZE '=' YY_NUMBER	{ ipht.iph_size = $3; }
295 	;
296 
297 seed:	IPT_SEED '=' YY_NUMBER	{ ipht.iph_seed = $3; }
298 	;
299 
300 ipv4:	YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
301 		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
302 			yyerror("Invalid octet string for IP address");
303 			return 0;
304 		  }
305 		  $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
306 		  $$.s_addr = htonl($$.s_addr);
307 		}
308 	;
309 %%
310 static	wordtab_t	yywords[] = {
311 	{ "auth",	IPT_AUTH },
312 	{ "count",	IPT_COUNT },
313 	{ "group",	IPT_GROUP },
314 	{ "group-map",	IPT_GROUPMAP },
315 	{ "hash",	IPT_HASH },
316 	{ "in",		IPT_IN },
317 	{ "ipf",	IPT_IPF },
318 	{ "name",	IPT_NAME },
319 	{ "nat",	IPT_NAT },
320 	{ "number",	IPT_NUM },
321 	{ "out",	IPT_OUT },
322 	{ "role",	IPT_ROLE },
323 	{ "seed",	IPT_SEED },
324 	{ "size",	IPT_SIZE },
325 	{ "table",	IPT_TABLE },
326 	{ "tree",	IPT_TREE },
327 	{ "type",	IPT_TYPE },
328 	{ NULL,		0 }
329 };
330 
331 
332 int ippool_parsefile(fd, filename, iocfunc)
333 int fd;
334 char *filename;
335 ioctlfunc_t iocfunc;
336 {
337 	FILE *fp = NULL;
338 	char *s;
339 
340 	yylineNum = 1;
341 	(void) yysettab(yywords);
342 
343 	s = getenv("YYDEBUG");
344 	if (s)
345 		yydebug = atoi(s);
346 	else
347 		yydebug = 0;
348 
349 	if (strcmp(filename, "-")) {
350 		fp = fopen(filename, "r");
351 		if (!fp) {
352 			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
353 				STRERROR(errno));
354 			return -1;
355 		}
356 	} else
357 		fp = stdin;
358 
359 	while (ippool_parsesome(fd, fp, iocfunc) == 1)
360 		;
361 	if (fp != NULL)
362 		fclose(fp);
363 	return 0;
364 }
365 
366 
367 int ippool_parsesome(fd, fp, iocfunc)
368 int fd;
369 FILE *fp;
370 ioctlfunc_t iocfunc;
371 {
372 	char *s;
373 	int i;
374 
375 	poolioctl = iocfunc;
376 
377 	if (feof(fp))
378 		return 0;
379 	i = fgetc(fp);
380 	if (i == EOF)
381 		return 0;
382 	if (ungetc(i, fp) == EOF)
383 		return 0;
384 	if (feof(fp))
385 		return 0;
386 	s = getenv("YYDEBUG");
387 	if (s)
388 		yydebug = atoi(s);
389 	else
390 		yydebug = 0;
391 
392 	yyin = fp;
393 	yyparse();
394 	return 1;
395 }
396