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 */
81 guint8 *sample_buffer;
82 int sample_wtap_encap;
86 /* Ethernet, indicating ARP */
88 0xff, 0xff, 0xff, 0xff,
89 0xff, 0xff, 0x00, 0x00,
90 0x32, 0x25, 0x0f, 0xff,
94 /* Ethernet+IP+UDP, indicating DNS */
96 0xff, 0xff, 0xff, 0xff,
97 0xff, 0xff, 0x01, 0x01,
98 0x01, 0x01, 0x01, 0x01,
101 0x45, 0x00, 0x00, 0x3c,
102 0xc5, 0x9e, 0x40, 0x00,
103 0xff, 0x11, 0xd7, 0xe0,
104 0xd0, 0x15, 0x02, 0xb8,
105 0x0a, 0x01, 0x01, 0x63,
107 0x05, 0xe8, 0x00, 0x35,
108 0xff, 0xff, 0x2a, 0xb9,
112 /* Ethernet+IP, indicating ICMP */
113 guint8 pkt_icmp[] = {
114 0xff, 0xff, 0xff, 0xff,
115 0xff, 0xff, 0x01, 0x01,
116 0x01, 0x01, 0x01, 0x01,
119 0x45, 0x00, 0x00, 0x54,
120 0x8f, 0xb3, 0x40, 0x00,
121 0xfd, 0x01, 0x8a, 0x99,
122 0xcc, 0xfc, 0x66, 0x0b,
123 0xce, 0x41, 0x62, 0x12
126 /* Ethernet, indicating IP */
128 0xff, 0xff, 0xff, 0xff,
129 0xff, 0xff, 0x01, 0x01,
130 0x01, 0x01, 0x01, 0x01,
134 /* TR, indicating LLC */
136 0x10, 0x40, 0x68, 0x00,
137 0x19, 0x69, 0x95, 0x8b,
138 0x00, 0x01, 0xfa, 0x68,
142 /* Ethernet, indicating WiMAX M2M */
144 0xff, 0xff, 0xff, 0xff,
145 0xff, 0xff, 0x00, 0x00,
146 0x32, 0x25, 0x0f, 0xff,
150 /* Ethernet+IP+UDP, indicating NBNS */
151 guint8 pkt_nbns[] = {
152 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0x01, 0x01,
154 0x01, 0x01, 0x01, 0x01,
157 0x45, 0x00, 0x00, 0x3c,
158 0xc5, 0x9e, 0x40, 0x00,
159 0xff, 0x11, 0xd7, 0xe0,
160 0xd0, 0x15, 0x02, 0xb8,
161 0x0a, 0x01, 0x01, 0x63,
163 0x00, 0x89, 0x00, 0x89,
164 0x00, 0x00, 0x2a, 0xb9,
168 /* Ethernet+IP+UDP, indicating syslog */
169 guint8 pkt_syslog[] = {
170 0xff, 0xff, 0xff, 0xff,
171 0xff, 0xff, 0x01, 0x01,
172 0x01, 0x01, 0x01, 0x01,
175 0x45, 0x00, 0x00, 0x64,
176 0x20, 0x48, 0x00, 0x00,
177 0xfc, 0x11, 0xf8, 0x03,
178 0xd0, 0x15, 0x02, 0xb8,
179 0x0a, 0x01, 0x01, 0x63,
181 0x05, 0xe8, 0x02, 0x02,
182 0x00, 0x50, 0x51, 0xe1,
186 /* TR+LLC+IP, indicating TCP */
188 0x10, 0x40, 0x68, 0x00,
189 0x19, 0x69, 0x95, 0x8b,
190 0x00, 0x01, 0xfa, 0x68,
193 0xaa, 0xaa, 0x03, 0x00,
194 0x00, 0x00, 0x08, 0x00,
196 0x45, 0x00, 0x00, 0x28,
197 0x0b, 0x0b, 0x40, 0x00,
198 0x20, 0x06, 0x85, 0x37,
199 0xc0, 0xa8, 0x27, 0x01,
200 0xc0, 0xa8, 0x22, 0x3c
203 /* Ethernet+IP, indicating UDP */
205 0xff, 0xff, 0xff, 0xff,
206 0xff, 0xff, 0x01, 0x01,
207 0x01, 0x01, 0x01, 0x01,
210 0x45, 0x00, 0x00, 0x3c,
211 0xc5, 0x9e, 0x40, 0x00,
212 0xff, 0x11, 0xd7, 0xe0,
213 0xd0, 0x15, 0x02, 0xb8,
214 0x0a, 0x01, 0x01, 0x63
217 /* Ethernet+IP+UDP, indicating BVLC */
218 guint8 pkt_bvlc[] = {
219 0xff, 0xff, 0xff, 0xff,
220 0xff, 0xff, 0x01, 0x01,
221 0x01, 0x01, 0x01, 0x01,
224 0x45, 0x00, 0x00, 0x3c,
225 0xc5, 0x9e, 0x40, 0x00,
226 0xff, 0x11, 0x01, 0xaa,
227 0xc1, 0xff, 0x19, 0x1e,
228 0xc1, 0xff, 0x19, 0xff,
229 0xba, 0xc0, 0xba, 0xc0,
230 0x00, 0xff, 0x2d, 0x5e,
234 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
235 guint8 pkt_ncp2222[] = {
236 0x10, 0x40, 0x00, 0x00,
237 0xf6, 0x7c, 0x9b, 0x70,
238 0x68, 0x00, 0x19, 0x69,
239 0x95, 0x8b, 0xe0, 0xe0,
240 0x03, 0xff, 0xff, 0x00,
241 0x25, 0x02, 0x11, 0x00,
242 0x00, 0x74, 0x14, 0x00,
243 0x00, 0x00, 0x00, 0x00,
244 0x01, 0x04, 0x51, 0x00,
245 0x00, 0x00, 0x04, 0x00,
246 0x02, 0x16, 0x19, 0x7a,
247 0x84, 0x40, 0x01, 0x22,
251 /* Ethernet+IP+TCP, indicating GIOP */
252 guint8 pkt_giop[] = {
253 0xff, 0xff, 0xff, 0xff,
254 0xff, 0xff, 0x01, 0x01,
255 0x01, 0x01, 0x01, 0x01,
258 0x45, 0x00, 0x00, 0xa6,
259 0x00, 0x2f, 0x40, 0x00,
260 0x40, 0x06, 0x3c, 0x21,
261 0x7f, 0x00, 0x00, 0x01,
262 0x7f, 0x00, 0x00, 0x01,
264 0x30, 0x39, 0x04, 0x05,
265 0xac, 0x02, 0x1e, 0x69,
266 0xab, 0x74, 0xab, 0x64,
267 0x80, 0x18, 0x79, 0x60,
268 0xc4, 0xb8, 0x00, 0x00,
269 0x01, 0x01, 0x08, 0x0a,
270 0x00, 0x00, 0x48, 0xf5,
271 0x00, 0x00, 0x48, 0xf5,
273 0x47, 0x49, 0x4f, 0x50,
274 0x01, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x30,
276 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x01,
281 /* Ethernet+IP+TCP, indicating BGP */
283 0xff, 0xff, 0xff, 0xff,
284 0xff, 0xff, 0x01, 0x01,
285 0x01, 0x01, 0x01, 0x01,
288 0x45, 0x00, 0x00, 0xa6,
289 0x00, 0x2f, 0x40, 0x00,
290 0x40, 0x06, 0x3c, 0x21,
291 0x7f, 0x00, 0x00, 0x01,
292 0x7f, 0x00, 0x00, 0x01,
294 0x30, 0x39, 0x00, 0xb3,
295 0xac, 0x02, 0x1e, 0x69,
296 0xab, 0x74, 0xab, 0x64,
297 0x80, 0x18, 0x79, 0x60,
298 0xc4, 0xb8, 0x00, 0x00,
299 0x01, 0x01, 0x08, 0x0a,
300 0x00, 0x00, 0x48, 0xf5,
301 0x00, 0x00, 0x48, 0xf5,
303 0xff, 0xff, 0xff, 0xff,
304 0xff, 0xff, 0xff, 0xff,
305 0xff, 0xff, 0xff, 0xff,
306 0xff, 0xff, 0xff, 0xff,
309 /* Ethernet+IP+TCP, indicating TDS NetLib */
311 0x00, 0x50, 0x8b, 0x0d,
312 0x7a, 0xed, 0x00, 0x08,
313 0xa3, 0x98, 0x39, 0x81,
316 0x45, 0x00, 0x03, 0x8d,
317 0x90, 0xd4, 0x40, 0x00,
318 0x7c, 0x06, 0xc3, 0x1b,
319 0xac, 0x14, 0x02, 0x22,
320 0x0a, 0xc2, 0xee, 0x82,
322 0x05, 0x99, 0x08, 0xf8,
323 0xff, 0x4e, 0x85, 0x46,
324 0xa2, 0xb4, 0x42, 0xaa,
325 0x50, 0x18, 0x3c, 0x28,
326 0x0f, 0xda, 0x00, 0x00,
329 /* Ethernet+IP, indicating SCTP */
330 guint8 pkt_sctp[] = {
331 0x00, 0xa0, 0x80, 0x00,
332 0x5e, 0x46, 0x08, 0x00,
333 0x03, 0x4a, 0x00, 0x35,
336 0x45, 0x00, 0x00, 0x7c,
337 0x14, 0x1c, 0x00, 0x00,
338 0x3b, 0x84, 0x4a, 0x54,
339 0x0a, 0x1c, 0x06, 0x2b,
340 0x0a, 0x1c, 0x06, 0x2c,
344 /* Ethernet+IP+SCTP, indicating MEGACO */
345 guint8 pkt_megaco[] = {
346 0x00, 0xa0, 0x80, 0x00,
347 0x5e, 0x46, 0x08, 0x00,
348 0x03, 0x4a, 0x00, 0x35,
351 0x45, 0x00, 0x00, 0x7c,
352 0x14, 0x1c, 0x00, 0x00,
353 0x3b, 0x84, 0x4a, 0x54,
354 0x0a, 0x1c, 0x06, 0x2b,
355 0x0a, 0x1c, 0x06, 0x2c,
357 0x40, 0x00, 0x0b, 0x80,
358 0x00, 0x01, 0x6f, 0x0a,
359 0x6d, 0xb0, 0x18, 0x82,
360 0x00, 0x03, 0x00, 0x5b,
361 0x28, 0x02, 0x43, 0x45,
362 0x00, 0x00, 0xa0, 0xbd,
363 0x00, 0x00, 0x00, 0x07,
366 /* This little data table drives the whole program */
367 pkt_example examples[] = {
368 { "arp", "Address Resolution Protocol",
369 PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) },
371 { "bgp", "Border Gateway Protocol",
372 PKT_BGP, pkt_bgp, WTAP_ENCAP_ETHERNET, array_length(pkt_bgp) },
374 { "bvlc", "BACnet Virtual Link Control",
375 PKT_BVLC, pkt_bvlc, WTAP_ENCAP_ETHERNET, array_length(pkt_bvlc) },
377 { "dns", "Domain Name Service",
378 PKT_DNS, pkt_dns, WTAP_ENCAP_ETHERNET, array_length(pkt_dns) },
381 PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 },
383 { "fddi", "Fiber Distributed Data Interface",
384 PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 },
386 { "giop", "General Inter-ORB Protocol",
387 PKT_GIOP, pkt_giop, WTAP_ENCAP_ETHERNET, array_length(pkt_giop) },
389 { "icmp", "Internet Control Message Protocol",
390 PKT_ICMP, pkt_icmp, WTAP_ENCAP_ETHERNET, array_length(pkt_icmp) },
392 { "ip", "Internet Protocol",
393 PKT_IP, pkt_ip, WTAP_ENCAP_ETHERNET, array_length(pkt_ip) },
395 { "llc", "Logical Link Control",
396 PKT_LLC, pkt_llc, WTAP_ENCAP_TOKEN_RING, array_length(pkt_llc) },
398 { "m2m", "WiMAX M2M Encapsulation Protocol",
399 PKT_M2M, pkt_m2m, WTAP_ENCAP_ETHERNET, array_length(pkt_m2m) },
401 { "megaco", "MEGACO",
402 PKT_MEGACO, pkt_megaco, WTAP_ENCAP_ETHERNET, array_length(pkt_megaco) },
404 { "nbns", "NetBIOS-over-TCP Name Service",
405 PKT_NBNS, pkt_nbns, WTAP_ENCAP_ETHERNET, array_length(pkt_nbns) },
407 { "ncp2222", "NetWare Core Protocol",
408 PKT_NCP2222, pkt_ncp2222, WTAP_ENCAP_TOKEN_RING, array_length(pkt_ncp2222) },
410 { "sctp", "Stream Control Transmission Protocol",
411 PKT_SCTP, pkt_sctp, WTAP_ENCAP_ETHERNET, array_length(pkt_sctp) },
413 { "syslog", "Syslog message",
414 PKT_SYSLOG, pkt_syslog, WTAP_ENCAP_ETHERNET, array_length(pkt_syslog) },
416 { "tds", "TDS NetLib",
417 PKT_TDS, pkt_tds, WTAP_ENCAP_ETHERNET, array_length(pkt_tds) },
419 { "tcp", "Transmission Control Protocol",
420 PKT_TCP, pkt_tcp, WTAP_ENCAP_TOKEN_RING, array_length(pkt_tcp) },
422 { "tr", "Token-Ring",
423 PKT_TR, NULL, WTAP_ENCAP_TOKEN_RING, 0 },
425 { "udp", "User Datagram Protocol",
426 PKT_UDP, pkt_udp, WTAP_ENCAP_ETHERNET, array_length(pkt_udp) },
432 static int parse_type(char *string);
433 static void usage(void);
434 static void seed(void);
436 static pkt_example* find_example(int type);
439 main(int argc, char **argv)
443 struct wtap_pkthdr pkthdr;
444 union wtap_pseudo_header ps_header;
445 int i, j, len_this_pkt, len_random, err;
446 guint8 buffer[65536];
452 int produce_count = 1000; /* number of pkts to produce */
453 int produce_type = PKT_ETHERNET;
454 char *produce_filename = NULL;
455 int produce_max_bytes = 5000;
456 pkt_example *example;
458 while ((opt = getopt(argc, argv, "b:c:t:")) != -1) {
460 case 'b': /* max bytes */
461 produce_max_bytes = atoi(optarg);
462 if (produce_max_bytes > 65536) {
463 printf("Max bytes is 65536\n");
468 case 'c': /* count */
469 produce_count = atoi(optarg);
472 case 't': /* type of packet to produce */
473 produce_type = parse_type(optarg);
482 /* any more command line parameters? */
484 produce_filename = argv[optind];
490 example = find_example(produce_type);
494 pkthdr.pkt_encap = example->sample_wtap_encap;
496 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
497 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
499 printf("Error writing to %s\n", produce_filename);
505 /* reduce max_bytes by # of bytes already in sample */
506 if (produce_max_bytes <= example->sample_length) {
507 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
508 printf("your requested max_bytes value of %d\n", produce_max_bytes);
512 produce_max_bytes -= example->sample_length;
515 /* Load the sample into our buffer */
516 if (example->sample_buffer)
517 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
519 /* Produce random packets */
520 for (i = 0; i < produce_count; i++) {
521 if (produce_max_bytes > 0) {
522 len_random = (rand() % produce_max_bytes + 1);
528 len_this_pkt = example->sample_length + len_random;
530 pkthdr.caplen = len_this_pkt;
531 pkthdr.len = len_this_pkt;
532 pkthdr.ts.secs = i; /* just for variety */
534 for (j = example->sample_length; j < len_this_pkt; j++) {
535 /* Add format strings here and there */
536 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
537 memcpy(&buffer[j], "%s", 3);
540 buffer[j] = (rand() % 0x100);
544 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
547 wtap_dump_close(dump, &err);
553 /* Print usage statement and exit program */
557 int num_entries = array_length(examples);
560 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
561 printf("Default max bytes (per packet) is 5000\n");
562 printf("Default count is 1000.\n");
565 for (i = 0; i < num_entries; i++) {
566 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
574 /* Parse command-line option "type" and return enum type */
576 int parse_type(char *string)
578 int num_entries = array_length(examples);
581 for (i = 0; i < num_entries; i++) {
582 if (strcmp(examples[i].abbrev, string) == 0) {
583 return examples[i].produceable_type;
588 printf("Type %s not known.\n", string);
592 /* Find pkt_example record and return pointer to it */
594 pkt_example* find_example(int type)
596 int num_entries = array_length(examples);
599 for (i = 0; i < num_entries; i++) {
600 if (examples[i].produceable_type == type) {
605 printf("Internal error. Type %d has no entry in examples table.\n", type);
609 /* Seed the random-number generator */
613 unsigned int randomness;
616 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
619 fd = open("/dev/random", O_RDONLY);
621 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
625 read(fd, &randomness, sizeof(randomness));
630 randomness = (unsigned int) now;