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.
24 #include "randpkt-core.h"
32 #include "wsutil/file_util.h"
35 #include <wsutil/unicode-utils.h>
38 #define array_length(x) (sizeof x / sizeof x[0])
40 /* Types of produceable packets */
66 /* Ethernet, indicating ARP */
68 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0x00, 0x00,
70 0x32, 0x25, 0x0f, 0xff,
74 /* Ethernet+IP+UDP, indicating DNS */
76 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0x01, 0x01,
78 0x01, 0x01, 0x01, 0x01,
81 0x45, 0x00, 0x00, 0x3c,
82 0xc5, 0x9e, 0x40, 0x00,
83 0xff, 0x11, 0xd7, 0xe0,
84 0xd0, 0x15, 0x02, 0xb8,
85 0x0a, 0x01, 0x01, 0x63,
87 0x05, 0xe8, 0x00, 0x35,
88 0xff, 0xff, 0x2a, 0xb9,
92 /* Ethernet+IP, indicating ICMP */
94 0xff, 0xff, 0xff, 0xff,
95 0xff, 0xff, 0x01, 0x01,
96 0x01, 0x01, 0x01, 0x01,
99 0x45, 0x00, 0x00, 0x54,
100 0x8f, 0xb3, 0x40, 0x00,
101 0xfd, 0x01, 0x8a, 0x99,
102 0xcc, 0xfc, 0x66, 0x0b,
103 0xce, 0x41, 0x62, 0x12
106 /* Ethernet, indicating IP */
108 0xff, 0xff, 0xff, 0xff,
109 0xff, 0xff, 0x01, 0x01,
110 0x01, 0x01, 0x01, 0x01,
114 /* TR, indicating LLC */
116 0x10, 0x40, 0x68, 0x00,
117 0x19, 0x69, 0x95, 0x8b,
118 0x00, 0x01, 0xfa, 0x68,
122 /* Ethernet, indicating WiMAX M2M */
124 0xff, 0xff, 0xff, 0xff,
125 0xff, 0xff, 0x00, 0x00,
126 0x32, 0x25, 0x0f, 0xff,
130 /* Ethernet+IP+UDP, indicating NBNS */
131 guint8 pkt_nbns[] = {
132 0xff, 0xff, 0xff, 0xff,
133 0xff, 0xff, 0x01, 0x01,
134 0x01, 0x01, 0x01, 0x01,
137 0x45, 0x00, 0x00, 0x3c,
138 0xc5, 0x9e, 0x40, 0x00,
139 0xff, 0x11, 0xd7, 0xe0,
140 0xd0, 0x15, 0x02, 0xb8,
141 0x0a, 0x01, 0x01, 0x63,
143 0x00, 0x89, 0x00, 0x89,
144 0x00, 0x00, 0x2a, 0xb9,
148 /* Ethernet+IP+UDP, indicating syslog */
149 guint8 pkt_syslog[] = {
150 0xff, 0xff, 0xff, 0xff,
151 0xff, 0xff, 0x01, 0x01,
152 0x01, 0x01, 0x01, 0x01,
155 0x45, 0x00, 0x00, 0x64,
156 0x20, 0x48, 0x00, 0x00,
157 0xfc, 0x11, 0xf8, 0x03,
158 0xd0, 0x15, 0x02, 0xb8,
159 0x0a, 0x01, 0x01, 0x63,
161 0x05, 0xe8, 0x02, 0x02,
162 0x00, 0x50, 0x51, 0xe1,
166 /* TR+LLC+IP, indicating TCP */
168 0x10, 0x40, 0x68, 0x00,
169 0x19, 0x69, 0x95, 0x8b,
170 0x00, 0x01, 0xfa, 0x68,
173 0xaa, 0xaa, 0x03, 0x00,
174 0x00, 0x00, 0x08, 0x00,
176 0x45, 0x00, 0x00, 0x28,
177 0x0b, 0x0b, 0x40, 0x00,
178 0x20, 0x06, 0x85, 0x37,
179 0xc0, 0xa8, 0x27, 0x01,
180 0xc0, 0xa8, 0x22, 0x3c
183 /* Ethernet+IP, indicating UDP */
185 0xff, 0xff, 0xff, 0xff,
186 0xff, 0xff, 0x01, 0x01,
187 0x01, 0x01, 0x01, 0x01,
190 0x45, 0x00, 0x00, 0x3c,
191 0xc5, 0x9e, 0x40, 0x00,
192 0xff, 0x11, 0xd7, 0xe0,
193 0xd0, 0x15, 0x02, 0xb8,
194 0x0a, 0x01, 0x01, 0x63
197 /* Ethernet+IP+UDP, indicating BVLC */
198 guint8 pkt_bvlc[] = {
199 0xff, 0xff, 0xff, 0xff,
200 0xff, 0xff, 0x01, 0x01,
201 0x01, 0x01, 0x01, 0x01,
204 0x45, 0x00, 0x00, 0x3c,
205 0xc5, 0x9e, 0x40, 0x00,
206 0xff, 0x11, 0x01, 0xaa,
207 0xc1, 0xff, 0x19, 0x1e,
208 0xc1, 0xff, 0x19, 0xff,
209 0xba, 0xc0, 0xba, 0xc0,
210 0x00, 0xff, 0x2d, 0x5e,
214 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
215 guint8 pkt_ncp2222[] = {
216 0x10, 0x40, 0x00, 0x00,
217 0xf6, 0x7c, 0x9b, 0x70,
218 0x68, 0x00, 0x19, 0x69,
219 0x95, 0x8b, 0xe0, 0xe0,
220 0x03, 0xff, 0xff, 0x00,
221 0x25, 0x02, 0x11, 0x00,
222 0x00, 0x74, 0x14, 0x00,
223 0x00, 0x00, 0x00, 0x00,
224 0x01, 0x04, 0x51, 0x00,
225 0x00, 0x00, 0x04, 0x00,
226 0x02, 0x16, 0x19, 0x7a,
227 0x84, 0x40, 0x01, 0x22,
231 /* Ethernet+IP+TCP, indicating GIOP */
232 guint8 pkt_giop[] = {
233 0xff, 0xff, 0xff, 0xff,
234 0xff, 0xff, 0x01, 0x01,
235 0x01, 0x01, 0x01, 0x01,
238 0x45, 0x00, 0x00, 0xa6,
239 0x00, 0x2f, 0x40, 0x00,
240 0x40, 0x06, 0x3c, 0x21,
241 0x7f, 0x00, 0x00, 0x01,
242 0x7f, 0x00, 0x00, 0x01,
244 0x30, 0x39, 0x04, 0x05,
245 0xac, 0x02, 0x1e, 0x69,
246 0xab, 0x74, 0xab, 0x64,
247 0x80, 0x18, 0x79, 0x60,
248 0xc4, 0xb8, 0x00, 0x00,
249 0x01, 0x01, 0x08, 0x0a,
250 0x00, 0x00, 0x48, 0xf5,
251 0x00, 0x00, 0x48, 0xf5,
253 0x47, 0x49, 0x4f, 0x50,
254 0x01, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x30,
256 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x01,
261 /* Ethernet+IP+TCP, indicating BGP */
263 0xff, 0xff, 0xff, 0xff,
264 0xff, 0xff, 0x01, 0x01,
265 0x01, 0x01, 0x01, 0x01,
268 0x45, 0x00, 0x00, 0xa6,
269 0x00, 0x2f, 0x40, 0x00,
270 0x40, 0x06, 0x3c, 0x21,
271 0x7f, 0x00, 0x00, 0x01,
272 0x7f, 0x00, 0x00, 0x01,
274 0x30, 0x39, 0x00, 0xb3,
275 0xac, 0x02, 0x1e, 0x69,
276 0xab, 0x74, 0xab, 0x64,
277 0x80, 0x18, 0x79, 0x60,
278 0xc4, 0xb8, 0x00, 0x00,
279 0x01, 0x01, 0x08, 0x0a,
280 0x00, 0x00, 0x48, 0xf5,
281 0x00, 0x00, 0x48, 0xf5,
283 0xff, 0xff, 0xff, 0xff,
284 0xff, 0xff, 0xff, 0xff,
285 0xff, 0xff, 0xff, 0xff,
286 0xff, 0xff, 0xff, 0xff,
289 /* Ethernet+IP+TCP, indicating TDS NetLib */
291 0x00, 0x50, 0x8b, 0x0d,
292 0x7a, 0xed, 0x00, 0x08,
293 0xa3, 0x98, 0x39, 0x81,
296 0x45, 0x00, 0x03, 0x8d,
297 0x90, 0xd4, 0x40, 0x00,
298 0x7c, 0x06, 0xc3, 0x1b,
299 0xac, 0x14, 0x02, 0x22,
300 0x0a, 0xc2, 0xee, 0x82,
302 0x05, 0x99, 0x08, 0xf8,
303 0xff, 0x4e, 0x85, 0x46,
304 0xa2, 0xb4, 0x42, 0xaa,
305 0x50, 0x18, 0x3c, 0x28,
306 0x0f, 0xda, 0x00, 0x00,
309 /* Ethernet+IP, indicating SCTP */
310 guint8 pkt_sctp[] = {
311 0x00, 0xa0, 0x80, 0x00,
312 0x5e, 0x46, 0x08, 0x00,
313 0x03, 0x4a, 0x00, 0x35,
316 0x45, 0x00, 0x00, 0x7c,
317 0x14, 0x1c, 0x00, 0x00,
318 0x3b, 0x84, 0x4a, 0x54,
319 0x0a, 0x1c, 0x06, 0x2b,
320 0x0a, 0x1c, 0x06, 0x2c,
324 /* Ethernet+IP+SCTP, indicating MEGACO */
325 guint8 pkt_megaco[] = {
326 0x00, 0xa0, 0x80, 0x00,
327 0x5e, 0x46, 0x08, 0x00,
328 0x03, 0x4a, 0x00, 0x35,
331 0x45, 0x00, 0x00, 0x7c,
332 0x14, 0x1c, 0x00, 0x00,
333 0x3b, 0x84, 0x4a, 0x54,
334 0x0a, 0x1c, 0x06, 0x2b,
335 0x0a, 0x1c, 0x06, 0x2c,
337 0x40, 0x00, 0x0b, 0x80,
338 0x00, 0x01, 0x6f, 0x0a,
339 0x6d, 0xb0, 0x18, 0x82,
340 0x00, 0x03, 0x00, 0x5b,
341 0x28, 0x02, 0x43, 0x45,
342 0x00, 0x00, 0xa0, 0xbd,
343 0x00, 0x00, 0x00, 0x07,
346 /* This little data table drives the whole program */
347 static randpkt_example examples[] = {
348 { "arp", "Address Resolution Protocol",
349 PKT_ARP, WTAP_ENCAP_ETHERNET,
350 pkt_arp, array_length(pkt_arp),
356 { "bgp", "Border Gateway Protocol",
357 PKT_BGP, WTAP_ENCAP_ETHERNET,
358 pkt_bgp, array_length(pkt_bgp),
364 { "bvlc", "BACnet Virtual Link Control",
365 PKT_BVLC, WTAP_ENCAP_ETHERNET,
366 pkt_bvlc, array_length(pkt_bvlc),
372 { "dns", "Domain Name Service",
373 PKT_DNS, WTAP_ENCAP_ETHERNET,
374 pkt_dns, array_length(pkt_dns),
381 PKT_ETHERNET, WTAP_ENCAP_ETHERNET,
388 { "fddi", "Fiber Distributed Data Interface",
389 PKT_FDDI, WTAP_ENCAP_FDDI,
396 { "giop", "General Inter-ORB Protocol",
397 PKT_GIOP, WTAP_ENCAP_ETHERNET,
398 pkt_giop, array_length(pkt_giop),
404 { "icmp", "Internet Control Message Protocol",
405 PKT_ICMP, WTAP_ENCAP_ETHERNET,
406 pkt_icmp, array_length(pkt_icmp),
412 { "ip", "Internet Protocol",
413 PKT_IP, WTAP_ENCAP_ETHERNET,
414 pkt_ip, array_length(pkt_ip),
420 { "llc", "Logical Link Control",
421 PKT_LLC, WTAP_ENCAP_TOKEN_RING,
422 pkt_llc, array_length(pkt_llc),
428 { "m2m", "WiMAX M2M Encapsulation Protocol",
429 PKT_M2M, WTAP_ENCAP_ETHERNET,
430 pkt_m2m, array_length(pkt_m2m),
436 { "megaco", "MEGACO",
437 PKT_MEGACO, WTAP_ENCAP_ETHERNET,
438 pkt_megaco, array_length(pkt_megaco),
444 { "nbns", "NetBIOS-over-TCP Name Service",
445 PKT_NBNS, WTAP_ENCAP_ETHERNET,
446 pkt_nbns, array_length(pkt_nbns),
452 { "ncp2222", "NetWare Core Protocol",
453 PKT_NCP2222, WTAP_ENCAP_TOKEN_RING,
454 pkt_ncp2222, array_length(pkt_ncp2222),
460 { "sctp", "Stream Control Transmission Protocol",
461 PKT_SCTP, WTAP_ENCAP_ETHERNET,
462 pkt_sctp, array_length(pkt_sctp),
468 { "syslog", "Syslog message",
469 PKT_SYSLOG, WTAP_ENCAP_ETHERNET,
470 pkt_syslog, array_length(pkt_syslog),
476 { "tds", "TDS NetLib",
477 PKT_TDS, WTAP_ENCAP_ETHERNET,
478 pkt_tds, array_length(pkt_tds),
484 { "tcp", "Transmission Control Protocol",
485 PKT_TCP, WTAP_ENCAP_TOKEN_RING,
486 pkt_tcp, array_length(pkt_tcp),
492 { "tr", "Token-Ring",
493 PKT_TR, WTAP_ENCAP_TOKEN_RING,
500 { "udp", "User Datagram Protocol",
501 PKT_UDP, WTAP_ENCAP_ETHERNET,
502 pkt_udp, array_length(pkt_udp),
508 { "usb", "Universal Serial Bus",
509 PKT_USB, WTAP_ENCAP_USB,
516 { "usb-linux", "Universal Serial Bus with Linux specific header",
517 PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX,
526 guint randpkt_example_count(void)
528 return array_length(examples);
531 /* Find pkt_example record and return pointer to it */
532 randpkt_example* randpkt_find_example(int type)
534 int num_entries = array_length(examples);
537 for (i = 0; i < num_entries; i++) {
538 if (examples[i].produceable_type == type) {
543 fprintf(stderr, "randpkt: Internal error. Type %d has no entry in examples table.\n",
548 void randpkt_loop(randpkt_example* example, guint64 produce_count)
556 union wtap_pseudo_header* ps_header;
557 guint8 buffer[65536];
558 struct wtap_pkthdr* pkthdr;
560 pkthdr = g_new0(struct wtap_pkthdr, 1);
562 pkthdr->rec_type = REC_TYPE_PACKET;
563 pkthdr->presence_flags = WTAP_HAS_TS;
564 pkthdr->pkt_encap = example->sample_wtap_encap;
566 memset(pkthdr, 0, sizeof(struct wtap_pkthdr));
567 memset(buffer, 0, sizeof(buffer));
569 ps_header = &pkthdr->pseudo_header;
571 /* Load the sample pseudoheader into our pseudoheader buffer */
572 if (example->pseudo_buffer)
573 memcpy(ps_header, example->pseudo_buffer, example->pseudo_length);
575 /* Load the sample into our buffer */
576 if (example->sample_buffer)
577 memcpy(buffer, example->sample_buffer, example->sample_length);
579 /* Produce random packets */
580 for (i = 0; i < produce_count; i++) {
581 if (example->produce_max_bytes > 0) {
582 len_random = (rand() % example->produce_max_bytes + 1);
588 len_this_pkt = example->sample_length + len_random;
590 pkthdr->caplen = len_this_pkt;
591 pkthdr->len = len_this_pkt;
592 pkthdr->ts.secs = i; /* just for variety */
594 for (j = example->pseudo_length; j < (int) sizeof(*ps_header); j++) {
595 ((guint8*)ps_header)[j] = (rand() % 0x100);
598 for (j = example->sample_length; j < len_this_pkt; j++) {
599 /* Add format strings here and there */
600 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
601 memcpy(&buffer[j], "%s", 3);
604 buffer[j] = (rand() % 0x100);
608 if (!wtap_dump(example->dump, pkthdr, buffer, &err, &err_info)) {
609 fprintf(stderr, "randpkt: Error writing to %s: %s\n",
610 example->filename, wtap_strerror(err));
613 case WTAP_ERR_UNWRITABLE_ENCAP:
615 * This is a problem with the particular
616 * frame we're writing and the file type
617 * and subtype we're writing; note that,
618 * and report the file type/subtype.
621 "Frame has a network type that can't be saved in a \"%s\" file.\n",
622 wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
625 case WTAP_ERR_PACKET_TOO_LARGE:
627 * This is a problem with the particular
628 * frame we're writing and the file type
629 * and subtype we're writing; note that,
630 * and report the file type/subtype.
633 "Frame is too large for a \"%s\" file.\n",
634 wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
637 case WTAP_ERR_UNWRITABLE_REC_TYPE:
639 * This is a problem with the particular
640 * record we're writing and the file type
641 * and subtype we're writing; note that,
642 * and report the file type/subtype.
645 "Record has a record type that can't be saved in a \"%s\" file.\n",
646 wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
649 case WTAP_ERR_UNWRITABLE_REC_DATA:
651 * This is a problem with the particular
652 * record we're writing and the file type
653 * and subtype we're writing; note that,
654 * and report the file type/subtype.
657 "Record has data that can't be saved in a \"%s\" file.\n(%s)\n",
658 wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP),
659 err_info != NULL ? err_info : "no information supplied");
672 gboolean randpkt_example_close(randpkt_example* example)
676 if (!wtap_dump_close(example->dump, &err)) {
677 fprintf(stderr, "Error writing to %s: %s\n",
678 example->filename, wtap_strerror(err));
684 void randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes)
688 if (strcmp(produce_filename, "-") == 0) {
689 /* Write to the standard output. */
690 example->dump = wtap_dump_open_stdout(WTAP_FILE_TYPE_SUBTYPE_PCAP,
691 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
692 example->filename = "the standard output";
694 example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
695 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
696 example->filename = produce_filename;
698 if (!example->dump) {
699 fprintf(stderr, "randpkt: Error writing to %s\n", example->filename);
703 /* reduce max_bytes by # of bytes already in sample */
704 if (produce_max_bytes <= example->sample_length) {
705 fprintf(stderr, "randpkt: Sample packet length is %d, which is greater than "
706 "or equal to\n", example->sample_length);
707 fprintf(stderr, "your requested max_bytes value of %d\n", produce_max_bytes);
710 example->produce_max_bytes = produce_max_bytes - example->sample_length;
714 /* Seed the random-number generator */
718 unsigned int randomness;
724 #define RANDOM_DEV "/dev/urandom"
727 * Assume it's at least worth trying /dev/urandom on UN*X.
728 * If it doesn't exist, fall back on time().
730 * XXX - Use CryptGenRandom on Windows?
732 fd = ws_open(RANDOM_DEV, O_RDONLY);
734 if (errno != ENOENT) {
736 "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
743 ret = ws_read(fd, &randomness, sizeof randomness);
746 "randpkt: Could not read from " RANDOM_DEV ": %s\n",
750 if ((size_t)ret != sizeof randomness) {
752 "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
753 (unsigned long)sizeof randomness, (long)ret);
763 randomness = (unsigned int) now;
768 /* Parse command-line option "type" and return enum type */
769 int randpkt_parse_type(char *string)
771 int num_entries = array_length(examples);
774 /* Called with NULL, choose a random packet */
776 return examples[rand() % num_entries].produceable_type;
779 for (i = 0; i < num_entries; i++) {
780 if (g_strcmp0(examples[i].abbrev, string) == 0) {
781 return examples[i].produceable_type;
786 fprintf(stderr, "randpkt: Type %s not known.\n", string);
790 void randpkt_example_list(const char*** abbrev_list, const char*** longname_list, unsigned* list_num)
793 *list_num = randpkt_example_count();
794 *abbrev_list = g_new0(const char*, *list_num);
795 *longname_list = g_new0(const char*, *list_num);
796 for (i = 0; i < *list_num; i++) {
797 (*abbrev_list)[i] = examples[i].abbrev;
798 (*longname_list)[i] = examples[i].longname;
803 * Editor modelines - http://www.wireshark.org/tools/modelines.html
808 * indent-tabs-mode: t
811 * vi: set shiftwidth=4 tabstop=4 noexpandtab:
812 * :indentSize=4:tabSize=4:noTabs=false: