1TRAFGEN(8)                    netsniff-ng toolkit                   TRAFGEN(8)
2
3
4

NAME

6       trafgen - a fast, multithreaded network packet generator
7

SYNOPSIS

9       trafgen [options]
10

DESCRIPTION

12       trafgen  is  a fast, zero-copy network traffic generator for debugging,
13       performance  evaluation,  and  fuzz-testing.   trafgen   utilizes   the
14       packet(7)  socket  interface  of Linux which postpones complete control
15       over packet data and packet headers into the user space. It has a  pow‐
16       erful  packet configuration language, which is rather low-level and not
17       limited to particular protocols.  Thus, trafgen can be  used  for  many
18       purposes.  Its  only  limitation  is  that it cannot mimic full streams
19       resp. sessions. However, it is very useful for various  kinds  of  load
20       testing  in order to analyze and subsequently improve systems behaviour
21       under DoS attack scenarios, for instance.
22
23       trafgen is Linux specific, meaning there is no support for other  oper‐
24       ating  systems, same as netsniff-ng(8), thus we can keep the code foot‐
25       print quite minimal and to the point. trafgen makes  use  of  packet(7)
26       socket's  TX_RING  interface of the Linux kernel, which is a mmap(2)'ed
27       ring buffer shared between user and kernel space.
28
29       By default, trafgen starts as many processes as  available  CPUs,  pins
30       each  of  them to their respective CPU and sets up the ring buffer each
31       in their own process space after having compiled a list of  packets  to
32       transmit.  Thus,  this is likely the fastest one can get out of the box
33       in terms of transmission performance from user space, without having to
34       load unsupported or non-mainline third-party kernel modules. On Gigabit
35       Ethernet, trafgen has a comparable performance to pktgen, the  built-in
36       Linux kernel traffic generator, except that trafgen is more flexible in
37       terms of packet configuration possibilities.  On  10-Gigabit-per-second
38       Ethernet,  trafgen  might  be slower than pktgen due to the user/kernel
39       space overhead but still has a fairly high performance for out  of  the
40       box kernels.
41
42       trafgen has the potential to do fuzz testing, meaning a packet configu‐
43       ration can be built with random numbers on all or certain  packet  off‐
44       sets  that are freshly generated each time a packet is sent out. With a
45       built-in IPv4 ping, trafgen can send  out  an  ICMP  probe  after  each
46       packet  injection  to  the  remote host in order to test if it is still
47       responsive/alive. Assuming there is no  answer  from  the  remote  host
48       after a certain threshold of probes, the machine is considered dead and
49       the last sent packet is printed together with the random seed that  was
50       used  by trafgen. You might not really get lucky fuzz-testing the Linux
51       kernel, but presumably there are buggy closed-source  embedded  systems
52       or  network driver's firmware files that are prone to bugs, where traf‐
53       gen could help in finding them.
54
55       trafgen's configuration language is quite powerful,  also  due  to  the
56       fact,  that  it  supports  C  preprocessor  macros. A stddef.h is being
57       shipped with trafgen for this purpose, so that well known defines  from
58       Linux  kernel  or network programming can be reused. After a configura‐
59       tion file has passed the C preprocessor stage, it is processed  by  the
60       trafgen  packet compiler. The language itself supports a couple of fea‐
61       tures that are useful when assembling packets, such as built-in runtime
62       checksum support for IP, UDP and TCP. Also it has an expression evalua‐
63       tor where arithmetic (basic operations, bit operations,  bit  shifting,
64       ...)  on  constant expressions is being reduced to a single constant on
65       compile time. Other features are ''fill'' macros, where a packet can be
66       filled with n bytes by a constant, a compile-time random number or run-
67       time random number (as mentioned with fuzz  testing).  Also,  netsniff-
68       ng(8) is able to convert a pcap file into a trafgen configuration file,
69       thus such a configuration can then be further tweaked for a given  sce‐
70       nario.
71

OPTIONS

