1%{
2/*	$OpenBSD: scanner.l,v 1.30 2024/04/08 02:51:14 jsg 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
49static int stoi(char *);
50static 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
74extern YYSTYPE yylval;
75
76static const char *in_buffer;
77
78%}
79
80N		([0-9]+|(0X|0x)[0-9A-Fa-f]+)
81B		([0-9A-Fa-f][0-9A-Fa-f]?)
82W		([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
90V680		{W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
91
92V670		::{W}:{W}:{W}:{W}:{W}:{W}:{W}
93V671		{W}::{W}:{W}:{W}:{W}:{W}:{W}
94V672		{W}:{W}::{W}:{W}:{W}:{W}:{W}
95V673		{W}:{W}:{W}::{W}:{W}:{W}:{W}
96V674		{W}:{W}:{W}:{W}::{W}:{W}:{W}
97V675		{W}:{W}:{W}:{W}:{W}::{W}:{W}
98V676		{W}:{W}:{W}:{W}:{W}:{W}::{W}
99V677		{W}:{W}:{W}:{W}:{W}:{W}:{W}::
100
101V660		::{W}:{W}:{W}:{W}:{W}:{W}
102V661		{W}::{W}:{W}:{W}:{W}:{W}
103V662		{W}:{W}::{W}:{W}:{W}:{W}
104V663		{W}:{W}:{W}::{W}:{W}:{W}
105V664		{W}:{W}:{W}:{W}::{W}:{W}
106V665		{W}:{W}:{W}:{W}:{W}::{W}
107V666		{W}:{W}:{W}:{W}:{W}:{W}::
108
109V650		::{W}:{W}:{W}:{W}:{W}
110V651		{W}::{W}:{W}:{W}:{W}
111V652		{W}:{W}::{W}:{W}:{W}
112V653		{W}:{W}:{W}::{W}:{W}
113V654		{W}:{W}:{W}:{W}::{W}
114V655		{W}:{W}:{W}:{W}:{W}::
115
116V640		::{W}:{W}:{W}:{W}
117V641		{W}::{W}:{W}:{W}
118V642		{W}:{W}::{W}:{W}
119V643		{W}:{W}:{W}::{W}
120V644		{W}:{W}:{W}:{W}::
121
122V630		::{W}:{W}:{W}
123V631		{W}::{W}:{W}
124V632		{W}:{W}::{W}
125V633		{W}:{W}:{W}::
126
127V620		::{W}:{W}
128V621		{W}::{W}
129V622		{W}:{W}::
130
131V610		::{W}
132V611		{W}::
133
134V600		::
135
136V6604		{W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
137
138V6504		::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
139V6514		{W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
140V6524		{W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
141V6534		{W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
142V6544		{W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
143V6554		{W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
144
145V6404		::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
146V6414		{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
147V6424		{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
148V6434		{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
149V6444		{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
150
151V6304		::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
152V6314		{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
153V6324		{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
154V6334		{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
155
156V6204		::{W}:{W}:{N}\.{N}\.{N}\.{N}
157V6214		{W}::{W}:{N}\.{N}\.{N}\.{N}
158V6224		{W}:{W}::{N}\.{N}\.{N}\.{N}
159
160V6104		::{W}:{N}\.{N}\.{N}\.{N}
161V6114		{W}::{N}\.{N}\.{N}\.{N}
162
163V6004		::{N}\.{N}\.{N}\.{N}
164
165
166V6		({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%%
169dst		return DST;
170src		return SRC;
171
172link|ether|ppp|slip  return LINK;
173fddi		return LINK;
174arp		return ARP;
175rarp		return RARP;
176ip		return IP;
177tcp		return TCP;
178udp		return UDP;
179icmp		return ICMP;
180igmp		return IGMP;
181igrp		return IGRP;
182pim		return PIM;
183
184ip6		return IPV6;
185icmp6		return ICMPV6;
186ah		return AH;
187esp		return ESP;
188
189atalk		return ATALK;
190decnet		return DECNET;
191lat		return LAT;
192sca		return SCA;
193moprc		return MOPRC;
194mopdl		return MOPDL;
195stp		return STP;
196
197host		return HOST;
198net		return NET;
199mask		return MASK;
200port		return PORT;
201proto		return PROTO;
202protochain	{
203#ifdef NO_PROTOCHAIN
204		  bpf_error("%s not supported", yytext);
205#else
206		  return PROTOCHAIN;
207#endif
208		}
209
210gateway		return GATEWAY;
211
212less		return LESS;
213greater		return GREATER;
214byte		return BYTE;
215broadcast	return TK_BROADCAST;
216multicast	return TK_MULTICAST;
217
218and|"&&"	return AND;
219or|"||"		return OR;
220not		return '!';
221
222len|length	return LEN;
223rnd|random	return RND;
224sample		return SAMPLE;
225inbound		return INBOUND;
226outbound	return OUTBOUND;
227
228vlan		return VLAN;
229mpls		return MPLS;
230
231on|ifname	return PF_IFNAME;
232rset|ruleset	return PF_RSET;
233rnr|rulenum	return PF_RNR;
234srnr|subrulenum	return PF_SRNR;
235reason		return PF_REASON;
236action		return PF_ACTION;
237
238wlan		return LINK;
239type		return TYPE;
240subtype		return SUBTYPE;
241direction|dir	return DIR;
242address1|addr1	return ADDR1;
243address2|addr2	return ADDR2;
244address3|addr3	return ADDR3;
245address4|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); }
276icmptype		{ yylval.i = 0; return NUM; }
277icmpcode		{ yylval.i = 1; return NUM; }
278icmp-echoreply		{ yylval.i = 0; return NUM; }
279icmp-unreach		{ yylval.i = 3; return NUM; }
280icmp-sourcequench	{ yylval.i = 4; return NUM; }
281icmp-redirect		{ yylval.i = 5; return NUM; }
282icmp-echo		{ yylval.i = 8; return NUM; }
283icmp-routeradvert	{ yylval.i = 9; return NUM; }
284icmp-routersolicit	{ yylval.i = 10; return NUM; }
285icmp-timxceed		{ yylval.i = 11; return NUM; }
286icmp-paramprob		{ yylval.i = 12; return NUM; }
287icmp-tstamp		{ yylval.i = 13; return NUM; }
288icmp-tstampreply	{ yylval.i = 14; return NUM; }
289icmp-ireq		{ yylval.i = 15; return NUM; }
290icmp-ireqreply		{ yylval.i = 16; return NUM; }
291icmp-maskreq		{ yylval.i = 17; return NUM; }
292icmp-maskreply		{ yylval.i = 18; return NUM; }
293tcpflags		{ yylval.i = 13; return NUM; }
294tcp-fin			{ yylval.i = 0x01; return NUM; }
295tcp-syn			{ yylval.i = 0x02; return NUM; }
296tcp-rst			{ yylval.i = 0x04; return NUM; }
297tcp-push		{ yylval.i = 0x08; return NUM; }
298tcp-ack			{ yylval.i = 0x10; return NUM; }
299tcp-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%%
319void
320lex_init(const char *buf)
321{
322	in_buffer = buf;
323	yyrestart(NULL);
324}
325
326/*
327 * Also define a yywrap.  Note that if we're using flex, it will
328 * define a macro to map this identifier to pcap_wrap.
329 */
330int
331yywrap(void)
332{
333	return 1;
334}
335
336/* Hex digit to integer. */
337static inline int
338xdtoi(int c)
339{
340	if (isdigit(c))
341		return c - '0';
342	else if (islower(c))
343		return c - 'a' + 10;
344	else
345		return c - 'A' + 10;
346}
347
348/*
349 * Convert string to integer.  Just like atoi(), but checks for
350 * preceding 0x or 0 and uses hex or octal instead of decimal.
351 */
352static int
353stoi(char *s)
354{
355	int base = 10;
356	int n = 0;
357
358	if (*s == '0') {
359		if (s[1] == 'x' || s[1] == 'X') {
360			s += 2;
361			base = 16;
362		}
363		else {
364			base = 8;
365			s += 1;
366		}
367	}
368	while (*s)
369		n = n * base + xdtoi(*s++);
370
371	return n;
372}
373
374