Add syntax to generate ARP header fields:

    { arp(op=req, sip=1.1.1.1, smac=11:22:33:44:55:66) }
    { arp() }

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

diff --git a/trafgen_lexer.l b/trafgen_lexer.l
index 670b5dc..9bbd982 100644
--- a/trafgen_lexer.l
+++ b/trafgen_lexer.l
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <stdbool.h>
+#include <arpa/inet.h>
 
 #include "trafgen_parser.tab.h"
 #include "xmalloc.h"
@@ -78,6 +79,7 @@ number_ascii  ([a-zA-Z])
 
 mac_hex                ([a-fA-F0-9]+)
 mac            ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex})
+ip_addr                ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)
 
 %%
 
@@ -107,7 +109,16 @@ mac                
({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex})
 "saddr"|"sa"   { return F_SADDR; }
 "prot"[o]?     { return F_PROT; }
 
+"sha"|"smac"   { return F_SHA; }
+"sta"|"sip"    { return F_SPA; }
+"tha"|"tmac"   { return F_THA; }
+"tpa"|"tip"    { return F_TPA; }
+"req"          { return F_REQ; }
+"resp"|"reply" { return F_RESP; }
+"op"           { return F_OPER; }
+
 "eth"          { return P_ETH; }
+"arp"          { return P_ARP; }
 
 [ ]*"-"[ ]*    { return '-'; }
 [ ]*"+"[ ]*    { return '+'; }
@@ -161,6 +172,10 @@ mac                
({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex})
                        panic("Failed to parse MAC addres %s\n", yytext);
                  return mac; }
 
+{ip_addr}      { if (inet_pton(AF_INET, yytext, &yylval.ip_addr) != 1)
+                       panic("Failed to parse IPv4 address %s\n", yytext);
+                 return ip_addr; };
+
 "'\\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 269cb13..185b4a8 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -17,6 +17,8 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <libgen.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
 
 #include "xmalloc.h"
 #include "trafgen_parser.tab.h"
@@ -337,6 +339,7 @@ static void proto_init(enum proto_id pid)
 %}
 
 %union {
+       struct in_addr ip_addr;
        long long int number;
        uint8_t bytes[256];
        char *str;
@@ -346,15 +349,19 @@ static void proto_init(enum proto_id pid)
 %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CSUMUDP6 K_CSUMTCP6 K_CONST8 
K_CONST16 K_CONST32 K_CONST64
 
 %token F_DADDR F_SADDR F_PROT
+%token F_OPER F_SHA F_SPA F_THA F_TPA F_REQ F_RESP
+
 %token P_ETH
+%token P_ARP
 
 %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
 
-%token number string mac
+%token number string mac ip_addr
 
 %type <number> number expression
 %type <str> string
 %type <bytes> mac
+%type <ip_addr> ip_addr
 
 %left '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
 
@@ -566,6 +573,7 @@ ddec
 
 proto
        : eth_proto { }
+       | arp_proto { }
        ;
 
 eth_proto
@@ -591,6 +599,34 @@ eth_field
                { proto_field_set_be16(PROTO_ETH, ETH_PROTO_ID, $5); }
        ;
 
+arp_proto
+       : arp '(' arp_param_list ')' { }
+       ;
+
+arp_param_list
+       : { }
+       | arp_field { }
+       | arp_field delimiter arp_param_list { }
+       ;
+
+arp_field
+       : F_OPER  skip_white '=' skip_white F_REQ
+               { proto_field_set_be16(PROTO_ARP, ARP_OPER, ARPOP_REQUEST); }
+       | F_OPER  skip_white '=' skip_white F_RESP
+               { proto_field_set_be16(PROTO_ARP, ARP_OPER, ARPOP_REPLY); }
+       | F_SHA skip_white '=' skip_white mac
+               { proto_field_set_bytes(PROTO_ARP, ARP_SHA, $5); }
+       | F_THA skip_white '=' skip_white mac
+               { proto_field_set_bytes(PROTO_ARP, ARP_THA, $5); }
+       | F_SPA skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(PROTO_ARP, ARP_SPA, $5.s_addr); }
+       | F_TPA skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(PROTO_ARP, ARP_TPA, $5.s_addr); }
+       ;
+arp
+       : P_ARP { proto_init(PROTO_ARP); }
+       ;
+
 %%
 
 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