Craft packet direct from command line with same syntax as for conf file.
It might be as first step to extend current syntax with specific proto fields.

Signed-off-by: Vadim Kochan <[email protected]>
---
 trafgen.8        |  8 ++++++--
 trafgen.c        | 23 ++++++++++++++++++-----
 trafgen_conf.h   |  4 ++++
 trafgen_parser.y | 23 +++++++++++++++++++++++
 4 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/trafgen.8 b/trafgen.8
index 84ef518..71b55b1 100644
--- a/trafgen.8
+++ b/trafgen.8
@@ -7,7 +7,7 @@ trafgen \- a fast, multithreaded network packet generator
 .PP
 .SH SYNOPSIS
 .PP
-\fBtrafgen\fR [\fIoptions\fR]
+\fBtrafgen\fR [\fIoptions\fR] [\fIpacket\fR]
 .PP
 .SH DESCRIPTION
 .PP
@@ -189,7 +189,8 @@ Show user help and exit.
 .PP
 .SH SYNTAX
 .PP
-trafgen's packet configuration syntax is fairly simple. The very basic things
+trafgen's packet configuration syntax is fairly simple, it might be specified
+via command line or configuration file. The very basic things
 one needs to know is that a configuration file is a simple plain text file
 where packets are defined. It can contain one or more packets. Packets are
 enclosed by opening '{' and closing '}' braces, for example:
@@ -397,6 +398,9 @@ Send out packets generated from the configuration file 
''tcp_syn.cfg'' via
 the ''eth0'' networking device. After setting up the ring for transmission,
 drop credentials to the non-root user/group bob/bob.
 .PP
+.SS trafgen --dev eth0 '{ fill(0xff, 6), 0x00, 0x02, 0xb3, rnd(3), 
c16(0x0800), fill(0xca, 64) }' -n 1
+Send out 1 invaid IPv4 packet built from command line to all hosts.
+.PP
 .SH NOTE
 .PP
 trafgen can saturate a Gigabit Ethernet link without problems. As always,
diff --git a/trafgen.c b/trafgen.c
index 1da1897..b38c2f6 100644
--- a/trafgen.c
+++ b/trafgen.c
@@ -64,6 +64,7 @@ struct ctx {
        char *device, *device_trans, *rhost;
        struct timespec gap;
        struct sockaddr_in dest;
+       char *packet_str;
 };
 
 struct cpu_stats {
@@ -157,7 +158,7 @@ static void __noreturn help(void)
 {
        printf("trafgen %s, multithreaded zero-copy network packet 
generator\n", VERSION_STRING);
        puts("http://www.netsniff-ng.org\n\n";
-            "Usage: trafgen [options]\n"
+            "Usage: trafgen [options] [packet]\n"
             "Options:\n"
             "  -i|-c|--in|--conf <cfg/->      Packet configuration 
file/stdin\n"
             "  -o|-d|--out|--dev <netdev>     Networking device i.e., eth0\n"
@@ -189,7 +190,8 @@ static void __noreturn help(void)
             "  trafgen --dev wlan0 --rfraw --conf beacon-test.txf -V --cpus 
2\n"
             "  trafgen --dev eth0 --conf frag_dos.cfg --rand --gap 1000us\n"
             "  trafgen --dev eth0 --conf icmp.cfg --rand --num 1400000 
-k1000\n"
-            "  trafgen --dev eth0 --conf tcp_syn.cfg -u `id -u bob` -g `id -g 
bob`\n\n"
+            "  trafgen --dev eth0 --conf tcp_syn.cfg -u `id -u bob` -g `id -g 
bob`\n"
+            "  trafgen --dev eth0 '{ fill(0xff, 6), 0x00, 0x02, 0xb3, rnd(3), 
c16(0x0800), fill(0xca, 64) }'\n\n"
             "Arbitrary packet config examples (e.g. trafgen -e > 
trafgen.cfg):\n"
             "  Run packet on  all CPUs:              { fill(0xff, 64) 
csum16(0, 64) }\n"
             "  Run packet only on CPU1:    cpu(1):   { rnd(64), 0b11001100, 
0xaa }\n"
@@ -827,7 +829,11 @@ static void xmit_packet_precheck(struct ctx *ctx, unsigned 
int cpu)
 static void main_loop(struct ctx *ctx, char *confname, bool slow,
                      unsigned int cpu, bool invoke_cpp, unsigned long orig_num)
 {
-       compile_packets(confname, ctx->verbose, cpu, invoke_cpp);
+       if (ctx->packet_str)
+               compile_packets_str(ctx->packet_str, ctx->verbose, cpu);
+       else
+               compile_packets(confname, ctx->verbose, cpu, invoke_cpp);
+
        xmit_packet_precheck(ctx, cpu);
 
        if (cpu == 0) {
@@ -891,6 +897,7 @@ int main(int argc, char **argv)
        unsigned long cpus_tmp, orig_num = 0;
        unsigned long long tx_packets, tx_bytes;
        struct ctx ctx;
+       int min_opts = 5;
 
        fmemset(&ctx, 0, sizeof(ctx));
        ctx.cpus = get_number_cpus_online();
@@ -1067,11 +1074,16 @@ int main(int argc, char **argv)
                }
        }
 
-       if (argc < 5)
+       if (argc >= optind) {
+               min_opts = 4;
+               ctx.packet_str = cmdl2str(optind, argc, argv);
+       }
+
+       if (argc < min_opts)
                help();
        if (ctx.device == NULL)
                panic("No networking device given!\n");
-       if (confname == NULL)
+       if (confname == NULL && !ctx.packet_str)
                panic("No configuration file given!\n");
        if (device_mtu(ctx.device) == 0)
                panic("This is no networking device!\n");
@@ -1173,6 +1185,7 @@ thread_out:
        free(ctx.device_trans);
        free(ctx.rhost);
        free(confname);
+       free(ctx.packet_str);
 
        return 0;
 }
diff --git a/trafgen_conf.h b/trafgen_conf.h
index dddee8c..9bbdff5 100644
--- a/trafgen_conf.h
+++ b/trafgen_conf.h
@@ -5,6 +5,9 @@
 #include <stdio.h>
 #include <sys/types.h>
 
+void yy_scan_string(char *);
+void yylex_destroy();
+
 #define TYPE_INC       0
 #define TYPE_DEC       1
 
@@ -55,6 +58,7 @@ static inline bool packet_dyn_has_only_csums(struct 
packet_dyn *p)
        return (p->clen == 0 && p->rlen == 0 && p->slen);
 }
 
+extern void compile_packets_str(char *str, bool verbose, unsigned int cpu);
 extern void compile_packets(char *file, bool verbose, unsigned int cpu, bool 
invoke_cpp);
 extern void cleanup_packets(void);
 
diff --git a/trafgen_parser.y b/trafgen_parser.y
index 88daf7a..9d34242 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -641,6 +641,29 @@ err:
                die();
 }
 
+void compile_packets_str(char *str, bool verbose, unsigned int cpu)
+{
+       int ret = 1;
+
+       our_cpu = cpu;
+       realloc_packet();
+
+       yy_scan_string(str);
+       if (yyparse() != 0)
+               goto err;
+
+       finalize_packet();
+       if (our_cpu == 0 && verbose)
+               dump_conf();
+
+       ret = 0;
+err:
+       yylex_destroy();
+
+       if (ret)
+               die();
+}
+
 void yyerror(const char *err)
 {
        fprintf(stderr, "Syntax error at line %d, char '%s': %s\n", yylineno, 
yytext, err);
-- 
2.6.1

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to