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