xref: /openbsd/lib/libpcap/scanner.l (revision 73471bf0)
1 %{
2 /*	$OpenBSD: scanner.l,v 1.28 2020/08/03 03:40:02 dlg Exp $	*/
3 
4 /*
5  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that: (1) source code distributions
10  * retain the above copyright notice and this paragraph in its entirety, (2)
11  * distributions including binary code include the above copyright notice and
12  * this paragraph in its entirety in the documentation or other materials
13  * provided with the distribution, and (3) all advertising materials mentioning
14  * features or use of this software display the following acknowledgement:
15  * ``This product includes software developed by the University of California,
16  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
17  * the University nor the names of its contributors may be used to endorse
18  * or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
21  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23  */
24 
25 #include <sys/types.h>
26 #include <sys/time.h>
27 
28 #include <ctype.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <vis.h>
32 
33 #include "pcap-int.h"
34 
35 #include "gencode.h"
36 #include <pcap-namedb.h>
37 
38 #ifdef INET6
39 #include <netdb.h>
40 #include <sys/socket.h>
41 #endif /*INET6*/
42 
43 #ifdef HAVE_OS_PROTO_H
44 #include "os-proto.h"
45 #endif
46 
47 #include "grammar.h"
48 
49 static int stoi(char *);
50 static inline int xdtoi(int);
51 
52 #ifdef FLEX_SCANNER
53 #define YY_NO_UNPUT
54 #undef YY_INPUT
55 #define YY_INPUT(buf, result, max)\
56  {\
57 	const char *src = in_buffer;\
58 	int i;\
59 \
60 	if (*src == 0)\
61 		result = YY_NULL;\
62 	else {\
63 		for (i = 0; *src && i < max; ++i)\
64 			buf[i] = *src++;\
65 		in_buffer += i;\
66 		result = i;\
67 	}\
68  }
69 #else
70 #undef getc
71 #define getc(fp)  (*in_buffer == 0 ? EOF : *in_buffer++)
72 #endif
73 
74 extern YYSTYPE yylval;
75 
76 static const char *in_buffer;
77 
78 %}
79 
80 N		([0-9]+|(0X|0x)[0-9A-Fa-f]+)
81 B		([0-9A-Fa-f][0-9A-Fa-f]?)
82 W		([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
83 
84 %a 15000
85 %o 17000
86 %e 6000
87 %k 4000
88 %p 19000
89 
90 V680		{W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
91 
92 V670		::{W}:{W}:{W}:{W}:{W}:{W}:{W}
93 V671		{W}::{W}:{W}:{W}:{W}:{W}:{W}
94 V672		{W}:{W}::{W}:{W}:{W}:{W}:{W}
95 V673		{W}:{W}:{W}::{W}:{W}:{W}:{W}
96 V674		{W}:{W}:{W}:{W}::{W}:{W}:{W}
97 V675		{W}:{W}:{W}:{W}:{W}::{W}:{W}
98 V676		{W}:{W}:{W}:{W}:{W}:{W}::{W}
99 V677		{W}:{W}:{W}:{W}:{W}:{W}:{W}::
100 
101 V660		::{W}:{W}:{W}:{W}:{W}:{W}
102 V661		{W}::{W}:{W}:{W}:{W}:{W}
103 V662		{W}:{W}::{W}:{W}:{W}:{W}
104 V663		{W}:{W}:{W}::{W}:{W}:{W}
105 V664		{W}:{W}:{W}:{W}::{W}:{W}
106 V665		{W}:{W}:{W}:{W}:{W}::{W}
107 V666		{W}:{W}:{W}:{W}:{W}:{W}::
108 
109 V650		::{W}:{W}:{W}:{W}:{W}
110 V651		{W}::{W}:{W}:{W}:{W}
111 V652		{W}:{W}::{W}:{W}:{W}
112 V653		{W}:{W}:{W}::{W}:{W}
113 V654		{W}:{W}:{W}:{W}::{W}
114 V655		{W}:{W}:{W}:{W}:{W}::
115 
116 V640		::{W}:{W}:{W}:{W}
117 V641		{W}::{W}:{W}:{W}
118 V642		{W}:{W}::{W}:{W}
119 V643		{W}:{W}:{W}::{W}
120 V644		{W}:{W}:{W}:{W}::
121 
122 V630		::{W}:{W}:{W}
123 V631		{W}::{W}:{W}
124 V632		{W}:{W}::{W}
125 V633		{W}:{W}:{W}::
126 
127 V620		::{W}:{W}
128 V621		{W}::{W}
129 V622		{W}:{W}::
130 
131 V610		::{W}
132 V611		{W}::
133 
134 V600		::
135 
136 V6604		{W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
137 
138 V6504		::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
139 V6514		{W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
140 V6524		{W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
141 V6534		{W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
142 V6544		{W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
143 V6554		{W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
144 
145 V6404		::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
146 V6414		{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
147 V6424		{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
148 V6434		{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
149 V6444		{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
150 
151 V6304		::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
152 V6314		{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
153 V6324		{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
154 V6334		{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
155 
156 V6204		::{W}:{W}:{N}\.{N}\.{N}\.{N}
157 V6214		{W}::{W}:{N}\.{N}\.{N}\.{N}
158 V6224		{W}:{W}::{N}\.{N}\.{N}\.{N}
159 
160 V6104		::{W}:{N}\.{N}\.{N}\.{N}
161 V6114		{W}::{N}\.{N}\.{N}\.{N}
162 
163 V6004		::{N}\.{N}\.{N}\.{N}
164 
165 
166 V6		({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004})
167 
168 %%
169 dst		return DST;
170 src		return SRC;
171 
172 link|ether|ppp|slip  return LINK;
173 fddi		return LINK;
174 arp		return ARP;
175 rarp		return RARP;
176 ip		return IP;
177 tcp		return TCP;
178 udp		return UDP;
179 icmp		return ICMP;
180 igmp		return IGMP;
181 igrp		return IGRP;
182 pim		return PIM;
183 
184 ip6		return IPV6;
185 icmp6		return ICMPV6;
186 ah		return AH;
187 esp		return ESP;
188 
189 atalk		return ATALK;
190 decnet		return DECNET;
191 lat		return LAT;
192 sca		return SCA;
193 moprc		return MOPRC;
194 mopdl		return MOPDL;
195 stp		return STP;
196 
197 host		return HOST;
198 net		return NET;
199 mask		return MASK;
200 port		return PORT;
201 proto		return PROTO;
202 protochain	{
203 #ifdef NO_PROTOCHAIN
204 		  bpf_error("%s not supported", yytext);
205 #else
206 		  return PROTOCHAIN;
207 #endif
208 		}
209 
210 gateway		return GATEWAY;
211 
212 less		return LESS;
213 greater		return GREATER;
214 byte		return BYTE;
215 broadcast	return TK_BROADCAST;
216 multicast	return TK_MULTICAST;
217 
218 and|"&&"	return AND;
219 or|"||"		return OR;
220 not		return '!';
221 
222 len|length	return LEN;
223 rnd|random	return RND;
224 sample		return SAMPLE;
225 inbound		return INBOUND;
226 outbound	return OUTBOUND;
227 
228 vlan		return VLAN;
229 mpls		return MPLS;
230 
231 on|ifname	return PF_IFNAME;
232 rset|ruleset	return PF_RSET;
233 rnr|rulenum	return PF_RNR;
234 srnr|subrulenum	return PF_SRNR;
235 reason		return PF_REASON;
236 action		return PF_ACTION;
237 
238 wlan		return LINK;
239 type		return TYPE;
240 subtype		return SUBTYPE;
241 direction|dir	return DIR;
242 address1|addr1	return ADDR1;
243 address2|addr2	return ADDR2;
244 address3|addr3	return ADDR3;
245 address4|addr4	return ADDR4;
246 
247 [ \n\t]			;
248 [+\-*/:\[\]!<>()&|=]	return yytext[0];
249 ">="			return GEQ;
250 "<="			return LEQ;
251 "!="			return NEQ;
252 "=="			return '=';
253 "<<"			return LSH;
254 ">>"			return RSH;
255 {N}			{ yylval.i = stoi((char *)yytext); return NUM; }
256 ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N})	{
257 			yylval.s = sdup((char *)yytext); return HID; }
258 {B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
259 			  return EID; }
260 {V6}			{
261 #ifdef INET6
262 			  struct addrinfo hints, *res;
263 			  memset(&hints, 0, sizeof(hints));
264 			  hints.ai_family = AF_INET6;
265 			  hints.ai_flags = AI_NUMERICHOST;
266 			  if (getaddrinfo(yytext, NULL, &hints, &res))
267 				bpf_error("bogus IPv6 address %s", yytext);
268 			  else {
269 				yylval.e = sdup((char *)yytext); return HID6;
270 			  }
271 #else
272 			  bpf_error("IPv6 address %s not supported", yytext);
273 #endif /*INET6*/
274 			}
275 {B}:+({B}:+)+		{ bpf_error("bogus ethernet address %s", yytext); }
276 icmptype		{ yylval.i = 0; return NUM; }
277 icmpcode		{ yylval.i = 1; return NUM; }
278 icmp-echoreply		{ yylval.i = 0; return NUM; }
279 icmp-unreach		{ yylval.i = 3; return NUM; }
280 icmp-sourcequench	{ yylval.i = 4; return NUM; }
281 icmp-redirect		{ yylval.i = 5; return NUM; }
282 icmp-echo		{ yylval.i = 8; return NUM; }
283 icmp-routeradvert	{ yylval.i = 9; return NUM; }
284 icmp-routersolicit	{ yylval.i = 10; return NUM; }
285 icmp-timxceed		{ yylval.i = 11; return NUM; }
286 icmp-paramprob		{ yylval.i = 12; return NUM; }
287 icmp-tstamp		{ yylval.i = 13; return NUM; }
288 icmp-tstampreply	{ yylval.i = 14; return NUM; }
289 icmp-ireq		{ yylval.i = 15; return NUM; }
290 icmp-ireqreply		{ yylval.i = 16; return NUM; }
291 icmp-maskreq		{ yylval.i = 17; return NUM; }
292 icmp-maskreply		{ yylval.i = 18; return NUM; }
293 tcpflags		{ yylval.i = 13; return NUM; }
294 tcp-fin			{ yylval.i = 0x01; return NUM; }
295 tcp-syn			{ yylval.i = 0x02; return NUM; }
296 tcp-rst			{ yylval.i = 0x04; return NUM; }
297 tcp-push		{ yylval.i = 0x08; return NUM; }
298 tcp-ack			{ yylval.i = 0x10; return NUM; }
299 tcp-urg			{ yylval.i = 0x20; return NUM; }
300 [A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] {
301 			 yylval.s = sdup((char *)yytext); return ID; }
302 [A-Za-z] {		 yylval.s = sdup((char *)yytext); return ID; }
303 "\\"[^ !()\n\t]+	{ yylval.s = sdup((char *)yytext + 1); return ID; }
304 [^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
305 			size_t len = strlen(yytext) * 4 + 1;
306 			char *v = malloc(len);
307 			if (v != NULL)
308 				strnvis(v, yytext, len, 0);
309 			bpf_error("illegal token: %s", v);
310 			free(v);
311 			}
312 .			{
313 			  char v[5];
314 
315 			  vis(v, *yytext, VIS_OCTAL, 0);
316 			  bpf_error("illegal char '%s'", v);
317 			}
318 %%
319 void
320 lex_init(buf)
321 	const char *buf;
322 {
323 	in_buffer = buf;
324 	yyrestart(NULL);
325 }
326 
327 /*
328  * Also define a yywrap.  Note that if we're using flex, it will
329  * define a macro to map this identifier to pcap_wrap.
330  */
331 int
332 yywrap()
333 {
334 	return 1;
335 }
336 
337 /* Hex digit to integer. */
338 static inline int
339 xdtoi(c)
340 	int c;
341 {
342 	if (isdigit(c))
343 		return c - '0';
344 	else if (islower(c))
345 		return c - 'a' + 10;
346 	else
347 		return c - 'A' + 10;
348 }
349 
350 /*
351  * Convert string to integer.  Just like atoi(), but checks for
352  * preceding 0x or 0 and uses hex or octal instead of decimal.
353  */
354 static int
355 stoi(s)
356 	char *s;
357 {
358 	int base = 10;
359 	int n = 0;
360 
361 	if (*s == '0') {
362 		if (s[1] == 'x' || s[1] == 'X') {
363 			s += 2;
364 			base = 16;
365 		}
366 		else {
367 			base = 8;
368 			s += 1;
369 		}
370 	}
371 	while (*s)
372 		n = n * base + xdtoi(*s++);
373 
374 	return n;
375 }
376 
377