4 * Creates random packet traces. Useful for debugging sniffers by testing
5 * assumptions about the veracity of the data found in the packet.
9 * Copyright (C) 1999 by Gilbert Ramirez <gram@alumni.rice.edu>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include "wsutil/wsgetopt.h"
51 #include "wiretap/wtap.h"
58 #define array_length(x) (sizeof x / sizeof x[0])
60 /* Types of produceable packets */
90 int sample_wtap_encap;
91 guint8 *sample_buffer;
93 guint8 *pseudo_buffer;
97 /* Ethernet, indicating ARP */
99 0xff, 0xff, 0xff, 0xff,
100 0xff, 0xff, 0x00, 0x00,
101 0x32, 0x25, 0x0f, 0xff,
105 /* Ethernet+IP+UDP, indicating DNS */
107 0xff, 0xff, 0xff, 0xff,
108 0xff, 0xff, 0x01, 0x01,
109 0x01, 0x01, 0x01, 0x01,
112 0x45, 0x00, 0x00, 0x3c,
113 0xc5, 0x9e, 0x40, 0x00,
114 0xff, 0x11, 0xd7, 0xe0,
115 0xd0, 0x15, 0x02, 0xb8,
116 0x0a, 0x01, 0x01, 0x63,
118 0x05, 0xe8, 0x00, 0x35,
119 0xff, 0xff, 0x2a, 0xb9,
123 /* Ethernet+IP, indicating ICMP */
124 guint8 pkt_icmp[] = {
125 0xff, 0xff, 0xff, 0xff,
126 0xff, 0xff, 0x01, 0x01,
127 0x01, 0x01, 0x01, 0x01,
130 0x45, 0x00, 0x00, 0x54,
131 0x8f, 0xb3, 0x40, 0x00,
132 0xfd, 0x01, 0x8a, 0x99,
133 0xcc, 0xfc, 0x66, 0x0b,
134 0xce, 0x41, 0x62, 0x12
137 /* Ethernet, indicating IP */
139 0xff, 0xff, 0xff, 0xff,
140 0xff, 0xff, 0x01, 0x01,
141 0x01, 0x01, 0x01, 0x01,
145 /* TR, indicating LLC */
147 0x10, 0x40, 0x68, 0x00,
148 0x19, 0x69, 0x95, 0x8b,
149 0x00, 0x01, 0xfa, 0x68,
153 /* Ethernet, indicating WiMAX M2M */
155 0xff, 0xff, 0xff, 0xff,
156 0xff, 0xff, 0x00, 0x00,
157 0x32, 0x25, 0x0f, 0xff,
161 /* Ethernet+IP+UDP, indicating NBNS */
162 guint8 pkt_nbns[] = {
163 0xff, 0xff, 0xff, 0xff,
164 0xff, 0xff, 0x01, 0x01,
165 0x01, 0x01, 0x01, 0x01,
168 0x45, 0x00, 0x00, 0x3c,
169 0xc5, 0x9e, 0x40, 0x00,
170 0xff, 0x11, 0xd7, 0xe0,
171 0xd0, 0x15, 0x02, 0xb8,
172 0x0a, 0x01, 0x01, 0x63,
174 0x00, 0x89, 0x00, 0x89,
175 0x00, 0x00, 0x2a, 0xb9,
179 /* Ethernet+IP+UDP, indicating syslog */
180 guint8 pkt_syslog[] = {
181 0xff, 0xff, 0xff, 0xff,
182 0xff, 0xff, 0x01, 0x01,
183 0x01, 0x01, 0x01, 0x01,
186 0x45, 0x00, 0x00, 0x64,
187 0x20, 0x48, 0x00, 0x00,
188 0xfc, 0x11, 0xf8, 0x03,
189 0xd0, 0x15, 0x02, 0xb8,
190 0x0a, 0x01, 0x01, 0x63,
192 0x05, 0xe8, 0x02, 0x02,
193 0x00, 0x50, 0x51, 0xe1,
197 /* TR+LLC+IP, indicating TCP */
199 0x10, 0x40, 0x68, 0x00,
200 0x19, 0x69, 0x95, 0x8b,
201 0x00, 0x01, 0xfa, 0x68,
204 0xaa, 0xaa, 0x03, 0x00,
205 0x00, 0x00, 0x08, 0x00,
207 0x45, 0x00, 0x00, 0x28,
208 0x0b, 0x0b, 0x40, 0x00,
209 0x20, 0x06, 0x85, 0x37,
210 0xc0, 0xa8, 0x27, 0x01,
211 0xc0, 0xa8, 0x22, 0x3c
214 /* Ethernet+IP, indicating UDP */
216 0xff, 0xff, 0xff, 0xff,
217 0xff, 0xff, 0x01, 0x01,
218 0x01, 0x01, 0x01, 0x01,
221 0x45, 0x00, 0x00, 0x3c,
222 0xc5, 0x9e, 0x40, 0x00,
223 0xff, 0x11, 0xd7, 0xe0,
224 0xd0, 0x15, 0x02, 0xb8,
225 0x0a, 0x01, 0x01, 0x63
228 /* Ethernet+IP+UDP, indicating BVLC */
229 guint8 pkt_bvlc[] = {
230 0xff, 0xff, 0xff, 0xff,
231 0xff, 0xff, 0x01, 0x01,
232 0x01, 0x01, 0x01, 0x01,
235 0x45, 0x00, 0x00, 0x3c,
236 0xc5, 0x9e, 0x40, 0x00,
237 0xff, 0x11, 0x01, 0xaa,
238 0xc1, 0xff, 0x19, 0x1e,
239 0xc1, 0xff, 0x19, 0xff,
240 0xba, 0xc0, 0xba, 0xc0,
241 0x00, 0xff, 0x2d, 0x5e,
245 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
246 guint8 pkt_ncp2222[] = {
247 0x10, 0x40, 0x00, 0x00,
248 0xf6, 0x7c, 0x9b, 0x70,
249 0x68, 0x00, 0x19, 0x69,
250 0x95, 0x8b, 0xe0, 0xe0,
251 0x03, 0xff, 0xff, 0x00,
252 0x25, 0x02, 0x11, 0x00,
253 0x00, 0x74, 0x14, 0x00,
254 0x00, 0x00, 0x00, 0x00,
255 0x01, 0x04, 0x51, 0x00,
256 0x00, 0x00, 0x04, 0x00,
257 0x02, 0x16, 0x19, 0x7a,
258 0x84, 0x40, 0x01, 0x22,
262 /* Ethernet+IP+TCP, indicating GIOP */
263 guint8 pkt_giop[] = {
264 0xff, 0xff, 0xff, 0xff,
265 0xff, 0xff, 0x01, 0x01,
266 0x01, 0x01, 0x01, 0x01,
269 0x45, 0x00, 0x00, 0xa6,
270 0x00, 0x2f, 0x40, 0x00,
271 0x40, 0x06, 0x3c, 0x21,
272 0x7f, 0x00, 0x00, 0x01,
273 0x7f, 0x00, 0x00, 0x01,
275 0x30, 0x39, 0x04, 0x05,
276 0xac, 0x02, 0x1e, 0x69,
277 0xab, 0x74, 0xab, 0x64,
278 0x80, 0x18, 0x79, 0x60,
279 0xc4, 0xb8, 0x00, 0x00,
280 0x01, 0x01, 0x08, 0x0a,
281 0x00, 0x00, 0x48, 0xf5,
282 0x00, 0x00, 0x48, 0xf5,
284 0x47, 0x49, 0x4f, 0x50,
285 0x01, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x30,
287 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x01,
292 /* Ethernet+IP+TCP, indicating BGP */
294 0xff, 0xff, 0xff, 0xff,
295 0xff, 0xff, 0x01, 0x01,
296 0x01, 0x01, 0x01, 0x01,
299 0x45, 0x00, 0x00, 0xa6,
300 0x00, 0x2f, 0x40, 0x00,
301 0x40, 0x06, 0x3c, 0x21,
302 0x7f, 0x00, 0x00, 0x01,
303 0x7f, 0x00, 0x00, 0x01,
305 0x30, 0x39, 0x00, 0xb3,
306 0xac, 0x02, 0x1e, 0x69,
307 0xab, 0x74, 0xab, 0x64,
308 0x80, 0x18, 0x79, 0x60,
309 0xc4, 0xb8, 0x00, 0x00,
310 0x01, 0x01, 0x08, 0x0a,
311 0x00, 0x00, 0x48, 0xf5,
312 0x00, 0x00, 0x48, 0xf5,
314 0xff, 0xff, 0xff, 0xff,
315 0xff, 0xff, 0xff, 0xff,
316 0xff, 0xff, 0xff, 0xff,
317 0xff, 0xff, 0xff, 0xff,
320 /* Ethernet+IP+TCP, indicating TDS NetLib */
322 0x00, 0x50, 0x8b, 0x0d,
323 0x7a, 0xed, 0x00, 0x08,
324 0xa3, 0x98, 0x39, 0x81,
327 0x45, 0x00, 0x03, 0x8d,
328 0x90, 0xd4, 0x40, 0x00,
329 0x7c, 0x06, 0xc3, 0x1b,
330 0xac, 0x14, 0x02, 0x22,
331 0x0a, 0xc2, 0xee, 0x82,
333 0x05, 0x99, 0x08, 0xf8,
334 0xff, 0x4e, 0x85, 0x46,
335 0xa2, 0xb4, 0x42, 0xaa,
336 0x50, 0x18, 0x3c, 0x28,
337 0x0f, 0xda, 0x00, 0x00,
340 /* Ethernet+IP, indicating SCTP */
341 guint8 pkt_sctp[] = {
342 0x00, 0xa0, 0x80, 0x00,
343 0x5e, 0x46, 0x08, 0x00,
344 0x03, 0x4a, 0x00, 0x35,
347 0x45, 0x00, 0x00, 0x7c,
348 0x14, 0x1c, 0x00, 0x00,
349 0x3b, 0x84, 0x4a, 0x54,
350 0x0a, 0x1c, 0x06, 0x2b,
351 0x0a, 0x1c, 0x06, 0x2c,
355 /* Ethernet+IP+SCTP, indicating MEGACO */
356 guint8 pkt_megaco[] = {
357 0x00, 0xa0, 0x80, 0x00,
358 0x5e, 0x46, 0x08, 0x00,
359 0x03, 0x4a, 0x00, 0x35,
362 0x45, 0x00, 0x00, 0x7c,
363 0x14, 0x1c, 0x00, 0x00,
364 0x3b, 0x84, 0x4a, 0x54,
365 0x0a, 0x1c, 0x06, 0x2b,
366 0x0a, 0x1c, 0x06, 0x2c,
368 0x40, 0x00, 0x0b, 0x80,
369 0x00, 0x01, 0x6f, 0x0a,
370 0x6d, 0xb0, 0x18, 0x82,
371 0x00, 0x03, 0x00, 0x5b,
372 0x28, 0x02, 0x43, 0x45,
373 0x00, 0x00, 0xa0, 0xbd,
374 0x00, 0x00, 0x00, 0x07,
377 /* This little data table drives the whole program */
378 pkt_example examples[] = {
379 { "arp", "Address Resolution Protocol",
380 PKT_ARP, WTAP_ENCAP_ETHERNET,
381 pkt_arp, array_length(pkt_arp),
384 { "bgp", "Border Gateway Protocol",
385 PKT_BGP, WTAP_ENCAP_ETHERNET,
386 pkt_bgp, array_length(pkt_bgp),
389 { "bvlc", "BACnet Virtual Link Control",
390 PKT_BVLC, WTAP_ENCAP_ETHERNET,
391 pkt_bvlc, array_length(pkt_bvlc),
394 { "dns", "Domain Name Service",
395 PKT_DNS, WTAP_ENCAP_ETHERNET,
396 pkt_dns, array_length(pkt_dns),
400 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
404 { "fddi", "Fiber Distributed Data Interface",
405 PKT_FDDI, WTAP_ENCAP_FDDI,
409 { "giop", "General Inter-ORB Protocol",
410 PKT_GIOP, WTAP_ENCAP_ETHERNET,
411 pkt_giop, array_length(pkt_giop),
414 { "icmp", "Internet Control Message Protocol",
415 PKT_ICMP, WTAP_ENCAP_ETHERNET,
416 pkt_icmp, array_length(pkt_icmp),
419 { "ip", "Internet Protocol",
420 PKT_IP, WTAP_ENCAP_ETHERNET,
421 pkt_ip, array_length(pkt_ip),
424 { "llc", "Logical Link Control",
425 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
426 pkt_llc, array_length(pkt_llc),
429 { "m2m", "WiMAX M2M Encapsulation Protocol",
430 PKT_M2M, WTAP_ENCAP_ETHERNET,
431 pkt_m2m, array_length(pkt_m2m),
434 { "megaco", "MEGACO",
435 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
436 pkt_megaco, array_length(pkt_megaco),
439 { "nbns", "NetBIOS-over-TCP Name Service",
440 PKT_NBNS, WTAP_ENCAP_ETHERNET,
441 pkt_nbns, array_length(pkt_nbns),
444 { "ncp2222", "NetWare Core Protocol",
445 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
446 pkt_ncp2222, array_length(pkt_ncp2222),
449 { "sctp", "Stream Control Transmission Protocol",
450 PKT_SCTP, WTAP_ENCAP_ETHERNET,
451 pkt_sctp, array_length(pkt_sctp),
454 { "syslog", "Syslog message",
455 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
456 pkt_syslog, array_length(pkt_syslog),
459 { "tds", "TDS NetLib",
460 PKT_TDS, WTAP_ENCAP_ETHERNET,
461 pkt_tds, array_length(pkt_tds),
464 { "tcp", "Transmission Control Protocol",
465 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
466 pkt_tcp, array_length(pkt_tcp),
469 { "tr", "Token-Ring",
470 PKT_TR, WTAP_ENCAP_TOKEN_RING,
474 { "udp", "User Datagram Protocol",
475 PKT_UDP, WTAP_ENCAP_ETHERNET,
476 pkt_udp, array_length(pkt_udp),
479 { "usb", "Universal Serial Bus",
480 PKT_USB, WTAP_ENCAP_USB,
484 { "usb-linux", "Universal Serial Bus with Linux specific header",
485 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
493 static int parse_type(char *string);
494 static void usage(void);
495 static void seed(void);
497 static pkt_example* find_example(int type);
500 main(int argc, char **argv)
504 struct wtap_pkthdr pkthdr;
505 union wtap_pseudo_header ps_header;
506 int i, j, len_this_pkt, len_random, err;
507 guint8 buffer[65536];
517 int produce_count = 1000; /* number of pkts to produce */
518 int produce_type = PKT_ETHERNET;
519 char *produce_filename = NULL;
520 int produce_max_bytes = 5000;
521 pkt_example *example;
524 /* Convert our arg list to UTF-8. */
525 wc_argv = CommandLineToArgvW(GetCommandLineW(), &wc_argc);
526 if (wc_argv && wc_argc == argc) {
527 for (i = 0; i < argc; i++) {
528 argv[i] = g_utf16_to_utf8(wc_argv[i], -1, NULL, NULL, NULL);
530 } /* XXX else bail because something is horribly, horribly wrong? */
533 while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
535 case 'b': /* max bytes */
536 produce_max_bytes = atoi(optarg);
537 if (produce_max_bytes > 65536) {
539 "randpkt: Max bytes is 65536\n");
544 case 'c': /* count */
545 produce_count = atoi(optarg);
548 case 't': /* type of packet to produce */
549 produce_type = parse_type(optarg);
559 /* any more command line parameters? */
561 produce_filename = argv[optind];
567 example = find_example(produce_type);
570 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
571 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
574 "randpkt: Error writing to %s\n", produce_filename);
580 /* reduce max_bytes by # of bytes already in sample */
581 if (produce_max_bytes <= example->sample_length) {
583 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
584 example->sample_length);
585 fprintf(stderr, "your requested max_bytes value of %d\n",
590 produce_max_bytes -= example->sample_length;
593 memset(&pkthdr, 0, sizeof(pkthdr));
594 memset(&ps_header, 0, sizeof(ps_header));
595 memset(buffer, 0, sizeof(buffer));
597 pkthdr.pkt_encap = example->sample_wtap_encap;
599 /* Load the sample pseudoheader into our pseudoheader buffer */
600 if (example->pseudo_buffer)
601 memcpy(&ps_header, example->pseudo_buffer, example->pseudo_length);
603 /* Load the sample into our buffer */
604 if (example->sample_buffer)
605 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
607 /* Produce random packets */
608 for (i = 0; i < produce_count; i++) {
609 if (produce_max_bytes > 0) {
610 len_random = (rand() % produce_max_bytes + 1);
616 len_this_pkt = example->sample_length + len_random;
618 pkthdr.caplen = len_this_pkt;
619 pkthdr.len = len_this_pkt;
620 pkthdr.ts.secs = i; /* just for variety */
622 for (j = example->pseudo_length; j < (int) sizeof(ps_header); j++) {
623 ((guint8*)&ps_header)[j] = (rand() % 0x100);
626 for (j = example->sample_length; j < len_this_pkt; j++) {
627 /* Add format strings here and there */
628 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
629 memcpy(&buffer[j], "%s", 3);
632 buffer[j] = (rand() % 0x100);
636 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
639 wtap_dump_close(dump, &err);
645 /* Print usage statement and exit program */
649 int num_entries = array_length(examples);
652 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
653 printf("Default max bytes (per packet) is 5000\n");
654 printf("Default count is 1000.\n");
657 for (i = 0; i < num_entries; i++) {
658 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
666 /* Parse command-line option "type" and return enum type */
668 int parse_type(char *string)
670 int num_entries = array_length(examples);
673 for (i = 0; i < num_entries; i++) {
674 if (strcmp(examples[i].abbrev, string) == 0) {
675 return examples[i].produceable_type;
680 fprintf(stderr, "randpkt: Type %s not known.\n", string);
684 /* Find pkt_example record and return pointer to it */
686 pkt_example* find_example(int type)
688 int num_entries = array_length(examples);
691 for (i = 0; i < num_entries; i++) {
692 if (examples[i].produceable_type == type) {
698 "randpkt: Internal error. Type %d has no entry in examples table.\n",
703 /* Seed the random-number generator */
707 unsigned int randomness;
713 #define RANDOM_DEV "/dev/urandom"
716 * Assume it's at least worth trying /dev/urandom on UN*X.
717 * If it doesn't exist, fall back on time().
719 * XXX - Use CryptGenRandom on Windows?
721 fd = open(RANDOM_DEV, O_RDONLY);
723 if (errno != ENOENT) {
725 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
732 ret = read(fd, &randomness, sizeof randomness);
735 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
739 if ((size_t)ret != sizeof randomness) {
741 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
742 (unsigned long)sizeof randomness, (long)ret);
751 randomness = (unsigned int) now;