randpkt: Support different capture formats, default to pcapng

Related to #18009 - Have randpkt default to pcapng, allow selecting
a different capture file format via the common -F option that other
command line tools use, and document it.

For the randpktdump extcap, just use pcapng.

This fixes --all-random, because --all-random requires different
encapsulation per packet. It also fixes the related -r option to
randpkt (though note that picking a file format that doesn't support
ENCAP_PER_PACKET with -r causes problems.)

Document -r in the randpkt man page.

Fix #18944
This commit is contained in:
John Thacker 2023-06-03 07:56:57 -04:00
parent f4723eeb7e
commit 1cdebcd80c
5 changed files with 75 additions and 14 deletions

View File

@ -15,13 +15,14 @@ randpkt - Random packet generator
*randpkt*
[ *-b* <maxbytes> ]
[ *-c* <count> ]
[ *-F* <file format> ]
[ *-r* ]
[ *-t* <type> ]
<filename>
== DESCRIPTION
*randpkt* is a small utility that creates a *pcap* trace file
full of random packets.
*randpkt* is a small utility that creates a trace file full of random packets.
By creating many randomized packets of a certain type, you can
test packet sniffers to see how well they handle malformed packets.
@ -60,6 +61,25 @@ Default 1000.
Defines the number of packets to generate.
--
-F <file format>::
+
--
Default *pcapng*.
Sets the file format of the output capture file. *randpkt* can write
the file in several formats; *randpkt -F* provides a list of the
available output formats. Note that not all output formats support
all packet types.
--
-r::
+
--
The packet type is determined randomly for each packet. This requires
an output format that can support different encapsulations per packet,
like *pcapng*.
--
-t <type>::
+
--
@ -102,11 +122,11 @@ To see a description of the randpkt options use:
To generate a capture file with 1000 DNS packets use:
randpkt -b 500 -t dns rand_dns.pcap
randpkt -b 500 -t dns rand_dns.pcapng
To generate a small capture file with just a single LLC frame use:
randpkt -b 100 -c 1 -t llc single_llc.pcap
randpkt -b 100 -c 1 -t llc single_llc.pcapng
== SEE ALSO

View File

