blob: bd83149e7be04c3968f9e60d730aca4b1c40b331 [file] [log] [blame]
Daniel Borkmann3f356382013-12-11 23:43:44 +01001/*
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>
Ray Bellisb1d95ae2016-02-22 11:02:40 +010026#include <string.h>
27
28#include <linux/filter.h>
Daniel Borkmann3f356382013-12-11 23:43:44 +010029
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; }
Ray Bellisb1d95ae2016-02-22 11:02:40 +010085
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 }
Daniel Borkmann3f356382013-12-11 23:43:44 +0100150
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-9]+) {
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%%