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.
31 #include "wsutil/wsgetopt.h"
45 #include "wiretap/wtap.h"
46 #include "wsutil/file_util.h"
49 #include <wsutil/unicode-utils.h>
52 #define array_length(x) (sizeof x / sizeof x[0])
54 /* Types of produceable packets */
84 int sample_wtap_encap;
85 guint8 *sample_buffer;
87 guint8 *pseudo_buffer;
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 pkt_example examples[] = {
373 { "arp", "Address Resolution Protocol",
374 PKT_ARP, WTAP_ENCAP_ETHERNET,
375 pkt_arp, array_length(pkt_arp),
378 { "bgp", "Border Gateway Protocol",
379 PKT_BGP, WTAP_ENCAP_ETHERNET,
380 pkt_bgp, array_length(pkt_bgp),
383 { "bvlc", "BACnet Virtual Link Control",
384 PKT_BVLC, WTAP_ENCAP_ETHERNET,
385 pkt_bvlc, array_length(pkt_bvlc),
388 { "dns", "Domain Name Service",
389 PKT_DNS, WTAP_ENCAP_ETHERNET,
390 pkt_dns, array_length(pkt_dns),
394 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
398 { "fddi", "Fiber Distributed Data Interface",
399 PKT_FDDI, WTAP_ENCAP_FDDI,
403 { "giop", "General Inter-ORB Protocol",
404 PKT_GIOP, WTAP_ENCAP_ETHERNET,
405 pkt_giop, array_length(pkt_giop),
408 { "icmp", "Internet Control Message Protocol",
409 PKT_ICMP, WTAP_ENCAP_ETHERNET,
410 pkt_icmp, array_length(pkt_icmp),
413 { "ip", "Internet Protocol",
414 PKT_IP, WTAP_ENCAP_ETHERNET,
415 pkt_ip, array_length(pkt_ip),
418 { "llc", "Logical Link Control",
419 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
420 pkt_llc, array_length(pkt_llc),
423 { "m2m", "WiMAX M2M Encapsulation Protocol",
424 PKT_M2M, WTAP_ENCAP_ETHERNET,
425 pkt_m2m, array_length(pkt_m2m),
428 { "megaco", "MEGACO",
429 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
430 pkt_megaco, array_length(pkt_megaco),
433 { "nbns", "NetBIOS-over-TCP Name Service",
434 PKT_NBNS, WTAP_ENCAP_ETHERNET,
435 pkt_nbns, array_length(pkt_nbns),
438 { "ncp2222", "NetWare Core Protocol",
439 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
440 pkt_ncp2222, array_length(pkt_ncp2222),
443 { "sctp", "Stream Control Transmission Protocol",
444 PKT_SCTP, WTAP_ENCAP_ETHERNET,
445 pkt_sctp, array_length(pkt_sctp),
448 { "syslog", "Syslog message",
449 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
450 pkt_syslog, array_length(pkt_syslog),
453 { "tds", "TDS NetLib",
454 PKT_TDS, WTAP_ENCAP_ETHERNET,
455 pkt_tds, array_length(pkt_tds),
458 { "tcp", "Transmission Control Protocol",
459 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
460 pkt_tcp, array_length(pkt_tcp),
463 { "tr", "Token-Ring",
464 PKT_TR, WTAP_ENCAP_TOKEN_RING,
468 { "udp", "User Datagram Protocol",
469 PKT_UDP, WTAP_ENCAP_ETHERNET,
470 pkt_udp, array_length(pkt_udp),
473 { "usb", "Universal Serial Bus",
474 PKT_USB, WTAP_ENCAP_USB,
478 { "usb-linux", "Universal Serial Bus with Linux specific header",
479 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
487 static int parse_type(char *string);
488 static void usage(gboolean is_error);
489 static void seed(void);
491 static pkt_example* find_example(int type);
494 main(int argc, char **argv)
498 struct wtap_pkthdr pkthdr;
499 union wtap_pseudo_header *ps_header = &pkthdr.pseudo_header;
500 int i, j, len_this_pkt, len_random, err;
502 guint8 buffer[65536];
506 int produce_count = 1000; /* number of pkts to produce */
507 int produce_type = PKT_ETHERNET;
508 char *produce_filename = NULL;
509 int produce_max_bytes = 5000;
510 pkt_example *example;
513 arg_list_utf_16to8(argc, argv);
514 create_app_running_mutex();
517 while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
519 case 'b': /* max bytes */
520 produce_max_bytes = atoi(optarg);
521 if (produce_max_bytes > 65536) {
523 "randpkt: Max bytes is 65536\n");
528 case 'c': /* count */
529 produce_count = atoi(optarg);
532 case 't': /* type of packet to produce */
533 produce_type = parse_type(optarg);
545 /* any more command line parameters? */
547 produce_filename = argv[optind];
553 example = find_example(produce_type);
556 dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
557 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
560 "randpkt: Error writing to %s\n", produce_filename);
566 /* reduce max_bytes by # of bytes already in sample */
567 if (produce_max_bytes <= example->sample_length) {
569 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
570 example->sample_length);
571 fprintf(stderr, "your requested max_bytes value of %d\n",
576 produce_max_bytes -= example->sample_length;
579 memset(&pkthdr, 0, sizeof(pkthdr));
580 memset(buffer, 0, sizeof(buffer));
582 pkthdr.rec_type = REC_TYPE_PACKET;
583 pkthdr.presence_flags = WTAP_HAS_TS;
584 pkthdr.pkt_encap = example->sample_wtap_encap;
586 /* Load the sample pseudoheader into our pseudoheader buffer */
587 if (example->pseudo_buffer)
588 memcpy(ps_header, example->pseudo_buffer, example->pseudo_length);
590 /* Load the sample into our buffer */
591 if (example->sample_buffer)
592 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
594 /* Produce random packets */
595 for (i = 0; i < produce_count; i++) {
596 if (produce_max_bytes > 0) {
597 len_random = (rand() % produce_max_bytes + 1);
603 len_this_pkt = example->sample_length + len_random;
605 pkthdr.caplen = len_this_pkt;
606 pkthdr.len = len_this_pkt;
607 pkthdr.ts.secs = i; /* just for variety */
609 for (j = example->pseudo_length; j < (int) sizeof(*ps_header); j++) {
610 ((guint8*)ps_header)[j] = (rand() % 0x100);
613 for (j = example->sample_length; j < len_this_pkt; j++) {
614 /* Add format strings here and there */
615 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
616 memcpy(&buffer[j], "%s", 3);
619 buffer[j] = (rand() % 0x100);
623 /* XXX - report errors! */
624 if (!wtap_dump(dump, &pkthdr, &buffer[0], &err, &err_info)) {
625 if (err_info != NULL)
630 wtap_dump_close(dump, &err);
636 /* Print usage statement and exit program */
638 usage(gboolean is_error)
641 int num_entries = array_length(examples);
651 fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
652 fprintf(output, "Default max bytes (per packet) is 5000\n");
653 fprintf(output, "Default count is 1000.\n");
654 fprintf(output, "Types:\n");
656 for (i = 0; i < num_entries; i++) {
657 fprintf(output, "\t%-16s%s\n", examples[i].abbrev, examples[i].longname);
660 fprintf(output, "\n");
662 exit(is_error ? 1 : 0);
665 /* Parse command-line option "type" and return enum type */
667 int parse_type(char *string)
669 int num_entries = array_length(examples);
672 for (i = 0; i < num_entries; i++) {
673 if (strcmp(examples[i].abbrev, string) == 0) {
674 return examples[i].produceable_type;
679 fprintf(stderr, "randpkt: Type %s not known.\n", string);
683 /* Find pkt_example record and return pointer to it */
685 pkt_example* find_example(int type)
687 int num_entries = array_length(examples);
690 for (i = 0; i < num_entries; i++) {
691 if (examples[i].produceable_type == type) {
697 "randpkt: Internal error. Type %d has no entry in examples table.\n",
702 /* Seed the random-number generator */
706 unsigned int randomness;
712 #define RANDOM_DEV "/dev/urandom"
715 * Assume it's at least worth trying /dev/urandom on UN*X.
716 * If it doesn't exist, fall back on time().
718 * XXX - Use CryptGenRandom on Windows?
720 fd = ws_open(RANDOM_DEV, O_RDONLY);
722 if (errno != ENOENT) {
724 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
731 ret = ws_read(fd, &randomness, sizeof randomness);
734 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
738 if ((size_t)ret != sizeof randomness) {
740 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
741 (unsigned long)sizeof randomness, (long)ret);
751 randomness = (unsigned int) now;
757 * Editor modelines - http://www.wireshark.org/tools/modelines.html
762 * indent-tabs-mode: t
765 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
766 * :indentSize=8:tabSize=8:noTabs=false: