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 
32 extern 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