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.
49 #include "wiretap/wtap.h"
51 #define array_length(x) (sizeof x / sizeof x[0])
53 /* Types of produceable packets */
83 int sample_wtap_encap;
84 guint8 *sample_buffer;
86 guint8 *pseudo_buffer;
90 /* Ethernet, indicating ARP */
92 0xff, 0xff, 0xff, 0xff,
93 0xff, 0xff, 0x00, 0x00,
94 0x32, 0x25, 0x0f, 0xff,
98 /* Ethernet+IP+UDP, indicating DNS */
100 0xff, 0xff, 0xff, 0xff,
101 0xff, 0xff, 0x01, 0x01,
102 0x01, 0x01, 0x01, 0x01,
105 0x45, 0x00, 0x00, 0x3c,
106 0xc5, 0x9e, 0x40, 0x00,
107 0xff, 0x11, 0xd7, 0xe0,
108 0xd0, 0x15, 0x02, 0xb8,
109 0x0a, 0x01, 0x01, 0x63,
111 0x05, 0xe8, 0x00, 0x35,
112 0xff, 0xff, 0x2a, 0xb9,
116 /* Ethernet+IP, indicating ICMP */
117 guint8 pkt_icmp[] = {
118 0xff, 0xff, 0xff, 0xff,
119 0xff, 0xff, 0x01, 0x01,
120 0x01, 0x01, 0x01, 0x01,
123 0x45, 0x00, 0x00, 0x54,
124 0x8f, 0xb3, 0x40, 0x00,
125 0xfd, 0x01, 0x8a, 0x99,
126 0xcc, 0xfc, 0x66, 0x0b,
127 0xce, 0x41, 0x62, 0x12
130 /* Ethernet, indicating IP */
132 0xff, 0xff, 0xff, 0xff,
133 0xff, 0xff, 0x01, 0x01,
134 0x01, 0x01, 0x01, 0x01,
138 /* TR, indicating LLC */
140 0x10, 0x40, 0x68, 0x00,
141 0x19, 0x69, 0x95, 0x8b,
142 0x00, 0x01, 0xfa, 0x68,
146 /* Ethernet, indicating WiMAX M2M */
148 0xff, 0xff, 0xff, 0xff,
149 0xff, 0xff, 0x00, 0x00,
150 0x32, 0x25, 0x0f, 0xff,
154 /* Ethernet+IP+UDP, indicating NBNS */
155 guint8 pkt_nbns[] = {
156 0xff, 0xff, 0xff, 0xff,
157 0xff, 0xff, 0x01, 0x01,
158 0x01, 0x01, 0x01, 0x01,
161 0x45, 0x00, 0x00, 0x3c,
162 0xc5, 0x9e, 0x40, 0x00,
163 0xff, 0x11, 0xd7, 0xe0,
164 0xd0, 0x15, 0x02, 0xb8,
165 0x0a, 0x01, 0x01, 0x63,
167 0x00, 0x89, 0x00, 0x89,
168 0x00, 0x00, 0x2a, 0xb9,
172 /* Ethernet+IP+UDP, indicating syslog */
173 guint8 pkt_syslog[] = {
174 0xff, 0xff, 0xff, 0xff,
175 0xff, 0xff, 0x01, 0x01,
176 0x01, 0x01, 0x01, 0x01,
179 0x45, 0x00, 0x00, 0x64,
180 0x20, 0x48, 0x00, 0x00,
181 0xfc, 0x11, 0xf8, 0x03,
182 0xd0, 0x15, 0x02, 0xb8,
183 0x0a, 0x01, 0x01, 0x63,
185 0x05, 0xe8, 0x02, 0x02,
186 0x00, 0x50, 0x51, 0xe1,
190 /* TR+LLC+IP, indicating TCP */
192 0x10, 0x40, 0x68, 0x00,
193 0x19, 0x69, 0x95, 0x8b,
194 0x00, 0x01, 0xfa, 0x68,
197 0xaa, 0xaa, 0x03, 0x00,
198 0x00, 0x00, 0x08, 0x00,
200 0x45, 0x00, 0x00, 0x28,
201 0x0b, 0x0b, 0x40, 0x00,
202 0x20, 0x06, 0x85, 0x37,
203 0xc0, 0xa8, 0x27, 0x01,
204 0xc0, 0xa8, 0x22, 0x3c
207 /* Ethernet+IP, indicating UDP */
209 0xff, 0xff, 0xff, 0xff,
210 0xff, 0xff, 0x01, 0x01,
211 0x01, 0x01, 0x01, 0x01,
214 0x45, 0x00, 0x00, 0x3c,
215 0xc5, 0x9e, 0x40, 0x00,
216 0xff, 0x11, 0xd7, 0xe0,
217 0xd0, 0x15, 0x02, 0xb8,
218 0x0a, 0x01, 0x01, 0x63
221 /* Ethernet+IP+UDP, indicating BVLC */
222 guint8 pkt_bvlc[] = {
223 0xff, 0xff, 0xff, 0xff,
224 0xff, 0xff, 0x01, 0x01,
225 0x01, 0x01, 0x01, 0x01,
228 0x45, 0x00, 0x00, 0x3c,
229 0xc5, 0x9e, 0x40, 0x00,
230 0xff, 0x11, 0x01, 0xaa,
231 0xc1, 0xff, 0x19, 0x1e,
232 0xc1, 0xff, 0x19, 0xff,
233 0xba, 0xc0, 0xba, 0xc0,
234 0x00, 0xff, 0x2d, 0x5e,
238 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
239 guint8 pkt_ncp2222[] = {
240 0x10, 0x40, 0x00, 0x00,
241 0xf6, 0x7c, 0x9b, 0x70,
242 0x68, 0x00, 0x19, 0x69,
243 0x95, 0x8b, 0xe0, 0xe0,
244 0x03, 0xff, 0xff, 0x00,
245 0x25, 0x02, 0x11, 0x00,
246 0x00, 0x74, 0x14, 0x00,
247 0x00, 0x00, 0x00, 0x00,
248 0x01, 0x04, 0x51, 0x00,
249 0x00, 0x00, 0x04, 0x00,
250 0x02, 0x16, 0x19, 0x7a,
251 0x84, 0x40, 0x01, 0x22,
255 /* Ethernet+IP+TCP, indicating GIOP */
256 guint8 pkt_giop[] = {
257 0xff, 0xff, 0xff, 0xff,
258 0xff, 0xff, 0x01, 0x01,
259 0x01, 0x01, 0x01, 0x01,
262 0x45, 0x00, 0x00, 0xa6,
263 0x00, 0x2f, 0x40, 0x00,
264 0x40, 0x06, 0x3c, 0x21,
265 0x7f, 0x00, 0x00, 0x01,
266 0x7f, 0x00, 0x00, 0x01,
268 0x30, 0x39, 0x04, 0x05,
269 0xac, 0x02, 0x1e, 0x69,
270 0xab, 0x74, 0xab, 0x64,
271 0x80, 0x18, 0x79, 0x60,
272 0xc4, 0xb8, 0x00, 0x00,
273 0x01, 0x01, 0x08, 0x0a,
274 0x00, 0x00, 0x48, 0xf5,
275 0x00, 0x00, 0x48, 0xf5,
277 0x47, 0x49, 0x4f, 0x50,
278 0x01, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x30,
280 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x01,
285 /* Ethernet+IP+TCP, indicating BGP */
287 0xff, 0xff, 0xff, 0xff,
288 0xff, 0xff, 0x01, 0x01,
289 0x01, 0x01, 0x01, 0x01,
292 0x45, 0x00, 0x00, 0xa6,
293 0x00, 0x2f, 0x40, 0x00,
294 0x40, 0x06, 0x3c, 0x21,
295 0x7f, 0x00, 0x00, 0x01,
296 0x7f, 0x00, 0x00, 0x01,
298 0x30, 0x39, 0x00, 0xb3,
299 0xac, 0x02, 0x1e, 0x69,
300 0xab, 0x74, 0xab, 0x64,
301 0x80, 0x18, 0x79, 0x60,
302 0xc4, 0xb8, 0x00, 0x00,
303 0x01, 0x01, 0x08, 0x0a,
304 0x00, 0x00, 0x48, 0xf5,
305 0x00, 0x00, 0x48, 0xf5,
307 0xff, 0xff, 0xff, 0xff,
308 0xff, 0xff, 0xff, 0xff,
309 0xff, 0xff, 0xff, 0xff,
310 0xff, 0xff, 0xff, 0xff,
313 /* Ethernet+IP+TCP, indicating TDS NetLib */
315 0x00, 0x50, 0x8b, 0x0d,
316 0x7a, 0xed, 0x00, 0x08,
317 0xa3, 0x98, 0x39, 0x81,
320 0x45, 0x00, 0x03, 0x8d,
321 0x90, 0xd4, 0x40, 0x00,
322 0x7c, 0x06, 0xc3, 0x1b,
323 0xac, 0x14, 0x02, 0x22,
324 0x0a, 0xc2, 0xee, 0x82,
326 0x05, 0x99, 0x08, 0xf8,
327 0xff, 0x4e, 0x85, 0x46,
328 0xa2, 0xb4, 0x42, 0xaa,
329 0x50, 0x18, 0x3c, 0x28,
330 0x0f, 0xda, 0x00, 0x00,
333 /* Ethernet+IP, indicating SCTP */
334 guint8 pkt_sctp[] = {
335 0x00, 0xa0, 0x80, 0x00,
336 0x5e, 0x46, 0x08, 0x00,
337 0x03, 0x4a, 0x00, 0x35,
340 0x45, 0x00, 0x00, 0x7c,
341 0x14, 0x1c, 0x00, 0x00,
342 0x3b, 0x84, 0x4a, 0x54,
343 0x0a, 0x1c, 0x06, 0x2b,
344 0x0a, 0x1c, 0x06, 0x2c,
348 /* Ethernet+IP+SCTP, indicating MEGACO */
349 guint8 pkt_megaco[] = {
350 0x00, 0xa0, 0x80, 0x00,
351 0x5e, 0x46, 0x08, 0x00,
352 0x03, 0x4a, 0x00, 0x35,
355 0x45, 0x00, 0x00, 0x7c,
356 0x14, 0x1c, 0x00, 0x00,
357 0x3b, 0x84, 0x4a, 0x54,
358 0x0a, 0x1c, 0x06, 0x2b,
359 0x0a, 0x1c, 0x06, 0x2c,
361 0x40, 0x00, 0x0b, 0x80,
362 0x00, 0x01, 0x6f, 0x0a,
363 0x6d, 0xb0, 0x18, 0x82,
364 0x00, 0x03, 0x00, 0x5b,
365 0x28, 0x02, 0x43, 0x45,
366 0x00, 0x00, 0xa0, 0xbd,
367 0x00, 0x00, 0x00, 0x07,
370 /* This little data table drives the whole program */
371 pkt_example examples[] = {
372 { "arp", "Address Resolution Protocol",
373 PKT_ARP, WTAP_ENCAP_ETHERNET,
374 pkt_arp, array_length(pkt_arp),
377 { "bgp", "Border Gateway Protocol",
378 PKT_BGP, WTAP_ENCAP_ETHERNET,
379 pkt_bgp, array_length(pkt_bgp),
382 { "bvlc", "BACnet Virtual Link Control",
383 PKT_BVLC, WTAP_ENCAP_ETHERNET,
384 pkt_bvlc, array_length(pkt_bvlc),
387 { "dns", "Domain Name Service",
388 PKT_DNS, WTAP_ENCAP_ETHERNET,
389 pkt_dns, array_length(pkt_dns),
393 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
397 { "fddi", "Fiber Distributed Data Interface",
398 PKT_FDDI, WTAP_ENCAP_FDDI,
402 { "giop", "General Inter-ORB Protocol",
403 PKT_GIOP, WTAP_ENCAP_ETHERNET,
404 pkt_giop, array_length(pkt_giop),
407 { "icmp", "Internet Control Message Protocol",
408 PKT_ICMP, WTAP_ENCAP_ETHERNET,
409 pkt_icmp, array_length(pkt_icmp),
412 { "ip", "Internet Protocol",
413 PKT_IP, WTAP_ENCAP_ETHERNET,
414 pkt_ip, array_length(pkt_ip),
417 { "llc", "Logical Link Control",
418 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
419 pkt_llc, array_length(pkt_llc),
422 { "m2m", "WiMAX M2M Encapsulation Protocol",
423 PKT_M2M, WTAP_ENCAP_ETHERNET,
424 pkt_m2m, array_length(pkt_m2m),
427 { "megaco", "MEGACO",
428 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
429 pkt_megaco, array_length(pkt_megaco),
432 { "nbns", "NetBIOS-over-TCP Name Service",
433 PKT_NBNS, WTAP_ENCAP_ETHERNET,
434 pkt_nbns, array_length(pkt_nbns),
437 { "ncp2222", "NetWare Core Protocol",
438 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
439 pkt_ncp2222, array_length(pkt_ncp2222),
442 { "sctp", "Stream Control Transmission Protocol",
443 PKT_SCTP, WTAP_ENCAP_ETHERNET,
444 pkt_sctp, array_length(pkt_sctp),
447 { "syslog", "Syslog message",
448 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
449 pkt_syslog, array_length(pkt_syslog),
452 { "tds", "TDS NetLib",
453 PKT_TDS, WTAP_ENCAP_ETHERNET,
454 pkt_tds, array_length(pkt_tds),
457 { "tcp", "Transmission Control Protocol",
458 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
459 pkt_tcp, array_length(pkt_tcp),
462 { "tr", "Token-Ring",
463 PKT_TR, WTAP_ENCAP_TOKEN_RING,
467 { "udp", "User Datagram Protocol",
468 PKT_UDP, WTAP_ENCAP_ETHERNET,
469 pkt_udp, array_length(pkt_udp),
472 { "usb", "Universal Serial Bus",
473 PKT_USB, WTAP_ENCAP_USB,
477 { "usb-linux", "Universal Serial Bus with Linux specific header",
478 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
486 static int parse_type(char *string);
487 static void usage(void);
488 static void seed(void);
490 static pkt_example* find_example(int type);
493 main(int argc, char **argv)
497 struct wtap_pkthdr pkthdr;
498 union wtap_pseudo_header ps_header;
499 int i, j, len_this_pkt, len_random, err;
500 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;
512 while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
514 case 'b': /* max bytes */
515 produce_max_bytes = atoi(optarg);
516 if (produce_max_bytes > 65536) {
518 "randpkt: Max bytes is 65536\n");
523 case 'c': /* count */
524 produce_count = atoi(optarg);
527 case 't': /* type of packet to produce */
528 produce_type = parse_type(optarg);
538 /* any more command line parameters? */
540 produce_filename = argv[optind];
546 example = find_example(produce_type);
549 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
550 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
553 "randpkt: Error writing to %s\n", produce_filename);
559 /* reduce max_bytes by # of bytes already in sample */
560 if (produce_max_bytes <= example->sample_length) {
562 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
563 example->sample_length);
564 fprintf(stderr, "your requested max_bytes value of %d\n",
569 produce_max_bytes -= example->sample_length;
572 memset(&pkthdr, 0, sizeof(pkthdr));
573 memset(&ps_header, 0, sizeof(ps_header));
574 memset(buffer, 0, sizeof(buffer));
576 pkthdr.pkt_encap = example->sample_wtap_encap;
578 /* Load the sample pseudoheader into our pseudoheader buffer */
579 if (example->pseudo_buffer)
580 memcpy(&ps_header, example->pseudo_buffer, example->pseudo_length);
582 /* Load the sample into our buffer */
583 if (example->sample_buffer)
584 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
586 /* Produce random packets */
587 for (i = 0; i < produce_count; i++) {
588 if (produce_max_bytes > 0) {
589 len_random = (rand() % produce_max_bytes + 1);
595 len_this_pkt = example->sample_length + len_random;
597 pkthdr.caplen = len_this_pkt;
598 pkthdr.len = len_this_pkt;
599 pkthdr.ts.secs = i; /* just for variety */
601 for (j = example->pseudo_length; j < (int) sizeof(ps_header); j++) {
602 ((guint8*)&ps_header)[j] = (rand() % 0x100);
605 for (j = example->sample_length; j < len_this_pkt; j++) {
606 /* Add format strings here and there */
607 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
608 memcpy(&buffer[j], "%s", 3);
611 buffer[j] = (rand() % 0x100);
615 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
618 wtap_dump_close(dump, &err);
624 /* Print usage statement and exit program */
628 int num_entries = array_length(examples);
631 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
632 printf("Default max bytes (per packet) is 5000\n");
633 printf("Default count is 1000.\n");
636 for (i = 0; i < num_entries; i++) {
637 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
645 /* Parse command-line option "type" and return enum type */
647 int parse_type(char *string)
649 int num_entries = array_length(examples);
652 for (i = 0; i < num_entries; i++) {
653 if (strcmp(examples[i].abbrev, string) == 0) {
654 return examples[i].produceable_type;
659 fprintf(stderr, "randpkt: Type %s not known.\n", string);
663 /* Find pkt_example record and return pointer to it */
665 pkt_example* find_example(int type)
667 int num_entries = array_length(examples);
670 for (i = 0; i < num_entries; i++) {
671 if (examples[i].produceable_type == type) {
677 "randpkt: Internal error. Type %d has no entry in examples table.\n",
682 /* Seed the random-number generator */
686 unsigned int randomness;
693 * Assume it's at least worth trying /dev/random on UN*X.
694 * If it doesn't exist, fall back on time().
696 * XXX - does Windows have a system source of entropy?
698 fd = open("/dev/random", O_RDONLY);
700 if (errno != ENOENT) {
702 "randpkt: Could not open /dev/random for reading: %s\n",
709 ret = read(fd, &randomness, sizeof randomness);
712 "randpkt: Could not read from /dev/random: %s\n",
716 if ((size_t)ret != sizeof randomness) {
718 "randpkt: Tried to read %lu bytes from /dev/random, got %ld\n",
719 (unsigned long)sizeof randomness, (long)ret);
728 randomness = (unsigned int) now;