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);
489 /* reduce max_bytes by # of bytes already in sample */
490 if (produce_max_bytes <= example->sample_length) {
491 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
492 printf("your requested max_bytes value of %d\n", produce_max_bytes);
496 produce_max_bytes -= example->sample_length;
499 /* Load the sample into our buffer */
500 if (example->sample_buffer)
501 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
503 /* Produce random packets */
504 for (i = 0; i < produce_count; i++) {
505 if (produce_max_bytes > 0) {
506 len_random = (rand() % produce_max_bytes + 1);
512 len_this_pkt = example->sample_length + len_random;
514 pkthdr.caplen = len_this_pkt;
515 pkthdr.len = len_this_pkt;
516 pkthdr.ts.secs = i; /* just for variety */
518 for (j = example->sample_length; j < len_this_pkt; j++) {
519 /* Add format strings here and there */
520 if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
521 memcpy(&buffer[j], "%s", 3);
524 buffer[j] = (rand() % 0x100);
528 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
531 wtap_dump_close(dump, &err);
537 /* Print usage statement and exit program */
541 int num_entries = array_length(examples);
544 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
545 printf("Default max bytes (per packet) is 5000\n");
546 printf("Default count is 1000.\n");
549 for (i = 0; i < num_entries; i++) {
550 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
558 /* Parse command-line option "type" and return enum type */
560 int parse_type(char *string)
562 int num_entries = array_length(examples);
565 for (i = 0; i < num_entries; i++) {
566 if (strcmp(examples[i].abbrev, string) == 0) {
567 return examples[i].produceable_type;
572 printf("Type %s not known.\n", string);
576 /* Find pkt_example record and return pointer to it */
578 pkt_example* find_example(int type)
580 int num_entries = array_length(examples);
583 for (i = 0; i < num_entries; i++) {
584 if (examples[i].produceable_type == type) {
589 printf("Internal error. Type %d has no entry in examples table.\n", type);
593 /* Seed the random-number generator */
597 unsigned int randomness;
600 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
603 fd = open("/dev/random", O_RDONLY);
605 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
609 read(fd, &randomness, sizeof(randomness));
614 randomness = (unsigned int) now;