199 lines
4.0 KiB
Plaintext
199 lines
4.0 KiB
Plaintext
|
/*
|
||
|
* BPF asm code lexer
|
||
|
*
|
||
|
* This program is free software; you can distribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published
|
||
|
* by the Free Software Foundation; either version 2 of the License,
|
||
|
* or (at your option) any later version.
|
||
|
*
|
||
|
* Syntax kept close to:
|
||
|
*
|
||
|
* Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new
|
||
|
* architecture for user-level packet capture. In Proceedings of the
|
||
|
* USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993
|
||
|
* Conference Proceedings (USENIX'93). USENIX Association, Berkeley,
|
||
|
* CA, USA, 2-2.
|
||
|
*
|
||
|
* Copyright 2013 Daniel Borkmann <borkmann@redhat.com>
|
||
|
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
|
||
|
*/
|
||
|
|
||
|
%{
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdint.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <linux/filter.h>
|
||
|
|
||
|
#include "bpf_exp.yacc.h"
|
||
|
|
||
|
extern void yyerror(const char *str);
|
||
|
|
||
|
%}
|
||
|
|
||
|
%option align
|
||
|
%option ecs
|
||
|
|
||
|
%option nounput
|
||
|
%option noreject
|
||
|
%option noinput
|
||
|
%option noyywrap
|
||
|
|
||
|
%option 8bit
|
||
|
%option caseless
|
||
|
%option yylineno
|
||
|
|
||
|
%%
|
||
|
|
||
|
"ldb" { return OP_LDB; }
|
||
|
"ldh" { return OP_LDH; }
|
||
|
"ld" { return OP_LD; }
|
||
|
"ldi" { return OP_LDI; }
|
||
|
"ldx" { return OP_LDX; }
|
||
|
"ldxi" { return OP_LDXI; }
|
||
|
"ldxb" { return OP_LDXB; }
|
||
|
"st" { return OP_ST; }
|
||
|
"stx" { return OP_STX; }
|
||
|
"jmp" { return OP_JMP; }
|
||
|
"ja" { return OP_JMP; }
|
||
|
"jeq" { return OP_JEQ; }
|
||
|
"jneq" { return OP_JNEQ; }
|
||
|
"jne" { return OP_JNEQ; }
|
||
|
"jlt" { return OP_JLT; }
|
||
|
"jle" { return OP_JLE; }
|
||
|
"jgt" { return OP_JGT; }
|
||
|
"jge" { return OP_JGE; }
|
||
|
"jset" { return OP_JSET; }
|
||
|
"add" { return OP_ADD; }
|
||
|
"sub" { return OP_SUB; }
|
||
|
"mul" { return OP_MUL; }
|
||
|
"div" { return OP_DIV; }
|
||
|
"mod" { return OP_MOD; }
|
||
|
"neg" { return OP_NEG; }
|
||
|
"and" { return OP_AND; }
|
||
|
"xor" { return OP_XOR; }
|
||
|
"or" { return OP_OR; }
|
||
|
"lsh" { return OP_LSH; }
|
||
|
"rsh" { return OP_RSH; }
|
||
|
"ret" { return OP_RET; }
|
||
|
"tax" { return OP_TAX; }
|
||
|
"txa" { return OP_TXA; }
|
||
|
|
||
|
"#"?("len") { return K_PKT_LEN; }
|
||
|
|
||
|
"#"?("proto") {
|
||
|
yylval.number = SKF_AD_PROTOCOL;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("type") {
|
||
|
yylval.number = SKF_AD_PKTTYPE;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("poff") {
|
||
|
yylval.number = SKF_AD_PAY_OFFSET;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("ifidx") {
|
||
|
yylval.number = SKF_AD_IFINDEX;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("nla") {
|
||
|
yylval.number = SKF_AD_NLATTR;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("nlan") {
|
||
|
yylval.number = SKF_AD_NLATTR_NEST;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("mark") {
|
||
|
yylval.number = SKF_AD_MARK;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("queue") {
|
||
|
yylval.number = SKF_AD_QUEUE;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("hatype") {
|
||
|
yylval.number = SKF_AD_HATYPE;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("rxhash") {
|
||
|
yylval.number = SKF_AD_RXHASH;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("cpu") {
|
||
|
yylval.number = SKF_AD_CPU;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("vlan_tci") {
|
||
|
yylval.number = SKF_AD_VLAN_TAG;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("vlan_pr") {
|
||
|
yylval.number = SKF_AD_VLAN_TAG_PRESENT;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("vlan_avail") {
|
||
|
yylval.number = SKF_AD_VLAN_TAG_PRESENT;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("vlan_tpid") {
|
||
|
yylval.number = SKF_AD_VLAN_TPID;
|
||
|
return extension;
|
||
|
}
|
||
|
"#"?("rand") {
|
||
|
yylval.number = SKF_AD_RANDOM;
|
||
|
return extension;
|
||
|
}
|
||
|
|
||
|
":" { return ':'; }
|
||
|
"," { return ','; }
|
||
|
"#" { return '#'; }
|
||
|
"%" { return '%'; }
|
||
|
"[" { return '['; }
|
||
|
"]" { return ']'; }
|
||
|
"(" { return '('; }
|
||
|
")" { return ')'; }
|
||
|
"x" { return 'x'; }
|
||
|
"a" { return 'a'; }
|
||
|
"+" { return '+'; }
|
||
|
"M" { return 'M'; }
|
||
|
"*" { return '*'; }
|
||
|
"&" { return '&'; }
|
||
|
|
||
|
([0][x][a-fA-F0-9]+) {
|
||
|
yylval.number = strtoul(yytext, NULL, 16);
|
||
|
return number;
|
||
|
}
|
||
|
([0][b][0-1]+) {
|
||
|
yylval.number = strtol(yytext + 2, NULL, 2);
|
||
|
return number;
|
||
|
}
|
||
|
(([0])|([-+]?[1-9][0-9]*)) {
|
||
|
yylval.number = strtol(yytext, NULL, 10);
|
||
|
return number;
|
||
|
}
|
||
|
([0][0-7]+) {
|
||
|
yylval.number = strtol(yytext + 1, NULL, 8);
|
||
|
return number;
|
||
|
}
|
||
|
[a-zA-Z_][a-zA-Z0-9_]+ {
|
||
|
yylval.label = strdup(yytext);
|
||
|
return label;
|
||
|
}
|
||
|
|
||
|
"/*"([^\*]|\*[^/])*"*/" { /* NOP */ }
|
||
|
";"[^\n]* { /* NOP */ }
|
||
|
^#.* { /* NOP */ }
|
||
|
[ \t]+ { /* NOP */ }
|
||
|
[ \n]+ { /* NOP */ }
|
||
|
|
||
|
. {
|
||
|
printf("unknown character \'%s\'", yytext);
|
||
|
yyerror("lex unknown character");
|
||
|
}
|
||
|
|
||
|
%%
|