| /* |
| * 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-9]+) { |
| 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"); |
| } |
| |
| %% |