0001 /*
0002 * BPF asm code lexer
0003 *
0004 * This program is free software; you can distribute it and/or modify
0005 * it under the terms of the GNU General Public License as published
0006 * by the Free Software Foundation; either version 2 of the License,
0007 * or (at your option) any later version.
0008 *
0009 * Syntax kept close to:
0010 *
0011 * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new
0012 * architecture for user-level packet capture. In Proceedings of the
0013 * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993
0014 * Conference Proceedings (USENIX'93). USENIX Association, Berkeley,
0015 * CA, USA, 2-2.
0016 *
0017 * Copyright 2013 Daniel Borkmann <borkmann@redhat.com>
0018 * Licensed under the GNU General Public License, version 2.0 (GPLv2)
0019 */
0020
0021 %{
0022
0023 #include <stdio.h>
0024 #include <stdint.h>
0025 #include <stdlib.h>
0026 #include <string.h>
0027
0028 #include <linux/filter.h>
0029
0030 #include "bpf_exp.yacc.h"
0031
0032 extern void yyerror(const char *str);
0033
0034 %}
0035
0036 %option align
0037 %option ecs
0038
0039 %option nounput
0040 %option noreject
0041 %option noinput
0042 %option noyywrap
0043
0044 %option 8bit
0045 %option caseless
0046 %option yylineno
0047
0048 %%
0049
0050 "ldb" { return OP_LDB; }
0051 "ldh" { return OP_LDH; }
0052 "ld" { return OP_LD; }
0053 "ldi" { return OP_LDI; }
0054 "ldx" { return OP_LDX; }
0055 "ldxi" { return OP_LDXI; }
0056 "ldxb" { return OP_LDXB; }
0057 "st" { return OP_ST; }
0058 "stx" { return OP_STX; }
0059 "jmp" { return OP_JMP; }
0060 "ja" { return OP_JMP; }
0061 "jeq" { return OP_JEQ; }
0062 "jneq" { return OP_JNEQ; }
0063 "jne" { return OP_JNEQ; }
0064 "jlt" { return OP_JLT; }
0065 "jle" { return OP_JLE; }
0066 "jgt" { return OP_JGT; }
0067 "jge" { return OP_JGE; }
0068 "jset" { return OP_JSET; }
0069 "add" { return OP_ADD; }
0070 "sub" { return OP_SUB; }
0071 "mul" { return OP_MUL; }
0072 "div" { return OP_DIV; }
0073 "mod" { return OP_MOD; }
0074 "neg" { return OP_NEG; }
0075 "and" { return OP_AND; }
0076 "xor" { return OP_XOR; }
0077 "or" { return OP_OR; }
0078 "lsh" { return OP_LSH; }
0079 "rsh" { return OP_RSH; }
0080 "ret" { return OP_RET; }
0081 "tax" { return OP_TAX; }
0082 "txa" { return OP_TXA; }
0083
0084 "#"?("len") { return K_PKT_LEN; }
0085
0086 "#"?("proto") {
0087 yylval.number = SKF_AD_PROTOCOL;
0088 return extension;
0089 }
0090 "#"?("type") {
0091 yylval.number = SKF_AD_PKTTYPE;
0092 return extension;
0093 }
0094 "#"?("poff") {
0095 yylval.number = SKF_AD_PAY_OFFSET;
0096 return extension;
0097 }
0098 "#"?("ifidx") {
0099 yylval.number = SKF_AD_IFINDEX;
0100 return extension;
0101 }
0102 "#"?("nla") {
0103 yylval.number = SKF_AD_NLATTR;
0104 return extension;
0105 }
0106 "#"?("nlan") {
0107 yylval.number = SKF_AD_NLATTR_NEST;
0108 return extension;
0109 }
0110 "#"?("mark") {
0111 yylval.number = SKF_AD_MARK;
0112 return extension;
0113 }
0114 "#"?("queue") {
0115 yylval.number = SKF_AD_QUEUE;
0116 return extension;
0117 }
0118 "#"?("hatype") {
0119 yylval.number = SKF_AD_HATYPE;
0120 return extension;
0121 }
0122 "#"?("rxhash") {
0123 yylval.number = SKF_AD_RXHASH;
0124 return extension;
0125 }
0126 "#"?("cpu") {
0127 yylval.number = SKF_AD_CPU;
0128 return extension;
0129 }
0130 "#"?("vlan_tci") {
0131 yylval.number = SKF_AD_VLAN_TAG;
0132 return extension;
0133 }
0134 "#"?("vlan_pr") {
0135 yylval.number = SKF_AD_VLAN_TAG_PRESENT;
0136 return extension;
0137 }
0138 "#"?("vlan_avail") {
0139 yylval.number = SKF_AD_VLAN_TAG_PRESENT;
0140 return extension;
0141 }
0142 "#"?("vlan_tpid") {
0143 yylval.number = SKF_AD_VLAN_TPID;
0144 return extension;
0145 }
0146 "#"?("rand") {
0147 yylval.number = SKF_AD_RANDOM;
0148 return extension;
0149 }
0150
0151 ":" { return ':'; }
0152 "," { return ','; }
0153 "#" { return '#'; }
0154 "%" { return '%'; }
0155 "[" { return '['; }
0156 "]" { return ']'; }
0157 "(" { return '('; }
0158 ")" { return ')'; }
0159 "x" { return 'x'; }
0160 "a" { return 'a'; }
0161 "+" { return '+'; }
0162 "M" { return 'M'; }
0163 "*" { return '*'; }
0164 "&" { return '&'; }
0165
0166 ([0][x][a-fA-F0-9]+) {
0167 yylval.number = strtoul(yytext, NULL, 16);
0168 return number;
0169 }
0170 ([0][b][0-1]+) {
0171 yylval.number = strtol(yytext + 2, NULL, 2);
0172 return number;
0173 }
0174 (([0])|([-+]?[1-9][0-9]*)) {
0175 yylval.number = strtol(yytext, NULL, 10);
0176 return number;
0177 }
0178 ([0][0-7]+) {
0179 yylval.number = strtol(yytext + 1, NULL, 8);
0180 return number;
0181 }
0182 [a-zA-Z_][a-zA-Z0-9_]+ {
0183 yylval.label = strdup(yytext);
0184 return label;
0185 }
0186
0187 "/*"([^\*]|\*[^/])*"*/" { /* NOP */ }
0188 ";"[^\n]* { /* NOP */ }
0189 ^#.* { /* NOP */ }
0190 [ \t]+ { /* NOP */ }
0191 [ \n]+ { /* NOP */ }
0192
0193 . {
0194 printf("unknown character \'%s\'", yytext);
0195 yyerror("lex unknown character");
0196 }
0197
0198 %%