mate runtime did not get initialized when configured after loading a capture file
[obnox/wireshark/wip.git] / randpkt.c
1 /*
2  * randpkt.c
3  * ---------
4  * Creates random packet traces. Useful for debugging sniffers by testing
5  * assumptions about the veracity of the data found in the packet.
6  *
7  * $Id$
8  *
9  * Copyright (C) 1999 by Gilbert Ramirez <gram@alumni.rice.edu>
10  *
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.
15  *
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.
20  *
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.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #ifdef NEED_GETOPT_H
31 #include "getopt.h"
32 #endif
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41
42 #include <time.h>
43 #include <errno.h>
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <glib.h>
49 #include "wiretap/wtap.h"
50
51 #define array_length(x) (sizeof x / sizeof x[0])
52
53 /* Types of produceable packets */
54 enum {
55         PKT_ARP,
56         PKT_DNS,
57         PKT_ETHERNET,
58         PKT_FDDI,
59         PKT_ICMP,
60         PKT_IP,
61         PKT_LLC,
62         PKT_NBNS,
63         PKT_SYSLOG,
64         PKT_TCP,
65         PKT_TR,
66         PKT_UDP,
67         PKT_BVLC,
68         PKT_NCP2222,
69         PKT_GIOP,
70         PKT_BGP,
71         PKT_TDS
72 };
73
74 typedef struct {
75         char    *abbrev;
76         char    *longname;
77         int     produceable_type;
78         guint8  *sample_buffer;
79         int     sample_wtap_encap;
80         int     sample_length;
81 } pkt_example;
82
83 /* Ethernet, indicating ARP */
84 guint8 pkt_arp[] = {
85         0xff, 0xff, 0xff, 0xff,
86         0xff, 0xff, 0x00, 0x00,
87         0x32, 0x25, 0x0f, 0xff,
88         0x08, 0x06
89 };
90
91 /* Ethernet+IP+UDP, indicating DNS */
92 guint8 pkt_dns[] = {
93         0xff, 0xff, 0xff, 0xff,
94         0xff, 0xff, 0x01, 0x01,
95         0x01, 0x01, 0x01, 0x01,
96         0x08, 0x00,
97
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,
103
104         0x05, 0xe8, 0x00, 0x35,
105         0x00, 0x00, 0x2a, 0xb9,
106         0x30
107 };
108
109 /* Ethernet+IP, indicating ICMP */
110 guint8 pkt_icmp[] = {
111         0xff, 0xff, 0xff, 0xff,
112         0xff, 0xff, 0x01, 0x01,
113         0x01, 0x01, 0x01, 0x01,
114         0x08, 0x00,
115
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
121 };
122
123 /* Ethernet, indicating IP */
124 guint8 pkt_ip[] = {
125         0xff, 0xff, 0xff, 0xff,
126         0xff, 0xff, 0x01, 0x01,
127         0x01, 0x01, 0x01, 0x01,
128         0x08, 0x00
129 };
130
131 /* TR, indicating LLC */
132 guint8 pkt_llc[] = {
133         0x10, 0x40, 0x68, 0x00,
134         0x19, 0x69, 0x95, 0x8b,
135         0x00, 0x01, 0xfa, 0x68,
136         0xc4, 0x67
137 };
138
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,
144         0x08, 0x00,
145
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,
151
152         0x00, 0x89, 0x00, 0x89,
153         0x00, 0x00, 0x2a, 0xb9,
154         0x30
155 };
156
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,
162         0x08, 0x00,
163
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,
169
170         0x05, 0xe8, 0x02, 0x02,
171         0x00, 0x50, 0x51, 0xe1,
172         0x3c
173 };
174
175 /* TR+LLC+IP, indicating TCP */
176 guint8 pkt_tcp[] = {
177         0x10, 0x40, 0x68, 0x00,
178         0x19, 0x69, 0x95, 0x8b,
179         0x00, 0x01, 0xfa, 0x68,
180         0xc4, 0x67,
181
182         0xaa, 0xaa, 0x03, 0x00,
183         0x00, 0x00, 0x08, 0x00,
184
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
190 };
191
192 /* Ethernet+IP, indicating UDP */
193 guint8 pkt_udp[] = {
194         0xff, 0xff, 0xff, 0xff,
195         0xff, 0xff, 0x01, 0x01,
196         0x01, 0x01, 0x01, 0x01,
197         0x08, 0x00,
198
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
204 };
205
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,
211         0x08, 0x00,
212
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,
220         0x81
221 };
222
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,
237         0x22
238 };
239
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,
245         0x08, 0x00,
246
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,
252
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,
261
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,
267         0x01
268 };
269
270 /* Ethernet+IP+TCP, indicating BGP */
271 guint8 pkt_bgp[] = {
272         0xff, 0xff, 0xff, 0xff,
273         0xff, 0xff, 0x01, 0x01,
274         0x01, 0x01, 0x01, 0x01,
275         0x08, 0x00,
276
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,
282
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,
291
292         0xff, 0xff, 0xff, 0xff,
293         0xff, 0xff, 0xff, 0xff,
294         0xff, 0xff, 0xff, 0xff,
295         0xff, 0xff, 0xff, 0xff,
296 };
297
298 /* Ethernet+IP+TCP, indicating TDS NetLib */
299 guint8 pkt_tds[] = {
300         0x00, 0x50, 0x8b, 0x0d,
301         0x7a, 0xed, 0x00, 0x08,
302         0xa3, 0x98, 0x39, 0x81,
303         0x08, 0x00,
304
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,
310
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,
316 };
317
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) },
322
323         { "dns", "Domain Name Service",
324                 PKT_DNS,        pkt_dns,        WTAP_ENCAP_ETHERNET,    array_length(pkt_dns) },
325
326         { "eth", "Ethernet",
327                 PKT_ETHERNET,   NULL,           WTAP_ENCAP_ETHERNET,    0 },
328
329         { "fddi", "Fiber Distributed Data Interface",
330                 PKT_FDDI,       NULL,           WTAP_ENCAP_FDDI,        0 },
331
332         { "icmp", "Internet Control Message Protocol",
333                 PKT_ICMP,       pkt_icmp,       WTAP_ENCAP_ETHERNET,    array_length(pkt_icmp) },
334
335         { "ip", "Internet Protocol",
336                 PKT_IP,         pkt_ip,         WTAP_ENCAP_ETHERNET,    array_length(pkt_ip) },
337
338         { "llc", "Logical Link Control",
339                 PKT_LLC,        pkt_llc,        WTAP_ENCAP_TOKEN_RING,  array_length(pkt_llc) },
340
341         { "nbns", "NetBIOS-over-TCP Name Service",
342                 PKT_NBNS,       pkt_nbns,       WTAP_ENCAP_ETHERNET,    array_length(pkt_nbns) },
343
344         { "syslog", "Syslog message",
345                 PKT_SYSLOG,     pkt_syslog,     WTAP_ENCAP_ETHERNET,    array_length(pkt_syslog) },
346
347         { "tcp", "Transmission Control Protocol",
348                 PKT_TCP,        pkt_tcp,        WTAP_ENCAP_TOKEN_RING,  array_length(pkt_tcp) },
349
350         { "tr",  "Token-Ring",
351                 PKT_TR,         NULL,           WTAP_ENCAP_TOKEN_RING,  0 },
352
353         { "udp", "User Datagram Protocol",
354                 PKT_UDP,        pkt_udp,        WTAP_ENCAP_ETHERNET,    array_length(pkt_udp) },
355
356         { "bvlc", "BACnet Virtual Link Control",
357                 PKT_BVLC,       pkt_bvlc,       WTAP_ENCAP_ETHERNET,    array_length(pkt_bvlc) },
358
359         { "ncp2222", "NetWare Core Protocol",
360                 PKT_NCP2222,    pkt_ncp2222,    WTAP_ENCAP_TOKEN_RING,  array_length(pkt_ncp2222) },
361
362         { "giop", "General Inter-ORB Protocol",
363                 PKT_GIOP,       pkt_giop,       WTAP_ENCAP_ETHERNET,    array_length(pkt_giop) },
364
365         { "bgp", "Border Gateway Protocol",
366                 PKT_BGP,        pkt_bgp,        WTAP_ENCAP_ETHERNET,    array_length(pkt_bgp) },
367
368         { "tds", "TDS NetLib",
369                 PKT_TDS,        pkt_tds,        WTAP_ENCAP_ETHERNET,    array_length(pkt_tds) },
370
371 };
372
373
374
375 static int parse_type(char *string);
376 static void usage(void);
377 static void seed(void);
378
379 static pkt_example* find_example(int type);
380
381 int
382 main(int argc, char **argv)
383 {
384
385         wtap_dumper             *dump;
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];
390
391         int                     opt;
392         extern char             *optarg;
393         extern int              optind;
394
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;
400
401         while ((opt = getopt(argc, argv, "b:c:t:")) != -1) {
402                 switch (opt) {
403                         case 'b':       /* max bytes */
404                                 produce_max_bytes = atoi(optarg);
405                                 if (produce_max_bytes > 65536) {
406                                         printf("Max bytes is 65536\n");
407                                         exit(0);
408                                 }
409                                 break;
410
411                         case 'c':       /* count */
412                                 produce_count = atoi(optarg);
413                                 break;
414
415                         case 't':       /* type of packet to produce */
416                                 produce_type = parse_type(optarg);
417                                 break;
418
419                         default:
420                                 usage();
421                                 break;
422                 }
423         }
424
425         /* any more command line parameters? */
426         if (argc > optind) {
427                 produce_filename = argv[optind];
428         }
429         else {
430                 usage();
431         }
432
433         example = find_example(produce_type);
434
435         pkthdr.ts.tv_sec = 0;
436         pkthdr.ts.tv_usec = 0;
437         pkthdr.pkt_encap = example->sample_wtap_encap;
438
439         dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
440                 example->sample_wtap_encap, produce_max_bytes, &err);
441
442         seed();
443
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);
448                 exit(0);
449         }
450         else {
451                 produce_max_bytes -= example->sample_length;
452         }
453
454         /* Load the sample into our buffer */
455         if (example->sample_buffer)
456                 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
457
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);
462                 }
463                 else {
464                         len_random = 0;
465                 }
466
467                 len_this_pkt = example->sample_length + len_random;
468
469                 pkthdr.caplen = len_this_pkt;
470                 pkthdr.len = len_this_pkt;
471                 pkthdr.ts.tv_sec = i; /* just for variety */
472
473                 for (j = example->sample_length; j < len_random; j++) {
474                         buffer[j] = (rand() % 0x100);
475                 }
476
477                 wtap_dump(dump, &pkthdr, &ps_header, &buffer[0], &err);
478         }
479
480         wtap_dump_close(dump, &err);
481
482         return 0;
483
484 }
485
486 /* Print usage statement and exit program */
487 static
488 void usage(void)
489 {
490         int     num_entries = array_length(examples);
491         int     i;
492
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");
496         printf("Types:\n");
497
498         for (i = 0; i < num_entries; i++) {
499                 printf("\t%s\t%s\n", examples[i].abbrev, examples[i].longname);
500         }
501
502         printf("\n");
503
504         exit(0);
505 }
506
507 /* Parse command-line option "type" and return enum type */
508 static
509 int parse_type(char *string)
510 {
511         int     num_entries = array_length(examples);
512         int     i;
513
514         for (i = 0; i < num_entries; i++) {
515                 if (strcmp(examples[i].abbrev, string) == 0) {
516                         return examples[i].produceable_type;
517                 }
518         }
519
520         /* Complain */
521         printf("Type %s not known.\n", string);
522         exit(1);
523 }
524
525 /* Find pkt_example record and return pointer to it */
526 static
527 pkt_example* find_example(int type)
528 {
529         int     num_entries = array_length(examples);
530         int     i;
531
532         for (i = 0; i < num_entries; i++) {
533                 if (examples[i].produceable_type == type) {
534                         return &examples[i];
535                 }
536         }
537
538         printf("Internal error. Type %d has no entry in examples table.\n", type);
539         exit(1);
540 }
541
542 /* Seed the random-number generator */
543 void
544 seed(void)
545 {
546         unsigned int    randomness;
547
548 #if defined(linux)
549         /* Okay, I should use #ifdef HAVE_DEV_RANDOM, but this is a quick hack */
550         int             fd;
551
552         fd = open("/dev/random", O_RDONLY);
553         if (fd < 0) {
554                 printf("Could not open /dev/random for reading: %s\n", strerror(errno));
555                 exit(0);
556         }
557
558         read(fd, &randomness, sizeof(randomness));
559 #else
560         time_t now;
561
562         now = time(NULL);
563         randomness = (unsigned int) now;
564 #endif
565
566         srand(randomness);
567 }