@ -144,6 +144,7 @@ int main(int argc, char *argv[])
int all_random = FALSE;
char* type = NULL;
int produce_type = -1;
int file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
randpkt_example *example;
wtap_dumper* savedump;
int ret = EXIT_FAILURE;
@ -306,6 +307,10 @@ int main(int argc, char *argv[])
wtap_init(FALSE);
if (file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
file_type_subtype = wtap_pcapng_file_type_subtype();
}
if (!all_random) {
produce_type = randpkt_parse_type(type);
@ -315,7 +320,7 @@ int main(int argc, char *argv[])
ws_debug("Generating packets: %s", example->abbrev);
randpkt_example_init(example, extcap_conf->fifo, maxbytes);
randpkt_example_init(example, extcap_conf->fifo, maxbytes, file_type_subtype);
randpkt_loop(example, count, packet_delay_ms);
randpkt_example_close(example);
} else {
@ -323,7 +328,7 @@ int main(int argc, char *argv[])
example = randpkt_find_example(produce_type);
if (!example)
goto end;
randpkt_example_init(example, extcap_conf->fifo, maxbytes);
randpkt_example_init(example, extcap_conf->fifo, maxbytes, file_type_subtype);
while (count-- > 0) {
randpkt_loop(example, 1, packet_delay_ms);

View File

@ -41,6 +41,20 @@
#define INVALID_TYPE 2
#define CLOSE_ERROR 2
static void
list_capture_types(void) {
GArray *writable_type_subtypes;
cmdarg_err("The available capture file types for the \"-F\" flag are:\n");
writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
for (guint i = 0; i < writable_type_subtypes->len; i++) {
int ft = g_array_index(writable_type_subtypes, int, i);
fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
wtap_file_type_subtype_description(ft));
}
g_array_free(writable_type_subtypes, TRUE);
}
/*
* Report an error in command-line arguments.
*/
@ -78,9 +92,10 @@ usage(gboolean is_error)
output = stderr;
}
fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] [-r] filename\n");
fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] [-r] [-F output file type] filename\n");
fprintf(output, "Default max bytes (per packet) is 5000\n");
fprintf(output, "Default count is 1000.\n");
fprintf(output, "Default output file type is pcapng.\n");
fprintf(output, "-r: random packet type selection\n");
fprintf(output, "\n");
fprintf(output, "Types:\n");
@ -119,6 +134,7 @@ main(int argc, char *argv[])
char *produce_filename = NULL;
int produce_max_bytes = 5000;
int produce_count = 1000;
int file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
randpkt_example *example;
guint8* type = NULL;
int allrandom = FALSE;
@ -164,7 +180,7 @@ main(int argc, char *argv[])
create_app_running_mutex();
#endif /* _WIN32 */
while ((opt = ws_getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) {
while ((opt = ws_getopt_long(argc, argv, "b:c:F:ht:r", long_options, NULL)) != -1) {
switch (opt) {
case 'b': /* max bytes */
produce_max_bytes = get_positive_int(ws_optarg, "max bytes");
@ -179,6 +195,15 @@ main(int argc, char *argv[])
produce_count = get_positive_int(ws_optarg, "count");
break;
case 'F':
file_type_subtype = wtap_name_to_file_type_subtype(ws_optarg);
if (file_type_subtype < 0) {
cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
list_capture_types();
return WS_EXIT_INVALID_OPTION;
}
break;
case 't': /* type of packet to produce */
type = g_strdup(ws_optarg);
break;
@ -192,6 +217,15 @@ main(int argc, char *argv[])
allrandom = TRUE;
break;
case '?':
switch(ws_optopt) {
case 'F':
list_capture_types();
return WS_EXIT_INVALID_OPTION;
break;
}
/* FALLTHROUGH */
default:
usage(TRUE);
ret = WS_EXIT_INVALID_OPTION;
@ -209,6 +243,10 @@ main(int argc, char *argv[])
goto clean_exit;
}
if (file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
file_type_subtype = wtap_pcapng_file_type_subtype();
}
if (!allrandom) {
produce_type = randpkt_parse_type(type);
g_free(type);
@ -219,7 +257,7 @@ main(int argc, char *argv[])
goto clean_exit;
}
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
ret = randpkt_example_init(example, produce_filename, produce_max_bytes, file_type_subtype);
if (ret != EXIT_SUCCESS)
goto clean_exit;
randpkt_loop(example, produce_count, 0);
@ -236,7 +274,7 @@ main(int argc, char *argv[])
ret = WS_EXIT_INVALID_OPTION;
goto clean_exit;
}
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
ret = randpkt_example_init(example, produce_filename, produce_max_bytes, file_type_subtype);
if (ret != EXIT_SUCCESS)
goto clean_exit;

View File

@ -659,11 +659,10 @@ gboolean randpkt_example_close(randpkt_example* example)
return ok;
}
int randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes)
int randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes, int file_type_subtype)
{
int err;
gchar *err_info;
int file_type_subtype;
if (pkt_rand == NULL) {
pkt_rand = g_rand_new();
@ -673,7 +672,6 @@ int randpkt_example_init(randpkt_example* example, char* produce_filename, int p
.encap = example->sample_wtap_encap,
.snaplen = produce_max_bytes,
};
file_type_subtype = wtap_pcap_file_type_subtype();
if (strcmp(produce_filename, "-") == 0) {
/* Write to the standard output. */
example->dump = wtap_dump_open_stdout(file_type_subtype,

View File

@ -44,7 +44,7 @@ int randpkt_parse_type(char *string);
randpkt_example* randpkt_find_example(int type);
/* Init a new example */
int randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes);
int randpkt_example_init(randpkt_example* example, char* produce_filename, int produce_max_bytes, int file_type_subtype);
/* Loop the packet generation */
void randpkt_loop(randpkt_example* example, guint64 produce_count, guint64 packet_delay_ms);