iplang_l.l revision 302408
1/*	$FreeBSD: stable/11/contrib/ipfilter/iplang/iplang_l.l 255332 2013-09-06 23:11:19Z cy $	*/
2
3%{
4/*
5 * Copyright (C) 2012 by Darren Reed.
6 *
7 * See the IPFILTER.LICENCE file for details on licencing.
8 *
9 * $Id$
10 */
11#include <stdio.h>
12#include <string.h>
13#include <sys/param.h>
14#if defined(__SVR4) || defined(__sysv__)
15#include <sys/stream.h>
16#endif
17#include <sys/types.h>
18#include <netinet/in_systm.h>
19#include <netinet/in.h>
20#include "iplang_y.h"
21#include "ipf.h"
22
23#ifndef	__P
24# ifdef __STDC__
25#  define	__P(x)	x
26# else
27#  define	__P(x)	()
28# endif
29#endif
30
31extern int opts;
32
33int lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0;
34int *prstack = NULL, numpr = 0, state = 0, token = 0;
35
36void    yyerror __P((char *));
37void	push_proto __P((void));
38void	pop_proto __P((void));
39int	next_state __P((int, int));
40int	next_item __P((int));
41int	save_token __P((void));
42void	swallow __P((void));
43int	yylex __P((void));
44
45struct	lwordtab	{
46	char	*word;
47	int	state;
48	int	next;
49};
50
51struct	lwordtab	words[] = {
52	{ "interface",	IL_INTERFACE,		-1 },
53	{ "iface",	IL_INTERFACE,		-1 },
54	{ "name",	IL_IFNAME,		IL_TOKEN },
55	{ "ifname",	IL_IFNAME,		IL_TOKEN },
56	{ "router",	IL_DEFROUTER,		IL_TOKEN },
57	{ "mtu",	IL_MTU,			IL_NUMBER },
58	{ "eaddr",	IL_EADDR,		IL_TOKEN },
59	{ "v4addr",	IL_V4ADDR,		IL_TOKEN },
60	{ "ipv4",	IL_IPV4,		-1 },
61	{ "v",		IL_V4V,			IL_TOKEN },
62	{ "proto",	IL_V4PROTO,		IL_TOKEN },
63	{ "hl",		IL_V4HL,		IL_TOKEN },
64	{ "id",		IL_V4ID,		IL_TOKEN },
65	{ "ttl",	IL_V4TTL,		IL_TOKEN },
66	{ "tos",	IL_V4TOS,		IL_TOKEN },
67	{ "src",	IL_V4SRC,		IL_TOKEN },
68	{ "dst",	IL_V4DST,		IL_TOKEN },
69	{ "opt",	IL_OPT,			-1 },
70	{ "len",	IL_LEN,			IL_TOKEN },
71	{ "off",	IL_OFF,			IL_TOKEN },
72	{ "sum",	IL_SUM,			IL_TOKEN },
73	{ "tcp",	IL_TCP,			-1 },
74	{ "sport",	IL_SPORT,		IL_TOKEN },
75	{ "dport",	IL_DPORT,		IL_TOKEN },
76	{ "seq",	IL_TCPSEQ,		IL_TOKEN },
77	{ "ack",	IL_TCPACK,		IL_TOKEN },
78	{ "flags",	IL_TCPFL,		IL_TOKEN },
79	{ "urp",	IL_TCPURP,		IL_TOKEN },
80	{ "win",	IL_TCPWIN,		IL_TOKEN },
81	{ "udp",	IL_UDP,			-1 },
82	{ "send",	IL_SEND,		-1 },
83	{ "via",	IL_VIA,			IL_TOKEN },
84	{ "arp",	IL_ARP,			-1 },
85	{ "data",	IL_DATA,		-1 },
86	{ "value",	IL_DVALUE,		IL_TOKEN },
87	{ "file",	IL_DFILE,		IL_TOKEN },
88	{ "nop",	IL_IPO_NOP,		-1 },
89	{ "eol",	IL_IPO_EOL,		-1 },
90	{ "rr",		IL_IPO_RR,		-1 },
91	{ "zsu",	IL_IPO_ZSU,		-1 },
92	{ "mtup",	IL_IPO_MTUP,		-1 },
93	{ "mtur",	IL_IPO_MTUR,		-1 },
94	{ "encode",	IL_IPO_ENCODE,		-1 },
95	{ "ts",		IL_IPO_TS,		-1 },
96	{ "tr",		IL_IPO_TR,		-1 },
97	{ "sec",	IL_IPO_SEC,		-1 },
98	{ "secclass",	IL_IPO_SECCLASS,	IL_TOKEN },
99	{ "lsrr",	IL_IPO_LSRR,		-1 },
100	{ "esec",	IL_IPO_ESEC,		-1 },
101	{ "cipso",	IL_IPO_CIPSO,		-1 },
102	{ "satid",	IL_IPO_SATID,		-1 },
103	{ "ssrr",	IL_IPO_SSRR,		-1 },
104	{ "addext",	IL_IPO_ADDEXT,		-1 },
105	{ "visa",	IL_IPO_VISA,		-1 },
106	{ "imitd",	IL_IPO_IMITD,		-1 },
107	{ "eip",	IL_IPO_EIP,		-1 },
108	{ "finn",	IL_IPO_FINN,		-1 },
109	{ "mss",	IL_TCPO_MSS,		IL_TOKEN },
110	{ "wscale",	IL_TCPO_WSCALE,		IL_TOKEN },
111	{ "reserv-4",	IL_IPS_RESERV4,		-1 },
112	{ "topsecret",	IL_IPS_TOPSECRET,	-1 },
113	{ "secret",	IL_IPS_SECRET,		-1 },
114	{ "reserv-3",	IL_IPS_RESERV3,		-1 },
115	{ "confid",	IL_IPS_CONFID,		-1 },
116	{ "unclass",	IL_IPS_UNCLASS,		-1 },
117	{ "reserv-2",	IL_IPS_RESERV2,		-1 },
118	{ "reserv-1",	IL_IPS_RESERV1,		-1 },
119	{ "icmp",	IL_ICMP,		-1 },
120	{ "type",	IL_ICMPTYPE,		-1 },
121	{ "code",	IL_ICMPCODE,		-1 },
122	{ "echorep",	IL_ICMP_ECHOREPLY,	-1 },
123	{ "unreach",	IL_ICMP_UNREACH,	-1 },
124	{ "squench",	IL_ICMP_SOURCEQUENCH,	-1 },
125	{ "redir",	IL_ICMP_REDIRECT,	-1 },
126	{ "echo",	IL_ICMP_ECHO,		-1 },
127	{ "routerad",	IL_ICMP_ROUTERADVERT,	-1 },
128	{ "routersol",	IL_ICMP_ROUTERSOLICIT,	-1 },
129	{ "timex",	IL_ICMP_TIMXCEED,	-1 },
130	{ "paramprob",	IL_ICMP_PARAMPROB,	-1 },
131	{ "timest",	IL_ICMP_TSTAMP,		-1 },
132	{ "timestrep",	IL_ICMP_TSTAMPREPLY,	-1 },
133	{ "inforeq",	IL_ICMP_IREQ,		-1 },
134	{ "inforep",	IL_ICMP_IREQREPLY,	-1 },
135	{ "maskreq",	IL_ICMP_MASKREQ,	-1 },
136	{ "maskrep",	IL_ICMP_MASKREPLY,	-1 },
137	{ "net-unr",	IL_ICMP_UNREACH_NET,	-1 },
138	{ "host-unr",	IL_ICMP_UNREACH_HOST,	-1 },
139	{ "proto-unr",	IL_ICMP_UNREACH_PROTOCOL,	-1 },
140	{ "port-unr",	IL_ICMP_UNREACH_PORT,	-1 },
141	{ "needfrag",	IL_ICMP_UNREACH_NEEDFRAG,	-1 },
142	{ "srcfail",	IL_ICMP_UNREACH_SRCFAIL,	-1 },
143	{ "net-unk",	IL_ICMP_UNREACH_NET_UNKNOWN,	-1 },
144	{ "host-unk",	IL_ICMP_UNREACH_HOST_UNKNOWN,	-1 },
145	{ "isolate",	IL_ICMP_UNREACH_ISOLATED,	-1 },
146	{ "net-prohib",	IL_ICMP_UNREACH_NET_PROHIB,	-1 },
147	{ "host-prohib",	IL_ICMP_UNREACH_HOST_PROHIB,	-1 },
148	{ "net-tos",	IL_ICMP_UNREACH_TOSNET,	-1 },
149	{ "host-tos",	IL_ICMP_UNREACH_TOSHOST,	-1 },
150	{ "filter-prohib",	IL_ICMP_UNREACH_FILTER_PROHIB,	-1 },
151	{ "host-preced",	IL_ICMP_UNREACH_HOST_PRECEDENCE,	-1 },
152	{ "cutoff-preced",	IL_ICMP_UNREACH_PRECEDENCE_CUTOFF,	-1 },
153	{ "net-redir",	IL_ICMP_REDIRECT_NET,	-1 },
154	{ "host-redir",	IL_ICMP_REDIRECT_HOST,	-1 },
155	{ "tos-net-redir",	IL_ICMP_REDIRECT_TOSNET,	-1 },
156	{ "tos-host-redir",	IL_ICMP_REDIRECT_TOSHOST,	-1 },
157	{ "intrans",	IL_ICMP_TIMXCEED_INTRANS,	-1 },
158	{ "reass",	IL_ICMP_TIMXCEED_REASS,	-1 },
159	{ "optabsent",	IL_ICMP_PARAMPROB_OPTABSENT,	-1 },
160	{ "otime",	IL_ICMP_OTIME,		-1 },
161	{ "rtime",	IL_ICMP_RTIME,		-1 },
162	{ "ttime",	IL_ICMP_TTIME,		-1 },
163	{ "icmpseq",	IL_ICMP_SEQ,		-1 },
164	{ "icmpid",	IL_ICMP_SEQ,		-1 },
165	{ ".",		IL_DOT,			-1 },
166	{ NULL, 0, 0 }
167};
168%}
169white	[ \t\r]+
170%%
171{white}	;
172\n	{ lineNum++; swallow(); }
173\{	{ push_proto(); return next_item('{'); }
174\}	{ pop_proto(); return next_item('}'); }
175;	{ return next_item(';'); }
176[0-9]+	{ return next_item(IL_NUMBER); }
177[0-9a-fA-F]	{ return next_item(IL_HEXDIGIT); }
178:	{ return next_item(IL_COLON); }
179#[^\n]*	{ return next_item(IL_COMMENT); }
180[^ \{\}\n\t;:{}]*	{ return next_item(IL_TOKEN); }
181\"[^\"]*\"	{ return next_item(IL_TOKEN); }
182%%
183void    yyerror(msg)
184char    *msg;
185{
186	fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
187		lineNum + 1);
188	exit(1);
189}
190
191
192void push_proto()
193{
194	numpr++;
195	if (!prstack)
196		prstack = (int *)malloc(sizeof(int));
197	else
198		prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
199	prstack[numpr - 1] = oldipproto;
200}
201
202
203void pop_proto()
204{
205	numpr--;
206	ipproto = prstack[numpr];
207	if (!numpr) {
208		free(prstack);
209		prstack = NULL;
210		return;
211	}
212	prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
213}
214
215
216int save_token()
217{
218
219	yylval.str = strdup((char *)yytext);
220	return IL_TOKEN;
221}
222
223
224int next_item(nstate)
225int nstate;
226{
227	struct	lwordtab	*wt;
228
229	if (opts & OPT_DEBUG)
230		printf("text=[%s] id=%d next=%d\n", yytext, nstate, next);
231	if (next == IL_TOKEN) {
232		next = -1;
233		return save_token();
234	}
235	token++;
236
237	for (wt = words; wt->word; wt++)
238		if (!strcasecmp(wt->word, (char *)yytext))
239			return next_state(wt->state, wt->next);
240	if (opts & OPT_DEBUG)
241		printf("unknown keyword=[%s]\n", yytext);
242	next = -1;
243	if (nstate == IL_NUMBER)
244		yylval.num = atoi((char *)yytext);
245	token++;
246	return nstate;
247}
248
249
250int next_state(nstate, fornext)
251int nstate, fornext;
252{
253	next = fornext;
254
255	switch (nstate)
256	{
257	case IL_IPV4 :
258	case IL_TCP :
259	case IL_UDP :
260	case IL_ICMP :
261	case IL_DATA :
262	case IL_INTERFACE :
263	case IL_ARP :
264		oldipproto = ipproto;
265		ipproto = nstate;
266		break;
267	case IL_SUM :
268		if (ipproto == IL_IPV4)
269			nstate = IL_V4SUM;
270		else if (ipproto == IL_TCP)
271			nstate = IL_TCPSUM;
272		else if (ipproto == IL_UDP)
273			nstate = IL_UDPSUM;
274		break;
275	case IL_OPT :
276		if (ipproto == IL_IPV4)
277			nstate = IL_V4OPT;
278		else if (ipproto == IL_TCP)
279			nstate = IL_TCPOPT;
280		break;
281	case IL_IPO_NOP :
282		if (ipproto == IL_TCP)
283			nstate = IL_TCPO_NOP;
284		break;
285	case IL_IPO_EOL :
286		if (ipproto == IL_TCP)
287			nstate = IL_TCPO_EOL;
288		break;
289	case IL_IPO_TS :
290		if (ipproto == IL_TCP)
291			nstate = IL_TCPO_TS;
292		break;
293	case IL_OFF :
294		if (ipproto == IL_IPV4)
295			nstate = IL_V4OFF;
296		else if (ipproto == IL_TCP)
297			nstate = IL_TCPOFF;
298		break;
299	case IL_LEN :
300		if (ipproto == IL_IPV4)
301			nstate = IL_V4LEN;
302		else if (ipproto == IL_UDP)
303			nstate = IL_UDPLEN;
304		break;
305	}
306	return nstate;
307}
308
309
310void swallow()
311{
312	int c;
313
314	c = input();
315
316	if (c == '#') {
317		while ((c != '\n') && (c != EOF))
318			c = input();
319	}
320	if (c != EOF)
321		unput(c);
322}
323