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