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