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.9 2000/09/21 04:41:09 gram Exp $
9 * Copyright (C) 1999 by Gilbert Ramirez <gram@xiexie.org>
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.
45 #include "wiretap/wtap.h"
47 #define array_length(x) (sizeof x / sizeof x[0])
49 /* Types of produceable packets */
69 guint8 *sample_buffer;
70 int sample_wtap_encap;
74 /* Ethernet, indicating ARP */
76 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0x00, 0x00,
78 0x32, 0x25, 0x0f, 0xff,
82 /* Ethernet+IP+UDP, indicating DNS */
84 0xff, 0xff, 0xff, 0xff,
85 0xff, 0xff, 0x01, 0x01,
86 0x01, 0x01, 0x01, 0x01,
89 0x45, 0x00, 0x00, 0x3c,
90 0xc5, 0x9e, 0x40, 0x00,
91 0xff, 0x11, 0xd7, 0xe0,
92 0xd0, 0x15, 0x02, 0xb8,
93 0x0a, 0x01, 0x01, 0x63,
95 0x05, 0xe8, 0x00, 0x35,
96 0x00, 0x00, 0x2a, 0xb9,
100 /* Ethernet+IP, indicating ICMP */
101 guint8 pkt_icmp[] = {
102 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0x01, 0x01,
104 0x01, 0x01, 0x01, 0x01,
107 0x45, 0x00, 0x00, 0x54,
108 0x8f, 0xb3, 0x40, 0x00,
109 0xfd, 0x01, 0x8a, 0x99,
110 0xcc, 0xfc, 0x66, 0x0b,
111 0xce, 0x41, 0x62, 0x12
114 /* Ethernet, indicating IP */
116 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0x01, 0x01,
118 0x01, 0x01, 0x01, 0x01,
122 /* TR, indicating LLC */
124 0x10, 0x40, 0x68, 0x00,
125 0x19, 0x69, 0x95, 0x8b,
126 0x00, 0x01, 0xfa, 0x68,
130 /* Ethernet+IP+UP, 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 /* This little data table drives the whole program */
198 pkt_example examples[] = {
199 { "arp", "Address Resolution Protocol",
200 PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) },
202 { "dns", "Domain Name Service",
203 PKT_DNS, pkt_dns, WTAP_ENCAP_ETHERNET, array_length(pkt_dns) },
206 PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 },
208 { "fddi", "Fiber Distributed Data Interface",
209 PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 },
211 { "icmp", "Internet Control Message Protocol",
212 PKT_ICMP, pkt_icmp, WTAP_ENCAP_ETHERNET, array_length(pkt_icmp) },
214 { "ip", "Internet Protocol",
215 PKT_IP, pkt_ip, WTAP_ENCAP_ETHERNET, array_length(pkt_ip) },
217 { "llc", "Logical Link Control",
218 PKT_LLC, pkt_llc, WTAP_ENCAP_TOKEN_RING, array_length(pkt_llc) },
220 { "nbns", "NetBIOS-over-TCP Name Service",
221 PKT_NBNS, pkt_nbns, WTAP_ENCAP_ETHERNET, array_length(pkt_nbns) },
223 { "syslog", "Syslog message",
224 PKT_SYSLOG, pkt_syslog, WTAP_ENCAP_ETHERNET, array_length(pkt_syslog) },
226 { "tcp", "Transmission Control Protocol",
227 PKT_TCP, pkt_tcp, WTAP_ENCAP_TOKEN_RING, array_length(pkt_tcp) },
229 { "tr", "Token-Ring",
230 PKT_TR, NULL, WTAP_ENCAP_TOKEN_RING, 0 },
232 { "udp", "User Datagram Protocol",
233 PKT_UDP, pkt_udp, WTAP_ENCAP_ETHERNET, array_length(pkt_udp) }
238 static int parse_type(char *string);
239 static void usage(void);
240 static void seed(void);
242 static pkt_example* find_example(int type);
245 main(int argc, char **argv)
249 struct wtap_pkthdr pkthdr;
250 union wtap_pseudo_header ps_header;
251 int i, j, len_this_pkt, len_random, err;
252 guint8 buffer[65536];
258 int produce_count = 1000; /* number of pkts to produce */
259 int produce_type = PKT_ETHERNET;
260 char *produce_filename = NULL;
261 int produce_max_bytes = 5000;
262 pkt_example *example;
264 while ((opt = getopt(argc, argv, "b:c:t:")) != EOF) {
266 case 'b': /* max bytes */
267 produce_max_bytes = atoi(optarg);
268 if (produce_max_bytes > 65536) {
269 printf("Max bytes is 65536\n");
274 case 'c': /* count */
275 produce_count = atoi(optarg);
278 case 't': /* type of packet to produce */
279 produce_type = parse_type(optarg);
288 /* any more command line parameters? */
290 produce_filename = argv[optind];
296 example = find_example(produce_type);
298 pkthdr.ts.tv_sec = 0;
299 pkthdr.ts.tv_usec = 0;
300 pkthdr.pkt_encap = example->sample_wtap_encap;
302 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
303 example->sample_wtap_encap, produce_max_bytes, &err);
307 /* reduce max_bytes by # of bytes already in sample */
308 if (produce_max_bytes <= example->sample_length) {
309 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
310 printf("your requested max_bytes value of %d\n", produce_max_bytes);
314 produce_max_bytes -= example->sample_length;
317 /* Load the sample into our buffer */
318 if (example->sample_buffer)
319 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
321 /* Produce random packets */
322 for (i = 0; i < produce_count; i++) {
323 if (produce_max_bytes > 0) {
324 len_random = (rand() % produce_max_bytes + 1);
330 len_this_pkt = example->sample_length + len_random;
332 pkthdr.caplen = len_this_pkt;
333 pkthdr.len = len_this_pkt;
334 pkthdr.ts.tv_sec = i; /* just for variety */
336 for (j = example->sample_length; j < len_random; j++) {
337 buffer[j] = (rand() % 0x100);
340 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
343 wtap_dump_close(dump, &err);
349 /* Print usage statement and exit program */
353 int num_entries = array_length(examples);
356 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
357 printf("Default max bytes (per packet) is 5000\n");
358 printf("Default count is 1000.\n");
361 for (i = 0; i < num_entries; i++) {
362 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
370 /* Parse command-line option "type" and return enum type */
372 int parse_type(char *string)
374 int num_entries = array_length(examples);
377 for (i = 0; i < num_entries; i++) {
378 if (strcmp(examples[i].abbrev, string) == 0) {
379 return examples[i].produceable_type;
387 /* Find pkt_example record and return pointer to it */
389 pkt_example* find_example(int type)
391 int num_entries = array_length(examples);
394 for (i = 0; i < num_entries; i++) {
395 if (examples[i].produceable_type == type) {
400 printf("Internal error. Type %d has no entry in examples table.\n", type);
404 /* Seed the random-number generator */
408 unsigned int randomness;
411 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
414 fd = open("/dev/random", O_RDONLY);
416 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
420 read(fd, &randomness, sizeof(randomness));
425 randomness = (unsigned int) now;