73   -i <cfg|->, -c <cfg|i>, --in <cfg|->, --conf <cfg|->
74       Defines  the  input  configuration  file that can either be passed as a
75       normal plain text file or via stdin (''-''). Note that currently, if  a
76       configuration is passed through stdin, only 1 CPU will be used.
77
78   -o <dev>, -d <dev>, --out <dev>, --dev <dev>
79       Defines the outgoing networking device such as eth0, wlan0 and others.
80
81   -p, --cpp
82       Pass  the  packet configuration to the C preprocessor before reading it
83       into trafgen. This allows #define  and  #include  directives  (e.g.  to
84       include definitions from system headers) to be used in the trafgen con‐
85       figuration file.
86
87   -J, --jumbo-support
88       By default trafgen's ring buffer frames are of a  fixed  size  of  2048
89       bytes.   This means that if you're expecting jumbo frames or even super
90       jumbo frames to pass your line, then you will need  to  enable  support
91       for  that with the help of this option. However, this has the disadvan‐
92       tage of a performance regression and a bigger memory footprint for  the
93       ring buffer.
94
95   -R, --rfraw
96       In case the output networking device is a wireless device, it is possi‐
97       ble with trafgen to turn this into monitor mode  and  create  a  mon<X>
98       device  that  trafgen  will  be transmitting on instead of wlan<X>, for
99       instance. This enables trafgen to inject raw 802.11 frames.
100
101   -s <ipv4>, --smoke-test <ipv4>
102       In case this option is enabled, trafgen will perform a smoke  test.  In
103       other  words,  it  will  probe  the  remote end, specified by an <ipv4>
104       address, that is being ''attacked'' with trafgen network traffic, if it
105       is  still  alive  and  responsive.  That  means, after each transmitted
106       packet that has been configured, trafgen sends out ICMP  echo  requests
107       and  waits  for  an answer before it continues.  In case the remote end
108       stays unresponsive, trafgen assumes that the machine  has  crashed  and
109       will  print out the content of the last packet as a trafgen packet con‐
110       figuration and the random seed that has been used in order to reproduce
111       a  possible bug. This might be useful when testing proprietary embedded
112       devices. It is recommended to have a direct link between the host  run‐
113       ning trafgen and the host being attacked by trafgen.
114
115   -n <0|uint>, --num <0|uint>
116       Process  a number of packets and then exit. If the number of packets is
117       0, then this is equivalent to infinite packets resp.  processing  until
118       interrupted.   Otherwise,  a  number  given as an unsigned integer will
119       limit processing.
120
121   -r, --rand
122       Randomize the packet selection of the configuration file.  By  default,
123       if  more  than one packet is defined in a packet configuration, packets
124       are scheduled for transmission in a  round  robin  fashion.  With  this
125       option, they are selected randomly instread.
126
127   -P <uint>, --cpus <uint>
128       Specify  the  number of processes trafgen shall fork(2) off. By default
129       trafgen will start as many processes as CPUs that are  online  and  pin
130       them  to  each,  respectively.  Allowed  value  must be within interval
131       [1,CPUs].
132
133   -t <uint>, --gap <uint>
134       Specify a static inter-packet timegap in micro-seconds. If this  option
135       is  given,  then instead of packet(7)'s TX_RING interface, trafgen will
136       use sendto(2) I/O for network packets, even if the <uint>  argument  is
137       0. This option is useful for a couple of reasons: i) comparison between
138       sendto(2) and TX_RING performance, ii) low-traffic packet probing for a
139       given  interval,  iii)  ping-like  debugging with specific payload pat‐
140       terns. Furthermore, the TX_RING interface does  not  cope  with  inter‐
141       packet gaps.
142
143   -S <size>, --ring-size <size>
144       Manually define the TX_RING resp. TX_RING size in ''<num>KiB/MiB/GiB''.
145       On default the size is being determined based on the network connectiv‐
146       ity rate.
147
148   -k <uint>, --kernel-pull <uint>
149       Manually  define  the interval in micro-seconds where the kernel should
150       be triggered to batch process the ring buffer frames. By default, it is
151       every 10us, but it can manually be prolonged, for instance..
152
153   -E <uint>, --seed <uint>
154       Manually  set  the  seed  for  pseudo random number generator (PRNG) in
155       trafgen. By default, a random seed from /dev/urandom is  used  to  feed
156       glibc's  PRNG.  If  that fails, it falls back to the unix timestamp. It
157       can be useful to set the seed manually in order to be able to reproduce
158       a trafgen session, e.g. after fuzz testing.
159
160   -u <uid>, --user <uid> resp. -g <gid>, --group <gid>
161       After ring setup, drop privileges to a non-root user/group combination.
162
163   -V, --verbose
164       Let trafgen be more talkative and let it print the parsed configuration
165       and some ring buffer statistics.
166
167   -e, --example
168       Show a built-in packet configuration example.  This  might  be  a  good
169       starting point for an initial packet configuration scenario.
170
171   -C, --no-cpu-stats
172       Do not print CPU time statistics on exit.
173
174   -v, --version
175       Show version information and exit.
176
177   -h, --help
178       Show user help and exit.
179

