Add syntax for generating Ethernet header fields like:

    { eth(prot=0x0800, da=11:22:33:44:55:66), fill(0xff, 60) }
    { eth(prot=0x0800) }
    { eth() }

It is important that proto_init is called before fields will be filled
to initialize the specified proto with header fields.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 trafgen_lexer.l  | 15 +++++++++++++++
 trafgen_parser.y | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/trafgen_lexer.l b/trafgen_lexer.l
index 6c27b0c..ac4fec1 100644
--- a/trafgen_lexer.l
+++ b/trafgen_lexer.l
@@ -19,6 +19,7 @@
 #include "trafgen_parser.tab.h"
 #include "xmalloc.h"
 #include "built_in.h"
+#include "str.h"
 
 extern void yyerror(const char *);
 
@@ -75,6 +76,9 @@ number_bin    ([0]?[b][0-1]+)
 number_dec     (([0])|([1-9][0-9]*))
 number_ascii   ([a-zA-Z])
 
+mac_hex                ([a-fA-F0-9]+)
+mac            ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex})
+
 %%
 
 "cpu"          { return K_CPU; }
@@ -99,6 +103,12 @@ number_ascii        ([a-zA-Z])
 "const32"|"c32"        { return K_CONST32; }
 "const64"|"c64"        { return K_CONST64; }
 
+"daddr"|"da"   { return K_DADDR; }
+"saddr"|"sa"   { return K_SADDR; }
+"prot"[o]?     { return K_PROT; }
+
+"eth"          { return K_ETH; }
+
 [ ]*"-"[ ]*    { return '-'; }
 [ ]*"+"[ ]*    { return '+'; }
 [ ]*"*"[ ]*    { return '*'; }
@@ -117,6 +127,7 @@ number_ascii        ([a-zA-Z])
 "]"            { return ']'; }
 ","            { return ','; }
 ":"            { return ':'; }
+"="            { return '='; }
 
 "\n"           { yylineno++; }
 
@@ -146,6 +157,10 @@ number_ascii       ([a-zA-Z])
 {number_ascii} { yylval.number = (uint8_t) (*yytext);
                  return number; }
 
+{mac}          { if (str2mac(yytext, yylval.bytes))
+                       panic("Failed to parse MAC addres %s\n", yytext);
+                 return mac; }
+
 "'\\x"[a-fA-F0-9]{2}"'" { yylval.number = strtol(yytext + 3, NULL, 16);
                  return number; }
 
diff --git a/trafgen_parser.y b/trafgen_parser.y
index 4725f7c..df1b1a6 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -21,6 +21,8 @@
 #include "xmalloc.h"
 #include "trafgen_parser.tab.h"
 #include "trafgen_conf.h"
+#include "trafgen_proto.h"
+#include "trafgen_l2.h"
 #include "built_in.h"
 #include "die.h"
 #include "str.h"
@@ -59,6 +61,8 @@ extern size_t dlen;
 
 static int our_cpu, min_cpu = -1, max_cpu = -1;
 
+static struct proto_hdr *hdr;
+
 static inline int test_ignore(void)
 {
        if (min_cpu < 0 && max_cpu < 0)
@@ -324,22 +328,33 @@ static void set_dynamic_incdec(uint8_t start, uint8_t 
stop, uint8_t stepping,
        __setup_new_counter(&pktd->cnt[packetdc_last], start, stop, stepping, 
type);
 }
 
+static void proto_add(enum proto_id pid)
+{
+       proto_header_init(pid);
+       hdr = proto_current_header();
+}
+
 %}
 
 %union {
        long long int number;
+       uint8_t bytes[256];
        char *str;
 }
 
 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
 %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CSUMUDP6 K_CSUMTCP6 K_CONST8 
K_CONST16 K_CONST32 K_CONST64
 
+%token K_DADDR K_SADDR K_PROT
+%token K_ETH
+
 %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
 
-%token number string
+%token number string mac
 
 %type <number> number expression
 %type <str> string
+%type <bytes> mac
 
 %left '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
 
@@ -372,9 +387,16 @@ noenforce_white
        | delimiter_nowhite { }
        ;
 
+skip_white
+       : { }
+       | K_WHITE { }
+       ;
 packet
        : '{' noenforce_white payload noenforce_white '}' {
                        min_cpu = max_cpu = -1;
+
+                       proto_packet_finish();
+
                        realloc_packet();
                }
        | K_CPU '(' number cpu_delim number ')' ':' noenforce_white '{' 
noenforce_white payload noenforce_white '}' {
@@ -388,10 +410,15 @@ packet
                                max_cpu = tmp;
                        }
 
+                       proto_packet_finish();
+
                        realloc_packet();
                }
        | K_CPU '(' number ')' ':' noenforce_white '{' noenforce_white payload 
noenforce_white '}' {
                        min_cpu = max_cpu = $3;
+
+                       proto_packet_finish();
+
                        realloc_packet();
                }
        ;
@@ -422,6 +449,7 @@ elem
        | ddec { }
        | csum { }
        | const { }
+       | proto { proto_header_finish(hdr); }
        | inline_comment { }
        ;
 
@@ -536,6 +564,33 @@ ddec
                { set_dynamic_incdec($3, $5, $7, TYPE_DEC); }
        ;
 
+proto
+       : eth_proto { }
+       ;
+
+eth_proto
+       : eth '(' eth_param_list ')' { }
+       ;
+
+eth
+       : K_ETH { proto_add(PROTO_ETH); }
+       ;
+
+eth_param_list
+       : { }
+       | eth_field { }
+       | eth_field delimiter eth_param_list { }
+       ;
+
+eth_field
+       : K_DADDR  skip_white '=' skip_white mac
+               { proto_field_set_bytes(hdr, ETH_DST_ADDR, $5); }
+       | K_SADDR  skip_white '=' skip_white mac
+               { proto_field_set_bytes(hdr, ETH_SRC_ADDR, $5); }
+       | K_PROT skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, ETH_PROTO_ID, $5); }
+       ;
+
 %%
 
 static void finalize_packet(void)
-- 
2.6.3

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to