On Sat, Nov 07, 2015 at 04:55:16PM +0200, Vadim Kochan wrote:
> 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
> 

If you conceptually agree with this idea, I probably may re-work series
and add separate '-p, --pkt' option for the specify packet language from
command line, or additionally send this as separate patch.

-- 
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