Add 'ip4(), ipv4()' function to build IPv4 header.

Fields supported:

        ihl             IPv4 header length (default 5 )
        ver|version     IPv4 version (default 4)
        ttl             Time To Live (TTL) field (default 0)
        dscp            DiffServ field (default 0)
        ecn             ECN bits (default 0)
        tos             TOS (DSCP + ECN) field (default 0)
        len|length      IPv4 header + payload length (calculated by default)
        id              Identifier (default 0)
        flags           Flags field (default 0)
        frag            Fragment offset (default 0)
        csum            IPv4 header checksum (calculated by default)
        df              Set DF (Dont Fragment) bit to 1 (default is 0)
        mf              Set MF (More Fragments) bit to 1 (default is 0)
        sa|saddr        IPv4 source address (default used from output device)
        da|daddr        IPv4 destination address (default 0.0.0.0)
        proto           IPv4 protocol id (default 0)

Example:

    { ip4(df, mf, frag=100, prot=0x1, ecn=2, dscp=20) }
    { ip4(da=1.1.1.1), ip4(sa=3.3.3.3, da=3.3.3.4) }

Last example generates IP-in-IP packet.

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

diff --git a/trafgen_lexer.l b/trafgen_lexer.l
index 5467c70..eeb252f 100644
--- a/trafgen_lexer.l
+++ b/trafgen_lexer.l
@@ -119,8 +119,23 @@ ip_addr            ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)
 "htype"                { return K_HTYPE; }
 "ptype"                { return K_PTYPE; }
 
+"ihl"          { return K_IHL; }
+"ver"|"version"        { return K_VER; }
+"ttl"          { return K_TTL; }
+"dscp"         { return K_DSCP; }
+"ecn"          { return K_ECN; }
+"tos"          { return K_TOS; }
+"len"|"length" { return K_LEN; }
+"id"           { return K_ID; }
+"flags"                { return K_FLAGS; }
+"frag"         { return K_FRAG; }
+"csum"         { return K_CSUM; }
+"df"           { return K_DF; }
+"mf"           { return K_MF; }
+
 "eth"          { return K_ETH; }
 "arp"          { return K_ARP; }
+"ip4"|"ipv4"   { return K_IP4; }
 
 [ ]*"-"[ ]*    { return '-'; }
 [ ]*"+"[ ]*    { return '+'; }
diff --git a/trafgen_parser.y b/trafgen_parser.y
index 16f9025..ebc4054 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -25,6 +25,7 @@
 #include "trafgen_conf.h"
 #include "trafgen_proto.h"
 #include "trafgen_l2.h"
+#include "trafgen_l3.h"
 #include "built_in.h"
 #include "die.h"
 #include "str.h"
@@ -350,9 +351,11 @@ static void proto_add(enum proto_id pid)
 
 %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_TTL K_DSCP K_ECN K_TOS K_LEN K_ID K_FLAGS K_FRAG K_IHL K_VER K_CSUM 
K_DF K_MF
 
 %token K_ETH
 %token K_ARP
+%token K_IP4
 
 %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
 
@@ -574,6 +577,7 @@ ddec
 proto
        : eth_proto { }
        | arp_proto { }
+       | ip4_proto { }
        ;
 
 eth_proto
@@ -637,6 +641,53 @@ arp
        : K_ARP { proto_add(PROTO_ARP); }
        ;
 
+ip4_proto
+       : ip4 '(' ip4_param_list ')' { }
+       ;
+
+ip4_param_list
+       : { }
+       | ip4_field { }
+       | ip4_field delimiter ip4_param_list { }
+       ;
+
+ip4_field
+       : K_VER skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_VER, $5); }
+       | K_IHL skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_IHL, $5); }
+       | K_DADDR  skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(hdr, IP4_DADDR, $5.s_addr); }
+       | K_SADDR  skip_white '=' skip_white ip_addr
+               { proto_field_set_u32(hdr, IP4_SADDR, $5.s_addr); }
+       | K_PROT skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_PROTO, $5); }
+       | K_TTL skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_TTL, $5); }
+       | K_DSCP skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_DSCP, $5); }
+       | K_ECN skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_ECN, $5); }
+       | K_TOS skip_white '=' skip_white number
+               { proto_field_set_u8(hdr, IP4_TOS, $5); }
+       | K_LEN skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, IP4_LEN, $5); }
+       | K_ID skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, IP4_ID, $5); }
+       | K_FLAGS skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, IP4_FLAGS, $5); }
+       | K_DF  { proto_field_set_be16(hdr, IP4_DF, 1); }
+       | K_MF  { proto_field_set_be16(hdr, IP4_MF, 1); }
+       | K_FRAG skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, IP4_FRAG_OFFS, $5); }
+       | K_CSUM skip_white '=' skip_white number
+               { proto_field_set_be16(hdr, IP4_CSUM, $5); }
+       ;
+
+ip4
+       : K_IP4 { proto_add(PROTO_IP4); }
+       ;
+
 %%
 
 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