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.
35 #include "wsutil/wsgetopt.h"
49 #include "wiretap/wtap.h"
50 #include "wsutil/file_util.h"
53 #include <wsutil/unicode-utils.h>
56 #define array_length(x) (sizeof x / sizeof x[0])
58 /* Types of produceable packets */
88 int sample_wtap_encap;
89 guint8 *sample_buffer;
91 guint8 *pseudo_buffer;
95 /* Ethernet, indicating ARP */
97 0xff, 0xff, 0xff, 0xff,
98 0xff, 0xff, 0x00, 0x00,
99 0x32, 0x25, 0x0f, 0xff,
103 /* Ethernet+IP+UDP, indicating DNS */
105 0xff, 0xff, 0xff, 0xff,
106 0xff, 0xff, 0x01, 0x01,
107 0x01, 0x01, 0x01, 0x01,
110 0x45, 0x00, 0x00, 0x3c,
111 0xc5, 0x9e, 0x40, 0x00,
112 0xff, 0x11, 0xd7, 0xe0,
113 0xd0, 0x15, 0x02, 0xb8,
114 0x0a, 0x01, 0x01, 0x63,
116 0x05, 0xe8, 0x00, 0x35,
117 0xff, 0xff, 0x2a, 0xb9,
121 /* Ethernet+IP, indicating ICMP */
122 guint8 pkt_icmp[] = {
123 0xff, 0xff, 0xff, 0xff,
124 0xff, 0xff, 0x01, 0x01,
125 0x01, 0x01, 0x01, 0x01,
128 0x45, 0x00, 0x00, 0x54,
129 0x8f, 0xb3, 0x40, 0x00,
130 0xfd, 0x01, 0x8a, 0x99,
131 0xcc, 0xfc, 0x66, 0x0b,
132 0xce, 0x41, 0x62, 0x12
135 /* Ethernet, indicating IP */
137 0xff, 0xff, 0xff, 0xff,
138 0xff, 0xff, 0x01, 0x01,
139 0x01, 0x01, 0x01, 0x01,
143 /* TR, indicating LLC */
145 0x10, 0x40, 0x68, 0x00,
146 0x19, 0x69, 0x95, 0x8b,
147 0x00, 0x01, 0xfa, 0x68,
151 /* Ethernet, indicating WiMAX M2M */
153 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0x00, 0x00,
155 0x32, 0x25, 0x0f, 0xff,
159 /* Ethernet+IP+UDP, indicating NBNS */
160 guint8 pkt_nbns[] = {
161 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0x01, 0x01,
163 0x01, 0x01, 0x01, 0x01,
166 0x45, 0x00, 0x00, 0x3c,
167 0xc5, 0x9e, 0x40, 0x00,
168 0xff, 0x11, 0xd7, 0xe0,
169 0xd0, 0x15, 0x02, 0xb8,
170 0x0a, 0x01, 0x01, 0x63,
172 0x00, 0x89, 0x00, 0x89,
173 0x00, 0x00, 0x2a, 0xb9,
177 /* Ethernet+IP+UDP, indicating syslog */
178 guint8 pkt_syslog[] = {
179 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0x01, 0x01,
181 0x01, 0x01, 0x01, 0x01,
184 0x45, 0x00, 0x00, 0x64,
185 0x20, 0x48, 0x00, 0x00,
186 0xfc, 0x11, 0xf8, 0x03,
187 0xd0, 0x15, 0x02, 0xb8,
188 0x0a, 0x01, 0x01, 0x63,
190 0x05, 0xe8, 0x02, 0x02,
191 0x00, 0x50, 0x51, 0xe1,
195 /* TR+LLC+IP, indicating TCP */
197 0x10, 0x40, 0x68, 0x00,
198 0x19, 0x69, 0x95, 0x8b,
199 0x00, 0x01, 0xfa, 0x68,
202 0xaa, 0xaa, 0x03, 0x00,
203 0x00, 0x00, 0x08, 0x00,
205 0x45, 0x00, 0x00, 0x28,
206 0x0b, 0x0b, 0x40, 0x00,
207 0x20, 0x06, 0x85, 0x37,
208 0xc0, 0xa8, 0x27, 0x01,
209 0xc0, 0xa8, 0x22, 0x3c
212 /* Ethernet+IP, indicating UDP */
214 0xff, 0xff, 0xff, 0xff,
215 0xff, 0xff, 0x01, 0x01,
216 0x01, 0x01, 0x01, 0x01,
219 0x45, 0x00, 0x00, 0x3c,
220 0xc5, 0x9e, 0x40, 0x00,
221 0xff, 0x11, 0xd7, 0xe0,
222 0xd0, 0x15, 0x02, 0xb8,
223 0x0a, 0x01, 0x01, 0x63
226 /* Ethernet+IP+UDP, indicating BVLC */
227 guint8 pkt_bvlc[] = {
228 0xff, 0xff, 0xff, 0xff,
229 0xff, 0xff, 0x01, 0x01,
230 0x01, 0x01, 0x01, 0x01,
233 0x45, 0x00, 0x00, 0x3c,
234 0xc5, 0x9e, 0x40, 0x00,
235 0xff, 0x11, 0x01, 0xaa,
236 0xc1, 0xff, 0x19, 0x1e,
237 0xc1, 0xff, 0x19, 0xff,
238 0xba, 0xc0, 0xba, 0xc0,
239 0x00, 0xff, 0x2d, 0x5e,
243 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
244 guint8 pkt_ncp2222[] = {
245 0x10, 0x40, 0x00, 0x00,
246 0xf6, 0x7c, 0x9b, 0x70,
247 0x68, 0x00, 0x19, 0x69,
248 0x95, 0x8b, 0xe0, 0xe0,
249 0x03, 0xff, 0xff, 0x00,
250 0x25, 0x02, 0x11, 0x00,
251 0x00, 0x74, 0x14, 0x00,
252 0x00, 0x00, 0x00, 0x00,
253 0x01, 0x04, 0x51, 0x00,
254 0x00, 0x00, 0x04, 0x00,
255 0x02, 0x16, 0x19, 0x7a,
256 0x84, 0x40, 0x01, 0x22,
260 /* Ethernet+IP+TCP, indicating GIOP */
261 guint8 pkt_giop[] = {
262 0xff, 0xff, 0xff, 0xff,
263 0xff, 0xff, 0x01, 0x01,
264 0x01, 0x01, 0x01, 0x01,
267 0x45, 0x00, 0x00, 0xa6,
268 0x00, 0x2f, 0x40, 0x00,
269 0x40, 0x06, 0x3c, 0x21,
270 0x7f, 0x00, 0x00, 0x01,
271 0x7f, 0x00, 0x00, 0x01,
273 0x30, 0x39, 0x04, 0x05,
274 0xac, 0x02, 0x1e, 0x69,
275 0xab, 0x74, 0xab, 0x64,
276 0x80, 0x18, 0x79, 0x60,
277 0xc4, 0xb8, 0x00, 0x00,
278 0x01, 0x01, 0x08, 0x0a,
279 0x00, 0x00, 0x48, 0xf5,
280 0x00, 0x00, 0x48, 0xf5,
282 0x47, 0x49, 0x4f, 0x50,
283 0x01, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x30,
285 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x01,
290 /* Ethernet+IP+TCP, indicating BGP */
292 0xff, 0xff, 0xff, 0xff,
293 0xff, 0xff, 0x01, 0x01,
294 0x01, 0x01, 0x01, 0x01,
297 0x45, 0x00, 0x00, 0xa6,
298 0x00, 0x2f, 0x40, 0x00,
299 0x40, 0x06, 0x3c, 0x21,
300 0x7f, 0x00, 0x00, 0x01,
301 0x7f, 0x00, 0x00, 0x01,
303 0x30, 0x39, 0x00, 0xb3,
304 0xac, 0x02, 0x1e, 0x69,
305 0xab, 0x74, 0xab, 0x64,
306 0x80, 0x18, 0x79, 0x60,
307 0xc4, 0xb8, 0x00, 0x00,
308 0x01, 0x01, 0x08, 0x0a,
309 0x00, 0x00, 0x48, 0xf5,
310 0x00, 0x00, 0x48, 0xf5,
312 0xff, 0xff, 0xff, 0xff,
313 0xff, 0xff, 0xff, 0xff,
314 0xff, 0xff, 0xff, 0xff,
315 0xff, 0xff, 0xff, 0xff,
318 /* Ethernet+IP+TCP, indicating TDS NetLib */
320 0x00, 0x50, 0x8b, 0x0d,
321 0x7a, 0xed, 0x00, 0x08,
322 0xa3, 0x98, 0x39, 0x81,
325 0x45, 0x00, 0x03, 0x8d,
326 0x90, 0xd4, 0x40, 0x00,
327 0x7c, 0x06, 0xc3, 0x1b,
328 0xac, 0x14, 0x02, 0x22,
329 0x0a, 0xc2, 0xee, 0x82,
331 0x05, 0x99, 0x08, 0xf8,
332 0xff, 0x4e, 0x85, 0x46,
333 0xa2, 0xb4, 0x42, 0xaa,
334 0x50, 0x18, 0x3c, 0x28,
335 0x0f, 0xda, 0x00, 0x00,
338 /* Ethernet+IP, indicating SCTP */
339 guint8 pkt_sctp[] = {
340 0x00, 0xa0, 0x80, 0x00,
341 0x5e, 0x46, 0x08, 0x00,
342 0x03, 0x4a, 0x00, 0x35,
345 0x45, 0x00, 0x00, 0x7c,
346 0x14, 0x1c, 0x00, 0x00,
347 0x3b, 0x84, 0x4a, 0x54,
348 0x0a, 0x1c, 0x06, 0x2b,
349 0x0a, 0x1c, 0x06, 0x2c,
353 /* Ethernet+IP+SCTP, indicating MEGACO */
354 guint8 pkt_megaco[] = {
355 0x00, 0xa0, 0x80, 0x00,
356 0x5e, 0x46, 0x08, 0x00,
357 0x03, 0x4a, 0x00, 0x35,
360 0x45, 0x00, 0x00, 0x7c,
361 0x14, 0x1c, 0x00, 0x00,
362 0x3b, 0x84, 0x4a, 0x54,
363 0x0a, 0x1c, 0x06, 0x2b,
364 0x0a, 0x1c, 0x06, 0x2c,
366 0x40, 0x00, 0x0b, 0x80,
367 0x00, 0x01, 0x6f, 0x0a,
368 0x6d, 0xb0, 0x18, 0x82,
369 0x00, 0x03, 0x00, 0x5b,
370 0x28, 0x02, 0x43, 0x45,
371 0x00, 0x00, 0xa0, 0xbd,
372 0x00, 0x00, 0x00, 0x07,
375 /* This little data table drives the whole program */
376 pkt_example examples[] = {
377 { "arp", "Address Resolution Protocol",
378 PKT_ARP, WTAP_ENCAP_ETHERNET,
379 pkt_arp, array_length(pkt_arp),
382 { "bgp", "Border Gateway Protocol",
383 PKT_BGP, WTAP_ENCAP_ETHERNET,
384 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),
392 { "dns", "Domain Name Service",
393 PKT_DNS, WTAP_ENCAP_ETHERNET,
394 pkt_dns, array_length(pkt_dns),
398 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
402 { "fddi", "Fiber Distributed Data Interface",
403 PKT_FDDI, WTAP_ENCAP_FDDI,
407 { "giop", "General Inter-ORB Protocol",
408 PKT_GIOP, WTAP_ENCAP_ETHERNET,
409 pkt_giop, array_length(pkt_giop),
412 { "icmp", "Internet Control Message Protocol",
413 PKT_ICMP, WTAP_ENCAP_ETHERNET,
414 pkt_icmp, array_length(pkt_icmp),
417 { "ip", "Internet Protocol",
418 PKT_IP, WTAP_ENCAP_ETHERNET,
419 pkt_ip, array_length(pkt_ip),
422 { "llc", "Logical Link Control",
423 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
424 pkt_llc, array_length(pkt_llc),
427 { "m2m", "WiMAX M2M Encapsulation Protocol",
428 PKT_M2M, WTAP_ENCAP_ETHERNET,
429 pkt_m2m, array_length(pkt_m2m),
432 { "megaco", "MEGACO",
433 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
434 pkt_megaco, array_length(pkt_megaco),
437 { "nbns", "NetBIOS-over-TCP Name Service",
438 PKT_NBNS, WTAP_ENCAP_ETHERNET,
439 pkt_nbns, array_length(pkt_nbns),
442 { "ncp2222", "NetWare Core Protocol",
443 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
444 pkt_ncp2222, array_length(pkt_ncp2222),
447 { "sctp", "Stream Control Transmission Protocol",
448 PKT_SCTP, WTAP_ENCAP_ETHERNET,
449 pkt_sctp, array_length(pkt_sctp),
452 { "syslog", "Syslog message",
453 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
454 pkt_syslog, array_length(pkt_syslog),
457 { "tds", "TDS NetLib",
458 PKT_TDS, WTAP_ENCAP_ETHERNET,
459 pkt_tds, array_length(pkt_tds),
462 { "tcp", "Transmission Control Protocol",
463 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
464 pkt_tcp, array_length(pkt_tcp),
467 { "tr", "Token-Ring",
468 PKT_TR, WTAP_ENCAP_TOKEN_RING,
472 { "udp", "User Datagram Protocol",
473 PKT_UDP, WTAP_ENCAP_ETHERNET,
474 pkt_udp, array_length(pkt_udp),
477 { "usb", "Universal Serial Bus",
478 PKT_USB, WTAP_ENCAP_USB,
482 { "usb-linux", "Universal Serial Bus with Linux specific header",
483 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
491 static int parse_type(char *string);
492 static void usage(void);
493 static void seed(void);
495 static pkt_example* find_example(int type);
498 main(int argc, char **argv)
502 struct wtap_pkthdr pkthdr;
503 union wtap_pseudo_header ps_header;
504 int i, j, len_this_pkt, len_random, err;
505 guint8 buffer[65536];
509 int produce_count = 1000; /* number of pkts to produce */
510 int produce_type = PKT_ETHERNET;
511 char *produce_filename = NULL;
512 int produce_max_bytes = 5000;
513 pkt_example *example;
516 arg_list_utf_16to8(argc, argv);
519 while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
521 case 'b': /* max bytes */
522 produce_max_bytes = atoi(optarg);
523 if (produce_max_bytes > 65536) {
525 "randpkt: Max bytes is 65536\n");
530 case 'c': /* count */
531 produce_count = atoi(optarg);
534 case 't': /* type of packet to produce */
535 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_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(&ps_header, 0, sizeof(ps_header));
581 memset(buffer, 0, sizeof(buffer));
583 pkthdr.pkt_encap = example->sample_wtap_encap;
585 /* Load the sample pseudoheader into our pseudoheader buffer */
586 if (example->pseudo_buffer)
587 memcpy(&ps_header, example->pseudo_buffer, example->pseudo_length);
589 /* Load the sample into our buffer */
590 if (example->sample_buffer)
591 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
593 /* Produce random packets */
594 for (i = 0; i < produce_count; i++) {
595 if (produce_max_bytes > 0) {
596 len_random = (rand() % produce_max_bytes + 1);
602 len_this_pkt = example->sample_length + len_random;
604 pkthdr.caplen = len_this_pkt;
605 pkthdr.len = len_this_pkt;
606 pkthdr.ts.secs = i; /* just for variety */
608 for (j = example->pseudo_length; j < (int) sizeof(ps_header); j++) {
609 ((guint8*)&ps_header)[j] = (rand() % 0x100);
612 for (j = example->sample_length; j < len_this_pkt; j++) {
613 /* Add format strings here and there */
614 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
615 memcpy(&buffer[j], "%s", 3);
618 buffer[j] = (rand() % 0x100);
622 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
625 wtap_dump_close(dump, &err);
631 /* Print usage statement and exit program */
635 int num_entries = array_length(examples);
638 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
639 printf("Default max bytes (per packet) is 5000\n");
640 printf("Default count is 1000.\n");
643 for (i = 0; i < num_entries; i++) {
644 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
652 /* Parse command-line option "type" and return enum type */
654 int parse_type(char *string)
656 int num_entries = array_length(examples);
659 for (i = 0; i < num_entries; i++) {
660 if (strcmp(examples[i].abbrev, string) == 0) {
661 return examples[i].produceable_type;
666 fprintf(stderr, "randpkt: Type %s not known.\n", string);
670 /* Find pkt_example record and return pointer to it */
672 pkt_example* find_example(int type)
674 int num_entries = array_length(examples);
677 for (i = 0; i < num_entries; i++) {
678 if (examples[i].produceable_type == type) {
684 "randpkt: Internal error. Type %d has no entry in examples table.\n",
689 /* Seed the random-number generator */
693 unsigned int randomness;
699 #define RANDOM_DEV "/dev/urandom"
702 * Assume it's at least worth trying /dev/urandom on UN*X.
703 * If it doesn't exist, fall back on time().
705 * XXX - Use CryptGenRandom on Windows?
707 fd = ws_open(RANDOM_DEV, O_RDONLY);
709 if (errno != ENOENT) {
711 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
718 ret = ws_read(fd, &randomness, sizeof randomness);
721 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
725 if ((size_t)ret != sizeof randomness) {
727 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
728 (unsigned long)sizeof randomness, (long)ret);
738 randomness = (unsigned int) now;