give names to sec_vt_command's
[metze/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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include "config.h"
27
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #ifndef HAVE_GETOPT
33 #include "wsutil/wsgetopt.h"
34 #endif
35
36 #ifdef HAVE_FCNTL_H
37 #include <fcntl.h>
38 #endif
39
40 #include <time.h>
41 #include <errno.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <glib.h>
47 #include "wiretap/wtap.h"
48 #include "wsutil/file_util.h"
49
50 #ifdef _WIN32
51 #include <wsutil/unicode-utils.h>
52 #endif /* _WIN32 */
53
54 #define array_length(x) (sizeof x / sizeof x[0])
55
56 /* Types of produceable packets */
57 enum {
58         PKT_ARP,
59         PKT_BGP,
60         PKT_BVLC,
61         PKT_DNS,
62         PKT_ETHERNET,
63         PKT_FDDI,
64         PKT_GIOP,
65         PKT_ICMP,
66         PKT_IP,
67         PKT_LLC,
68         PKT_M2M,
69         PKT_MEGACO,
70         PKT_NBNS,
71         PKT_NCP2222,
72         PKT_SCTP,
73         PKT_SYSLOG,
74         PKT_TCP,
75         PKT_TDS,
76         PKT_TR,
77         PKT_UDP,
78         PKT_USB,
79         PKT_USB_LINUX
80 };
81
82 typedef struct {
83         const char      *abbrev;
84         const char      *longname;
85         int             produceable_type;
86         int             sample_wtap_encap;
87         guint8          *sample_buffer;
88         int             sample_length;
89         guint8          *pseudo_buffer;
90         int             pseudo_length;
91 } pkt_example;
92
93 /* Ethernet, indicating ARP */
94 guint8 pkt_arp[] = {
95         0xff, 0xff, 0xff, 0xff,
96         0xff, 0xff, 0x00, 0x00,
97         0x32, 0x25, 0x0f, 0xff,
98         0x08, 0x06
99 };
100
101 /* Ethernet+IP+UDP, indicating DNS */
102 guint8 pkt_dns[] = {
103         0xff, 0xff, 0xff, 0xff,
104         0xff, 0xff, 0x01, 0x01,
105         0x01, 0x01, 0x01, 0x01,
106         0x08, 0x00,
107
108         0x45, 0x00, 0x00, 0x3c,
109         0xc5, 0x9e, 0x40, 0x00,
110         0xff, 0x11, 0xd7, 0xe0,
111         0xd0, 0x15, 0x02, 0xb8,
112         0x0a, 0x01, 0x01, 0x63,
113
114         0x05, 0xe8, 0x00, 0x35,
115         0xff, 0xff, 0x2a, 0xb9,
116         0x30
117 };
118
119 /* Ethernet+IP, indicating ICMP */
120 guint8 pkt_icmp[] = {
121         0xff, 0xff, 0xff, 0xff,
122         0xff, 0xff, 0x01, 0x01,
123         0x01, 0x01, 0x01, 0x01,
124         0x08, 0x00,
125
126         0x45, 0x00, 0x00, 0x54,
127         0x8f, 0xb3, 0x40, 0x00,
128         0xfd, 0x01, 0x8a, 0x99,
129         0xcc, 0xfc, 0x66, 0x0b,
130         0xce, 0x41, 0x62, 0x12
131 };
132
133 /* Ethernet, indicating IP */
134 guint8 pkt_ip[] = {
135         0xff, 0xff, 0xff, 0xff,
136         0xff, 0xff, 0x01, 0x01,
137         0x01, 0x01, 0x01, 0x01,
138         0x08, 0x00
139 };
140
141 /* TR, indicating LLC */
142 guint8 pkt_llc[] = {
143         0x10, 0x40, 0x68, 0x00,
144         0x19, 0x69, 0x95, 0x8b,
145         0x00, 0x01, 0xfa, 0x68,
146         0xc4, 0x67
147 };
148
149 /* Ethernet, indicating WiMAX M2M */
150 guint8 pkt_m2m[] = {
151         0xff, 0xff, 0xff, 0xff,
152         0xff, 0xff, 0x00, 0x00,
153         0x32, 0x25, 0x0f, 0xff,
154         0x08, 0xf0
155 };
156
157 /* Ethernet+IP+UDP, indicating NBNS */
158 guint8 pkt_nbns[] = {
159         0xff, 0xff, 0xff, 0xff,
160         0xff, 0xff, 0x01, 0x01,
161         0x01, 0x01, 0x01, 0x01,
162         0x08, 0x00,
163
164         0x45, 0x00, 0x00, 0x3c,
165         0xc5, 0x9e, 0x40, 0x00,
166         0xff, 0x11, 0xd7, 0xe0,
167         0xd0, 0x15, 0x02, 0xb8,
168         0x0a, 0x01, 0x01, 0x63,
169
170         0x00, 0x89, 0x00, 0x89,
171         0x00, 0x00, 0x2a, 0xb9,
172         0x30
173 };
174
175 /* Ethernet+IP+UDP, indicating syslog */
176 guint8 pkt_syslog[] = {
177         0xff, 0xff, 0xff, 0xff,
178         0xff, 0xff, 0x01, 0x01,
179         0x01, 0x01, 0x01, 0x01,
180         0x08, 0x00,
181
182         0x45, 0x00, 0x00, 0x64,
183         0x20, 0x48, 0x00, 0x00,
184         0xfc, 0x11, 0xf8, 0x03,
185         0xd0, 0x15, 0x02, 0xb8,
186         0x0a, 0x01, 0x01, 0x63,
187
188         0x05, 0xe8, 0x02, 0x02,
189         0x00, 0x50, 0x51, 0xe1,
190         0x3c
191 };
192
193 /* TR+LLC+IP, indicating TCP */
194 guint8 pkt_tcp[] = {
195         0x10, 0x40, 0x68, 0x00,
196         0x19, 0x69, 0x95, 0x8b,
197         0x00, 0x01, 0xfa, 0x68,
198         0xc4, 0x67,
199
200         0xaa, 0xaa, 0x03, 0x00,
201         0x00, 0x00, 0x08, 0x00,
202
203         0x45, 0x00, 0x00, 0x28,
204         0x0b, 0x0b, 0x40, 0x00,
205         0x20, 0x06, 0x85, 0x37,
206         0xc0, 0xa8, 0x27, 0x01,
207         0xc0, 0xa8, 0x22, 0x3c
208 };
209
210 /* Ethernet+IP, indicating UDP */
211 guint8 pkt_udp[] = {
212         0xff, 0xff, 0xff, 0xff,
213         0xff, 0xff, 0x01, 0x01,
214         0x01, 0x01, 0x01, 0x01,
215         0x08, 0x00,
216
217         0x45, 0x00, 0x00, 0x3c,
218         0xc5, 0x9e, 0x40, 0x00,
219         0xff, 0x11, 0xd7, 0xe0,
220         0xd0, 0x15, 0x02, 0xb8,
221         0x0a, 0x01, 0x01, 0x63
222 };
223
224 /* Ethernet+IP+UDP, indicating BVLC */
225 guint8 pkt_bvlc[] = {
226         0xff, 0xff, 0xff, 0xff,
227         0xff, 0xff, 0x01, 0x01,
228         0x01, 0x01, 0x01, 0x01,
229         0x08, 0x00,
230
231         0x45, 0x00, 0x00, 0x3c,
232         0xc5, 0x9e, 0x40, 0x00,
233         0xff, 0x11, 0x01, 0xaa,
234         0xc1, 0xff, 0x19, 0x1e,
235         0xc1, 0xff, 0x19, 0xff,
236         0xba, 0xc0, 0xba, 0xc0,
237         0x00, 0xff, 0x2d, 0x5e,
238         0x81
239 };
240
241 /* TR+LLC+IPX, indicating NCP, with NCP Type == 0x2222 */
242 guint8 pkt_ncp2222[] = {
243         0x10, 0x40, 0x00, 0x00,
244         0xf6, 0x7c, 0x9b, 0x70,
245         0x68, 0x00, 0x19, 0x69,
246         0x95, 0x8b, 0xe0, 0xe0,
247         0x03, 0xff, 0xff, 0x00,
248         0x25, 0x02, 0x11, 0x00,
249         0x00, 0x74, 0x14, 0x00,
250         0x00, 0x00, 0x00, 0x00,
251         0x01, 0x04, 0x51, 0x00,
252         0x00, 0x00, 0x04, 0x00,
253         0x02, 0x16, 0x19, 0x7a,
254         0x84, 0x40, 0x01, 0x22,
255         0x22
256 };
257
258 /* Ethernet+IP+TCP, indicating GIOP */
259 guint8 pkt_giop[] = {
260         0xff, 0xff, 0xff, 0xff,
261         0xff, 0xff, 0x01, 0x01,
262         0x01, 0x01, 0x01, 0x01,
263         0x08, 0x00,
264
265         0x45, 0x00, 0x00, 0xa6,
266         0x00, 0x2f, 0x40, 0x00,
267         0x40, 0x06, 0x3c, 0x21,
268         0x7f, 0x00, 0x00, 0x01,
269         0x7f, 0x00, 0x00, 0x01,
270
271         0x30, 0x39, 0x04, 0x05,
272         0xac, 0x02, 0x1e, 0x69,
273         0xab, 0x74, 0xab, 0x64,
274         0x80, 0x18, 0x79, 0x60,
275         0xc4, 0xb8, 0x00, 0x00,
276         0x01, 0x01, 0x08, 0x0a,
277         0x00, 0x00, 0x48, 0xf5,
278         0x00, 0x00, 0x48, 0xf5,
279
280         0x47, 0x49, 0x4f, 0x50,
281         0x01, 0x00, 0x00, 0x00,
282         0x00, 0x00, 0x00, 0x30,
283         0x00, 0x00, 0x00, 0x00,
284         0x00, 0x00, 0x00, 0x01,
285         0x01
286 };
287
288 /* Ethernet+IP+TCP, indicating BGP */
289 guint8 pkt_bgp[] = {
290         0xff, 0xff, 0xff, 0xff,
291         0xff, 0xff, 0x01, 0x01,
292         0x01, 0x01, 0x01, 0x01,
293         0x08, 0x00,
294
295         0x45, 0x00, 0x00, 0xa6,
296         0x00, 0x2f, 0x40, 0x00,
297         0x40, 0x06, 0x3c, 0x21,
298         0x7f, 0x00, 0x00, 0x01,
299         0x7f, 0x00, 0x00, 0x01,
300
301         0x30, 0x39, 0x00, 0xb3,
302         0xac, 0x02, 0x1e, 0x69,
303         0xab, 0x74, 0xab, 0x64,
304         0x80, 0x18, 0x79, 0x60,
305         0xc4, 0xb8, 0x00, 0x00,
306         0x01, 0x01, 0x08, 0x0a,
307         0x00, 0x00, 0x48, 0xf5,
308         0x00, 0x00, 0x48, 0xf5,
309
310         0xff, 0xff, 0xff, 0xff,
311         0xff, 0xff, 0xff, 0xff,
312         0xff, 0xff, 0xff, 0xff,
313         0xff, 0xff, 0xff, 0xff,
314 };
315
316 /* Ethernet+IP+TCP, indicating TDS NetLib */
317 guint8 pkt_tds[] = {
318         0x00, 0x50, 0x8b, 0x0d,
319         0x7a, 0xed, 0x00, 0x08,
320         0xa3, 0x98, 0x39, 0x81,
321         0x08, 0x00,
322
323         0x45, 0x00, 0x03, 0x8d,
324         0x90, 0xd4, 0x40, 0x00,
325         0x7c, 0x06, 0xc3, 0x1b,
326         0xac, 0x14, 0x02, 0x22,
327         0x0a, 0xc2, 0xee, 0x82,
328
329         0x05, 0x99, 0x08, 0xf8,
330         0xff, 0x4e, 0x85, 0x46,
331         0xa2, 0xb4, 0x42, 0xaa,
332         0x50, 0x18, 0x3c, 0x28,
333         0x0f, 0xda, 0x00, 0x00,
334 };
335
336 /* Ethernet+IP, indicating SCTP */
337 guint8 pkt_sctp[] = {
338         0x00, 0xa0, 0x80, 0x00,
339         0x5e, 0x46, 0x08, 0x00,
340         0x03, 0x4a, 0x00, 0x35,
341         0x08, 0x00,
342
343         0x45, 0x00, 0x00, 0x7c,
344         0x14, 0x1c, 0x00, 0x00,
345         0x3b, 0x84, 0x4a, 0x54,
346         0x0a, 0x1c, 0x06, 0x2b,
347         0x0a, 0x1c, 0x06, 0x2c,
348 };
349
350
351 /* Ethernet+IP+SCTP, indicating MEGACO */
352 guint8 pkt_megaco[] = {
353         0x00, 0xa0, 0x80, 0x00,
354         0x5e, 0x46, 0x08, 0x00,
355         0x03, 0x4a, 0x00, 0x35,
356         0x08, 0x00,
357
358         0x45, 0x00, 0x00, 0x7c,
359         0x14, 0x1c, 0x00, 0x00,
360         0x3b, 0x84, 0x4a, 0x54,
361         0x0a, 0x1c, 0x06, 0x2b,
362         0x0a, 0x1c, 0x06, 0x2c,
363
364         0x40, 0x00, 0x0b, 0x80,
365         0x00, 0x01, 0x6f, 0x0a,
366         0x6d, 0xb0, 0x18, 0x82,
367         0x00, 0x03, 0x00, 0x5b,
368         0x28, 0x02, 0x43, 0x45,
369         0x00, 0x00, 0xa0, 0xbd,
370         0x00, 0x00, 0x00, 0x07,
371 };
372
373 /* This little data table drives the whole program */
374 pkt_example examples[] = {
375         { "arp", "Address Resolution Protocol",
376                 PKT_ARP,        WTAP_ENCAP_ETHERNET,
377                 pkt_arp,        array_length(pkt_arp),
378                 NULL,           0 },
379
380         { "bgp", "Border Gateway Protocol",
381                 PKT_BGP,        WTAP_ENCAP_ETHERNET,
382                 pkt_bgp,        array_length(pkt_bgp),
383                 NULL,           0 },
384
385         { "bvlc", "BACnet Virtual Link Control",
386                 PKT_BVLC,       WTAP_ENCAP_ETHERNET,
387                 pkt_bvlc,       array_length(pkt_bvlc),
388                 NULL,           0 },
389
390         { "dns", "Domain Name Service",
391                 PKT_DNS,        WTAP_ENCAP_ETHERNET,
392                 pkt_dns,        array_length(pkt_dns),
393                 NULL,           0 },
394
395         { "eth", "Ethernet",
396                 PKT_ETHERNET,   WTAP_ENCAP_ETHERNET,
397                 NULL,           0,
398                 NULL,           0 },
399
400         { "fddi", "Fiber Distributed Data Interface",
401                 PKT_FDDI,       WTAP_ENCAP_FDDI,
402                 NULL,           0,
403                 NULL,           0 },
404
405         { "giop", "General Inter-ORB Protocol",
406                 PKT_GIOP,       WTAP_ENCAP_ETHERNET,
407                 pkt_giop,       array_length(pkt_giop),
408                 NULL,           0 },
409
410         { "icmp", "Internet Control Message Protocol",
411                 PKT_ICMP,       WTAP_ENCAP_ETHERNET,
412                 pkt_icmp,       array_length(pkt_icmp),
413                 NULL,           0 },
414
415         { "ip", "Internet Protocol",
416                 PKT_IP,         WTAP_ENCAP_ETHERNET,
417                 pkt_ip,         array_length(pkt_ip),
418                 NULL,           0 },
419
420         { "llc", "Logical Link Control",
421                 PKT_LLC,        WTAP_ENCAP_TOKEN_RING,
422                 pkt_llc,        array_length(pkt_llc),
423                 NULL,           0 },
424
425         { "m2m", "WiMAX M2M Encapsulation Protocol",
426                 PKT_M2M,        WTAP_ENCAP_ETHERNET,
427                 pkt_m2m,        array_length(pkt_m2m),
428                 NULL,           0 },
429
430         { "megaco", "MEGACO",
431                 PKT_MEGACO,     WTAP_ENCAP_ETHERNET,
432                 pkt_megaco,     array_length(pkt_megaco),
433                 NULL,           0 },
434
435         { "nbns", "NetBIOS-over-TCP Name Service",
436                 PKT_NBNS,       WTAP_ENCAP_ETHERNET,
437                 pkt_nbns,       array_length(pkt_nbns),
438                 NULL,           0 },
439
440         { "ncp2222", "NetWare Core Protocol",
441                 PKT_NCP2222,    WTAP_ENCAP_TOKEN_RING,
442                 pkt_ncp2222,    array_length(pkt_ncp2222),
443                 NULL,           0 },
444
445         { "sctp", "Stream Control Transmission Protocol",
446                 PKT_SCTP,       WTAP_ENCAP_ETHERNET,
447                 pkt_sctp,       array_length(pkt_sctp),
448                 NULL,           0 },
449
450         { "syslog", "Syslog message",
451                 PKT_SYSLOG,     WTAP_ENCAP_ETHERNET,
452                 pkt_syslog,     array_length(pkt_syslog),
453                 NULL,           0 },
454
455         { "tds", "TDS NetLib",
456                 PKT_TDS,        WTAP_ENCAP_ETHERNET,
457                 pkt_tds,        array_length(pkt_tds),
458                 NULL,           0 },
459
460         { "tcp", "Transmission Control Protocol",
461                 PKT_TCP,        WTAP_ENCAP_TOKEN_RING,
462                 pkt_tcp,        array_length(pkt_tcp),
463                 NULL,           0 },
464
465         { "tr",  "Token-Ring",
466                 PKT_TR,         WTAP_ENCAP_TOKEN_RING,
467                 NULL,           0,
468                 NULL,           0 },
469
470         { "udp", "User Datagram Protocol",
471                 PKT_UDP,        WTAP_ENCAP_ETHERNET,
472                 pkt_udp,        array_length(pkt_udp),
473                 NULL,           0 },
474
475         { "usb", "Universal Serial Bus",
476                 PKT_USB,        WTAP_ENCAP_USB,
477                 NULL,           0,
478                 NULL,           0 },
479
480         { "usb-linux", "Universal Serial Bus with Linux specific header",
481                 PKT_USB_LINUX,  WTAP_ENCAP_USB_LINUX,
482                 NULL,           0,
483                 NULL,           0 },
484
485 };
486
487
488
489 static int parse_type(char *string);
490 static void usage(gboolean is_error);
491 static void seed(void);
492
493 static pkt_example* find_example(int type);
494
495 int
496 main(int argc, char **argv)
497 {
498
499         wtap_dumper             *dump;
500         struct wtap_pkthdr      pkthdr;
501         union wtap_pseudo_header *ps_header = &pkthdr.pseudo_header;
502         int                     i, j, len_this_pkt, len_random, err;
503         guint8                  buffer[65536];
504
505         int                     opt;
506
507         int                     produce_count = 1000; /* number of pkts to produce */
508         int                     produce_type = PKT_ETHERNET;
509         char                    *produce_filename = NULL;
510         int                     produce_max_bytes = 5000;
511         pkt_example             *example;
512
513 #ifdef _WIN32
514         arg_list_utf_16to8(argc, argv);
515         create_app_running_mutex();
516 #endif /* _WIN32 */
517
518         while ((opt = getopt(argc, argv, "b:c:ht:")) != -1) {
519                 switch (opt) {
520                         case 'b':       /* max bytes */
521                                 produce_max_bytes = atoi(optarg);
522                                 if (produce_max_bytes > 65536) {
523                                         fprintf(stderr,
524                                             "randpkt: Max bytes is 65536\n");
525                                         exit(1);
526                                 }
527                                 break;
528
529                         case 'c':       /* count */
530                                 produce_count = atoi(optarg);
531                                 break;
532
533                         case 't':       /* type of packet to produce */
534                                 produce_type = parse_type(optarg);
535                                 break;
536
537                         case 'h':
538                                 usage(FALSE);
539                                 break;
540                         default:
541                                 usage(TRUE);
542                                 break;
543                 }
544         }
545
546         /* any more command line parameters? */
547         if (argc > optind) {
548                 produce_filename = argv[optind];
549         }
550         else {
551                 usage(TRUE);
552         }
553
554         example = find_example(produce_type);
555
556
557         dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
558                 example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
559         if (!dump) {
560                 fprintf(stderr,
561                     "randpkt: Error writing to %s\n", produce_filename);
562                 exit(2);
563         }
564
565         seed();
566
567         /* reduce max_bytes by # of bytes already in sample */
568         if (produce_max_bytes <= example->sample_length) {
569                 fprintf(stderr,
570                     "randpkt: Sample packet length is %d, which is greater than or equal to\n",
571                     example->sample_length);
572                 fprintf(stderr, "your requested max_bytes value of %d\n",
573                     produce_max_bytes);
574                 exit(1);
575         }
576         else {
577                 produce_max_bytes -= example->sample_length;
578         }
579
580         memset(&pkthdr, 0, sizeof(pkthdr));
581         memset(buffer, 0, sizeof(buffer));
582
583         pkthdr.pkt_encap = example->sample_wtap_encap;
584
585         /* Load the sample pseudoheader into our pseudoheader buffer */
586         if (example->pseudo_buffer)
587                 memcpy(ps_header, example->pseudo_buffer, example->pseudo_length);
588
589         /* Load the sample into our buffer */
590         if (example->sample_buffer)
591                 memcpy(&buffer[0], example->sample_buffer, example->sample_length);
592
593         /* Produce random packets */
594         for (i = 0; i < produce_count; i++) {
595                 if (produce_max_bytes > 0) {
596                         len_random = (rand() % produce_max_bytes + 1);
597                 }
598                 else {
599                         len_random = 0;
600                 }
601
602                 len_this_pkt = example->sample_length + len_random;
603
604                 pkthdr.caplen = len_this_pkt;
605                 pkthdr.len = len_this_pkt;
606                 pkthdr.ts.secs = i; /* just for variety */
607
608                 for (j = example->pseudo_length; j < (int) sizeof(*ps_header); j++) {
609                         ((guint8*)ps_header)[j] = (rand() % 0x100);
610                 }
611
612                 for (j = example->sample_length; j < len_this_pkt; j++) {
613                         /* Add format strings here and there */
614                         if ((int) (100.0*rand()/(RAND_MAX+1.0)) < 3 && j < (len_random - 3)) {
615                                 memcpy(&buffer[j], "%s", 3);
616                                 j += 2;
617                         } else {
618                                 buffer[j] = (rand() % 0x100);
619                         }
620                 }
621
622                 wtap_dump(dump, &pkthdr, &buffer[0], &err);
623         }
624
625         wtap_dump_close(dump, &err);
626
627         return 0;
628
629 }
630
631 /* Print usage statement and exit program */
632 static void
633 usage(gboolean is_error)
634 {
635         FILE    *output;
636         int      num_entries = array_length(examples);
637         int      i;
638
639         if (!is_error) {
640                 output = stdout;
641         }
642         else {
643                 output = stderr;
644         }
645
646         fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
647         fprintf(output, "Default max bytes (per packet) is 5000\n");
648         fprintf(output, "Default count is 1000.\n");
649         fprintf(output, "Types:\n");
650
651         for (i = 0; i < num_entries; i++) {
652                 fprintf(output, "\t%-16s%s\n", examples[i].abbrev, examples[i].longname);
653         }
654
655         fprintf(output, "\n");
656
657         exit(is_error ? 1 : 0);
658 }
659
660 /* Parse command-line option "type" and return enum type */
661 static
662 int parse_type(char *string)
663 {
664         int     num_entries = array_length(examples);
665         int     i;
666
667         for (i = 0; i < num_entries; i++) {
668                 if (strcmp(examples[i].abbrev, string) == 0) {
669                         return examples[i].produceable_type;
670                 }
671         }
672
673         /* Complain */
674         fprintf(stderr, "randpkt: Type %s not known.\n", string);
675         exit(1);
676 }
677
678 /* Find pkt_example record and return pointer to it */
679 static
680 pkt_example* find_example(int type)
681 {
682         int     num_entries = array_length(examples);
683         int     i;
684
685         for (i = 0; i < num_entries; i++) {
686                 if (examples[i].produceable_type == type) {
687                         return &examples[i];
688                 }
689         }
690
691         fprintf(stderr,
692             "randpkt: Internal error. Type %d has no entry in examples table.\n",
693             type);
694         exit(1);
695 }
696
697 /* Seed the random-number generator */
698 void
699 seed(void)
700 {
701         unsigned int    randomness;
702         time_t          now;
703 #ifndef _WIN32
704         int             fd;
705         ssize_t         ret;
706
707 #define RANDOM_DEV "/dev/urandom"
708
709         /*
710          * Assume it's at least worth trying /dev/urandom on UN*X.
711          * If it doesn't exist, fall back on time().
712          *
713          * XXX - Use CryptGenRandom on Windows?
714          */
715         fd = ws_open(RANDOM_DEV, O_RDONLY);
716         if (fd == -1) {
717                 if (errno != ENOENT) {
718                         fprintf(stderr,
719                             "randpkt: Could not open " RANDOM_DEV " for reading: %s\n",
720                             g_strerror(errno));
721                         exit(2);
722                 }
723                 goto fallback;
724         }
725
726         ret = ws_read(fd, &randomness, sizeof randomness);
727         if (ret == -1) {
728                 fprintf(stderr,
729                     "randpkt: Could not read from " RANDOM_DEV ": %s\n",
730                     g_strerror(errno));
731                 exit(2);
732         }
733         if ((size_t)ret != sizeof randomness) {
734                 fprintf(stderr,
735                     "randpkt: Tried to read %lu bytes from " RANDOM_DEV ", got %ld\n",
736                     (unsigned long)sizeof randomness, (long)ret);
737                 exit(2);
738         }
739         srand(randomness);
740         ws_close(fd);
741         return;
742
743 fallback:
744 #endif
745         now = time(NULL);
746         randomness = (unsigned int) now;
747
748         srand(randomness);
749 }
750
751 /*
752  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
753  *
754  * Local variables:
755  * c-basic-offset: 8
756  * tab-width: 8
757  * indent-tabs-mode: t
758  * End:
759  *
760  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
761  * :indentSize=8:tabSize=8:noTabs=false:
762  */