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 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #ifndef HAVE_GETOPT_LONG
31 #include "wsutil/wsgetopt.h"
41 #include "wiretap/wtap.h"
42 #include "wsutil/file_util.h"
43 #include <wsutil/ws_diag_control.h>
46 #include <wsutil/unicode-utils.h>
49 #define array_length(x) (sizeof x / sizeof x[0])
51 /* Types of produceable packets */
81 int sample_wtap_encap;
82 guint8* sample_buffer;
84 guint8* pseudo_buffer;
87 guint produce_max_bytes;
91 /* Ethernet, indicating ARP */
93 0xff, 0xff, 0xff, 0xff,
94 0xff, 0xff, 0x00, 0x00,
95 0x32, 0x25, 0x0f, 0xff,
99 /* Ethernet+IP+UDP, indicating DNS */
101 0xff, 0xff, 0xff, 0xff,
102 0xff, 0xff, 0x01, 0x01,
103 0x01, 0x01, 0x01, 0x01,
106 0x45, 0x00, 0x00, 0x3c,
107 0xc5, 0x9e, 0x40, 0x00,
108 0xff, 0x11, 0xd7, 0xe0,
109 0xd0, 0x15, 0x02, 0xb8,
110 0x0a, 0x01, 0x01, 0x63,
112 0x05, 0xe8, 0x00, 0x35,
113 0xff, 0xff, 0x2a, 0xb9,
117 /* Ethernet+IP, indicating ICMP */
118 guint8 pkt_icmp[] = {
119 0xff, 0xff, 0xff, 0xff,
120 0xff, 0xff, 0x01, 0x01,
121 0x01, 0x01, 0x01, 0x01,
124 0x45, 0x00, 0x00, 0x54,
125 0x8f, 0xb3, 0x40, 0x00,
126 0xfd, 0x01, 0x8a, 0x99,
127 0xcc, 0xfc, 0x66, 0x0b,
128 0xce, 0x41, 0x62, 0x12
131 /* Ethernet, indicating IP */
133 0xff, 0xff, 0xff, 0xff,
134 0xff, 0xff, 0x01, 0x01,
135 0x01, 0x01, 0x01, 0x01,
139 /* TR, indicating LLC */
141 0x10, 0x40, 0x68, 0x00,
142 0x19, 0x69, 0x95, 0x8b,
143 0x00, 0x01, 0xfa, 0x68,
147 /* Ethernet, indicating WiMAX M2M */
149 0xff, 0xff, 0xff, 0xff,
150 0xff, 0xff, 0x00, 0x00,
151 0x32, 0x25, 0x0f, 0xff,
155 /* Ethernet+IP+UDP, indicating NBNS */
156 guint8 pkt_nbns[] = {
157 0xff, 0xff, 0xff, 0xff,
158 0xff, 0xff, 0x01, 0x01,
159 0x01, 0x01, 0x01, 0x01,
162 0x45, 0x00, 0x00, 0x3c,
163 0xc5, 0x9e, 0x40, 0x00,
164 0xff, 0x11, 0xd7, 0xe0,
165 0xd0, 0x15, 0x02, 0xb8,
166 0x0a, 0x01, 0x01, 0x63,
168 0x00, 0x89, 0x00, 0x89,
169 0x00, 0x00, 0x2a, 0xb9,
173 /* Ethernet+IP+UDP, indicating syslog */
174 guint8 pkt_syslog[] = {
175 0xff, 0xff, 0xff, 0xff,
176 0xff, 0xff, 0x01, 0x01,
177 0x01, 0x01, 0x01, 0x01,
180 0x45, 0x00, 0x00, 0x64,
181 0x20, 0x48, 0x00, 0x00,
182 0xfc, 0x11, 0xf8, 0x03,
183 0xd0, 0x15, 0x02, 0xb8,
184 0x0a, 0x01, 0x01, 0x63,
186 0x05, 0xe8, 0x02, 0x02,
187 0x00, 0x50, 0x51, 0xe1,
191 /* TR+LLC+IP, indicating TCP */
193 0x10, 0x40, 0x68, 0x00,
194 0x19, 0x69, 0x95, 0x8b,
195 0x00, 0x01, 0xfa, 0x68,
198 0xaa, 0xaa, 0x03, 0x00,
199 0x00, 0x00, 0x08, 0x00,
201 0x45, 0x00, 0x00, 0x28,
202 0x0b, 0x0b, 0x40, 0x00,
203 0x20, 0x06, 0x85, 0x37,
204 0xc0, 0xa8, 0x27, 0x01,
205 0xc0, 0xa8, 0x22, 0x3c
208 /* Ethernet+IP, indicating UDP */
210 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0x01, 0x01,
212 0x01, 0x01, 0x01, 0x01,
215 0x45, 0x00, 0x00, 0x3c,
216 0xc5, 0x9e, 0x40, 0x00,
217 0xff, 0x11, 0xd7, 0xe0,
218 0xd0, 0x15, 0x02, 0xb8,
219 0x0a, 0x01, 0x01, 0x63
222 /* Ethernet+IP+UDP, indicating BVLC */
223 guint8 pkt_bvlc[] = {
224 0xff, 0xff, 0xff, 0xff,
225 0xff, 0xff, 0x01, 0x01,
226 0x01, 0x01, 0x01, 0x01,
229 0x45, 0x00, 0x00, 0x3c,
230 0xc5, 0x9e, 0x40, 0x00,
231 0xff, 0x11, 0x01, 0xaa,
232 0xc1, 0xff, 0x19, 0x1e,
233 0xc1, 0xff, 0x19, 0xff,
234 0xba, 0xc0, 0xba, 0xc0,
235 0x00, 0xff, 0x2d, 0x5e,
239 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
240 guint8 pkt_ncp2222[] = {
241 0x10, 0x40, 0x00, 0x00,
242 0xf6, 0x7c, 0x9b, 0x70,
243 0x68, 0x00, 0x19, 0x69,
244 0x95, 0x8b, 0xe0, 0xe0,
245 0x03, 0xff, 0xff, 0x00,
246 0x25, 0x02, 0x11, 0x00,
247 0x00, 0x74, 0x14, 0x00,
248 0x00, 0x00, 0x00, 0x00,
249 0x01, 0x04, 0x51, 0x00,
250 0x00, 0x00, 0x04, 0x00,
251 0x02, 0x16, 0x19, 0x7a,
252 0x84, 0x40, 0x01, 0x22,
256 /* Ethernet+IP+TCP, indicating GIOP */
257 guint8 pkt_giop[] = {
258 0xff, 0xff, 0xff, 0xff,
259 0xff, 0xff, 0x01, 0x01,
260 0x01, 0x01, 0x01, 0x01,
263 0x45, 0x00, 0x00, 0xa6,
264 0x00, 0x2f, 0x40, 0x00,
265 0x40, 0x06, 0x3c, 0x21,
266 0x7f, 0x00, 0x00, 0x01,
267 0x7f, 0x00, 0x00, 0x01,
269 0x30, 0x39, 0x04, 0x05,
270 0xac, 0x02, 0x1e, 0x69,
271 0xab, 0x74, 0xab, 0x64,
272 0x80, 0x18, 0x79, 0x60,
273 0xc4, 0xb8, 0x00, 0x00,
274 0x01, 0x01, 0x08, 0x0a,
275 0x00, 0x00, 0x48, 0xf5,
276 0x00, 0x00, 0x48, 0xf5,
278 0x47, 0x49, 0x4f, 0x50,
279 0x01, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x30,
281 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x01,
286 /* Ethernet+IP+TCP, indicating BGP */
288 0xff, 0xff, 0xff, 0xff,
289 0xff, 0xff, 0x01, 0x01,
290 0x01, 0x01, 0x01, 0x01,
293 0x45, 0x00, 0x00, 0xa6,
294 0x00, 0x2f, 0x40, 0x00,
295 0x40, 0x06, 0x3c, 0x21,
296 0x7f, 0x00, 0x00, 0x01,
297 0x7f, 0x00, 0x00, 0x01,
299 0x30, 0x39, 0x00, 0xb3,
300 0xac, 0x02, 0x1e, 0x69,
301 0xab, 0x74, 0xab, 0x64,
302 0x80, 0x18, 0x79, 0x60,
303 0xc4, 0xb8, 0x00, 0x00,
304 0x01, 0x01, 0x08, 0x0a,
305 0x00, 0x00, 0x48, 0xf5,
306 0x00, 0x00, 0x48, 0xf5,
308 0xff, 0xff, 0xff, 0xff,
309 0xff, 0xff, 0xff, 0xff,
310 0xff, 0xff, 0xff, 0xff,
311 0xff, 0xff, 0xff, 0xff,
314 /* Ethernet+IP+TCP, indicating TDS NetLib */
316 0x00, 0x50, 0x8b, 0x0d,
317 0x7a, 0xed, 0x00, 0x08,
318 0xa3, 0x98, 0x39, 0x81,
321 0x45, 0x00, 0x03, 0x8d,
322 0x90, 0xd4, 0x40, 0x00,
323 0x7c, 0x06, 0xc3, 0x1b,
324 0xac, 0x14, 0x02, 0x22,
325 0x0a, 0xc2, 0xee, 0x82,
327 0x05, 0x99, 0x08, 0xf8,
328 0xff, 0x4e, 0x85, 0x46,
329 0xa2, 0xb4, 0x42, 0xaa,
330 0x50, 0x18, 0x3c, 0x28,
331 0x0f, 0xda, 0x00, 0x00,
334 /* Ethernet+IP, indicating SCTP */
335 guint8 pkt_sctp[] = {
336 0x00, 0xa0, 0x80, 0x00,
337 0x5e, 0x46, 0x08, 0x00,
338 0x03, 0x4a, 0x00, 0x35,
341 0x45, 0x00, 0x00, 0x7c,
342 0x14, 0x1c, 0x00, 0x00,
343 0x3b, 0x84, 0x4a, 0x54,
344 0x0a, 0x1c, 0x06, 0x2b,
345 0x0a, 0x1c, 0x06, 0x2c,
349 /* Ethernet+IP+SCTP, indicating MEGACO */
350 guint8 pkt_megaco[] = {
351 0x00, 0xa0, 0x80, 0x00,
352 0x5e, 0x46, 0x08, 0x00,
353 0x03, 0x4a, 0x00, 0x35,
356 0x45, 0x00, 0x00, 0x7c,
357 0x14, 0x1c, 0x00, 0x00,
358 0x3b, 0x84, 0x4a, 0x54,
359 0x0a, 0x1c, 0x06, 0x2b,
360 0x0a, 0x1c, 0x06, 0x2c,
362 0x40, 0x00, 0x0b, 0x80,
363 0x00, 0x01, 0x6f, 0x0a,
364 0x6d, 0xb0, 0x18, 0x82,
365 0x00, 0x03, 0x00, 0x5b,
366 0x28, 0x02, 0x43, 0x45,
367 0x00, 0x00, 0xa0, 0xbd,
368 0x00, 0x00, 0x00, 0x07,
371 /* This little data table drives the whole program */
372 randpkt_example examples[] = {
373 { "arp", "Address Resolution Protocol",
374 PKT_ARP, WTAP_ENCAP_ETHERNET,
375 pkt_arp, array_length(pkt_arp),
380 { "bgp", "Border Gateway Protocol",
381 PKT_BGP, WTAP_ENCAP_ETHERNET,
382 pkt_bgp, array_length(pkt_bgp),
387 { "bvlc", "BACnet Virtual Link Control",
388 PKT_BVLC, WTAP_ENCAP_ETHERNET,
389 pkt_bvlc, array_length(pkt_bvlc),
394 { "dns", "Domain Name Service",
395 PKT_DNS, WTAP_ENCAP_ETHERNET,
396 pkt_dns, array_length(pkt_dns),
402 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
408 { "fddi", "Fiber Distributed Data Interface",
409 PKT_FDDI, WTAP_ENCAP_FDDI,
415 { "giop", "General Inter-ORB Protocol",
416 PKT_GIOP, WTAP_ENCAP_ETHERNET,
417 pkt_giop, array_length(pkt_giop),
422 { "icmp", "Internet Control Message Protocol",
423 PKT_ICMP, WTAP_ENCAP_ETHERNET,
424 pkt_icmp, array_length(pkt_icmp),
429 { "ip", "Internet Protocol",
430 PKT_IP, WTAP_ENCAP_ETHERNET,
431 pkt_ip, array_length(pkt_ip),
436 { "llc", "Logical Link Control",
437 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
438 pkt_llc, array_length(pkt_llc),
443 { "m2m", "WiMAX M2M Encapsulation Protocol",
444 PKT_M2M, WTAP_ENCAP_ETHERNET,
445 pkt_m2m, array_length(pkt_m2m),
450 { "megaco", "MEGACO",
451 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
452 pkt_megaco, array_length(pkt_megaco),
457 { "nbns", "NetBIOS-over-TCP Name Service",
458 PKT_NBNS, WTAP_ENCAP_ETHERNET,
459 pkt_nbns, array_length(pkt_nbns),
464 { "ncp2222", "NetWare Core Protocol",
465 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
466 pkt_ncp2222, array_length(pkt_ncp2222),
471 { "sctp", "Stream Control Transmission Protocol",
472 PKT_SCTP, WTAP_ENCAP_ETHERNET,
473 pkt_sctp, array_length(pkt_sctp),
478 { "syslog", "Syslog message",
479 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
480 pkt_syslog, array_length(pkt_syslog),
485 { "tds", "TDS NetLib",
486 PKT_TDS, WTAP_ENCAP_ETHERNET,
487 pkt_tds, array_length(pkt_tds),
492 { "tcp", "Transmission Control Protocol",
493 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
494 pkt_tcp, array_length(pkt_tcp),
499 { "tr", "Token-Ring",
500 PKT_TR, WTAP_ENCAP_TOKEN_RING,
506 { "udp", "User Datagram Protocol",
507 PKT_UDP, WTAP_ENCAP_ETHERNET,
508 pkt_udp, array_length(pkt_udp),
513 { "usb", "Universal Serial Bus",
514 PKT_USB, WTAP_ENCAP_USB,
520 { "usb-linux", "Universal Serial Bus with Linux specific header",
521 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
529 /* Parse command-line option "type" and return enum type */
531 int randpkt_parse_type(char *string)
533 int num_entries = array_length(examples);
536 /* Called with NULL, choose a random packet */
538 return examples[rand() % num_entries].produceable_type;
541 for (i = 0; i < num_entries; i++) {
542 if (g_strcmp0(examples[i].abbrev, string) == 0) {
543 return examples[i].produceable_type;
548 fprintf(stderr, "randpkt: Type %s not known.\n", string);
552 static void usage(gboolean is_error);
554 /* Seed the random-number generator */
558 unsigned int randomness;
564 #define RANDOM_DEV "/dev/urandom"
567 * Assume it's at least worth trying /dev/urandom on UN*X.
568 * If it doesn't exist, fall back on time().
570 * XXX - Use CryptGenRandom on Windows?
572 fd = ws_open(RANDOM_DEV, O_RDONLY);
574 if (errno != ENOENT) {
576 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
583 ret = ws_read(fd, &randomness, sizeof randomness);
586 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
590 if ((size_t)ret != sizeof randomness) {
592 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
593 (unsigned long)sizeof randomness, (long)ret);
603 randomness = (unsigned int) now;
608 static randpkt_example* randpkt_find_example(int type);
610 void randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes)
614 example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
615 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
616 if (!example->dump) {
617 fprintf(stderr, "randpkt: Error writing to %s\n", produce_filename);
621 /* reduce max_bytes by # of bytes already in sample */
622 if (produce_max_bytes <= example->sample_length) {
623 fprintf(stderr, "randpkt: Sample packet length is %d, which is greater than "
624 "or equal to\n", example->sample_length);
625 fprintf(stderr, "your requested max_bytes value of %d\n", produce_max_bytes);
628 example->produce_max_bytes -= example->sample_length;
632 void randpkt_example_close(randpkt_example* example)
635 wtap_dump_close(example->dump, &err);
638 void randpkt_loop(randpkt_example* example, guint64 produce_count)
646 union wtap_pseudo_header* ps_header;
647 guint8 buffer[65536];
648 struct wtap_pkthdr* pkthdr;
650 pkthdr = g_new0(struct wtap_pkthdr, 1);
652 pkthdr->rec_type = REC_TYPE_PACKET;
653 pkthdr->presence_flags = WTAP_HAS_TS;
654 pkthdr->pkt_encap = example->sample_wtap_encap;
656 memset(pkthdr, 0, sizeof(struct wtap_pkthdr));
657 memset(buffer, 0, sizeof(buffer));
659 ps_header = &pkthdr->pseudo_header;
661 /* Load the sample pseudoheader into our pseudoheader buffer */
662 if (example->pseudo_buffer)
663 memcpy(ps_header, example->pseudo_buffer, example->pseudo_length);
665 /* Load the sample into our buffer */
666 if (example->sample_buffer)
667 memcpy(buffer, example->sample_buffer, example->sample_length);
669 /* Produce random packets */
670 for (i = 0; i < produce_count; i++) {
671 if (example->produce_max_bytes > 0) {
672 len_random = (rand() % example->produce_max_bytes + 1);
678 len_this_pkt = example->sample_length + len_random;
680 pkthdr->caplen = len_this_pkt;
681 pkthdr->len = len_this_pkt;
682 pkthdr->ts.secs = i; /* just for variety */
684 for (j = example->pseudo_length; j < (int) sizeof(*ps_header); j++) {
685 ((guint8*)ps_header)[j] = (rand() % 0x100);
688 for (j = example->sample_length; j < len_this_pkt; j++) {
689 /* Add format strings here and there */
690 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
691 memcpy(&buffer[j], "%s", 3);
694 buffer[j] = (rand() % 0x100);
698 /* XXX - report errors! */
699 if (!wtap_dump(example->dump, pkthdr, buffer, &err, &err_info)) {
700 if (err_info != NULL)
709 main(int argc, char **argv)
712 int produce_type = -1;
713 char *produce_filename = NULL;
714 int produce_max_bytes = 5000;
715 int produce_count = 1000;
716 randpkt_example *example;
718 int allrandom = FALSE;
719 wtap_dumper *savedump;
721 static const struct option long_options[] = {
722 {(char *)"help", no_argument, NULL, 'h'},
728 arg_list_utf_16to8(argc, argv);
729 create_app_running_mutex();
732 while ((opt = getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) {
734 case 'b': /* max bytes */
735 produce_max_bytes = atoi(optarg);
736 if (produce_max_bytes > 65536) {
737 fprintf(stderr, "randpkt: Max bytes is 65536\n");
742 case 'c': /* count */
743 produce_count = atoi(optarg);
746 case 't': /* type of packet to produce */
747 type = g_strdup(optarg);
764 /* any more command line parameters? */
766 produce_filename = argv[optind];
775 produce_type = randpkt_parse_type(type);
778 example = randpkt_find_example(produce_type);
782 randpkt_example_init(example, produce_filename, produce_max_bytes);
783 randpkt_loop(example, produce_count);
784 randpkt_example_close(example);
787 fprintf(stderr, "Can't set type in random mode\n");
791 produce_type = randpkt_parse_type(NULL);
792 example = randpkt_find_example(produce_type);
795 randpkt_example_init(example, produce_filename, produce_max_bytes);
797 while (produce_count-- > 0) {
798 randpkt_loop(example, 1);
799 produce_type = randpkt_parse_type(NULL);
801 savedump = example->dump;
803 example = randpkt_find_example(produce_type);
806 example->dump = savedump;
808 randpkt_example_close(example);
814 /* Print usage statement and exit program */
816 usage(gboolean is_error)
819 int num_entries = array_length(examples);
829 fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] [-r] filename\n");
830 fprintf(output, "Default max bytes (per packet) is 5000\n");
831 fprintf(output, "Default count is 1000.\n");
832 fprintf(output, "-r: random packet type selection\n");
833 fprintf(output, "\n");
834 fprintf(output, "Types:\n");
836 for (i = 0; i < num_entries; i++) {
837 fprintf(output, "\t%-16s%s\n", examples[i].abbrev, examples[i].longname);
840 fprintf(output, "\nIf type is not specified, a random packet will be chosen\n\n");
842 exit(is_error ? 1 : 0);
845 /* Find pkt_example record and return pointer to it */
847 randpkt_example* randpkt_find_example(int type)
849 int num_entries = array_length(examples);
852 for (i = 0; i < num_entries; i++) {
853 if (examples[i].produceable_type == type) {
858 fprintf(stderr, "randpkt: Internal error. Type %d has no entry in examples table.\n",
864 * Editor modelines - http://www.wireshark.org/tools/modelines.html
869 * indent-tabs-mode: t
872 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
873 * :indentSize=8:tabSize=8:noTabs=false: