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