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.14 2002/05/18 14:58:00 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.
45 #include "wiretap/wtap.h"
47 #define array_length(x) (sizeof x / sizeof x[0])
49 /* Types of produceable packets */
72 guint8 *sample_buffer;
73 int sample_wtap_encap;
77 /* Ethernet, indicating ARP */
79 0xff, 0xff, 0xff, 0xff,
80 0xff, 0xff, 0x00, 0x00,
81 0x32, 0x25, 0x0f, 0xff,
85 /* Ethernet+IP+UDP, indicating DNS */
87 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0x01, 0x01,
89 0x01, 0x01, 0x01, 0x01,
92 0x45, 0x00, 0x00, 0x3c,
93 0xc5, 0x9e, 0x40, 0x00,
94 0xff, 0x11, 0xd7, 0xe0,
95 0xd0, 0x15, 0x02, 0xb8,
96 0x0a, 0x01, 0x01, 0x63,
98 0x05, 0xe8, 0x00, 0x35,
99 0x00, 0x00, 0x2a, 0xb9,
103 /* Ethernet+IP, indicating ICMP */
104 guint8 pkt_icmp[] = {
105 0xff, 0xff, 0xff, 0xff,
106 0xff, 0xff, 0x01, 0x01,
107 0x01, 0x01, 0x01, 0x01,
110 0x45, 0x00, 0x00, 0x54,
111 0x8f, 0xb3, 0x40, 0x00,
112 0xfd, 0x01, 0x8a, 0x99,
113 0xcc, 0xfc, 0x66, 0x0b,
114 0xce, 0x41, 0x62, 0x12
117 /* Ethernet, indicating IP */
119 0xff, 0xff, 0xff, 0xff,
120 0xff, 0xff, 0x01, 0x01,
121 0x01, 0x01, 0x01, 0x01,
125 /* TR, indicating LLC */
127 0x10, 0x40, 0x68, 0x00,
128 0x19, 0x69, 0x95, 0x8b,
129 0x00, 0x01, 0xfa, 0x68,
133 /* Ethernet+IP+UDP, indicating NBNS */
134 guint8 pkt_nbns[] = {
135 0xff, 0xff, 0xff, 0xff,
136 0xff, 0xff, 0x01, 0x01,
137 0x01, 0x01, 0x01, 0x01,
140 0x45, 0x00, 0x00, 0x3c,
141 0xc5, 0x9e, 0x40, 0x00,
142 0xff, 0x11, 0xd7, 0xe0,
143 0xd0, 0x15, 0x02, 0xb8,
144 0x0a, 0x01, 0x01, 0x63,
146 0x00, 0x89, 0x00, 0x89,
147 0x00, 0x00, 0x2a, 0xb9,
151 /* Ethernet+IP+UDP, indicating syslog */
152 guint8 pkt_syslog[] = {
153 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0x01, 0x01,
155 0x01, 0x01, 0x01, 0x01,
158 0x45, 0x00, 0x00, 0x64,
159 0x20, 0x48, 0x00, 0x00,
160 0xfc, 0x11, 0xf8, 0x03,
161 0xd0, 0x15, 0x02, 0xb8,
162 0x0a, 0x01, 0x01, 0x63,
164 0x05, 0xe8, 0x02, 0x02,
165 0x00, 0x50, 0x51, 0xe1,
169 /* TR+LLC+IP, indicating TCP */
171 0x10, 0x40, 0x68, 0x00,
172 0x19, 0x69, 0x95, 0x8b,
173 0x00, 0x01, 0xfa, 0x68,
176 0xaa, 0xaa, 0x03, 0x00,
177 0x00, 0x00, 0x08, 0x00,
179 0x45, 0x00, 0x00, 0x28,
180 0x0b, 0x0b, 0x40, 0x00,
181 0x20, 0x06, 0x85, 0x37,
182 0xc0, 0xa8, 0x27, 0x01,
183 0xc0, 0xa8, 0x22, 0x3c
186 /* Ethernet+IP, indicating UDP */
188 0xff, 0xff, 0xff, 0xff,
189 0xff, 0xff, 0x01, 0x01,
190 0x01, 0x01, 0x01, 0x01,
193 0x45, 0x00, 0x00, 0x3c,
194 0xc5, 0x9e, 0x40, 0x00,
195 0xff, 0x11, 0xd7, 0xe0,
196 0xd0, 0x15, 0x02, 0xb8,
197 0x0a, 0x01, 0x01, 0x63
200 /* Ethernet+IP+UDP, indicating BVLC */
201 guint8 pkt_bvlc[] = {
202 0xff, 0xff, 0xff, 0xff,
203 0xff, 0xff, 0x01, 0x01,
204 0x01, 0x01, 0x01, 0x01,
207 0x45, 0x00, 0x00, 0x3c,
208 0xc5, 0x9e, 0x40, 0x00,
209 0xff, 0x11, 0x01, 0xaa,
210 0xc1, 0xff, 0x19, 0x1e,
211 0xc1, 0xff, 0x19, 0xff,
212 0xba, 0xc0, 0xba, 0xc0,
213 0x00, 0xff, 0x2d, 0x5e,
217 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
218 guint8 pkt_ncp2222[] = {
219 0x10, 0x40, 0x00, 0x00,
220 0xf6, 0x7c, 0x9b, 0x70,
221 0x68, 0x00, 0x19, 0x69,
222 0x95, 0x8b, 0xe0, 0xe0,
223 0x03, 0xff, 0xff, 0x00,
224 0x25, 0x02, 0x11, 0x00,
225 0x00, 0x74, 0x14, 0x00,
226 0x00, 0x00, 0x00, 0x00,
227 0x01, 0x04, 0x51, 0x00,
228 0x00, 0x00, 0x04, 0x00,
229 0x02, 0x16, 0x19, 0x7a,
230 0x84, 0x40, 0x01, 0x22,
234 /* Ethernet+IP+TCP, indicating GIOP */
235 guint8 pkt_giop[] = {
236 0xff, 0xff, 0xff, 0xff,
237 0xff, 0xff, 0x01, 0x01,
238 0x01, 0x01, 0x01, 0x01,
241 0x45, 0x00, 0x00, 0xa6,
242 0x00, 0x2f, 0x40, 0x00,
243 0x40, 0x06, 0x3c, 0x21,
244 0x7f, 0x00, 0x00, 0x01,
245 0x7f, 0x00, 0x00, 0x01,
247 0x30, 0x39, 0x04, 0x05,
248 0xac, 0x02, 0x1e, 0x69,
249 0xab, 0x74, 0xab, 0x64,
250 0x80, 0x18, 0x79, 0x60,
251 0xc4, 0xb8, 0x00, 0x00,
252 0x01, 0x01, 0x08, 0x0a,
253 0x00, 0x00, 0x48, 0xf5,
254 0x00, 0x00, 0x48, 0xf5,
256 0x47, 0x49, 0x4f, 0x50,
257 0x01, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x30,
259 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x01,
264 /* This little data table drives the whole program */
265 pkt_example examples[] = {
266 { "arp", "Address Resolution Protocol",
267 PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) },
269 { "dns", "Domain Name Service",
270 PKT_DNS, pkt_dns, WTAP_ENCAP_ETHERNET, array_length(pkt_dns) },
273 PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 },
275 { "fddi", "Fiber Distributed Data Interface",
276 PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 },
278 { "icmp", "Internet Control Message Protocol",
279 PKT_ICMP, pkt_icmp, WTAP_ENCAP_ETHERNET, array_length(pkt_icmp) },
281 { "ip", "Internet Protocol",
282 PKT_IP, pkt_ip, WTAP_ENCAP_ETHERNET, array_length(pkt_ip) },
284 { "llc", "Logical Link Control",
285 PKT_LLC, pkt_llc, WTAP_ENCAP_TOKEN_RING, array_length(pkt_llc) },
287 { "nbns", "NetBIOS-over-TCP Name Service",
288 PKT_NBNS, pkt_nbns, WTAP_ENCAP_ETHERNET, array_length(pkt_nbns) },
290 { "syslog", "Syslog message",
291 PKT_SYSLOG, pkt_syslog, WTAP_ENCAP_ETHERNET, array_length(pkt_syslog) },
293 { "tcp", "Transmission Control Protocol",
294 PKT_TCP, pkt_tcp, WTAP_ENCAP_TOKEN_RING, array_length(pkt_tcp) },
296 { "tr", "Token-Ring",
297 PKT_TR, NULL, WTAP_ENCAP_TOKEN_RING, 0 },
299 { "udp", "User Datagram Protocol",
300 PKT_UDP, pkt_udp, WTAP_ENCAP_ETHERNET, array_length(pkt_udp) },
302 { "bvlc", "BACnet Virtual Link Control",
303 PKT_BVLC, pkt_bvlc, WTAP_ENCAP_ETHERNET, array_length(pkt_bvlc) },
305 { "ncp2222", "NetWare Core Protocol",
306 PKT_NCP2222, pkt_ncp2222, WTAP_ENCAP_TOKEN_RING, array_length(pkt_ncp2222) },
308 { "giop", "General Inter-ORB Protocol",
309 PKT_GIOP, pkt_giop, WTAP_ENCAP_ETHERNET, array_length(pkt_giop) },
315 static int parse_type(char *string);
316 static void usage(void);
317 static void seed(void);
319 static pkt_example* find_example(int type);
322 main(int argc, char **argv)
326 struct wtap_pkthdr pkthdr;
327 union wtap_pseudo_header ps_header;
328 int i, j, len_this_pkt, len_random, err;
329 guint8 buffer[65536];
335 int produce_count = 1000; /* number of pkts to produce */
336 int produce_type = PKT_ETHERNET;
337 char *produce_filename = NULL;
338 int produce_max_bytes = 5000;
339 pkt_example *example;
341 while ((opt = getopt(argc, argv, "b:c:t:")) != -1) {
343 case 'b': /* max bytes */
344 produce_max_bytes = atoi(optarg);
345 if (produce_max_bytes > 65536) {
346 printf("Max bytes is 65536\n");
351 case 'c': /* count */
352 produce_count = atoi(optarg);
355 case 't': /* type of packet to produce */
356 produce_type = parse_type(optarg);
365 /* any more command line parameters? */
367 produce_filename = argv[optind];
373 example = find_example(produce_type);
375 pkthdr.ts.tv_sec = 0;
376 pkthdr.ts.tv_usec = 0;
377 pkthdr.pkt_encap = example->sample_wtap_encap;
379 dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
380 example->sample_wtap_encap, produce_max_bytes, &err);
384 /* reduce max_bytes by # of bytes already in sample */
385 if (produce_max_bytes <= example->sample_length) {
386 printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length);
387 printf("your requested max_bytes value of %d\n", produce_max_bytes);
391 produce_max_bytes -= example->sample_length;
394 /* Load the sample into our buffer */
395 if (example->sample_buffer)
396 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
398 /* Produce random packets */
399 for (i = 0; i < produce_count; i++) {
400 if (produce_max_bytes > 0) {
401 len_random = (rand() % produce_max_bytes + 1);
407 len_this_pkt = example->sample_length + len_random;
409 pkthdr.caplen = len_this_pkt;
410 pkthdr.len = len_this_pkt;
411 pkthdr.ts.tv_sec = i; /* just for variety */
413 for (j = example->sample_length; j < len_random; j++) {
414 buffer[j] = (rand() % 0x100);
417 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
420 wtap_dump_close(dump, &err);
426 /* Print usage statement and exit program */
430 int num_entries = array_length(examples);
433 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
434 printf("Default max bytes (per packet) is 5000\n");
435 printf("Default count is 1000.\n");
438 for (i = 0; i < num_entries; i++) {
439 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
447 /* Parse command-line option "type" and return enum type */
449 int parse_type(char *string)
451 int num_entries = array_length(examples);
454 for (i = 0; i < num_entries; i++) {
455 if (strcmp(examples[i].abbrev, string) == 0) {
456 return examples[i].produceable_type;
461 printf("Type %s not known.\n", string);
465 /* Find pkt_example record and return pointer to it */
467 pkt_example* find_example(int type)
469 int num_entries = array_length(examples);
472 for (i = 0; i < num_entries; i++) {
473 if (examples[i].produceable_type == type) {
478 printf("Internal error. Type %d has no entry in examples table.\n", type);
482 /* Seed the random-number generator */
486 unsigned int randomness;
489 /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
492 fd = open("/dev/random", O_RDONLY);
494 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
498 read(fd, &randomness, sizeof(randomness));
503 randomness = (unsigned int) now;