1TRAFGEN(8) netsniff-ng toolkit TRAFGEN(8)
2
3
4
6 trafgen - a fast, multithreaded network packet generator
7
9 trafgen [options]
10
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
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
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
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
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
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
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
462 netsniff-ng(8), mausezahn(8), ifpps(8), bpfc(8), flowtop(8), astracer‐
463 oute(8), curvetun(8)
464
466 Manpage was written by Daniel Borkmann.
467
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)