1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * BPF asm code lexer 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This program is free software; you can distribute it and/or modify 5*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published 6*4882a593Smuzhiyun * by the Free Software Foundation; either version 2 of the License, 7*4882a593Smuzhiyun * or (at your option) any later version. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Syntax kept close to: 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new 12*4882a593Smuzhiyun * architecture for user-level packet capture. In Proceedings of the 13*4882a593Smuzhiyun * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 14*4882a593Smuzhiyun * Conference Proceedings (USENIX'93). USENIX Association, Berkeley, 15*4882a593Smuzhiyun * CA, USA, 2-2. 16*4882a593Smuzhiyun * 17*4882a593Smuzhiyun * Copyright 2013 Daniel Borkmann <borkmann@redhat.com> 18*4882a593Smuzhiyun * Licensed under the GNU General Public License, version 2.0 (GPLv2) 19*4882a593Smuzhiyun */ 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun %{ 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #include <stdio.h> 24*4882a593Smuzhiyun #include <stdint.h> 25*4882a593Smuzhiyun #include <stdlib.h> 26*4882a593Smuzhiyun #include <string.h> 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #include <linux/filter.h> 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun #include "bpf_exp.yacc.h" 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun extern void yyerror(const char *str); 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun %} 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun %option align 37*4882a593Smuzhiyun %option ecs 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun %option nounput 40*4882a593Smuzhiyun %option noreject 41*4882a593Smuzhiyun %option noinput 42*4882a593Smuzhiyun %option noyywrap 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun %option 8bit 45*4882a593Smuzhiyun %option caseless 46*4882a593Smuzhiyun %option yylineno 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun %% 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun "ldb" { return OP_LDB; } 51*4882a593Smuzhiyun "ldh" { return OP_LDH; } 52*4882a593Smuzhiyun "ld" { return OP_LD; } 53*4882a593Smuzhiyun "ldi" { return OP_LDI; } 54*4882a593Smuzhiyun "ldx" { return OP_LDX; } 55*4882a593Smuzhiyun "ldxi" { return OP_LDXI; } 56*4882a593Smuzhiyun "ldxb" { return OP_LDXB; } 57*4882a593Smuzhiyun "st" { return OP_ST; } 58*4882a593Smuzhiyun "stx" { return OP_STX; } 59*4882a593Smuzhiyun "jmp" { return OP_JMP; } 60*4882a593Smuzhiyun "ja" { return OP_JMP; } 61*4882a593Smuzhiyun "jeq" { return OP_JEQ; } 62*4882a593Smuzhiyun "jneq" { return OP_JNEQ; } 63*4882a593Smuzhiyun "jne" { return OP_JNEQ; } 64*4882a593Smuzhiyun "jlt" { return OP_JLT; } 65*4882a593Smuzhiyun "jle" { return OP_JLE; } 66*4882a593Smuzhiyun "jgt" { return OP_JGT; } 67*4882a593Smuzhiyun "jge" { return OP_JGE; } 68*4882a593Smuzhiyun "jset" { return OP_JSET; } 69*4882a593Smuzhiyun "add" { return OP_ADD; } 70*4882a593Smuzhiyun "sub" { return OP_SUB; } 71*4882a593Smuzhiyun "mul" { return OP_MUL; } 72*4882a593Smuzhiyun "div" { return OP_DIV; } 73*4882a593Smuzhiyun "mod" { return OP_MOD; } 74*4882a593Smuzhiyun "neg" { return OP_NEG; } 75*4882a593Smuzhiyun "and" { return OP_AND; } 76*4882a593Smuzhiyun "xor" { return OP_XOR; } 77*4882a593Smuzhiyun "or" { return OP_OR; } 78*4882a593Smuzhiyun "lsh" { return OP_LSH; } 79*4882a593Smuzhiyun "rsh" { return OP_RSH; } 80*4882a593Smuzhiyun "ret" { return OP_RET; } 81*4882a593Smuzhiyun "tax" { return OP_TAX; } 82*4882a593Smuzhiyun "txa" { return OP_TXA; } 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun "#"?("len") { return K_PKT_LEN; } 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun "#"?("proto") { 87*4882a593Smuzhiyun yylval.number = SKF_AD_PROTOCOL; 88*4882a593Smuzhiyun return extension; 89*4882a593Smuzhiyun } 90*4882a593Smuzhiyun "#"?("type") { 91*4882a593Smuzhiyun yylval.number = SKF_AD_PKTTYPE; 92*4882a593Smuzhiyun return extension; 93*4882a593Smuzhiyun } 94*4882a593Smuzhiyun "#"?("poff") { 95*4882a593Smuzhiyun yylval.number = SKF_AD_PAY_OFFSET; 96*4882a593Smuzhiyun return extension; 97*4882a593Smuzhiyun } 98*4882a593Smuzhiyun "#"?("ifidx") { 99*4882a593Smuzhiyun yylval.number = SKF_AD_IFINDEX; 100*4882a593Smuzhiyun return extension; 101*4882a593Smuzhiyun } 102*4882a593Smuzhiyun "#"?("nla") { 103*4882a593Smuzhiyun yylval.number = SKF_AD_NLATTR; 104*4882a593Smuzhiyun return extension; 105*4882a593Smuzhiyun } 106*4882a593Smuzhiyun "#"?("nlan") { 107*4882a593Smuzhiyun yylval.number = SKF_AD_NLATTR_NEST; 108*4882a593Smuzhiyun return extension; 109*4882a593Smuzhiyun } 110*4882a593Smuzhiyun "#"?("mark") { 111*4882a593Smuzhiyun yylval.number = SKF_AD_MARK; 112*4882a593Smuzhiyun return extension; 113*4882a593Smuzhiyun } 114*4882a593Smuzhiyun "#"?("queue") { 115*4882a593Smuzhiyun yylval.number = SKF_AD_QUEUE; 116*4882a593Smuzhiyun return extension; 117*4882a593Smuzhiyun } 118*4882a593Smuzhiyun "#"?("hatype") { 119*4882a593Smuzhiyun yylval.number = SKF_AD_HATYPE; 120*4882a593Smuzhiyun return extension; 121*4882a593Smuzhiyun } 122*4882a593Smuzhiyun "#"?("rxhash") { 123*4882a593Smuzhiyun yylval.number = SKF_AD_RXHASH; 124*4882a593Smuzhiyun return extension; 125*4882a593Smuzhiyun } 126*4882a593Smuzhiyun "#"?("cpu") { 127*4882a593Smuzhiyun yylval.number = SKF_AD_CPU; 128*4882a593Smuzhiyun return extension; 129*4882a593Smuzhiyun } 130*4882a593Smuzhiyun "#"?("vlan_tci") { 131*4882a593Smuzhiyun yylval.number = SKF_AD_VLAN_TAG; 132*4882a593Smuzhiyun return extension; 133*4882a593Smuzhiyun } 134*4882a593Smuzhiyun "#"?("vlan_pr") { 135*4882a593Smuzhiyun yylval.number = SKF_AD_VLAN_TAG_PRESENT; 136*4882a593Smuzhiyun return extension; 137*4882a593Smuzhiyun } 138*4882a593Smuzhiyun "#"?("vlan_avail") { 139*4882a593Smuzhiyun yylval.number = SKF_AD_VLAN_TAG_PRESENT; 140*4882a593Smuzhiyun return extension; 141*4882a593Smuzhiyun } 142*4882a593Smuzhiyun "#"?("vlan_tpid") { 143*4882a593Smuzhiyun yylval.number = SKF_AD_VLAN_TPID; 144*4882a593Smuzhiyun return extension; 145*4882a593Smuzhiyun } 146*4882a593Smuzhiyun "#"?("rand") { 147*4882a593Smuzhiyun yylval.number = SKF_AD_RANDOM; 148*4882a593Smuzhiyun return extension; 149*4882a593Smuzhiyun } 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun ":" { return ':'; } 152*4882a593Smuzhiyun "," { return ','; } 153*4882a593Smuzhiyun "#" { return '#'; } 154*4882a593Smuzhiyun "%" { return '%'; } 155*4882a593Smuzhiyun "[" { return '['; } 156*4882a593Smuzhiyun "]" { return ']'; } 157*4882a593Smuzhiyun "(" { return '('; } 158*4882a593Smuzhiyun ")" { return ')'; } 159*4882a593Smuzhiyun "x" { return 'x'; } 160*4882a593Smuzhiyun "a" { return 'a'; } 161*4882a593Smuzhiyun "+" { return '+'; } 162*4882a593Smuzhiyun "M" { return 'M'; } 163*4882a593Smuzhiyun "*" { return '*'; } 164*4882a593Smuzhiyun "&" { return '&'; } 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun ([0][x][a-fA-F0-9]+) { 167*4882a593Smuzhiyun yylval.number = strtoul(yytext, NULL, 16); 168*4882a593Smuzhiyun return number; 169*4882a593Smuzhiyun } 170*4882a593Smuzhiyun ([0][b][0-1]+) { 171*4882a593Smuzhiyun yylval.number = strtol(yytext + 2, NULL, 2); 172*4882a593Smuzhiyun return number; 173*4882a593Smuzhiyun } 174*4882a593Smuzhiyun (([0])|([-+]?[1-9][0-9]*)) { 175*4882a593Smuzhiyun yylval.number = strtol(yytext, NULL, 10); 176*4882a593Smuzhiyun return number; 177*4882a593Smuzhiyun } 178*4882a593Smuzhiyun ([0][0-7]+) { 179*4882a593Smuzhiyun yylval.number = strtol(yytext + 1, NULL, 8); 180*4882a593Smuzhiyun return number; 181*4882a593Smuzhiyun } 182*4882a593Smuzhiyun [a-zA-Z_][a-zA-Z0-9_]+ { 183*4882a593Smuzhiyun yylval.label = strdup(yytext); 184*4882a593Smuzhiyun return label; 185*4882a593Smuzhiyun } 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun "/*"([^\*]|\*[^/])*"*/" { /* NOP */ } 188*4882a593Smuzhiyun ";"[^\n]* { /* NOP */ } 189*4882a593Smuzhiyun ^#.* { /* NOP */ } 190*4882a593Smuzhiyun [ \t]+ { /* NOP */ } 191*4882a593Smuzhiyun [ \n]+ { /* NOP */ } 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun . { 194*4882a593Smuzhiyun printf("unknown character \'%s\'", yytext); 195*4882a593Smuzhiyun yyerror("lex unknown character"); 196*4882a593Smuzhiyun } 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun %% 199