|  | /* | 
|  | * 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"); | 
|  | } | 
|  |  | 
|  | %% |