4 * Creates random packet traces. Useful for debugging sniffers by testing
5 * assumptions about the veracity of the data found in the packet.
7 * Copyright (C) 1999 by Gilbert Ramirez <gram@alumni.rice.edu>
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 #define WS_LOG_DOMAIN "randpkt"
15 #include "randpkt_core.h"
20 #include <wsutil/array.h>
21 #include <wsutil/file_util.h>
22 #include <wsutil/wslog.h>
23 #include <wiretap/wtap_opttypes.h>
25 #include "ui/failure_message.h"
32 /* Types of produceable packets */
60 /* Ethernet, indicating ARP */
62 0xff, 0xff, 0xff, 0xff,
63 0xff, 0xff, 0x00, 0x00,
64 0x32, 0x25, 0x0f, 0xff,
68 /* Ethernet+IP+UDP, indicating DNS */
70 0xff, 0xff, 0xff, 0xff,
71 0xff, 0xff, 0x01, 0x01,
72 0x01, 0x01, 0x01, 0x01,
75 0x45, 0x00, 0x00, 0x3c,
76 0xc5, 0x9e, 0x40, 0x00,
77 0xff, 0x11, 0xd7, 0xe0,
78 0xd0, 0x15, 0x02, 0xb8,
79 0x0a, 0x01, 0x01, 0x63,
81 0x05, 0xe8, 0x00, 0x35,
82 0xff, 0xff, 0x2a, 0xb9,
86 /* Ethernet+IP, indicating ICMP */
87 uint8_t pkt_icmp
[] = {
88 0xff, 0xff, 0xff, 0xff,
89 0xff, 0xff, 0x01, 0x01,
90 0x01, 0x01, 0x01, 0x01,
93 0x45, 0x00, 0x00, 0x54,
94 0x8f, 0xb3, 0x40, 0x00,
95 0xfd, 0x01, 0x8a, 0x99,
96 0xcc, 0xfc, 0x66, 0x0b,
97 0xce, 0x41, 0x62, 0x12
100 /* Ethernet, indicating IP */
102 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0x01, 0x01,
104 0x01, 0x01, 0x01, 0x01,
108 /* Ethernet, indicating IPv6 */
109 uint8_t pkt_ipv6
[] = {
110 0xff, 0xff, 0xff, 0xff,
111 0xff, 0xff, 0x01, 0x01,
112 0x01, 0x01, 0x01, 0x01,
116 /* TR, indicating LLC */
117 uint8_t pkt_llc
[] = {
118 0x10, 0x40, 0x68, 0x00,
119 0x19, 0x69, 0x95, 0x8b,
120 0x00, 0x01, 0xfa, 0x68,
124 /* Ethernet, indicating WiMAX M2M */
125 uint8_t pkt_m2m
[] = {
126 0xff, 0xff, 0xff, 0xff,
127 0xff, 0xff, 0x00, 0x00,
128 0x32, 0x25, 0x0f, 0xff,
132 /* Ethernet+IP+UDP, indicating NBNS */
133 uint8_t pkt_nbns
[] = {
134 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0x01, 0x01,
136 0x01, 0x01, 0x01, 0x01,
139 0x45, 0x00, 0x00, 0x3c,
140 0xc5, 0x9e, 0x40, 0x00,
141 0xff, 0x11, 0xd7, 0xe0,
142 0xd0, 0x15, 0x02, 0xb8,
143 0x0a, 0x01, 0x01, 0x63,
145 0x00, 0x89, 0x00, 0x89,
146 0x00, 0x00, 0x2a, 0xb9,
150 /* Ethernet+IP+UDP, indicating syslog */
151 uint8_t pkt_syslog
[] = {
152 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0x01, 0x01,
154 0x01, 0x01, 0x01, 0x01,
157 0x45, 0x00, 0x00, 0x64,
158 0x20, 0x48, 0x00, 0x00,
159 0xfc, 0x11, 0xf8, 0x03,
160 0xd0, 0x15, 0x02, 0xb8,
161 0x0a, 0x01, 0x01, 0x63,
163 0x05, 0xe8, 0x02, 0x02,
164 0x00, 0x50, 0x51, 0xe1,
168 /* TR+LLC+IP, indicating TCP */
169 uint8_t pkt_tcp
[] = {
170 0x10, 0x40, 0x68, 0x00,
171 0x19, 0x69, 0x95, 0x8b,
172 0x00, 0x01, 0xfa, 0x68,
175 0xaa, 0xaa, 0x03, 0x00,
176 0x00, 0x00, 0x08, 0x00,
178 0x45, 0x00, 0x00, 0x28,
179 0x0b, 0x0b, 0x40, 0x00,
180 0x20, 0x06, 0x85, 0x37,
181 0xc0, 0xa8, 0x27, 0x01,
182 0xc0, 0xa8, 0x22, 0x3c
185 /* Ethernet+IP, indicating UDP */
186 uint8_t pkt_udp
[] = {
187 0xff, 0xff, 0xff, 0xff,
188 0xff, 0xff, 0x01, 0x01,
189 0x01, 0x01, 0x01, 0x01,
192 0x45, 0x00, 0x00, 0x3c,
193 0xc5, 0x9e, 0x40, 0x00,
194 0xff, 0x11, 0xd7, 0xe0,
195 0xd0, 0x15, 0x02, 0xb8,
196 0x0a, 0x01, 0x01, 0x63
199 /* Ethernet+IP+UDP, indicating BVLC */
200 uint8_t pkt_bvlc
[] = {
201 0xff, 0xff, 0xff, 0xff,
202 0xff, 0xff, 0x01, 0x01,
203 0x01, 0x01, 0x01, 0x01,
206 0x45, 0x00, 0x00, 0x3c,
207 0xc5, 0x9e, 0x40, 0x00,
208 0xff, 0x11, 0x01, 0xaa,
209 0xc1, 0xff, 0x19, 0x1e,
210 0xc1, 0xff, 0x19, 0xff,
211 0xba, 0xc0, 0xba, 0xc0,
212 0x00, 0xff, 0x2d, 0x5e,
216 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
217 uint8_t pkt_ncp2222
[] = {
218 0x10, 0x40, 0x00, 0x00,
219 0xf6, 0x7c, 0x9b, 0x70,
220 0x68, 0x00, 0x19, 0x69,
221 0x95, 0x8b, 0xe0, 0xe0,
222 0x03, 0xff, 0xff, 0x00,
223 0x25, 0x02, 0x11, 0x00,
224 0x00, 0x74, 0x14, 0x00,
225 0x00, 0x00, 0x00, 0x00,
226 0x01, 0x04, 0x51, 0x00,
227 0x00, 0x00, 0x04, 0x00,
228 0x02, 0x16, 0x19, 0x7a,
229 0x84, 0x40, 0x01, 0x22,
233 /* Ethernet+IP+TCP, indicating GIOP */
234 uint8_t pkt_giop
[] = {
235 0xff, 0xff, 0xff, 0xff,
236 0xff, 0xff, 0x01, 0x01,
237 0x01, 0x01, 0x01, 0x01,
240 0x45, 0x00, 0x00, 0xa6,
241 0x00, 0x2f, 0x40, 0x00,
242 0x40, 0x06, 0x3c, 0x21,
243 0x7f, 0x00, 0x00, 0x01,
244 0x7f, 0x00, 0x00, 0x01,
246 0x30, 0x39, 0x04, 0x05,
247 0xac, 0x02, 0x1e, 0x69,
248 0xab, 0x74, 0xab, 0x64,
249 0x80, 0x18, 0x79, 0x60,
250 0xc4, 0xb8, 0x00, 0x00,
251 0x01, 0x01, 0x08, 0x0a,
252 0x00, 0x00, 0x48, 0xf5,
253 0x00, 0x00, 0x48, 0xf5,
255 0x47, 0x49, 0x4f, 0x50,
256 0x01, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x30,
258 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x00, 0x01,
263 /* Ethernet+IP+TCP, indicating BGP */
264 uint8_t pkt_bgp
[] = {
265 0xff, 0xff, 0xff, 0xff,
266 0xff, 0xff, 0x01, 0x01,
267 0x01, 0x01, 0x01, 0x01,
270 0x45, 0x00, 0x00, 0xa6,
271 0x00, 0x2f, 0x40, 0x00,
272 0x40, 0x06, 0x3c, 0x21,
273 0x7f, 0x00, 0x00, 0x01,
274 0x7f, 0x00, 0x00, 0x01,
276 0x30, 0x39, 0x00, 0xb3,
277 0xac, 0x02, 0x1e, 0x69,
278 0xab, 0x74, 0xab, 0x64,
279 0x80, 0x18, 0x79, 0x60,
280 0xc4, 0xb8, 0x00, 0x00,
281 0x01, 0x01, 0x08, 0x0a,
282 0x00, 0x00, 0x48, 0xf5,
283 0x00, 0x00, 0x48, 0xf5,
285 0xff, 0xff, 0xff, 0xff,
286 0xff, 0xff, 0xff, 0xff,
287 0xff, 0xff, 0xff, 0xff,
288 0xff, 0xff, 0xff, 0xff,
291 /* Ethernet+IP+TCP, indicating TDS NetLib */
292 uint8_t pkt_tds
[] = {
293 0x00, 0x50, 0x8b, 0x0d,
294 0x7a, 0xed, 0x00, 0x08,
295 0xa3, 0x98, 0x39, 0x81,
298 0x45, 0x00, 0x03, 0x8d,
299 0x90, 0xd4, 0x40, 0x00,
300 0x7c, 0x06, 0xc3, 0x1b,
301 0xac, 0x14, 0x02, 0x22,
302 0x0a, 0xc2, 0xee, 0x82,
304 0x05, 0x99, 0x08, 0xf8,
305 0xff, 0x4e, 0x85, 0x46,
306 0xa2, 0xb4, 0x42, 0xaa,
307 0x50, 0x18, 0x3c, 0x28,
308 0x0f, 0xda, 0x00, 0x00,
311 /* Ethernet+IP, indicating SCTP */
312 uint8_t pkt_sctp
[] = {
313 0x00, 0xa0, 0x80, 0x00,
314 0x5e, 0x46, 0x08, 0x00,
315 0x03, 0x4a, 0x00, 0x35,
318 0x45, 0x00, 0x00, 0x7c,
319 0x14, 0x1c, 0x00, 0x00,
320 0x3b, 0x84, 0x4a, 0x54,
321 0x0a, 0x1c, 0x06, 0x2b,
322 0x0a, 0x1c, 0x06, 0x2c,
326 /* Ethernet+IP+SCTP, indicating MEGACO */
327 uint8_t pkt_megaco
[] = {
328 0x00, 0xa0, 0x80, 0x00,
329 0x5e, 0x46, 0x08, 0x00,
330 0x03, 0x4a, 0x00, 0x35,
333 0x45, 0x00, 0x00, 0x7c,
334 0x14, 0x1c, 0x00, 0x00,
335 0x3b, 0x84, 0x4a, 0x54,
336 0x0a, 0x1c, 0x06, 0x2b,
337 0x0a, 0x1c, 0x06, 0x2c,
339 0x40, 0x00, 0x0b, 0x80,
340 0x00, 0x01, 0x6f, 0x0a,
341 0x6d, 0xb0, 0x18, 0x82,
342 0x00, 0x03, 0x00, 0x5b,
343 0x28, 0x02, 0x43, 0x45,
344 0x00, 0x00, 0xa0, 0xbd,
345 0x00, 0x00, 0x00, 0x07,
348 /* This little data table drives the whole program */
349 static randpkt_example examples
[] = {
350 { "arp", "Address Resolution Protocol",
351 PKT_ARP
, WTAP_ENCAP_ETHERNET
,
352 pkt_arp
, array_length(pkt_arp
),
358 { "bgp", "Border Gateway Protocol",
359 PKT_BGP
, WTAP_ENCAP_ETHERNET
,
360 pkt_bgp
, array_length(pkt_bgp
),
366 { "bvlc", "BACnet Virtual Link Control",
367 PKT_BVLC
, WTAP_ENCAP_ETHERNET
,
368 pkt_bvlc
, array_length(pkt_bvlc
),
374 { "dns", "Domain Name Service",
375 PKT_DNS
, WTAP_ENCAP_ETHERNET
,
376 pkt_dns
, array_length(pkt_dns
),
383 PKT_ETHERNET
, WTAP_ENCAP_ETHERNET
,
390 { "fddi", "Fiber Distributed Data Interface",
391 PKT_FDDI
, WTAP_ENCAP_FDDI
,
398 { "giop", "General Inter-ORB Protocol",
399 PKT_GIOP
, WTAP_ENCAP_ETHERNET
,
400 pkt_giop
, array_length(pkt_giop
),
406 { "icmp", "Internet Control Message Protocol",
407 PKT_ICMP
, WTAP_ENCAP_ETHERNET
,
408 pkt_icmp
, array_length(pkt_icmp
),
414 { "ieee802.15.4", "IEEE 802.15.4",
415 PKT_IEEE802154
, WTAP_ENCAP_IEEE802_15_4
,
422 { "ip", "Internet Protocol",
423 PKT_IP
, WTAP_ENCAP_ETHERNET
,
424 pkt_ip
, array_length(pkt_ip
),
430 { "ipv6", "Internet Protocol Version 6",
431 PKT_IPv6
, WTAP_ENCAP_ETHERNET
,
432 pkt_ipv6
, array_length(pkt_ipv6
),
438 { "llc", "Logical Link Control",
439 PKT_LLC
, WTAP_ENCAP_TOKEN_RING
,
440 pkt_llc
, array_length(pkt_llc
),
446 { "m2m", "WiMAX M2M Encapsulation Protocol",
447 PKT_M2M
, WTAP_ENCAP_ETHERNET
,
448 pkt_m2m
, array_length(pkt_m2m
),
454 { "megaco", "MEGACO",
455 PKT_MEGACO
, WTAP_ENCAP_ETHERNET
,
456 pkt_megaco
, array_length(pkt_megaco
),
462 { "nbns", "NetBIOS-over-TCP Name Service",
463 PKT_NBNS
, WTAP_ENCAP_ETHERNET
,
464 pkt_nbns
, array_length(pkt_nbns
),
470 { "ncp2222", "NetWare Core Protocol",
471 PKT_NCP2222
, WTAP_ENCAP_TOKEN_RING
,
472 pkt_ncp2222
, array_length(pkt_ncp2222
),
478 { "sctp", "Stream Control Transmission Protocol",
479 PKT_SCTP
, WTAP_ENCAP_ETHERNET
,
480 pkt_sctp
, array_length(pkt_sctp
),
486 { "syslog", "Syslog message",
487 PKT_SYSLOG
, WTAP_ENCAP_ETHERNET
,
488 pkt_syslog
, array_length(pkt_syslog
),
494 { "tds", "TDS NetLib",
495 PKT_TDS
, WTAP_ENCAP_ETHERNET
,
496 pkt_tds
, array_length(pkt_tds
),
502 { "tcp", "Transmission Control Protocol",
503 PKT_TCP
, WTAP_ENCAP_TOKEN_RING
,
504 pkt_tcp
, array_length(pkt_tcp
),
510 { "tr", "Token-Ring",
511 PKT_TR
, WTAP_ENCAP_TOKEN_RING
,
518 { "udp", "User Datagram Protocol",
519 PKT_UDP
, WTAP_ENCAP_ETHERNET
,
520 pkt_udp
, array_length(pkt_udp
),
526 { "usb-linux", "Universal Serial Bus with Linux specific header",
527 PKT_USB_LINUX
, WTAP_ENCAP_USB_LINUX
,
536 unsigned randpkt_example_count(void)
538 return array_length(examples
);
541 /* Find pkt_example record and return pointer to it */
542 randpkt_example
* randpkt_find_example(int type
)
544 int num_entries
= array_length(examples
);
547 for (i
= 0; i
< num_entries
; i
++) {
548 if (examples
[i
].produceable_type
== type
) {
553 fprintf(stderr
, "randpkt: Internal error. Type %d has no entry in examples table.\n",
558 void randpkt_loop(randpkt_example
* example
, uint64_t produce_count
, uint64_t packet_delay_ms
)
563 unsigned len_this_pkt
;
565 union wtap_pseudo_header
* ps_header
;
569 rec
= g_new0(wtap_rec
, 1);
570 buffer
= (uint8_t*)g_malloc0(65536);
572 rec
->rec_type
= REC_TYPE_PACKET
;
573 rec
->presence_flags
= WTAP_HAS_TS
;
574 rec
->rec_header
.packet_header
.pkt_encap
= example
->sample_wtap_encap
;
576 ps_header
= &rec
->rec_header
.packet_header
.pseudo_header
;
578 /* Load the sample pseudoheader into our pseudoheader buffer */
579 if (example
->pseudo_buffer
)
580 memcpy(ps_header
, example
->pseudo_buffer
, example
->pseudo_length
);
582 /* Load the sample into our buffer */
583 if (example
->sample_buffer
)
584 memcpy(buffer
, example
->sample_buffer
, example
->sample_length
);
586 /* Produce random packets */
587 for (i
= 0; i
< produce_count
; i
++) {
588 if (example
->produce_max_bytes
> 0) {
589 len_random
= g_rand_int_range(pkt_rand
, 0, example
->produce_max_bytes
+ 1);
595 len_this_pkt
= example
->sample_length
+ len_random
;
596 if (len_this_pkt
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
598 * Wiretap will fail when trying to read packets
599 * bigger than WTAP_MAX_PACKET_SIZE_STANDARD.
601 len_this_pkt
= WTAP_MAX_PACKET_SIZE_STANDARD
;
604 rec
->rec_header
.packet_header
.caplen
= len_this_pkt
;
605 rec
->rec_header
.packet_header
.len
= len_this_pkt
;
606 rec
->ts
.secs
= i
; /* just for variety */
608 for (j
= example
->pseudo_length
; j
< (int) sizeof(*ps_header
); j
++) {
609 ((uint8_t*)ps_header
)[j
] = g_rand_int_range(pkt_rand
, 0, 0x100);
612 for (j
= example
->sample_length
; j
< len_this_pkt
; j
++) {
613 /* Add format strings here and there */
614 if ((int) (100.0*g_rand_double(pkt_rand
)) < 3 && j
< (len_random
- 3)) {
615 memcpy(&buffer
[j
], "%s", 3);
618 buffer
[j
] = g_rand_int_range(pkt_rand
, 0, 0x100);
622 if (!wtap_dump(example
->dump
, rec
, buffer
, &err
, &err_info
)) {
623 cfile_write_failure_message(NULL
,
624 example
->filename
, err
, err_info
, 0,
625 wtap_dump_file_type_subtype(example
->dump
));
627 if (packet_delay_ms
) {
628 g_usleep(1000 * (unsigned long)packet_delay_ms
);
629 if (!wtap_dump_flush(example
->dump
, &err
)) {
630 cfile_write_failure_message(NULL
,
631 example
->filename
, err
, NULL
, 0,
632 wtap_dump_file_type_subtype(example
->dump
));
641 bool randpkt_example_close(randpkt_example
* example
)
647 if (!wtap_dump_close(example
->dump
, NULL
, &err
, &err_info
)) {
648 cfile_close_failure_message(example
->filename
, err
, err_info
);
652 if (pkt_rand
!= NULL
) {
653 g_rand_free(pkt_rand
);
660 int randpkt_example_init(randpkt_example
* example
, char* produce_filename
, int produce_max_bytes
, int file_type_subtype
)
665 if (pkt_rand
== NULL
) {
666 pkt_rand
= g_rand_new();
669 const wtap_dump_params params
= {
670 .encap
= example
->sample_wtap_encap
,
671 .snaplen
= produce_max_bytes
,
673 if (strcmp(produce_filename
, "-") == 0) {
674 /* Write to the standard output. */
675 example
->dump
= wtap_dump_open_stdout(file_type_subtype
,
676 WTAP_UNCOMPRESSED
, ¶ms
, &err
, &err_info
);
677 example
->filename
= "the standard output";
679 example
->dump
= wtap_dump_open(produce_filename
, file_type_subtype
,
680 WTAP_UNCOMPRESSED
, ¶ms
, &err
, &err_info
);
681 example
->filename
= produce_filename
;
683 if (!example
->dump
) {
684 cfile_dump_open_failure_message(produce_filename
,
685 err
, err_info
, file_type_subtype
);
689 /* reduce max_bytes by # of bytes already in sample */
690 if (produce_max_bytes
<= example
->sample_length
) {
691 fprintf(stderr
, "randpkt: Sample packet length is %d, which is greater than "
692 "or equal to\n", example
->sample_length
);
693 fprintf(stderr
, "your requested max_bytes value of %d\n", produce_max_bytes
);
696 example
->produce_max_bytes
= produce_max_bytes
- example
->sample_length
;
702 /* Parse command-line option "type" and return enum type */
703 int randpkt_parse_type(char *string
)
705 int num_entries
= array_length(examples
);
708 /* If called with NULL, or empty string, choose a random packet */
709 if (!string
|| !g_strcmp0(string
, "")) {
710 return examples
[g_random_int_range(0, num_entries
)].produceable_type
;
713 for (i
= 0; i
< num_entries
; i
++) {
714 if (g_strcmp0(examples
[i
].abbrev
, string
) == 0) {
715 return examples
[i
].produceable_type
;
720 ws_error("randpkt: Type %s not known.\n", string
);
724 void randpkt_example_list(char*** abbrev_list
, char*** longname_list
)
728 list_num
= randpkt_example_count();
729 *abbrev_list
= g_new0(char*, list_num
+ 1);
730 *longname_list
= g_new0(char*, list_num
+ 1);
731 for (i
= 0; i
< list_num
; i
++) {
732 (*abbrev_list
)[i
] = g_strdup(examples
[i
].abbrev
);
733 (*longname_list
)[i
] = g_strdup(examples
[i
].longname
);
738 * Editor modelines - https://www.wireshark.org/tools/modelines.html
743 * indent-tabs-mode: t
746 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
747 * :indentSize=8:tabSize=8:noTabs=false: