1/*
2 * BPF asm code lexer
3 *
4 * This program is free software; you can distribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * Syntax kept close to:
10 *
11 * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new
12 * architecture for user-level packet capture. In Proceedings of the
13 * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993
14 * Conference Proceedings (USENIX'93). USENIX Association, Berkeley,
15 * CA, USA, 2-2.
16 *
17 * Copyright 2013 Daniel Borkmann <borkmann@redhat.com>
18 * Licensed under the GNU General Public License, version 2.0 (GPLv2)
19 */
20
21%{
22
23#include <stdio.h>
24#include <stdint.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include <linux/filter.h>
29
30#include "bpf_exp.yacc.h"
31
32extern void yyerror(const char *str);
33
34%}
35
36%option align
37%option ecs
38
39%option nounput
40%option noreject
41%option noinput
42%option noyywrap
43
44%option 8bit
45%option caseless
46%option yylineno
47
48%%
49
50"ldb"		{ return OP_LDB; }
51"ldh"		{ return OP_LDH; }
52"ld"		{ return OP_LD; }
53"ldi"		{ return OP_LDI; }
54"ldx"		{ return OP_LDX; }
55"ldxi"		{ return OP_LDXI; }
56"ldxb"		{ return OP_LDXB; }
57"st"		{ return OP_ST; }
58"stx"		{ return OP_STX; }
59"jmp"		{ return OP_JMP; }
60"ja"		{ return OP_JMP; }
61"jeq"		{ return OP_JEQ; }
62"jneq"		{ return OP_JNEQ; }
63"jne"		{ return OP_JNEQ; }
64"jlt"		{ return OP_JLT; }
65"jle"		{ return OP_JLE; }
66"jgt"		{ return OP_JGT; }
67"jge"		{ return OP_JGE; }
68"jset"		{ return OP_JSET; }
69"add"		{ return OP_ADD; }
70"sub"		{ return OP_SUB; }
71"mul"		{ return OP_MUL; }
72"div"		{ return OP_DIV; }
73"mod"		{ return OP_MOD; }
74"neg"		{ return OP_NEG; }
75"and"		{ return OP_AND; }
76"xor"		{ return OP_XOR; }
77"or"		{ return OP_OR; }
78"lsh"		{ return OP_LSH; }
79"rsh"		{ return OP_RSH; }
80"ret"		{ return OP_RET; }
81"tax"		{ return OP_TAX; }
82"txa"		{ return OP_TXA; }
83
84"#"?("len")	{ return K_PKT_LEN; }
85
86"#"?("proto")	{
87		yylval.number = SKF_AD_PROTOCOL;
88		return extension;
89	}
90"#"?("type")	{
91		yylval.number = SKF_AD_PKTTYPE;
92		return extension;
93	}
94"#"?("poff")	{
95		yylval.number = SKF_AD_PAY_OFFSET;
96		return extension;
97	}
98"#"?("ifidx")	{
99		yylval.number = SKF_AD_IFINDEX;
100		return extension;
101	}
102"#"?("nla")	{
103		yylval.number = SKF_AD_NLATTR;
104		return extension;
105	}
106"#"?("nlan")	{
107		yylval.number = SKF_AD_NLATTR_NEST;
108		return extension;
109	}
110"#"?("mark")	{
111		yylval.number = SKF_AD_MARK;
112		return extension;
113	}
114"#"?("queue")	{
115		yylval.number = SKF_AD_QUEUE;
116		return extension;
117	}
118"#"?("hatype")	{
119		yylval.number = SKF_AD_HATYPE;
120		return extension;
121	}
122"#"?("rxhash")	{
123		yylval.number = SKF_AD_RXHASH;
124		return extension;
125	}
126"#"?("cpu")	{
127		yylval.number = SKF_AD_CPU;
128		return extension;
129	}
130"#"?("vlan_tci") {
131		yylval.number = SKF_AD_VLAN_TAG;
132		return extension;
133	}
134"#"?("vlan_pr")	{
135		yylval.number = SKF_AD_VLAN_TAG_PRESENT;
136		return extension;
137	}
138"#"?("vlan_avail") {
139		yylval.number = SKF_AD_VLAN_TAG_PRESENT;
140		return extension;
141	}
142"#"?("vlan_tpid") {
143		yylval.number = SKF_AD_VLAN_TPID;
144		return extension;
145	}
146"#"?("rand")	{
147		yylval.number = SKF_AD_RANDOM;
148		return extension;
149	}
150
151":"		{ return ':'; }
152","		{ return ','; }
153"#"		{ return '#'; }
154"%"		{ return '%'; }
155"["		{ return '['; }
156"]"		{ return ']'; }
157"("		{ return '('; }
158")"		{ return ')'; }
159"x"		{ return 'x'; }
160"a"		{ return 'a'; }
161"+"		{ return '+'; }
162"M"		{ return 'M'; }
163"*"		{ return '*'; }
164"&"		{ return '&'; }
165
166([0][x][a-fA-F0-9]+) {
167			yylval.number = strtoul(yytext, NULL, 16);
168			return number;
169		}
170([0][b][0-1]+)	{
171			yylval.number = strtol(yytext + 2, NULL, 2);
172			return number;
173		}
174(([0])|([-+]?[1-9][0-9]*)) {
175			yylval.number = strtol(yytext, NULL, 10);
176			return number;
177		}
178([0][0-7]+)	{
179			yylval.number = strtol(yytext + 1, NULL, 8);
180			return number;
181		}
182[a-zA-Z_][a-zA-Z0-9_]+ {
183			yylval.label = strdup(yytext);
184			return label;
185		}
186
187"/*"([^\*]|\*[^/])*"*/"		{ /* NOP */ }
188";"[^\n]*			{ /* NOP */ }
189^#.*				{ /* NOP */ }
190[ \t]+				{ /* NOP */ }
191[ \n]+				{ /* NOP */ }
192
193.		{
194			printf("unknown character \'%s\'", yytext);
195			yyerror("lex unknown character");
196		}
197
198%%
199