4 * Creates random packet traces. Useful for debugging sniffers by testing
5 * assumptions about the veracity of the data found in the packet.
7 * $Id: randpkt.c,v 1.18 2002/11/17 21:47:41 gerald Exp $
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 */
78 guint8 *sample_buffer;
79 int sample_wtap_encap;
83 /* Ethernet, indicating ARP */
85 0xff, 0xff, 0xff, 0xff,
86 0xff, 0xff, 0x00, 0x00,
87 0x32, 0x25, 0x0f, 0xff,
91 /* Ethernet+IP+UDP, indicating DNS */
93 0xff, 0xff, 0xff, 0xff,
94 0xff, 0xff, 0x01, 0x01,
95 0x01, 0x01, 0x01, 0x01,
98 0x45, 0x00, 0x00, 0x3c,
99 0xc5, 0x9e, 0x40, 0x00,
100 0xff, 0x11, 0xd7, 0xe0,
101 0xd0, 0x15, 0x02, 0xb8,
102 0x0a, 0x01, 0x01, 0x63,
104 0x05, 0xe8, 0x00, 0x35,
105 0x00, 0x00, 0x2a, 0xb9,
109 /* Ethernet+IP, indicating ICMP */
110 guint8 pkt_icmp[] = {
111 0xff, 0xff, 0xff, 0xff,
112 0xff, 0xff, 0x01, 0x01,
113 0x01, 0x01, 0x01, 0x01,
116 0x45, 0x00, 0x00, 0x54,
117 0x8f, 0xb3, 0x40, 0x00,
118 0xfd, 0x01, 0x8a, 0x99,
119 0xcc, 0xfc, 0x66, 0x0b,
120 0xce, 0x41, 0x62, 0x12
123 /* Ethernet, indicating IP */
125 0xff, 0xff, 0xff, 0xff,
126 0xff, 0xff, 0x01, 0x01,
127 0x01, 0x01, 0x01, 0x01,
131 /* TR, indicating LLC */
133 0x10, 0x40, 0x68, 0x00,
134 0x19, 0x69, 0x95, 0x8b,
135 0x00, 0x01, 0xfa, 0x68,
139 /* Ethernet+IP+UDP, indicating NBNS */
140 guint8 pkt_nbns[] = {
141 0xff, 0xff, 0xff, 0xff,
142 0xff, 0xff, 0x01, 0x01,
143 0x01, 0x01, 0x01, 0x01,
146 0x45, 0x00, 0x00, 0x3c,
147 0xc5, 0x9e, 0x40, 0x00,
148 0xff, 0x11, 0xd7, 0xe0,
149 0xd0, 0x15, 0x02, 0xb8,
150 0x0a, 0x01, 0x01, 0x63,
152 0x00, 0x89, 0x00, 0x89,
153 0x00, 0x00, 0x2a, 0xb9,
157 /* Ethernet+IP+UDP, indicating syslog */
158 guint8 pkt_syslog[] = {
159 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0x01, 0x01,
161 0x01, 0x01, 0x01, 0x01,
164 0x45, 0x00, 0x00, 0x64,
165 0x20, 0x48, 0x00, 0x00,
166 0xfc, 0x11, 0xf8, 0x03,
167 0xd0, 0x15, 0x02, 0xb8,
168 0x0a, 0x01, 0x01, 0x63,
170 0x05, 0xe8, 0x02, 0x02,
171 0x00, 0x50, 0x51, 0xe1,
175 /* TR+LLC+IP, indicating TCP */
177 0x10, 0x40, 0x68, 0x00,
178 0x19, 0x69, 0x95, 0x8b,
179 0x00, 0x01, 0xfa, 0x68,
182 0xaa, 0xaa, 0x03, 0x00,
183 0x00, 0x00, 0x08, 0x00,
185 0x45, 0x00, 0x00, 0x28,
186 0x0b, 0x0b, 0x40, 0x00,
187 0x20, 0x06, 0x85, 0x37,
188 0xc0, 0xa8, 0x27, 0x01,
189 0xc0, 0xa8, 0x22, 0x3c
192 /* Ethernet+IP, indicating UDP */
194 0xff, 0xff, 0xff, 0xff,
195 0xff, 0xff, 0x01, 0x01,
196 0x01, 0x01, 0x01, 0x01,
199 0x45, 0x00, 0x00, 0x3c,
200 0xc5, 0x9e, 0x40, 0x00,
201 0xff, 0x11, 0xd7, 0xe0,
202 0xd0, 0x15, 0x02, 0xb8,
203 0x0a, 0x01, 0x01, 0x63
206 /* Ethernet+IP+UDP, indicating BVLC */
207 guint8 pkt_bvlc[] = {
208 0xff, 0xff, 0xff, 0xff,
209 0xff, 0xff, 0x01, 0x01,
210 0x01, 0x01, 0x01, 0x01,
213 0x45, 0x00, 0x00, 0x3c,
214 0xc5, 0x9e, 0x40, 0x00,
215 0xff, 0x11, 0x01, 0xaa,
216 0xc1, 0xff, 0x19, 0x1e,
217 0xc1, 0xff, 0x19, 0xff,
218 0xba, 0xc0, 0xba, 0xc0,
219 0x00, 0xff, 0x2d, 0x5e,
223 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
224 guint8 pkt_ncp2222[] = {
225 0x10, 0x40, 0x00, 0x00,
226 0xf6, 0x7c, 0x9b, 0x70,
227 0x68, 0x00, 0x19, 0x69,
228 0x95, 0x8b, 0xe0, 0xe0,
229 0x03, 0xff, 0xff, 0x00,
230 0x25, 0x02, 0x11, 0x00,
231 0x00, 0x74, 0x14, 0x00,
232 0x00, 0x00, 0x00, 0x00,
233 0x01, 0x04, 0x51, 0x00,
234 0x00, 0x00, 0x04, 0x00,
235 0x02, 0x16, 0x19, 0x7a,
236 0x84, 0x40, 0x01, 0x22,
240 /* Ethernet+IP+TCP, indicating GIOP */
241 guint8 pkt_giop[] = {
242 0xff, 0xff, 0xff, 0xff,
243 0xff, 0xff, 0x01, 0x01,
244 0x01, 0x01, 0x01, 0x01,
247 0x45, 0x00, 0x00, 0xa6,
248 0x00, 0x2f, 0x40, 0x00,
249 0x40, 0x06, 0x3c, 0x21,
250 0x7f, 0x00, 0x00, 0x01,
251 0x7f, 0x00, 0x00, 0x01,
253 0x30, 0x39, 0x04, 0x05,
254 0xac, 0x02, 0x1e, 0x69,
255 0xab, 0x74, 0xab, 0x64,
256 0x80, 0x18, 0x79, 0x60,
257 0xc4, 0xb8, 0x00, 0x00,
258 0x01, 0x01, 0x08, 0x0a,
259 0x00, 0x00, 0x48, 0xf5,
260 0x00, 0x00, 0x48, 0xf5,
262 0x47, 0x49, 0x4f, 0x50,
263 0x01, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x30,
265 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x01,
270 /* Ethernet+IP+TCP, indicating BGP */
272 0xff, 0xff, 0xff, 0xff,
273 0xff, 0xff, 0x01, 0x01,
274 0x01, 0x01, 0x01, 0x01,
277 0x45, 0x00, 0x00, 0xa6,
278 0x00, 0x2f, 0x40, 0x00,
279 0x40, 0x06, 0x3c, 0x21,
280 0x7f, 0x00, 0x00, 0x01,
281 0x7f, 0x00, 0x00, 0x01,
283 0x30, 0x39, 0x00, 0xb3,
284 0xac, 0x02, 0x1e, 0x69,
285 0xab, 0x74, 0xab, 0x64,
286 0x80, 0x18, 0x79, 0x60,
287 0xc4, 0xb8, 0x00, 0x00,
288 0x01, 0x01, 0x08, 0x0a,
289 0x00, 0x00, 0x48, 0xf5,
290 0x00, 0x00, 0x48, 0xf5,
292 0xff, 0xff, 0xff, 0xff,
293 0xff, 0xff, 0xff, 0xff,
294 0xff, 0xff, 0xff, 0xff,
295 0xff, 0xff, 0xff, 0xff,
298 /* Ethernet+IP+TCP, indicating TDS NetLib */
300 0x00, 0x50, 0x8b, 0x0d,
301 0x7a, 0xed, 0x00, 0x08,
302 0xa3, 0x98, 0x39, 0x81,
305 0x45, 0x00, 0x03, 0x8d,
306 0x90, 0xd4, 0x40, 0x00,
307 0x7c, 0x06, 0xc3, 0x1b,
308 0xac, 0x14, 0x02, 0x22,
309 0x0a, 0xc2, 0xee, 0x82,
311 0x05, 0x99, 0x08, 0xf8,
312 0xff, 0x4e, 0x85, 0x46,
313 0xa2, 0xb4, 0x42, 0xaa,
314 0x50, 0x18, 0x3c, 0x28,
315 0x0f, 0xda, 0x00, 0x00,
318 /* This little data table drives the whole program */
319 pkt_example examples[] = {
320 { "arp", "Address Resolution Protocol",
321 PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) },
323 { "dns", "Domain Name Service",
324 PKT_DNS, pkt_dns, WTAP_ENCAP_ETHERNET, array_length(pkt_dns) },
327 PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 },
329 { "fddi", "Fiber Distributed Data Interface",
330 PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 },
332 { "icmp", "Internet Control Message Protocol",
333 PKT_ICMP, pkt_icmp, WTAP_ENCAP_ETHERNET, array_length(pkt_icmp) },
335 { "ip", "Internet Protocol",
336 PKT_IP, pkt_ip, WTAP_ENCAP_ETHERNET, array_length(pkt_ip) },
338 { "llc", "Logical Link Control",
339 PKT_LLC, pkt_llc, WTAP_ENCAP_TOKEN_RING, array_length(pkt_llc) },
341 { "nbns", "NetBIOS-over-TCP Name Service",
342 PKT_NBNS, pkt_nbns, WTAP_ENCAP_ETHERNET, array_length(pkt_nbns) },
344 { "syslog", "Syslog message",
345 PKT_SYSLOG, pkt_syslog, WTAP_ENCAP_ETHERNET, array_length(pkt_syslog) },
347 { "tcp", "Transmission Control Protocol",
348 PKT_TCP, pkt_tcp, WTAP_ENCAP_TOKEN_RING, array_length(pkt_tcp) },
350 { "tr", "Token-Ring",
351 PKT_TR, NULL, WTAP_ENCAP_TOKEN_RING, 0 },
353 { "udp", "User Datagram Protocol",
354 PKT_UDP, pkt_udp, WTAP_ENCAP_ETHERNET, array_length(pkt_udp) },
356 { "bvlc", "BACnet Virtual Link Control",
357 PKT_BVLC, pkt_bvlc, WTAP_ENCAP_ETHERNET, array_length(pkt_bvlc) },
359 { "ncp2222", "NetWare Core Protocol",
360 PKT_NCP2222, pkt_ncp2222, WTAP_ENCAP_TOKEN_RING, array_length(pkt_ncp2222) },
362 { "giop", "General Inter-ORB Protocol",
363 PKT_GIOP, pkt_giop, WTAP_ENCAP_ETHERNET, array_length(pkt_giop) },
365 { "bgp", "Border Gateway Protocol",
366 PKT_BGP, pkt_bgp, WTAP_ENCAP_ETHERNET, array_length(pkt_bgp) },
368 { "tds", "TDS NetLib",
369 PKT_TDS, pkt_tds, WTAP_ENCAP_ETHERNET, array_length(pkt_tds) },
375 static int parse_type(char *string);
376 static void usage(void);
377 static void seed(void);
379 static pkt_example* find_example(int type);
382 main(int argc, char **argv)
386 struct wtap_pkthdr pkthdr;
387 union wtap_pseudo_header ps_header;
388 int i, j, len_this_pkt, len_random, err;
389 guint8 buffer[65536];
395 int produce_count = 1000; /* number of pkts to produce */
396 int produce_type = PKT_ETHERNET;
397 char *produce_filename = NULL;
398 int produce_max_bytes = 5000;
399 pkt_example *example;
401 while ((opt = getopt(argc, argv, "b:c:t:")) != -1) {
403 case 'b': /* max bytes */
404 produce_max_bytes = atoi(optarg);
405 if (produce_max_bytes > 65536) {
406 printf("Max bytes is 65536\n");
411 case 'c': /* count */
412 produce_count = atoi(optarg);
415 case 't': /* type of packet to produce */
416 produce_type = parse_type(optarg);
425 /* any more command line parameters? */
427 produce_filename = argv[optind];
433 example = find_example(produce_type);
435 pkthdr.ts.tv_sec = 0;
436 pkthdr.ts.tv_usec = 0;
437 pkthdr.pkt_encap = example->sample_wtap_encap;
439 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
440 example->sample_wtap_encap, produce_max_bytes, &err);
444 /* reduce max_bytes by # of bytes already in sample */
445 if (produce_max_bytes <= example->sample_length) {
446 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
447 printf("your requested max_bytes value of %d\n", produce_max_bytes);
451 produce_max_bytes -= example->sample_length;
454 /* Load the sample into our buffer */
455 if (example->sample_buffer)
456 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
458 /* Produce random packets */
459 for (i = 0; i < produce_count; i++) {
460 if (produce_max_bytes > 0) {
461 len_random = (rand() % produce_max_bytes + 1);
467 len_this_pkt = example->sample_length + len_random;
469 pkthdr.caplen = len_this_pkt;
470 pkthdr.len = len_this_pkt;
471 pkthdr.ts.tv_sec = i; /* just for variety */
473 for (j = example->sample_length; j < len_random; j++) {
474 buffer[j] = (rand() % 0x100);
477 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
480 wtap_dump_close(dump, &err);
486 /* Print usage statement and exit program */
490 int num_entries = array_length(examples);
493 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
494 printf("Default max bytes (per packet) is 5000\n");
495 printf("Default count is 1000.\n");
498 for (i = 0; i < num_entries; i++) {
499 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
507 /* Parse command-line option "type" and return enum type */
509 int parse_type(char *string)
511 int num_entries = array_length(examples);
514 for (i = 0; i < num_entries; i++) {
515 if (strcmp(examples[i].abbrev, string) == 0) {
516 return examples[i].produceable_type;
521 printf("Type %s not known.\n", string);
525 /* Find pkt_example record and return pointer to it */
527 pkt_example* find_example(int type)
529 int num_entries = array_length(examples);
532 for (i = 0; i < num_entries; i++) {
533 if (examples[i].produceable_type == type) {
538 printf("Internal error. Type %d has no entry in examples table.\n", type);
542 /* Seed the random-number generator */
546 unsigned int randomness;
549 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
552 fd = open("/dev/random", O_RDONLY);
554 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
558 read(fd, &randomness, sizeof(randomness));
563 randomness = (unsigned int) now;