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 */
80 guint8 *sample_buffer;
81 int sample_wtap_encap;
85 /* Ethernet, indicating ARP */
87 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0x00, 0x00,
89 0x32, 0x25, 0x0f, 0xff,
93 /* Ethernet+IP+UDP, indicating DNS */
95 0xff, 0xff, 0xff, 0xff,
96 0xff, 0xff, 0x01, 0x01,
97 0x01, 0x01, 0x01, 0x01,
100 0x45, 0x00, 0x00, 0x3c,
101 0xc5, 0x9e, 0x40, 0x00,
102 0xff, 0x11, 0xd7, 0xe0,
103 0xd0, 0x15, 0x02, 0xb8,
104 0x0a, 0x01, 0x01, 0x63,
106 0x05, 0xe8, 0x00, 0x35,
107 0xff, 0xff, 0x2a, 0xb9,
111 /* Ethernet+IP, indicating ICMP */
112 guint8 pkt_icmp[] = {
113 0xff, 0xff, 0xff, 0xff,
114 0xff, 0xff, 0x01, 0x01,
115 0x01, 0x01, 0x01, 0x01,
118 0x45, 0x00, 0x00, 0x54,
119 0x8f, 0xb3, 0x40, 0x00,
120 0xfd, 0x01, 0x8a, 0x99,
121 0xcc, 0xfc, 0x66, 0x0b,
122 0xce, 0x41, 0x62, 0x12
125 /* Ethernet, indicating IP */
127 0xff, 0xff, 0xff, 0xff,
128 0xff, 0xff, 0x01, 0x01,
129 0x01, 0x01, 0x01, 0x01,
133 /* TR, indicating LLC */
135 0x10, 0x40, 0x68, 0x00,
136 0x19, 0x69, 0x95, 0x8b,
137 0x00, 0x01, 0xfa, 0x68,
141 /* Ethernet+IP+UDP, indicating NBNS */
142 guint8 pkt_nbns[] = {
143 0xff, 0xff, 0xff, 0xff,
144 0xff, 0xff, 0x01, 0x01,
145 0x01, 0x01, 0x01, 0x01,
148 0x45, 0x00, 0x00, 0x3c,
149 0xc5, 0x9e, 0x40, 0x00,
150 0xff, 0x11, 0xd7, 0xe0,
151 0xd0, 0x15, 0x02, 0xb8,
152 0x0a, 0x01, 0x01, 0x63,
154 0x00, 0x89, 0x00, 0x89,
155 0x00, 0x00, 0x2a, 0xb9,
159 /* Ethernet+IP+UDP, indicating syslog */
160 guint8 pkt_syslog[] = {
161 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0x01, 0x01,
163 0x01, 0x01, 0x01, 0x01,
166 0x45, 0x00, 0x00, 0x64,
167 0x20, 0x48, 0x00, 0x00,
168 0xfc, 0x11, 0xf8, 0x03,
169 0xd0, 0x15, 0x02, 0xb8,
170 0x0a, 0x01, 0x01, 0x63,
172 0x05, 0xe8, 0x02, 0x02,
173 0x00, 0x50, 0x51, 0xe1,
177 /* TR+LLC+IP, indicating TCP */
179 0x10, 0x40, 0x68, 0x00,
180 0x19, 0x69, 0x95, 0x8b,
181 0x00, 0x01, 0xfa, 0x68,
184 0xaa, 0xaa, 0x03, 0x00,
185 0x00, 0x00, 0x08, 0x00,
187 0x45, 0x00, 0x00, 0x28,
188 0x0b, 0x0b, 0x40, 0x00,
189 0x20, 0x06, 0x85, 0x37,
190 0xc0, 0xa8, 0x27, 0x01,
191 0xc0, 0xa8, 0x22, 0x3c
194 /* Ethernet+IP, indicating UDP */
196 0xff, 0xff, 0xff, 0xff,
197 0xff, 0xff, 0x01, 0x01,
198 0x01, 0x01, 0x01, 0x01,
201 0x45, 0x00, 0x00, 0x3c,
202 0xc5, 0x9e, 0x40, 0x00,
203 0xff, 0x11, 0xd7, 0xe0,
204 0xd0, 0x15, 0x02, 0xb8,
205 0x0a, 0x01, 0x01, 0x63
208 /* Ethernet+IP+UDP, indicating BVLC */
209 guint8 pkt_bvlc[] = {
210 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0x01, 0x01,
212 0x01, 0x01, 0x01, 0x01,
215 0x45, 0x00, 0x00, 0x3c,
216 0xc5, 0x9e, 0x40, 0x00,
217 0xff, 0x11, 0x01, 0xaa,
218 0xc1, 0xff, 0x19, 0x1e,
219 0xc1, 0xff, 0x19, 0xff,
220 0xba, 0xc0, 0xba, 0xc0,
221 0x00, 0xff, 0x2d, 0x5e,
225 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
226 guint8 pkt_ncp2222[] = {
227 0x10, 0x40, 0x00, 0x00,
228 0xf6, 0x7c, 0x9b, 0x70,
229 0x68, 0x00, 0x19, 0x69,
230 0x95, 0x8b, 0xe0, 0xe0,
231 0x03, 0xff, 0xff, 0x00,
232 0x25, 0x02, 0x11, 0x00,
233 0x00, 0x74, 0x14, 0x00,
234 0x00, 0x00, 0x00, 0x00,
235 0x01, 0x04, 0x51, 0x00,
236 0x00, 0x00, 0x04, 0x00,
237 0x02, 0x16, 0x19, 0x7a,
238 0x84, 0x40, 0x01, 0x22,
242 /* Ethernet+IP+TCP, indicating GIOP */
243 guint8 pkt_giop[] = {
244 0xff, 0xff, 0xff, 0xff,
245 0xff, 0xff, 0x01, 0x01,
246 0x01, 0x01, 0x01, 0x01,
249 0x45, 0x00, 0x00, 0xa6,
250 0x00, 0x2f, 0x40, 0x00,
251 0x40, 0x06, 0x3c, 0x21,
252 0x7f, 0x00, 0x00, 0x01,
253 0x7f, 0x00, 0x00, 0x01,
255 0x30, 0x39, 0x04, 0x05,
256 0xac, 0x02, 0x1e, 0x69,
257 0xab, 0x74, 0xab, 0x64,
258 0x80, 0x18, 0x79, 0x60,
259 0xc4, 0xb8, 0x00, 0x00,
260 0x01, 0x01, 0x08, 0x0a,
261 0x00, 0x00, 0x48, 0xf5,
262 0x00, 0x00, 0x48, 0xf5,
264 0x47, 0x49, 0x4f, 0x50,
265 0x01, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x30,
267 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x01,
272 /* Ethernet+IP+TCP, indicating BGP */
274 0xff, 0xff, 0xff, 0xff,
275 0xff, 0xff, 0x01, 0x01,
276 0x01, 0x01, 0x01, 0x01,
279 0x45, 0x00, 0x00, 0xa6,
280 0x00, 0x2f, 0x40, 0x00,
281 0x40, 0x06, 0x3c, 0x21,
282 0x7f, 0x00, 0x00, 0x01,
283 0x7f, 0x00, 0x00, 0x01,
285 0x30, 0x39, 0x00, 0xb3,
286 0xac, 0x02, 0x1e, 0x69,
287 0xab, 0x74, 0xab, 0x64,
288 0x80, 0x18, 0x79, 0x60,
289 0xc4, 0xb8, 0x00, 0x00,
290 0x01, 0x01, 0x08, 0x0a,
291 0x00, 0x00, 0x48, 0xf5,
292 0x00, 0x00, 0x48, 0xf5,
294 0xff, 0xff, 0xff, 0xff,
295 0xff, 0xff, 0xff, 0xff,
296 0xff, 0xff, 0xff, 0xff,
297 0xff, 0xff, 0xff, 0xff,
300 /* Ethernet+IP+TCP, indicating TDS NetLib */
302 0x00, 0x50, 0x8b, 0x0d,
303 0x7a, 0xed, 0x00, 0x08,
304 0xa3, 0x98, 0x39, 0x81,
307 0x45, 0x00, 0x03, 0x8d,
308 0x90, 0xd4, 0x40, 0x00,
309 0x7c, 0x06, 0xc3, 0x1b,
310 0xac, 0x14, 0x02, 0x22,
311 0x0a, 0xc2, 0xee, 0x82,
313 0x05, 0x99, 0x08, 0xf8,
314 0xff, 0x4e, 0x85, 0x46,
315 0xa2, 0xb4, 0x42, 0xaa,
316 0x50, 0x18, 0x3c, 0x28,
317 0x0f, 0xda, 0x00, 0x00,
320 /* Ethernet+IP, indicating SCTP */
321 guint8 pkt_sctp[] = {
322 0x00, 0xa0, 0x80, 0x00,
323 0x5e, 0x46, 0x08, 0x00,
324 0x03, 0x4a, 0x00, 0x35,
327 0x45, 0x00, 0x00, 0x7c,
328 0x14, 0x1c, 0x00, 0x00,
329 0x3b, 0x84, 0x4a, 0x54,
330 0x0a, 0x1c, 0x06, 0x2b,
331 0x0a, 0x1c, 0x06, 0x2c,
335 /* Ethernet+IP+SCTP, indicating MEGACO */
336 guint8 pkt_megaco[] = {
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,
348 0x40, 0x00, 0x0b, 0x80,
349 0x00, 0x01, 0x6f, 0x0a,
350 0x6d, 0xb0, 0x18, 0x82,
351 0x00, 0x03, 0x00, 0x5b,
352 0x28, 0x02, 0x43, 0x45,
353 0x00, 0x00, 0xa0, 0xbd,
354 0x00, 0x00, 0x00, 0x07,
357 /* This little data table drives the whole program */
358 pkt_example examples[] = {
359 { "arp", "Address Resolution Protocol",
360 PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) },
362 { "bgp", "Border Gateway Protocol",
363 PKT_BGP, pkt_bgp, WTAP_ENCAP_ETHERNET, array_length(pkt_bgp) },
365 { "bvlc", "BACnet Virtual Link Control",
366 PKT_BVLC, pkt_bvlc, WTAP_ENCAP_ETHERNET, array_length(pkt_bvlc) },
368 { "dns", "Domain Name Service",
369 PKT_DNS, pkt_dns, WTAP_ENCAP_ETHERNET, array_length(pkt_dns) },
372 PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 },
374 { "fddi", "Fiber Distributed Data Interface",
375 PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 },
377 { "giop", "General Inter-ORB Protocol",
378 PKT_GIOP, pkt_giop, WTAP_ENCAP_ETHERNET, array_length(pkt_giop) },
380 { "icmp", "Internet Control Message Protocol",
381 PKT_ICMP, pkt_icmp, WTAP_ENCAP_ETHERNET, array_length(pkt_icmp) },
383 { "ip", "Internet Protocol",
384 PKT_IP, pkt_ip, WTAP_ENCAP_ETHERNET, array_length(pkt_ip) },
386 { "llc", "Logical Link Control",
387 PKT_LLC, pkt_llc, WTAP_ENCAP_TOKEN_RING, array_length(pkt_llc) },
389 { "megaco", "MEGACO",
390 PKT_MEGACO, pkt_megaco, WTAP_ENCAP_ETHERNET, array_length(pkt_megaco) },
392 { "nbns", "NetBIOS-over-TCP Name Service",
393 PKT_NBNS, pkt_nbns, WTAP_ENCAP_ETHERNET, array_length(pkt_nbns) },
395 { "ncp2222", "NetWare Core Protocol",
396 PKT_NCP2222, pkt_ncp2222, WTAP_ENCAP_TOKEN_RING, array_length(pkt_ncp2222) },
398 { "sctp", "Stream Control Transmission Protocol",
399 PKT_SCTP, pkt_sctp, WTAP_ENCAP_ETHERNET, array_length(pkt_sctp) },
401 { "syslog", "Syslog message",
402 PKT_SYSLOG, pkt_syslog, WTAP_ENCAP_ETHERNET, array_length(pkt_syslog) },
404 { "tds", "TDS NetLib",
405 PKT_TDS, pkt_tds, WTAP_ENCAP_ETHERNET, array_length(pkt_tds) },
407 { "tcp", "Transmission Control Protocol",
408 PKT_TCP, pkt_tcp, WTAP_ENCAP_TOKEN_RING, array_length(pkt_tcp) },
410 { "tr", "Token-Ring",
411 PKT_TR, NULL, WTAP_ENCAP_TOKEN_RING, 0 },
413 { "udp", "User Datagram Protocol",
414 PKT_UDP, pkt_udp, WTAP_ENCAP_ETHERNET, array_length(pkt_udp) },
420 static int parse_type(char *string);
421 static void usage(void);
422 static void seed(void);
424 static pkt_example* find_example(int type);
427 main(int argc, char **argv)
431 struct wtap_pkthdr pkthdr;
432 union wtap_pseudo_header ps_header;
433 int i, j, len_this_pkt, len_random, err;
434 guint8 buffer[65536];
440 int produce_count = 1000; /* number of pkts to produce */
441 int produce_type = PKT_ETHERNET;
442 char *produce_filename = NULL;
443 int produce_max_bytes = 5000;
444 pkt_example *example;
446 while ((opt = getopt(argc, argv, "b:c:t:")) != -1) {
448 case 'b': /* max bytes */
449 produce_max_bytes = atoi(optarg);
450 if (produce_max_bytes > 65536) {
451 printf("Max bytes is 65536\n");
456 case 'c': /* count */
457 produce_count = atoi(optarg);
460 case 't': /* type of packet to produce */
461 produce_type = parse_type(optarg);
470 /* any more command line parameters? */
472 produce_filename = argv[optind];
478 example = find_example(produce_type);
482 pkthdr.pkt_encap = example->sample_wtap_encap;
484 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
485 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
487 printf("Error writing to %s\n", produce_filename);
493 /* reduce max_bytes by # of bytes already in sample */
494 if (produce_max_bytes <= example->sample_length) {
495 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
496 printf("your requested max_bytes value of %d\n", produce_max_bytes);
500 produce_max_bytes -= example->sample_length;
503 /* Load the sample into our buffer */
504 if (example->sample_buffer)
505 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
507 /* Produce random packets */
508 for (i = 0; i < produce_count; i++) {
509 if (produce_max_bytes > 0) {
510 len_random = (rand() % produce_max_bytes + 1);
516 len_this_pkt = example->sample_length + len_random;
518 pkthdr.caplen = len_this_pkt;
519 pkthdr.len = len_this_pkt;
520 pkthdr.ts.secs = i; /* just for variety */
522 for (j = example->sample_length; j < len_this_pkt; j++) {
523 /* Add format strings here and there */
524 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
525 memcpy(&buffer[j], "%s", 3);
528 buffer[j] = (rand() % 0x100);
532 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
535 wtap_dump_close(dump, &err);
541 /* Print usage statement and exit program */
545 int num_entries = array_length(examples);
548 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
549 printf("Default max bytes (per packet) is 5000\n");
550 printf("Default count is 1000.\n");
553 for (i = 0; i < num_entries; i++) {
554 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
562 /* Parse command-line option "type" and return enum type */
564 int parse_type(char *string)
566 int num_entries = array_length(examples);
569 for (i = 0; i < num_entries; i++) {
570 if (strcmp(examples[i].abbrev, string) == 0) {
571 return examples[i].produceable_type;
576 printf("Type %s not known.\n", string);
580 /* Find pkt_example record and return pointer to it */
582 pkt_example* find_example(int type)
584 int num_entries = array_length(examples);
587 for (i = 0; i < num_entries; i++) {
588 if (examples[i].produceable_type == type) {
593 printf("Internal error. Type %d has no entry in examples table.\n", type);
597 /* Seed the random-number generator */
601 unsigned int randomness;
604 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
607 fd = open("/dev/random", O_RDONLY);
609 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
613 read(fd, &randomness, sizeof(randomness));
618 randomness = (unsigned int) now;