SYNTAX

181       trafgen's  packet configuration syntax is fairly simple. The very basic
182       things one needs to know is that a configuration file is a simple plain
183       text  file  where packets are defined. It can contain one or more pack‐
184       ets. Packets are enclosed by opening '{' and closing  '}'  braces,  for
185       example:
186
187          { /* packet 1 content goes here ... */ }
188          { /* packet 2 content goes here ... */ }
189
190       When  trafgen  is  started  using multiple CPUs (default), then each of
191       those packets will  be  scheduled  for  transmission  on  all  CPUs  by
192       default.  However,  it is possible to tell trafgen to schedule a packet
193       only on a particular CPU:
194
195          cpu(1): { /* packet 1 content goes here ... */ }
196          cpu(2-3): { /* packet 2 content goes here ... */ }
197
198       Thus, in case we have a 4 core machine with CPU0-CPU3, packet 1 will be
199       scheduled  only  on CPU1, packet 2 on CPU2 and CPU3. When using trafgen
200       with --num option, then these constraints will still be valid  and  the
201       packet is fairly distributed among those CPUs.
202
203       Packet content is delimited either by a comma or whitespace, or both:
204
205          { 0xca, 0xfe, 0xba 0xbe }
206
207       Packet content can be of the following:
208
209          hex bytes:   0xca, xff
210          decimal:     42
211          binary:      0b11110000, b11110000
212          octal:       011
213          character:   'a'
214          string:      "hello world"
215          shellcode:   "\x31\xdb\x8d\x43\x17\x99\xcd\x80\x31\xc9"
216
217       Thus,  a quite useless packet packet configuration might look like this
218       (one can verify this when running this with trafgen in combination with
219       -V):
220
221          { 0xca, 42, 0b11110000, 011, 'a', "hello world",
222            "\x31\xdb\x8d\x43\x17\x99\xcd\x80\x31\xc9" }
223
224       There  are  a  couple of helper functions in trafgen's language to make
225       life easier to write configurations:
226
227       i) Fill with garbage functions:
228
229          byte fill function:      fill(<content>, <times>): fill(0xca, 128)
230          compile-time random:     rnd(<times>): rnd(128), rnd()
231          runtime random numbers:  drnd(<times>): drnd(128), drnd()
232          compile-time counter:    seqinc(<start-val>, <increment>, <times>)
233                                   seqdec(<start-val>, <decrement>, <times>)
234          runtime counter (1byte): dinc(<min-val>, <max-val>, <increment>)
235                                   ddec(<min-val>, <max-val>, <decrement>)
236
237       ii) Checksum helper functions (packet offsets start with 0):
238
239          IP/ICMP checksum:        csumip/csumicmp(<off-from>, <off-to>)
240          UDP checksum:            csumudp(<off-iphdr>, <off-udpdr>)
241          TCP checksum:            csumtcp(<off-iphdr>, <off-tcphdr>)
242
243       iii) Multibyte functions, compile-time expression evaluation:
244
245          const8(<content>),  c8(<content>),   const16(<content>),   c16(<con‐
246       tent>),
247          const32(<content>),  c32(<content>),  const64(<content>),  c64(<con‐
248       tent>)
249
250          These functions write their result in network byte  order  into  the
251       packet  configuration,  e.g.  const16(0xaa)  will  result in ''00 aa''.
252       Within  c*()  functions,  it  is  possible  to  do  some   arithmetics:
253       -,+,*,/,%,&,|,<<,>>,^  E.g.  const16((((1<<8)+0x32)|0b110)*2)  will  be
254       evaluated to ''02 6c''.
255
256       Furthermore, there are two types of comments in  trafgen  configuration
257       files:
258
259         1. Multi-line C-style comments:        /* put comment here */
260         2. Single-line Shell-style comments:   #  put comment here
261
262       Next  to  all of this, a configuration can be passed through the C pre‐
263       processor before the trafgen compiler gets to see it with option --cpp.
264       To  give  you  a  taste of a more advanced example, run ''trafgen -e'',
265       fields are commented:
266
267          /* Note: dynamic elements make trafgen slower! */
268          #include <stddef.h>
269
270          {
271            /* MAC Destination */
272            fill(0xff, ETH_ALEN),
273            /* MAC Source */
274            0x00, 0x02, 0xb3, drnd(3),
275            /* IPv4 Protocol */
276            c16(ETH_P_IP),
277            /* IPv4 Version, IHL, TOS */
278            0b01000101, 0,
279            /* IPv4 Total Len */
280            c16(59),
281            /* IPv4 Ident */
282            drnd(2),
283            /* IPv4 Flags, Frag Off */
284            0b01000000, 0,
285            /* IPv4 TTL */
286            64,
287            /* Proto TCP */
288            0x06,
289            /* IPv4 Checksum (IP header from, to) */
290            csumip(14, 33),
291            /* Source IP */
292            drnd(4),
293            /* Dest IP */
294            drnd(4),
295            /* TCP Source Port */
296            drnd(2),
297            /* TCP Dest Port */
298            c16(80),
299            /* TCP Sequence Number */
300            drnd(4),
301            /* TCP Ackn. Number */
302            c32(0),
303            /* TCP Header length + TCP SYN/ECN Flag */
304            c16((8 << 12) | TCP_FLAG_SYN | TCP_FLAG_ECE)
305            /* Window Size */
306            c16(16),
307            /* TCP Checksum (offset IP, offset TCP) */
308            csumtcp(14, 34),
309            /* TCP Options */
310            0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x06,
311            0x91, 0x68, 0x7d, 0x06, 0x91, 0x68, 0x6f,
312            /* Data blob */
313            "gotcha!",
314          }
315
316       Another real-world example by Jesper Dangaard Brouer [1]:
317
318          {
319            # --- ethernet header ---
320            0x00, 0x1b, 0x21, 0x3c, 0x9d, 0xf8,  # mac destination
321            0x90, 0xe2, 0xba, 0x0a, 0x56, 0xb4,  # mac source
322            const16(0x0800), # protocol
323            # --- ip header ---
324            # ipv4 version (4-bit) + ihl (4-bit), tos
325            0b01000101, 0,
326            # ipv4 total len
327            const16(40),
328            # id (note: runtime dynamic random)
329            drnd(2),
330            # ipv4 3-bit flags + 13-bit fragment offset
331            # 001 = more fragments
332            0b00100000, 0,
333            64, # ttl
334            17, # proto udp
335            # dynamic ip checksum (note: offsets are zero indexed)
336            csumip(14, 33),
337            192, 168, 51, 1, # source ip
338            192, 168, 51, 2, # dest ip
339            # --- udp header ---
340            # as this is a fragment the below stuff does not matter too much
341            const16(48054), # src port
342            const16(43514), # dst port
343            const16(20),    # udp length
344            # udp checksum can be dyn calc via csumudp(offset ip, offset tcp)
345            # which is csumudp(14, 34), but for udp its allowed to be zero
346            const16(0),
347            # payload
348            'A',  fill(0x41, 11),
349          }
350
351          [1] http://thread.gmane.org/gmane.linux.network/257155
352

