4 * Creates random packet traces. Useful for debugging sniffers by testing
5 * assumptions about the veracity of the data found in the packet.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "wsutil/wsgetopt.h"
47 #include "wiretap/wtap.h"
48 #include "wsutil/file_util.h"
51 #include <wsutil/unicode-utils.h>
54 #define array_length(x) (sizeof x / sizeof x[0])
56 /* Types of produceable packets */
86 int sample_wtap_encap
;
87 guint8
*sample_buffer
;
89 guint8
*pseudo_buffer
;
93 /* Ethernet, indicating ARP */
95 0xff, 0xff, 0xff, 0xff,
96 0xff, 0xff, 0x00, 0x00,
97 0x32, 0x25, 0x0f, 0xff,
101 /* Ethernet+IP+UDP, indicating DNS */
103 0xff, 0xff, 0xff, 0xff,
104 0xff, 0xff, 0x01, 0x01,
105 0x01, 0x01, 0x01, 0x01,
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,
114 0x05, 0xe8, 0x00, 0x35,
115 0xff, 0xff, 0x2a, 0xb9,
119 /* Ethernet+IP, indicating ICMP */
120 guint8 pkt_icmp
[] = {
121 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0x01, 0x01,
123 0x01, 0x01, 0x01, 0x01,
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
133 /* Ethernet, indicating IP */
135 0xff, 0xff, 0xff, 0xff,
136 0xff, 0xff, 0x01, 0x01,
137 0x01, 0x01, 0x01, 0x01,
141 /* TR, indicating LLC */
143 0x10, 0x40, 0x68, 0x00,
144 0x19, 0x69, 0x95, 0x8b,
145 0x00, 0x01, 0xfa, 0x68,
149 /* Ethernet, indicating WiMAX M2M */
151 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0x00, 0x00,
153 0x32, 0x25, 0x0f, 0xff,
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,
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,
170 0x00, 0x89, 0x00, 0x89,
171 0x00, 0x00, 0x2a, 0xb9,
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,
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,
188 0x05, 0xe8, 0x02, 0x02,
189 0x00, 0x50, 0x51, 0xe1,
193 /* TR+LLC+IP, indicating TCP */
195 0x10, 0x40, 0x68, 0x00,
196 0x19, 0x69, 0x95, 0x8b,
197 0x00, 0x01, 0xfa, 0x68,
200 0xaa, 0xaa, 0x03, 0x00,
201 0x00, 0x00, 0x08, 0x00,
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
210 /* Ethernet+IP, indicating UDP */
212 0xff, 0xff, 0xff, 0xff,
213 0xff, 0xff, 0x01, 0x01,
214 0x01, 0x01, 0x01, 0x01,
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
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,
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,
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,
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,
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,
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,
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,
288 /* Ethernet+IP+TCP, indicating BGP */
290 0xff, 0xff, 0xff, 0xff,
291 0xff, 0xff, 0x01, 0x01,
292 0x01, 0x01, 0x01, 0x01,
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,
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,
310 0xff, 0xff, 0xff, 0xff,
311 0xff, 0xff, 0xff, 0xff,
312 0xff, 0xff, 0xff, 0xff,
313 0xff, 0xff, 0xff, 0xff,
316 /* Ethernet+IP+TCP, indicating TDS NetLib */
318 0x00, 0x50, 0x8b, 0x0d,
319 0x7a, 0xed, 0x00, 0x08,
320 0xa3, 0x98, 0x39, 0x81,
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,
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,
336 /* Ethernet+IP, indicating SCTP */
337 guint8 pkt_sctp
[] = {
338 0x00, 0xa0, 0x80, 0x00,
339 0x5e, 0x46, 0x08, 0x00,
340 0x03, 0x4a, 0x00, 0x35,
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,
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,
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,
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,
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
),
380 { "bgp", "Border Gateway Protocol",
381 PKT_BGP
, WTAP_ENCAP_ETHERNET
,
382 pkt_bgp
, array_length(pkt_bgp
),
385 { "bvlc", "BACnet Virtual Link Control",
386 PKT_BVLC
, WTAP_ENCAP_ETHERNET
,
387 pkt_bvlc
, array_length(pkt_bvlc
),
390 { "dns", "Domain Name Service",
391 PKT_DNS
, WTAP_ENCAP_ETHERNET
,
392 pkt_dns
, array_length(pkt_dns
),
396 PKT_ETHERNET
, WTAP_ENCAP_ETHERNET
,
400 { "fddi", "Fiber Distributed Data Interface",
401 PKT_FDDI
, WTAP_ENCAP_FDDI
,
405 { "giop", "General Inter-ORB Protocol",
406 PKT_GIOP
, WTAP_ENCAP_ETHERNET
,
407 pkt_giop
, array_length(pkt_giop
),
410 { "icmp", "Internet Control Message Protocol",
411 PKT_ICMP
, WTAP_ENCAP_ETHERNET
,
412 pkt_icmp
, array_length(pkt_icmp
),
415 { "ip", "Internet Protocol",
416 PKT_IP
, WTAP_ENCAP_ETHERNET
,
417 pkt_ip
, array_length(pkt_ip
),
420 { "llc", "Logical Link Control",
421 PKT_LLC
, WTAP_ENCAP_TOKEN_RING
,
422 pkt_llc
, array_length(pkt_llc
),
425 { "m2m", "WiMAX M2M Encapsulation Protocol",
426 PKT_M2M
, WTAP_ENCAP_ETHERNET
,
427 pkt_m2m
, array_length(pkt_m2m
),
430 { "megaco", "MEGACO",
431 PKT_MEGACO
, WTAP_ENCAP_ETHERNET
,
432 pkt_megaco
, array_length(pkt_megaco
),
435 { "nbns", "NetBIOS-over-TCP Name Service",
436 PKT_NBNS
, WTAP_ENCAP_ETHERNET
,
437 pkt_nbns
, array_length(pkt_nbns
),
440 { "ncp2222", "NetWare Core Protocol",
441 PKT_NCP2222
, WTAP_ENCAP_TOKEN_RING
,
442 pkt_ncp2222
, array_length(pkt_ncp2222
),
445 { "sctp", "Stream Control Transmission Protocol",
446 PKT_SCTP
, WTAP_ENCAP_ETHERNET
,
447 pkt_sctp
, array_length(pkt_sctp
),
450 { "syslog", "Syslog message",
451 PKT_SYSLOG
, WTAP_ENCAP_ETHERNET
,
452 pkt_syslog
, array_length(pkt_syslog
),
455 { "tds", "TDS NetLib",
456 PKT_TDS
, WTAP_ENCAP_ETHERNET
,
457 pkt_tds
, array_length(pkt_tds
),
460 { "tcp", "Transmission Control Protocol",
461 PKT_TCP
, WTAP_ENCAP_TOKEN_RING
,
462 pkt_tcp
, array_length(pkt_tcp
),
465 { "tr", "Token-Ring",
466 PKT_TR
, WTAP_ENCAP_TOKEN_RING
,
470 { "udp", "User Datagram Protocol",
471 PKT_UDP
, WTAP_ENCAP_ETHERNET
,
472 pkt_udp
, array_length(pkt_udp
),
475 { "usb", "Universal Serial Bus",
476 PKT_USB
, WTAP_ENCAP_USB
,
480 { "usb-linux", "Universal Serial Bus with Linux specific header",
481 PKT_USB_LINUX
, WTAP_ENCAP_USB_LINUX
,
489 static int parse_type(char *string
);
490 static void usage(void);
491 static void seed(void);
493 static pkt_example
* find_example(int type
);
496 main(int argc
, char **argv
)
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];
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
;
514 arg_list_utf_16to8(argc
, argv
);
515 create_app_running_mutex();
518 while ((opt
= getopt(argc
, argv
, "b:c:ht:")) != -1) {
520 case 'b': /* max bytes */
521 produce_max_bytes
= atoi(optarg
);
522 if (produce_max_bytes
> 65536) {
524 "randpkt: Max bytes is 65536\n");
529 case 'c': /* count */
530 produce_count
= atoi(optarg
);
533 case 't': /* type of packet to produce */
534 produce_type
= parse_type(optarg
);
544 /* any more command line parameters? */
546 produce_filename
= argv
[optind
];
552 example
= find_example(produce_type
);
555 dump
= wtap_dump_open(produce_filename
, WTAP_FILE_TYPE_SUBTYPE_PCAP
,
556 example
->sample_wtap_encap
, produce_max_bytes
, FALSE
/* compressed */, &err
);
559 "randpkt: Error writing to %s\n", produce_filename
);
565 /* reduce max_bytes by # of bytes already in sample */
566 if (produce_max_bytes
<= example
->sample_length
) {
568 "randpkt: Sample packet length is %d, which is greater than or equal to\n",
569 example
->sample_length
);
570 fprintf(stderr
, "your requested max_bytes value of %d\n",
575 produce_max_bytes
-= example
->sample_length
;
578 memset(&pkthdr
, 0, sizeof(pkthdr
));
579 memset(buffer
, 0, sizeof(buffer
));
581 pkthdr
.pkt_encap
= example
->sample_wtap_encap
;
583 /* Load the sample pseudoheader into our pseudoheader buffer */
584 if (example
->pseudo_buffer
)
585 memcpy(ps_header
, example
->pseudo_buffer
, example
->pseudo_length
);
587 /* Load the sample into our buffer */
588 if (example
->sample_buffer
)
589 memcpy(&buffer
[0], example
->sample_buffer
, example
->sample_length
);
591 /* Produce random packets */
592 for (i
= 0; i
< produce_count
; i
++) {
593 if (produce_max_bytes
> 0) {
594 len_random
= (rand() % produce_max_bytes
+ 1);
600 len_this_pkt
= example
->sample_length
+ len_random
;
602 pkthdr
.caplen
= len_this_pkt
;
603 pkthdr
.len
= len_this_pkt
;
604 pkthdr
.ts
.secs
= i
; /* just for variety */
606 for (j
= example
->pseudo_length
; j
< (int) sizeof(*ps_header
); j
++) {
607 ((guint8
*)ps_header
)[j
] = (rand() % 0x100);
610 for (j
= example
->sample_length
; j
< len_this_pkt
; j
++) {
611 /* Add format strings here and there */
612 if ((int) (100.0*rand()/(RAND_MAX
+1.0)) < 3 && j
< (len_random
- 3)) {
613 memcpy(&buffer
[j
], "%s", 3);
616 buffer
[j
] = (rand() % 0x100);
620 wtap_dump(dump
, &pkthdr
, &buffer
[0], &err
);
623 wtap_dump_close(dump
, &err
);
629 /* Print usage statement and exit program */
633 int num_entries
= array_length(examples
);
636 printf("Usage: randpkt [-b maxbytes] [-c count] [-t type] filename\n");
637 printf("Default max bytes (per packet) is 5000\n");
638 printf("Default count is 1000.\n");
641 for (i
= 0; i
< num_entries
; i
++) {
642 printf("\t%-16s%s\n", examples
[i
].abbrev
, examples
[i
].longname
);
650 /* Parse command-line option "type" and return enum type */
652 int parse_type(char *string
)
654 int num_entries
= array_length(examples
);
657 for (i
= 0; i
< num_entries
; i
++) {
658 if (strcmp(examples
[i
].abbrev
, string
) == 0) {
659 return examples
[i
].produceable_type
;
664 fprintf(stderr
, "randpkt: Type %s not known.\n", string
);
668 /* Find pkt_example record and return pointer to it */
670 pkt_example
* find_example(int type
)
672 int num_entries
= array_length(examples
);
675 for (i
= 0; i
< num_entries
; i
++) {
676 if (examples
[i
].produceable_type
== type
) {
682 "randpkt: Internal error. Type %d has no entry in examples table.\n",
687 /* Seed the random-number generator */
691 unsigned int randomness
;
697 #define RANDOM_DEV "/dev/urandom"
700 * Assume it's at least worth trying /dev/urandom on UN*X.
701 * If it doesn't exist, fall back on time().
703 * XXX - Use CryptGenRandom on Windows?
705 fd
= ws_open(RANDOM_DEV
, O_RDONLY
);
707 if (errno
!= ENOENT
) {
709 "randpkt: Could not open " RANDOM_DEV
" for reading: %s\n",
716 ret
= ws_read(fd
, &randomness
, sizeof randomness
);
719 "randpkt: Could not read from " RANDOM_DEV
": %s\n",
723 if ((size_t)ret
!= sizeof randomness
) {
725 "randpkt: Tried to read %lu bytes from " RANDOM_DEV
", got %ld\n",
726 (unsigned long)sizeof randomness
, (long)ret
);
736 randomness
= (unsigned int) now
;