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.
34 #ifndef HAVE_GETOPT_LONG
35 #include "wsutil/wsgetopt.h"
49 #include "wiretap/wtap.h"
50 #include "wsutil/file_util.h"
51 #include <wsutil/ws_diag_control.h>
54 #include <wsutil/unicode-utils.h>
57 #define array_length(x) (sizeof x / sizeof x[0])
59 /* Types of produceable packets */
89 int sample_wtap_encap;
90 guint8 *sample_buffer;
92 guint8 *pseudo_buffer;
96 /* Ethernet, indicating ARP */
98 0xff, 0xff, 0xff, 0xff,
99 0xff, 0xff, 0x00, 0x00,
100 0x32, 0x25, 0x0f, 0xff,
104 /* Ethernet+IP+UDP, indicating DNS */
106 0xff, 0xff, 0xff, 0xff,
107 0xff, 0xff, 0x01, 0x01,
108 0x01, 0x01, 0x01, 0x01,
111 0x45, 0x00, 0x00, 0x3c,
112 0xc5, 0x9e, 0x40, 0x00,
113 0xff, 0x11, 0xd7, 0xe0,
114 0xd0, 0x15, 0x02, 0xb8,
115 0x0a, 0x01, 0x01, 0x63,
117 0x05, 0xe8, 0x00, 0x35,
118 0xff, 0xff, 0x2a, 0xb9,
122 /* Ethernet+IP, indicating ICMP */
123 guint8 pkt_icmp[] = {
124 0xff, 0xff, 0xff, 0xff,
125 0xff, 0xff, 0x01, 0x01,
126 0x01, 0x01, 0x01, 0x01,
129 0x45, 0x00, 0x00, 0x54,
130 0x8f, 0xb3, 0x40, 0x00,
131 0xfd, 0x01, 0x8a, 0x99,
132 0xcc, 0xfc, 0x66, 0x0b,
133 0xce, 0x41, 0x62, 0x12
136 /* Ethernet, indicating IP */
138 0xff, 0xff, 0xff, 0xff,
139 0xff, 0xff, 0x01, 0x01,
140 0x01, 0x01, 0x01, 0x01,
144 /* TR, indicating LLC */
146 0x10, 0x40, 0x68, 0x00,
147 0x19, 0x69, 0x95, 0x8b,
148 0x00, 0x01, 0xfa, 0x68,
152 /* Ethernet, indicating WiMAX M2M */
154 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0x00, 0x00,
156 0x32, 0x25, 0x0f, 0xff,
160 /* Ethernet+IP+UDP, indicating NBNS */
161 guint8 pkt_nbns[] = {
162 0xff, 0xff, 0xff, 0xff,
163 0xff, 0xff, 0x01, 0x01,
164 0x01, 0x01, 0x01, 0x01,
167 0x45, 0x00, 0x00, 0x3c,
168 0xc5, 0x9e, 0x40, 0x00,
169 0xff, 0x11, 0xd7, 0xe0,
170 0xd0, 0x15, 0x02, 0xb8,
171 0x0a, 0x01, 0x01, 0x63,
173 0x00, 0x89, 0x00, 0x89,
174 0x00, 0x00, 0x2a, 0xb9,
178 /* Ethernet+IP+UDP, indicating syslog */
179 guint8 pkt_syslog[] = {
180 0xff, 0xff, 0xff, 0xff,
181 0xff, 0xff, 0x01, 0x01,
182 0x01, 0x01, 0x01, 0x01,
185 0x45, 0x00, 0x00, 0x64,
186 0x20, 0x48, 0x00, 0x00,
187 0xfc, 0x11, 0xf8, 0x03,
188 0xd0, 0x15, 0x02, 0xb8,
189 0x0a, 0x01, 0x01, 0x63,
191 0x05, 0xe8, 0x02, 0x02,
192 0x00, 0x50, 0x51, 0xe1,
196 /* TR+LLC+IP, indicating TCP */
198 0x10, 0x40, 0x68, 0x00,
199 0x19, 0x69, 0x95, 0x8b,
200 0x00, 0x01, 0xfa, 0x68,
203 0xaa, 0xaa, 0x03, 0x00,
204 0x00, 0x00, 0x08, 0x00,
206 0x45, 0x00, 0x00, 0x28,
207 0x0b, 0x0b, 0x40, 0x00,
208 0x20, 0x06, 0x85, 0x37,
209 0xc0, 0xa8, 0x27, 0x01,
210 0xc0, 0xa8, 0x22, 0x3c
213 /* Ethernet+IP, indicating UDP */
215 0xff, 0xff, 0xff, 0xff,
216 0xff, 0xff, 0x01, 0x01,
217 0x01, 0x01, 0x01, 0x01,
220 0x45, 0x00, 0x00, 0x3c,
221 0xc5, 0x9e, 0x40, 0x00,
222 0xff, 0x11, 0xd7, 0xe0,
223 0xd0, 0x15, 0x02, 0xb8,
224 0x0a, 0x01, 0x01, 0x63
227 /* Ethernet+IP+UDP, indicating BVLC */
228 guint8 pkt_bvlc[] = {
229 0xff, 0xff, 0xff, 0xff,
230 0xff, 0xff, 0x01, 0x01,
231 0x01, 0x01, 0x01, 0x01,
234 0x45, 0x00, 0x00, 0x3c,
235 0xc5, 0x9e, 0x40, 0x00,
236 0xff, 0x11, 0x01, 0xaa,
237 0xc1, 0xff, 0x19, 0x1e,
238 0xc1, 0xff, 0x19, 0xff,
239 0xba, 0xc0, 0xba, 0xc0,
240 0x00, 0xff, 0x2d, 0x5e,
244 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
245 guint8 pkt_ncp2222[] = {
246 0x10, 0x40, 0x00, 0x00,
247 0xf6, 0x7c, 0x9b, 0x70,
248 0x68, 0x00, 0x19, 0x69,
249 0x95, 0x8b, 0xe0, 0xe0,
250 0x03, 0xff, 0xff, 0x00,
251 0x25, 0x02, 0x11, 0x00,
252 0x00, 0x74, 0x14, 0x00,
253 0x00, 0x00, 0x00, 0x00,
254 0x01, 0x04, 0x51, 0x00,
255 0x00, 0x00, 0x04, 0x00,
256 0x02, 0x16, 0x19, 0x7a,
257 0x84, 0x40, 0x01, 0x22,
261 /* Ethernet+IP+TCP, indicating GIOP */
262 guint8 pkt_giop[] = {
263 0xff, 0xff, 0xff, 0xff,
264 0xff, 0xff, 0x01, 0x01,
265 0x01, 0x01, 0x01, 0x01,
268 0x45, 0x00, 0x00, 0xa6,
269 0x00, 0x2f, 0x40, 0x00,
270 0x40, 0x06, 0x3c, 0x21,
271 0x7f, 0x00, 0x00, 0x01,
272 0x7f, 0x00, 0x00, 0x01,
274 0x30, 0x39, 0x04, 0x05,
275 0xac, 0x02, 0x1e, 0x69,
276 0xab, 0x74, 0xab, 0x64,
277 0x80, 0x18, 0x79, 0x60,
278 0xc4, 0xb8, 0x00, 0x00,
279 0x01, 0x01, 0x08, 0x0a,
280 0x00, 0x00, 0x48, 0xf5,
281 0x00, 0x00, 0x48, 0xf5,
283 0x47, 0x49, 0x4f, 0x50,
284 0x01, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x30,
286 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x01,
291 /* Ethernet+IP+TCP, indicating BGP */
293 0xff, 0xff, 0xff, 0xff,
294 0xff, 0xff, 0x01, 0x01,
295 0x01, 0x01, 0x01, 0x01,
298 0x45, 0x00, 0x00, 0xa6,
299 0x00, 0x2f, 0x40, 0x00,
300 0x40, 0x06, 0x3c, 0x21,
301 0x7f, 0x00, 0x00, 0x01,
302 0x7f, 0x00, 0x00, 0x01,
304 0x30, 0x39, 0x00, 0xb3,
305 0xac, 0x02, 0x1e, 0x69,
306 0xab, 0x74, 0xab, 0x64,
307 0x80, 0x18, 0x79, 0x60,
308 0xc4, 0xb8, 0x00, 0x00,
309 0x01, 0x01, 0x08, 0x0a,
310 0x00, 0x00, 0x48, 0xf5,
311 0x00, 0x00, 0x48, 0xf5,
313 0xff, 0xff, 0xff, 0xff,
314 0xff, 0xff, 0xff, 0xff,
315 0xff, 0xff, 0xff, 0xff,
316 0xff, 0xff, 0xff, 0xff,
319 /* Ethernet+IP+TCP, indicating TDS NetLib */
321 0x00, 0x50, 0x8b, 0x0d,
322 0x7a, 0xed, 0x00, 0x08,
323 0xa3, 0x98, 0x39, 0x81,
326 0x45, 0x00, 0x03, 0x8d,
327 0x90, 0xd4, 0x40, 0x00,
328 0x7c, 0x06, 0xc3, 0x1b,
329 0xac, 0x14, 0x02, 0x22,
330 0x0a, 0xc2, 0xee, 0x82,
332 0x05, 0x99, 0x08, 0xf8,
333 0xff, 0x4e, 0x85, 0x46,
334 0xa2, 0xb4, 0x42, 0xaa,
335 0x50, 0x18, 0x3c, 0x28,
336 0x0f, 0xda, 0x00, 0x00,
339 /* Ethernet+IP, indicating SCTP */
340 guint8 pkt_sctp[] = {
341 0x00, 0xa0, 0x80, 0x00,
342 0x5e, 0x46, 0x08, 0x00,
343 0x03, 0x4a, 0x00, 0x35,
346 0x45, 0x00, 0x00, 0x7c,
347 0x14, 0x1c, 0x00, 0x00,
348 0x3b, 0x84, 0x4a, 0x54,
349 0x0a, 0x1c, 0x06, 0x2b,
350 0x0a, 0x1c, 0x06, 0x2c,
354 /* Ethernet+IP+SCTP, indicating MEGACO */
355 guint8 pkt_megaco[] = {
356 0x00, 0xa0, 0x80, 0x00,
357 0x5e, 0x46, 0x08, 0x00,
358 0x03, 0x4a, 0x00, 0x35,
361 0x45, 0x00, 0x00, 0x7c,
362 0x14, 0x1c, 0x00, 0x00,
363 0x3b, 0x84, 0x4a, 0x54,
364 0x0a, 0x1c, 0x06, 0x2b,
365 0x0a, 0x1c, 0x06, 0x2c,
367 0x40, 0x00, 0x0b, 0x80,
368 0x00, 0x01, 0x6f, 0x0a,
369 0x6d, 0xb0, 0x18, 0x82,
370 0x00, 0x03, 0x00, 0x5b,
371 0x28, 0x02, 0x43, 0x45,
372 0x00, 0x00, 0xa0, 0xbd,
373 0x00, 0x00, 0x00, 0x07,
376 /* This little data table drives the whole program */
377 pkt_example examples[] = {
378 { "arp", "Address Resolution Protocol",
379 PKT_ARP, WTAP_ENCAP_ETHERNET,
380 pkt_arp, array_length(pkt_arp),
383 { "bgp", "Border Gateway Protocol",
384 PKT_BGP, WTAP_ENCAP_ETHERNET,
385 pkt_bgp, array_length(pkt_bgp),
388 { "bvlc", "BACnet Virtual Link Control",
389 PKT_BVLC, WTAP_ENCAP_ETHERNET,
390 pkt_bvlc, array_length(pkt_bvlc),
393 { "dns", "Domain Name Service",
394 PKT_DNS, WTAP_ENCAP_ETHERNET,
395 pkt_dns, array_length(pkt_dns),
399 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
403 { "fddi", "Fiber Distributed Data Interface",
404 PKT_FDDI, WTAP_ENCAP_FDDI,
408 { "giop", "General Inter-ORB Protocol",
409 PKT_GIOP, WTAP_ENCAP_ETHERNET,
410 pkt_giop, array_length(pkt_giop),
413 { "icmp", "Internet Control Message Protocol",
414 PKT_ICMP, WTAP_ENCAP_ETHERNET,
415 pkt_icmp, array_length(pkt_icmp),
418 { "ip", "Internet Protocol",
419 PKT_IP, WTAP_ENCAP_ETHERNET,
420 pkt_ip, array_length(pkt_ip),
423 { "llc", "Logical Link Control",
424 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
425 pkt_llc, array_length(pkt_llc),
428 { "m2m", "WiMAX M2M Encapsulation Protocol",
429 PKT_M2M, WTAP_ENCAP_ETHERNET,
430 pkt_m2m, array_length(pkt_m2m),
433 { "megaco", "MEGACO",
434 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
435 pkt_megaco, array_length(pkt_megaco),
438 { "nbns", "NetBIOS-over-TCP Name Service",
439 PKT_NBNS, WTAP_ENCAP_ETHERNET,
440 pkt_nbns, array_length(pkt_nbns),
443 { "ncp2222", "NetWare Core Protocol",
444 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
445 pkt_ncp2222, array_length(pkt_ncp2222),
448 { "sctp", "Stream Control Transmission Protocol",
449 PKT_SCTP, WTAP_ENCAP_ETHERNET,
450 pkt_sctp, array_length(pkt_sctp),
453 { "syslog", "Syslog message",
454 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
455 pkt_syslog, array_length(pkt_syslog),
458 { "tds", "TDS NetLib",
459 PKT_TDS, WTAP_ENCAP_ETHERNET,
460 pkt_tds, array_length(pkt_tds),
463 { "tcp", "Transmission Control Protocol",
464 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
465 pkt_tcp, array_length(pkt_tcp),
468 { "tr", "Token-Ring",
469 PKT_TR, WTAP_ENCAP_TOKEN_RING,
473 { "udp", "User Datagram Protocol",
474 PKT_UDP, WTAP_ENCAP_ETHERNET,
475 pkt_udp, array_length(pkt_udp),
478 { "usb", "Universal Serial Bus",
479 PKT_USB, WTAP_ENCAP_USB,
483 { "usb-linux", "Universal Serial Bus with Linux specific header",
484 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
492 static int parse_type(char *string);
493 static void usage(gboolean is_error);
494 static void seed(void);
496 static pkt_example* find_example(int type);
499 main(int argc, char **argv)
503 struct wtap_pkthdr pkthdr;
504 union wtap_pseudo_header *ps_header = &pkthdr.pseudo_header;
505 int i, j, len_this_pkt, len_random, err;
507 guint8 buffer[65536];
511 int produce_count = 1000; /* number of pkts to produce */
512 int produce_type = PKT_ETHERNET;
513 char *produce_filename = NULL;
514 int produce_max_bytes = 5000;
515 pkt_example *example;
517 static const struct option long_options[] = {
518 {(char *)"help", no_argument, NULL, 'h'},
524 arg_list_utf_16to8(argc, argv);
525 create_app_running_mutex();
528 while ((opt = getopt_long(argc, argv, "b:c:ht:", long_options, NULL)) != -1) {
530 case 'b': /* max bytes */
531 produce_max_bytes = atoi(optarg);
532 if (produce_max_bytes > 65536) {
534 "randpkt: Max bytes is 65536\n");
539 case 'c': /* count */
540 produce_count = atoi(optarg);
543 case 't': /* type of packet to produce */
544 produce_type = parse_type(optarg);
556 /* any more command line parameters? */
558 produce_filename = argv[optind];
564 example = find_example(produce_type);
567 dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
568 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
571 "randpkt: Error writing to %s\n", produce_filename);
577 /* reduce max_bytes by # of bytes already in sample */
578 if (produce_max_bytes <= example->sample_length) {
580 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
581 example->sample_length);
582 fprintf(stderr, "your requested max_bytes value of %d\n",
587 produce_max_bytes -= example->sample_length;
590 memset(&pkthdr, 0, sizeof(pkthdr));
591 memset(buffer, 0, sizeof(buffer));
593 pkthdr.rec_type = REC_TYPE_PACKET;
594 pkthdr.presence_flags = WTAP_HAS_TS;
595 pkthdr.pkt_encap = example->sample_wtap_encap;
597 /* Load the sample pseudoheader into our pseudoheader buffer */
598 if (example->pseudo_buffer)
599 memcpy(ps_header, example->pseudo_buffer, example->pseudo_length);
601 /* Load the sample into our buffer */
602 if (example->sample_buffer)
603 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
605 /* Produce random packets */
606 for (i = 0; i < produce_count; i++) {
607 if (produce_max_bytes > 0) {
608 len_random = (rand() % produce_max_bytes + 1);
614 len_this_pkt = example->sample_length + len_random;
616 pkthdr.caplen = len_this_pkt;
617 pkthdr.len = len_this_pkt;
618 pkthdr.ts.secs = i; /* just for variety */
620 for (j = example->pseudo_length; j < (int) sizeof(*ps_header); j++) {
621 ((guint8*)ps_header)[j] = (rand() % 0x100);
624 for (j = example->sample_length; j < len_this_pkt; j++) {
625 /* Add format strings here and there */
626 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
627 memcpy(&buffer[j], "%s", 3);
630 buffer[j] = (rand() % 0x100);
634 /* XXX - report errors! */
635 if (!wtap_dump(dump, &pkthdr, &buffer[0], &err, &err_info)) {
636 if (err_info != NULL)
641 wtap_dump_close(dump, &err);
647 /* Print usage statement and exit program */
649 usage(gboolean is_error)
652 int num_entries = array_length(examples);
662 fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
663 fprintf(output, "Default max bytes (per packet) is 5000\n");
664 fprintf(output, "Default count is 1000.\n");
665 fprintf(output, "Types:\n");
667 for (i = 0; i < num_entries; i++) {
668 fprintf(output, "\t%-16s%s\n", examples[i].abbrev, examples[i].longname);
671 fprintf(output, "\n");
673 exit(is_error ? 1 : 0);
676 /* Parse command-line option "type" and return enum type */
678 int parse_type(char *string)
680 int num_entries = array_length(examples);
683 for (i = 0; i < num_entries; i++) {
684 if (strcmp(examples[i].abbrev, string) == 0) {
685 return examples[i].produceable_type;
690 fprintf(stderr, "randpkt: Type %s not known.\n", string);
694 /* Find pkt_example record and return pointer to it */
696 pkt_example* find_example(int type)
698 int num_entries = array_length(examples);
701 for (i = 0; i < num_entries; i++) {
702 if (examples[i].produceable_type == type) {
708 "randpkt: Internal error. Type %d has no entry in examples table.\n",
713 /* Seed the random-number generator */
717 unsigned int randomness;
723 #define RANDOM_DEV "/dev/urandom"
726 * Assume it's at least worth trying /dev/urandom on UN*X.
727 * If it doesn't exist, fall back on time().
729 * XXX - Use CryptGenRandom on Windows?
731 fd = ws_open(RANDOM_DEV, O_RDONLY);
733 if (errno != ENOENT) {
735 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
742 ret = ws_read(fd, &randomness, sizeof randomness);
745 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
749 if ((size_t)ret != sizeof randomness) {
751 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
752 (unsigned long)sizeof randomness, (long)ret);
762 randomness = (unsigned int) now;
768 * Editor modelines - http://www.wireshark.org/tools/modelines.html
773 * indent-tabs-mode: t
776 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
777 * :indentSize=8:tabSize=8:noTabs=false: