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  | 17 +++++++++++++++++
 trafgen_parser.y | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/trafgen_lexer.l b/trafgen_lexer.l
index ac4fec1..7db0d5a 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,18 @@ mac                
({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex})
 "saddr"|"sa"   { return K_SADDR; }
 "prot"[o]?     { return K_PROT; }
 
+"sha"|"smac"   { return K_SHA; }
+"spa"|"sip"    { return K_SPA; }
+"tha"|"tmac"   { return K_THA; }
+"tpa"|"tip"    { return K_TPA; }
+"req"|"request"        { return K_REQUEST; }
+"reply"                { return K_REPLY; }
+"op"|"oper"    { return K_OPER; }
+"htype"                { return K_HTYPE; }
+"ptype"                { return K_PTYPE; }
+
 "eth"          { return K_ETH; }
+"arp"          { return K_ARP; }
 
 [ ]*"-"[ ]*    { return '-'; }
 [ ]*"+"[ ]*    { return '+'; }
@@ -161,6 +174,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 df1b1a6..16f9025 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_add(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_add(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 K_DADDR K_SADDR K_PROT
+%token K_OPER K_SHA K_SPA K_THA K_TPA K_REQUEST K_REPLY K_PTYPE K_HTYPE
+
 %token K_ETH
+%token K_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,44 @@ eth_field
                { proto_field_set_be16(hdr, ETH_PROTO_ID, $5); }
        ;
 
+arp_proto
+       : arp '(' arp_param_list ')' { }
+       ;
+
+arp_param_list
+       : { }
+       | arp_field { }
+       | arp_field delimiter arp_param_list { }
+       ;
+
+arp_field
+       : K_OPER  skip_white '=' skip_white K_REQUEST
+               { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); }
+       | K_OPER  skip_white '=' skip_white K_REPLY
+               { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); }
+       | K_OPER skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, ARP_OPER, $5); }
+       | K_REQUEST
+               { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); }
+       | K_REPLY
+               { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); }
+       | K_HTYPE skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, ARP_HTYPE, $5); }
+       | K_PTYPE skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, ARP_PTYPE, $5); }
+       | K_SHA skip_white '=' skip_white mac
+               { proto_field_set_bytes(hdr, ARP_SHA, $5); }
+       | K_THA skip_white '=' skip_white mac
+               { proto_field_set_bytes(hdr, ARP_THA, $5); }
+       | K_SPA skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(hdr, ARP_SPA, $5.s_addr); }
+       | K_TPA skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(hdr, ARP_TPA, $5.s_addr); }
+       ;
+arp
+       : K_ARP { proto_add(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