xref: /netbsd-src/external/bsd/ipf/dist/iplang/iplang_l.l (revision 13885a665959c62f13a82b3caedf986eaa17aa31)
1 /*	$NetBSD: iplang_l.l,v 1.2 2012/07/22 14:27:35 darrenr Exp $	*/
2 
3 %{
4 /*
5  * Copyright (C) 2012 by Darren Reed.
6  *
7  * See the IPFILTER.LICENCE file for details on licencing.
8  *
9  * Id: iplang_l.l,v 1.1.1.2 2012/07/22 13:44:33 darrenr Exp $
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 
31 extern int opts;
32 
33 int lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0;
34 int *prstack = NULL, numpr = 0, state = 0, token = 0;
35 
36 void    yyerror __P((char *));
37 void	push_proto __P((void));
38 void	pop_proto __P((void));
39 int	next_state __P((int, int));
40 int	next_item __P((int));
41 int	save_token __P((void));
42 void	swallow __P((void));
43 int	yylex __P((void));
44 
45 struct	lwordtab	{
46 	char	*word;
47 	int	state;
48 	int	next;
49 };
50 
51 struct	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 %}
169 white	[ \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 %%
183 void    yyerror(msg)
184 char    *msg;
185 {
186 	fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
187 		lineNum + 1);
188 	exit(1);
189 }
190 
191 
192 void 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 
203 void 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 
216 int save_token()
217 {
218 
219 	yylval.str = strdup((char *)yytext);
220 	return IL_TOKEN;
221 }
222 
223 
224 int next_item(nstate)
225 int 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 
250 int next_state(nstate, fornext)
251 int 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 
310 void 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