diff options
author | gram <gram@f5534014-38df-0310-8fa8-9805f1628bb7> | 1999-09-10 05:15:17 +0000 |
---|---|---|
committer | gram <gram@f5534014-38df-0310-8fa8-9805f1628bb7> | 1999-09-10 05:15:17 +0000 |
commit | 43c0f8299d341aacc92cfba72440b53558423c31 (patch) | |
tree | e245ca333afc8100c51125f85670683baeb8d183 /randpkt.c | |
parent | 8dad489f71f0d9b37942b15cafba8b9d65e2eeaf (diff) |
Added random packet generator.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@645 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'randpkt.c')
-rw-r--r-- | randpkt.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/randpkt.c b/randpkt.c new file mode 100644 index 0000000000..213421c977 --- /dev/null +++ b/randpkt.c @@ -0,0 +1,293 @@ +/* + * randpkt.c + * --------- + * Creates random packet traces. Useful for debugging sniffers by testing + * assumptions about the veracity of the data found in the packet. + * + * $Id: randpkt.c,v 1.1 1999/09/10 05:15:10 gram Exp $ + * + * Copyright (C) 1999 by Gilbert Ramirez <gram@xiexie.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include <time.h> +#include <errno.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <wtap.h> + +#define array_length(x) (sizeof x / sizeof x[0]) + +/* Types of produceable packets */ +enum { + PKT_ARP, + PKT_ETHERNET, + PKT_FDDI, + PKT_LLC, + PKT_TR +}; + +typedef struct { + char *abbrev; + char *longname; + int produceable_type; + guint8 *sample_buffer; + int sample_wtap_encap; + int sample_length; +} pkt_example; + +/* Ethernet, indicating ARP */ +guint8 pkt_arp[] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, + 0x32, 0x25, 0x0f, 0xff, + 0x08, 0x06 +}; + +/* TR, indicating LLC */ +guint8 pkt_llc[] = { + 0x10, 0x40, 0x68, 0x00, + 0x19, 0x69, 0x95, 0x8b, + 0x00, 0x01, 0xfa, 0x68, + 0xc4, 0x67 +}; + +/* This little data table drives the whole program */ +pkt_example examples[] = { + { "arp", "Address Resolution Protocol", + PKT_ARP, pkt_arp, WTAP_ENCAP_ETHERNET, array_length(pkt_arp) }, + + { "eth", "Ethernet", + PKT_ETHERNET, NULL, WTAP_ENCAP_ETHERNET, 0 }, + + { "fddi", "Fiber Distributed Data Interface", + PKT_FDDI, NULL, WTAP_ENCAP_FDDI, 0 }, + + { "llc", "Logical Link Control", + PKT_LLC, pkt_llc, WTAP_ENCAP_TR, array_length(pkt_llc) }, + + { "tr", "Token-Ring", + PKT_TR, NULL, WTAP_ENCAP_TR, 0 } +}; + + + +static int parse_type(char *string); +static void usage(void); +static void seed(void); + +static pkt_example* find_example(int type); + +int +main(int argc, char **argv) +{ + + wtap_dumper *dump; + struct wtap_pkthdr pkthdr; + int i, j, len_this_pkt, len_random, err; + guint8 buffer[65536]; + + int opt; + extern char *optarg; + extern int optind; + + int produce_count = 1000; /* number of pkts to produce */ + int produce_type = PKT_ETHERNET; + char *produce_filename = NULL; + int produce_max_bytes = 5000; + pkt_example *example; + + while ((opt = getopt(argc, argv, "b:c:t:")) != EOF) { + switch (opt) { + case 'b': /* max bytes */ + produce_max_bytes = atoi(optarg); + if (produce_max_bytes > 65536) { + printf("Max bytes is 65536\n"); + exit(0); + } + break; + + case 'c': /* count */ + produce_count = atoi(optarg); + break; + + case 't': /* type of packet to produce */ + produce_type = parse_type(optarg); + break; + + default: + usage(); + break; + } + } + + /* any more command line parameters? */ + if (argc > optind) { + produce_filename = argv[optind]; + } + else { + usage(); + } + + example = find_example(produce_type); + + pkthdr.ts.tv_sec = 0; + pkthdr.ts.tv_usec = 0; + pkthdr.pkt_encap = example->sample_wtap_encap; + + dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP, + example->sample_wtap_encap, produce_max_bytes, &err); + + seed(); + + /* reduce max_bytes by # of bytes already in sample */ + if (produce_max_bytes <= example->sample_length) { + printf("Sample packet length is %d, which is greater than or equal to\n", example->sample_length); + printf("your requested max_bytes value of %d\n", produce_max_bytes); + exit(0); + } + else { + produce_max_bytes -= example->sample_length; + } + + /* Load the sample into our buffer */ + if (example->sample_buffer) + memcpy(&buffer[0], example->sample_buffer, example->sample_length); + + /* Produce random packets */ + for (i = 0; i < produce_count; i++) { + if (produce_max_bytes > 0) { + len_random = (rand() % produce_max_bytes + 1); + } + else { + len_random = 0; + } + + len_this_pkt = example->sample_length + len_random; + + pkthdr.caplen = len_this_pkt; + pkthdr.len = len_this_pkt; + pkthdr.ts.tv_sec = i; /* just for variety */ + + for (j = example->sample_length; j < len_random; j++) { + buffer[j] = (rand() % 0x100); + } + + wtap_dump(dump, &pkthdr, &buffer[0], &err); + } + + wtap_dump_close(dump, &err); + + return 0; + +} + +/* Print usage statement and exit program */ +static +void usage(void) +{ + int num_entries = array_length(examples); + int i; + + printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n"); + printf("Default max bytes (per packet) is 5000\n"); + printf("Default count is 1000.\n"); + printf("Types:\n"); + + for (i = 0; i < num_entries; i++) { + printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname); + } + + printf("\n"); + + exit(0); +} + +/* Parse command-line option "type" and return enum type */ +static +int parse_type(char *string) +{ + int num_entries = array_length(examples); + int i; + + for (i = 0; i < num_entries; i++) { + if (strcmp(examples[i].abbrev, string) == 0) { + return examples[i].produceable_type; + } + } + + /* default type */ + return PKT_ETHERNET; +} + +/* Find pkt_example record and return pointer to it */ +static +pkt_example* find_example(int type) +{ + int num_entries = array_length(examples); + int i; + + for (i = 0; i < num_entries; i++) { + if (examples[i].produceable_type == type) { + return &examples[i]; + } + } + + printf("Internal error. Type %d has no entry in examples table.\n", type); + exit(0); +} + +/* Seed the random-number generator */ +void +seed(void) +{ + unsigned int randomness; + +#if defined(linux) + /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */ + int fd; + + fd = open("/dev/random", O_RDONLY); + if (fd < 0) { + printf("Could not open /dev/random for reading: %s\n", strerror(errno)); + exit(0); + } + + read(fd, &randomness, sizeof(randomness)); +#else + time_t now; + + now = time(NULL); + randomness = (unsigned int) now; +#endif + + srand(randomness); +} |