USAGE EXAMPLE

354   trafgen --dev eth0 --conf trafgen.cfg
355       This is the most simple and, probably, the most common use of  trafgen.
356       It  will  generate  traffic  defined  in the configuration file ''traf‐
357       gen.cfg'' and transmit this via the  ''eth0''  networking  device.  All
358       online CPUs are used.
359
360   trafgen -e | trafgen -i - -o lo --cpp -n 1
361       This  is  an  example  where we send one packet of the built-in example
362       through the loopback device. The example configuration  is  passed  via
363       stdin  and also through the C preprocessor before trafgen's packet com‐
364       piler will see it.
365
366   trafgen --dev eth0 --conf fuzzing.cfg --smoke-test 10.0.0.1
367       Read the ''fuzzing.cfg''  packet  configuration  file  (which  contains
368       drnd()  calls)  and  send  out  the  generated  packets to the ''eth0''
369       device. After each sent packet,  ping  probe  the  attacked  host  with
370       address 10.0.0.1 to check if it's still alive. This also means, that we
371       utilize 1 CPU only, and do not use the TX_RING,  but  sendto(2)  packet
372       I/O due to ''slow mode''.
373
374   trafgen --dev wlan0 --rfraw --conf beacon-test.txf -V --cpus 2
375       As  an  output  device  ''wlan0'' is used and put into monitoring mode,
376       thus we are going to transmit raw 802.11 frames through  the  air.  Use
377       the use only 2 CPUs.
378
379   trafgen --dev em1 --conf frag_dos.cfg --rand --gap 1000
380       Use  trafgen  in sendto(2) mode instead of TX_RING mode and sleep after
381       each sent packet a static timegap for  1000us.  Generate  packets  from
382       ''frag_dos.cfg''  and select next packets to send randomly instead of a
383       round-robin fashion.  The output device for packets is ''em1''.
384
385   trafgen --dev eth0 --conf icmp.cfg --rand --num 1400000 -k1000
386       Send only 1400000 packets using the ''icmp.cfg'' configuration file and
387       then exit trafgen. Select packets randomly from that file for transmis‐
388       sion and send them out via ''eth0''. Also,  trigger  the  kernel  every
389       1000us for batching the ring frames from user space (default is 10us).
390
391   trafgen --dev eth0 --conf tcp_syn.cfg -u `id -u bob` -g `id -g bob`
392       Send  out packets generated from the configuration file ''tcp_syn.cfg''
393       via the ''eth0'' networking device.  After  setting  up  the  ring  for
394       transmission, drop credentials to the non-root user/group bob/bob.
395

