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