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"
53 #define array_length(x) (sizeof x / sizeof x[0])
55 /* Types of produceable packets */
85 int sample_wtap_encap;
86 guint8 *sample_buffer;
88 guint8 *pseudo_buffer;
92 /* Ethernet, indicating ARP */
94 0xff, 0xff, 0xff, 0xff,
95 0xff, 0xff, 0x00, 0x00,
96 0x32, 0x25, 0x0f, 0xff,
100 /* Ethernet+IP+UDP, indicating DNS */
102 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0x01, 0x01,
104 0x01, 0x01, 0x01, 0x01,
107 0x45, 0x00, 0x00, 0x3c,
108 0xc5, 0x9e, 0x40, 0x00,
109 0xff, 0x11, 0xd7, 0xe0,
110 0xd0, 0x15, 0x02, 0xb8,
111 0x0a, 0x01, 0x01, 0x63,
113 0x05, 0xe8, 0x00, 0x35,
114 0xff, 0xff, 0x2a, 0xb9,
118 /* Ethernet+IP, indicating ICMP */
119 guint8 pkt_icmp[] = {
120 0xff, 0xff, 0xff, 0xff,
121 0xff, 0xff, 0x01, 0x01,
122 0x01, 0x01, 0x01, 0x01,
125 0x45, 0x00, 0x00, 0x54,
126 0x8f, 0xb3, 0x40, 0x00,
127 0xfd, 0x01, 0x8a, 0x99,
128 0xcc, 0xfc, 0x66, 0x0b,
129 0xce, 0x41, 0x62, 0x12
132 /* Ethernet, indicating IP */
134 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0x01, 0x01,
136 0x01, 0x01, 0x01, 0x01,
140 /* TR, indicating LLC */
142 0x10, 0x40, 0x68, 0x00,
143 0x19, 0x69, 0x95, 0x8b,
144 0x00, 0x01, 0xfa, 0x68,
148 /* Ethernet, indicating WiMAX M2M */
150 0xff, 0xff, 0xff, 0xff,
151 0xff, 0xff, 0x00, 0x00,
152 0x32, 0x25, 0x0f, 0xff,
156 /* Ethernet+IP+UDP, indicating NBNS */
157 guint8 pkt_nbns[] = {
158 0xff, 0xff, 0xff, 0xff,
159 0xff, 0xff, 0x01, 0x01,
160 0x01, 0x01, 0x01, 0x01,
163 0x45, 0x00, 0x00, 0x3c,
164 0xc5, 0x9e, 0x40, 0x00,
165 0xff, 0x11, 0xd7, 0xe0,
166 0xd0, 0x15, 0x02, 0xb8,
167 0x0a, 0x01, 0x01, 0x63,
169 0x00, 0x89, 0x00, 0x89,
170 0x00, 0x00, 0x2a, 0xb9,
174 /* Ethernet+IP+UDP, indicating syslog */
175 guint8 pkt_syslog[] = {
176 0xff, 0xff, 0xff, 0xff,
177 0xff, 0xff, 0x01, 0x01,
178 0x01, 0x01, 0x01, 0x01,
181 0x45, 0x00, 0x00, 0x64,
182 0x20, 0x48, 0x00, 0x00,
183 0xfc, 0x11, 0xf8, 0x03,
184 0xd0, 0x15, 0x02, 0xb8,
185 0x0a, 0x01, 0x01, 0x63,
187 0x05, 0xe8, 0x02, 0x02,
188 0x00, 0x50, 0x51, 0xe1,
192 /* TR+LLC+IP, indicating TCP */
194 0x10, 0x40, 0x68, 0x00,
195 0x19, 0x69, 0x95, 0x8b,
196 0x00, 0x01, 0xfa, 0x68,
199 0xaa, 0xaa, 0x03, 0x00,
200 0x00, 0x00, 0x08, 0x00,
202 0x45, 0x00, 0x00, 0x28,
203 0x0b, 0x0b, 0x40, 0x00,
204 0x20, 0x06, 0x85, 0x37,
205 0xc0, 0xa8, 0x27, 0x01,
206 0xc0, 0xa8, 0x22, 0x3c
209 /* Ethernet+IP, indicating UDP */
211 0xff, 0xff, 0xff, 0xff,
212 0xff, 0xff, 0x01, 0x01,
213 0x01, 0x01, 0x01, 0x01,
216 0x45, 0x00, 0x00, 0x3c,
217 0xc5, 0x9e, 0x40, 0x00,
218 0xff, 0x11, 0xd7, 0xe0,
219 0xd0, 0x15, 0x02, 0xb8,
220 0x0a, 0x01, 0x01, 0x63
223 /* Ethernet+IP+UDP, indicating BVLC */
224 guint8 pkt_bvlc[] = {
225 0xff, 0xff, 0xff, 0xff,
226 0xff, 0xff, 0x01, 0x01,
227 0x01, 0x01, 0x01, 0x01,
230 0x45, 0x00, 0x00, 0x3c,
231 0xc5, 0x9e, 0x40, 0x00,
232 0xff, 0x11, 0x01, 0xaa,
233 0xc1, 0xff, 0x19, 0x1e,
234 0xc1, 0xff, 0x19, 0xff,
235 0xba, 0xc0, 0xba, 0xc0,
236 0x00, 0xff, 0x2d, 0x5e,
240 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
241 guint8 pkt_ncp2222[] = {
242 0x10, 0x40, 0x00, 0x00,
243 0xf6, 0x7c, 0x9b, 0x70,
244 0x68, 0x00, 0x19, 0x69,
245 0x95, 0x8b, 0xe0, 0xe0,
246 0x03, 0xff, 0xff, 0x00,
247 0x25, 0x02, 0x11, 0x00,
248 0x00, 0x74, 0x14, 0x00,
249 0x00, 0x00, 0x00, 0x00,
250 0x01, 0x04, 0x51, 0x00,
251 0x00, 0x00, 0x04, 0x00,
252 0x02, 0x16, 0x19, 0x7a,
253 0x84, 0x40, 0x01, 0x22,
257 /* Ethernet+IP+TCP, indicating GIOP */
258 guint8 pkt_giop[] = {
259 0xff, 0xff, 0xff, 0xff,
260 0xff, 0xff, 0x01, 0x01,
261 0x01, 0x01, 0x01, 0x01,
264 0x45, 0x00, 0x00, 0xa6,
265 0x00, 0x2f, 0x40, 0x00,
266 0x40, 0x06, 0x3c, 0x21,
267 0x7f, 0x00, 0x00, 0x01,
268 0x7f, 0x00, 0x00, 0x01,
270 0x30, 0x39, 0x04, 0x05,
271 0xac, 0x02, 0x1e, 0x69,
272 0xab, 0x74, 0xab, 0x64,
273 0x80, 0x18, 0x79, 0x60,
274 0xc4, 0xb8, 0x00, 0x00,
275 0x01, 0x01, 0x08, 0x0a,
276 0x00, 0x00, 0x48, 0xf5,
277 0x00, 0x00, 0x48, 0xf5,
279 0x47, 0x49, 0x4f, 0x50,
280 0x01, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x30,
282 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x01,
287 /* Ethernet+IP+TCP, indicating BGP */
289 0xff, 0xff, 0xff, 0xff,
290 0xff, 0xff, 0x01, 0x01,
291 0x01, 0x01, 0x01, 0x01,
294 0x45, 0x00, 0x00, 0xa6,
295 0x00, 0x2f, 0x40, 0x00,
296 0x40, 0x06, 0x3c, 0x21,
297 0x7f, 0x00, 0x00, 0x01,
298 0x7f, 0x00, 0x00, 0x01,
300 0x30, 0x39, 0x00, 0xb3,
301 0xac, 0x02, 0x1e, 0x69,
302 0xab, 0x74, 0xab, 0x64,
303 0x80, 0x18, 0x79, 0x60,
304 0xc4, 0xb8, 0x00, 0x00,
305 0x01, 0x01, 0x08, 0x0a,
306 0x00, 0x00, 0x48, 0xf5,
307 0x00, 0x00, 0x48, 0xf5,
309 0xff, 0xff, 0xff, 0xff,
310 0xff, 0xff, 0xff, 0xff,
311 0xff, 0xff, 0xff, 0xff,
312 0xff, 0xff, 0xff, 0xff,
315 /* Ethernet+IP+TCP, indicating TDS NetLib */
317 0x00, 0x50, 0x8b, 0x0d,
318 0x7a, 0xed, 0x00, 0x08,
319 0xa3, 0x98, 0x39, 0x81,
322 0x45, 0x00, 0x03, 0x8d,
323 0x90, 0xd4, 0x40, 0x00,
324 0x7c, 0x06, 0xc3, 0x1b,
325 0xac, 0x14, 0x02, 0x22,
326 0x0a, 0xc2, 0xee, 0x82,
328 0x05, 0x99, 0x08, 0xf8,
329 0xff, 0x4e, 0x85, 0x46,
330 0xa2, 0xb4, 0x42, 0xaa,
331 0x50, 0x18, 0x3c, 0x28,
332 0x0f, 0xda, 0x00, 0x00,
335 /* Ethernet+IP, indicating SCTP */
336 guint8 pkt_sctp[] = {
337 0x00, 0xa0, 0x80, 0x00,
338 0x5e, 0x46, 0x08, 0x00,
339 0x03, 0x4a, 0x00, 0x35,
342 0x45, 0x00, 0x00, 0x7c,
343 0x14, 0x1c, 0x00, 0x00,
344 0x3b, 0x84, 0x4a, 0x54,
345 0x0a, 0x1c, 0x06, 0x2b,
346 0x0a, 0x1c, 0x06, 0x2c,
350 /* Ethernet+IP+SCTP, indicating MEGACO */
351 guint8 pkt_megaco[] = {
352 0x00, 0xa0, 0x80, 0x00,
353 0x5e, 0x46, 0x08, 0x00,
354 0x03, 0x4a, 0x00, 0x35,
357 0x45, 0x00, 0x00, 0x7c,
358 0x14, 0x1c, 0x00, 0x00,
359 0x3b, 0x84, 0x4a, 0x54,
360 0x0a, 0x1c, 0x06, 0x2b,
361 0x0a, 0x1c, 0x06, 0x2c,
363 0x40, 0x00, 0x0b, 0x80,
364 0x00, 0x01, 0x6f, 0x0a,
365 0x6d, 0xb0, 0x18, 0x82,
366 0x00, 0x03, 0x00, 0x5b,
367 0x28, 0x02, 0x43, 0x45,
368 0x00, 0x00, 0xa0, 0xbd,
369 0x00, 0x00, 0x00, 0x07,
372 /* This little data table drives the whole program */
373 pkt_example examples[] = {
374 { "arp", "Address Resolution Protocol",
375 PKT_ARP, WTAP_ENCAP_ETHERNET,
376 pkt_arp, array_length(pkt_arp),
379 { "bgp", "Border Gateway Protocol",
380 PKT_BGP, WTAP_ENCAP_ETHERNET,
381 pkt_bgp, array_length(pkt_bgp),
384 { "bvlc", "BACnet Virtual Link Control",
385 PKT_BVLC, WTAP_ENCAP_ETHERNET,
386 pkt_bvlc, array_length(pkt_bvlc),
389 { "dns", "Domain Name Service",
390 PKT_DNS, WTAP_ENCAP_ETHERNET,
391 pkt_dns, array_length(pkt_dns),
395 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
399 { "fddi", "Fiber Distributed Data Interface",
400 PKT_FDDI, WTAP_ENCAP_FDDI,
404 { "giop", "General Inter-ORB Protocol",
405 PKT_GIOP, WTAP_ENCAP_ETHERNET,
406 pkt_giop, array_length(pkt_giop),
409 { "icmp", "Internet Control Message Protocol",
410 PKT_ICMP, WTAP_ENCAP_ETHERNET,
411 pkt_icmp, array_length(pkt_icmp),
414 { "ip", "Internet Protocol",
415 PKT_IP, WTAP_ENCAP_ETHERNET,
416 pkt_ip, array_length(pkt_ip),
419 { "llc", "Logical Link Control",
420 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
421 pkt_llc, array_length(pkt_llc),
424 { "m2m", "WiMAX M2M Encapsulation Protocol",
425 PKT_M2M, WTAP_ENCAP_ETHERNET,
426 pkt_m2m, array_length(pkt_m2m),
429 { "megaco", "MEGACO",
430 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
431 pkt_megaco, array_length(pkt_megaco),
434 { "nbns", "NetBIOS-over-TCP Name Service",
435 PKT_NBNS, WTAP_ENCAP_ETHERNET,
436 pkt_nbns, array_length(pkt_nbns),
439 { "ncp2222", "NetWare Core Protocol",
440 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
441 pkt_ncp2222, array_length(pkt_ncp2222),
444 { "sctp", "Stream Control Transmission Protocol",
445 PKT_SCTP, WTAP_ENCAP_ETHERNET,
446 pkt_sctp, array_length(pkt_sctp),
449 { "syslog", "Syslog message",
450 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
451 pkt_syslog, array_length(pkt_syslog),
454 { "tds", "TDS NetLib",
455 PKT_TDS, WTAP_ENCAP_ETHERNET,
456 pkt_tds, array_length(pkt_tds),
459 { "tcp", "Transmission Control Protocol",
460 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
461 pkt_tcp, array_length(pkt_tcp),
464 { "tr", "Token-Ring",
465 PKT_TR, WTAP_ENCAP_TOKEN_RING,
469 { "udp", "User Datagram Protocol",
470 PKT_UDP, WTAP_ENCAP_ETHERNET,
471 pkt_udp, array_length(pkt_udp),
474 { "usb", "Universal Serial Bus",
475 PKT_USB, WTAP_ENCAP_USB,
479 { "usb-linux", "Universal Serial Bus with Linux specific header",
480 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
488 static int parse_type(char *string);
489 static void usage(void);
490 static void seed(void);
492 static pkt_example* find_example(int type);
495 main(int argc, char **argv)
499 struct wtap_pkthdr pkthdr;
500 union wtap_pseudo_header ps_header;
501 int i, j, len_this_pkt, len_random, err;
502 guint8 buffer[65536];
505 int produce_count = 1000; /* number of pkts to produce */
506 int produce_type = PKT_ETHERNET;
507 char *produce_filename = NULL;
508 int produce_max_bytes = 5000;
509 pkt_example *example;
511 while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
513 case 'b': /* max bytes */
514 produce_max_bytes = atoi(optarg);
515 if (produce_max_bytes > 65536) {
517 "randpkt: Max bytes is 65536\n");
522 case 'c': /* count */
523 produce_count = atoi(optarg);
526 case 't': /* type of packet to produce */
527 produce_type = parse_type(optarg);
537 /* any more command line parameters? */
539 produce_filename = argv[optind];
545 example = find_example(produce_type);
548 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
549 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
552 "randpkt: Error writing to %s\n", produce_filename);
558 /* reduce max_bytes by # of bytes already in sample */
559 if (produce_max_bytes <= example->sample_length) {
561 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
562 example->sample_length);
563 fprintf(stderr, "your requested max_bytes value of %d\n",
568 produce_max_bytes -= example->sample_length;
571 memset(&pkthdr, 0, sizeof(pkthdr));
572 memset(&ps_header, 0, sizeof(ps_header));
573 memset(buffer, 0, sizeof(buffer));
575 pkthdr.pkt_encap = example->sample_wtap_encap;
577 /* Load the sample pseudoheader into our pseudoheader buffer */
578 if (example->pseudo_buffer)
579 memcpy(&ps_header, example->pseudo_buffer, example->pseudo_length);
581 /* Load the sample into our buffer */
582 if (example->sample_buffer)
583 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
585 /* Produce random packets */
586 for (i = 0; i < produce_count; i++) {
587 if (produce_max_bytes > 0) {
588 len_random = (rand() % produce_max_bytes + 1);
594 len_this_pkt = example->sample_length + len_random;
596 pkthdr.caplen = len_this_pkt;
597 pkthdr.len = len_this_pkt;
598 pkthdr.ts.secs = i; /* just for variety */
600 for (j = example->pseudo_length; j < (int) sizeof(ps_header); j++) {
601 ((guint8*)&ps_header)[j] = (rand() % 0x100);
604 for (j = example->sample_length; j < len_this_pkt; j++) {
605 /* Add format strings here and there */
606 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
607 memcpy(&buffer[j], "%s", 3);
610 buffer[j] = (rand() % 0x100);
614 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
617 wtap_dump_close(dump, &err);
623 /* Print usage statement and exit program */
627 int num_entries = array_length(examples);
630 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
631 printf("Default max bytes (per packet) is 5000\n");
632 printf("Default count is 1000.\n");
635 for (i = 0; i < num_entries; i++) {
636 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
644 /* Parse command-line option "type" and return enum type */
646 int parse_type(char *string)
648 int num_entries = array_length(examples);
651 for (i = 0; i < num_entries; i++) {
652 if (strcmp(examples[i].abbrev, string) == 0) {
653 return examples[i].produceable_type;
658 fprintf(stderr, "randpkt: Type %s not known.\n", string);
662 /* Find pkt_example record and return pointer to it */
664 pkt_example* find_example(int type)
666 int num_entries = array_length(examples);
669 for (i = 0; i < num_entries; i++) {
670 if (examples[i].produceable_type == type) {
676 "randpkt: Internal error. Type %d has no entry in examples table.\n",
681 /* Seed the random-number generator */
685 unsigned int randomness;
691 #define RANDOM_DEV "/dev/urandom"
694 * Assume it's at least worth trying /dev/urandom on UN*X.
695 * If it doesn't exist, fall back on time().
697 * XXX - Use CryptGenRandom on Windows?
699 fd = open(RANDOM_DEV, O_RDONLY);
701 if (errno != ENOENT) {
703 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
710 ret = read(fd, &randomness, sizeof randomness);
713 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
717 if ((size_t)ret != sizeof randomness) {
719 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
720 (unsigned long)sizeof randomness, (long)ret);
729 randomness = (unsigned int) now;