NOTE

397       trafgen  can  saturate  a  Gigabit  Ethernet  link without problems. As
398       always, of course, this depends on your hardware as  well.  Not  every‐
399       where  where it says Gigabit Ethernet on the box, will you reach almost
400       physical line rate!  Please also read the netsniff-ng(8) man page, sec‐
401       tion  NOTE  for  further  details  about  tuning  your system e.g. with
402       tuned(8).
403
404       If you intend to use trafgen on a 10-Gbit/s Ethernet NIC, make sure you
405       are using a multiqueue tc(8) discipline, and make sure that the packets
406       you generate with trafgen will have a good distribution among tx_hashes
407       so that you'll actually make use of multiqueues.
408
409       For  introducing  bit  errors,  delays  with random variation and more,
410       there is no built-in option in trafgen. Rather, one should reuse exist‐
411       ing methods for that which integrate nicely with trafgen, such as tc(8)
412       with its different disciplines, i.e. netem.
413
414       For more complex packet configurations, it is recommended to use  high-
415       level  scripting for generating trafgen packet configurations in a more
416       automated way, i.e. also to create different traffic distributions that
417       are common for industrial benchmarking:
418
419           Traffic model              Distribution
420
421           IMIX                       64:7,  570:4,  1518:1
422           Tolly                      64:55,  78:5,   576:17, 1518:23
423           Cisco                      64:7,  594:4,  1518:1
424           RPR Trimodal               64:60, 512:20, 1518:20
425           RPR Quadrimodal            64:50, 512:15, 1518:15, 9218:20
426
427       The  low-level nature of trafgen makes trafgen rather protocol indepen‐
428       dent and therefore useful in many  scenarios  when  stress  testing  is
429       needed, for instance. However, if a traffic generator with higher level
430       packet descriptions is desired, netsniff-ng's mausezahn(8)  can  be  of
431       good use as well.
432
433       For smoke/fuzz testing with trafgen, it is recommended to have a direct
434       link between the host you want to analyze (''victim'' machine) and  the
435       host  you run trafgen on (''attacker'' machine). If the ICMP reply from
436       the victim fails, we assume that probably its kernel crashed,  thus  we
437       print  the  last sent packet togther with the seed and quit probing. It
438       might be very unlikely to find such a  ping-of-death  on  modern  Linux
439       systems.  However, there might be a good chance to find it on some pro‐
440       prietary (e.g. embedded) systems or buggy driver firmwares that are  in
441       the  wild.  Also,  fuzz  testing  can  be done on raw 802.11 frames, of
442       course. In case you find a ping-of-death, please mention that you  were
443       using trafgen in your commit message of the fix!
444

BUGS

446       For  old  trafgen  versions  only, there could occur kernel crashes: we
447       have fixed this bug in the mainline and  stable  kernels  under  commit
448       7f5c3e3a8 (''af_packet: remove BUG statement in tpacket_destruct_skb'')
449       and also in trafgen.
450
451       Probably the best is if you upgrade trafgen to the latest version.
452
454       trafgen is licensed under the GNU GPL version 2.0.
455

HISTORY

457       trafgen was originally written for the netsniff-ng  toolkit  by  Daniel
458       Borkmann.  It  is currently maintained by Tobias Klauser <tklauser@dis‐
459       tanz.ch> and Daniel Borkmann <dborkma@tik.ee.ethz.ch>.
460

SEE ALSO

462       netsniff-ng(8), mausezahn(8), ifpps(8), bpfc(8), flowtop(8),  astracer‐
463       oute(8), curvetun(8)
464

AUTHOR

466       Manpage was written by Daniel Borkmann.
467

COLOPHON

469       This  page is part of the Linux netsniff-ng toolkit project. A descrip‐
470       tion of the project, and information about reporting bugs, can be found
471       at http://netsniff-ng.org/.
472
473
474
475Linux                            03 March 2013                      TRAFGEN(8)
Impressum