CMake: Use $ORIGIN with RPATH
[metze/wireshark/wip.git] / extcap / randpktdump.c
1 /* randpktdump.c
2  * randpktdump is an extcap tool used to generate random data for testing/educational purpose
3  *
4  * Copyright 2015, Dario Lombardo
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "config.h"
14
15 #include "extcap-base.h"
16
17 #include "randpkt_core/randpkt_core.h"
18 #include <wsutil/strtoi.h>
19 #include <wsutil/filesystem.h>
20
21 #define RANDPKT_EXTCAP_INTERFACE "randpkt"
22 #define RANDPKTDUMP_VERSION_MAJOR "0"
23 #define RANDPKTDUMP_VERSION_MINOR "1"
24 #define RANDPKTDUMP_VERSION_RELEASE "0"
25
26 enum {
27         EXTCAP_BASE_OPTIONS_ENUM,
28         OPT_HELP,
29         OPT_VERSION,
30         OPT_MAXBYTES,
31         OPT_COUNT,
32         OPT_DELAY,
33         OPT_RANDOM_TYPE,
34         OPT_ALL_RANDOM,
35         OPT_TYPE
36 };
37
38 static struct option longopts[] = {
39         EXTCAP_BASE_OPTIONS,
40         { "help",                                       no_argument,            NULL, OPT_HELP},
41         { "version",                            no_argument,            NULL, OPT_VERSION},
42         { "maxbytes",                           required_argument,      NULL, OPT_MAXBYTES},
43         { "count",                                      required_argument,      NULL, OPT_COUNT},
44         { "delay",                                      required_argument,      NULL, OPT_DELAY},
45         { "random-type",                        no_argument,            NULL, OPT_RANDOM_TYPE},
46         { "all-random",                         no_argument,            NULL, OPT_ALL_RANDOM},
47         { "type",                                       required_argument,      NULL, OPT_TYPE},
48     { 0, 0, 0, 0 }
49 };
50
51
52 static void help(extcap_parameters* extcap_conf)
53 {
54         unsigned i = 0;
55         char** abbrev_list;
56         char** longname_list;
57
58         extcap_help_print(extcap_conf);
59
60         printf("\nPacket types:\n");
61         randpkt_example_list(&abbrev_list, &longname_list);
62         while (abbrev_list[i] && longname_list[i]) {
63                 printf("\t%-16s%s\n", abbrev_list[i], longname_list[i]);
64                 i++;
65         }
66         printf("\n");
67         g_strfreev(abbrev_list);
68         g_strfreev(longname_list);
69 }
70
71 static int list_config(char *interface)
72 {
73         unsigned inc = 0;
74         unsigned i = 0;
75         char** abbrev_list;
76         char** longname_list;
77
78         if (!interface) {
79                 g_warning("No interface specified.");
80                 return EXIT_FAILURE;
81         }
82
83         if (g_strcmp0(interface, RANDPKT_EXTCAP_INTERFACE)) {
84                 g_warning("Interface must be %s", RANDPKT_EXTCAP_INTERFACE);
85                 return EXIT_FAILURE;
86         }
87
88         printf("arg {number=%u}{call=--maxbytes}{display=Max bytes in a packet}"
89                 "{type=unsigned}{range=1,5000}{default=5000}{tooltip=The max number of bytes in a packet}\n",
90                 inc++);
91         printf("arg {number=%u}{call=--count}{display=Number of packets}"
92                 "{type=long}{default=1000}{tooltip=Number of packets to generate (-1 for infinite)}\n",
93                 inc++);
94         printf("arg {number=%u}{call=--delay}{display=Packet delay (ms)}"
95                 "{type=long}{default=0}{tooltip=Milliseconds to wait after writing each packet}\n",
96                 inc++);
97         printf("arg {number=%u}{call=--random-type}{display=Random type}"
98                 "{type=boolflag}{default=false}{tooltip=The packets type is randomly chosen}\n",
99                 inc++);
100         printf("arg {number=%u}{call=--all-random}{display=All random packets}"
101                 "{type=boolflag}{default=false}{tooltip=Packet type for each packet is randomly chosen}\n",
102                 inc++);
103
104         /* Now the types */
105         printf("arg {number=%u}{call=--type}{display=Type of packet}"
106                 "{type=selector}{tooltip=Type of packet to generate}\n",
107                 inc);
108         randpkt_example_list(&abbrev_list, &longname_list);
109         while (abbrev_list[i] && longname_list[i]) {
110                 printf("value {arg=%u}{value=%s}{display=%s}\n", inc, abbrev_list[i], longname_list[i]);
111                 i++;
112         }
113         g_strfreev(abbrev_list);
114         g_strfreev(longname_list);
115         inc++;
116
117         extcap_config_debug(&inc);
118
119         return EXIT_SUCCESS;
120 }
121
122 int real_main(int argc, char *argv[])
123 {
124         int option_idx = 0;
125         int result;
126         guint16 maxbytes = 5000;
127         guint64 count = 1000;
128         guint64 packet_delay_ms = 0;
129         int random_type = FALSE;
130         int all_random = FALSE;
131         char* type = NULL;
132         int produce_type = -1;
133         randpkt_example *example;
134         wtap_dumper* savedump;
135         int ret = EXIT_FAILURE;
136
137 #ifdef _WIN32
138         WSADATA wsaData;
139 #endif  /* _WIN32 */
140
141         extcap_parameters * extcap_conf = g_new0(extcap_parameters, 1);
142         char* help_url;
143         char* help_header = NULL;
144
145         help_url = data_file_url("randpktdump.html");
146         extcap_base_set_util_info(extcap_conf, argv[0], RANDPKTDUMP_VERSION_MAJOR, RANDPKTDUMP_VERSION_MINOR,
147                 RANDPKTDUMP_VERSION_RELEASE, help_url);
148         g_free(help_url);
149         extcap_base_register_interface(extcap_conf, RANDPKT_EXTCAP_INTERFACE, "Random packet generator", 147, "Generator dependent DLT");
150
151         help_header = g_strdup_printf(
152                 " %s --extcap-interfaces\n"
153                 " %s --extcap-interface=%s --extcap-dlts\n"
154                 " %s --extcap-interface=%s --extcap-config\n"
155                 " %s --extcap-interface=%s --type dns --count 10 "
156                 "--fifo=FILENAME --capture\n", argv[0], argv[0], RANDPKT_EXTCAP_INTERFACE, argv[0], RANDPKT_EXTCAP_INTERFACE,
157                 argv[0], RANDPKT_EXTCAP_INTERFACE);
158         extcap_help_add_header(extcap_conf, help_header);
159         g_free(help_header);
160
161         extcap_help_add_option(extcap_conf, "--help", "print this help");
162         extcap_help_add_option(extcap_conf, "--version", "print the version");
163         extcap_help_add_option(extcap_conf, "--maxbytes <bytes>", "max bytes per pack");
164         extcap_help_add_option(extcap_conf, "--count <num>", "number of packets to generate");
165         extcap_help_add_option(extcap_conf, "--delay <ms>", "milliseconds to wait after writing each packet");
166         extcap_help_add_option(extcap_conf, "--random-type", "one random type is chosen for all packets");
167         extcap_help_add_option(extcap_conf, "--all-random", "a random type is chosen for each packet");
168         extcap_help_add_option(extcap_conf, "--type <type>", "the packet type");
169
170         if (argc == 1) {
171                 help(extcap_conf);
172                 goto end;
173         }
174
175         while ((result = getopt_long(argc, argv, ":", longopts, &option_idx)) != -1) {
176                 switch (result) {
177                 case OPT_VERSION:
178                         printf("%s\n", extcap_conf->version);
179                         ret = EXIT_SUCCESS;
180                         goto end;
181
182                 case OPT_HELP:
183                         help(extcap_conf);
184                         ret = EXIT_SUCCESS;
185                         goto end;
186
187                 case OPT_MAXBYTES:
188                         if (!ws_strtou16(optarg, NULL, &maxbytes)) {
189                                 g_warning("Invalid parameter maxbytes: %s (max value is %u)",
190                                         optarg, G_MAXUINT16);
191                                 goto end;
192                         }
193                         break;
194
195                 case OPT_COUNT:
196                         if (!ws_strtou64(optarg, NULL, &count)) {
197                                 g_warning("Invalid packet count: %s", optarg);
198                                 goto end;
199                         }
200                         break;
201
202                 case OPT_DELAY:
203                         if (!ws_strtou64(optarg, NULL, &packet_delay_ms)) {
204                                 g_warning("Invalid packet delay: %s", optarg);
205                                 goto end;
206                         }
207                         break;
208
209                 case OPT_RANDOM_TYPE:
210                         random_type = TRUE;
211                         break;
212
213                 case OPT_ALL_RANDOM:
214                         all_random = TRUE;
215                         break;
216
217                 case OPT_TYPE:
218                         g_free(type);
219                         type = g_strdup(optarg);
220                         break;
221
222                 case ':':
223                         /* missing option argument */
224                         g_warning("Option '%s' requires an argument", argv[optind - 1]);
225                         break;
226
227                 default:
228                         /* Handle extcap specific options */
229                         if (!extcap_base_parse_options(extcap_conf, result - EXTCAP_OPT_LIST_INTERFACES, optarg))
230                         {
231                                 g_warning("Invalid option: %s", argv[optind - 1]);
232                                 goto end;
233                         }
234                 }
235         }
236
237         extcap_cmdline_debug(argv, argc);
238
239         if (extcap_base_handle_interface(extcap_conf)) {
240                 ret = EXIT_SUCCESS;
241                 goto end;
242         }
243
244         if (extcap_conf->show_config) {
245                 ret = list_config(extcap_conf->interface);
246                 goto end;
247         }
248
249         /* Some sanity checks */
250         if ((random_type) && (all_random)) {
251                 g_warning("You can specify only one between: --random-type, --all-random");
252                 goto end;
253         }
254
255         /* Wireshark sets the type, even when random options are selected. We don't want it */
256         if (random_type || all_random) {
257                 g_free(type);
258                 type = NULL;
259         }
260
261 #ifdef _WIN32
262         result = WSAStartup(MAKEWORD(1,1), &wsaData);
263         if (result != 0) {
264                 g_warning("ERROR: WSAStartup failed with error: %d", result);
265                 goto end;
266         }
267 #endif  /* _WIN32 */
268
269         if (extcap_conf->capture) {
270
271                 if (g_strcmp0(extcap_conf->interface, RANDPKT_EXTCAP_INTERFACE)) {
272                         g_warning("ERROR: invalid interface");
273                         goto end;
274                 }
275
276                 wtap_init(FALSE);
277
278                 if (!all_random) {
279                         produce_type = randpkt_parse_type(type);
280
281                         example = randpkt_find_example(produce_type);
282                         if (!example)
283                                 goto end;
284
285                         g_debug("Generating packets: %s", example->abbrev);
286
287                         randpkt_example_init(example, extcap_conf->fifo, maxbytes);
288                         randpkt_loop(example, count, packet_delay_ms);
289                         randpkt_example_close(example);
290                 } else {
291                         produce_type = randpkt_parse_type(NULL);
292                         example = randpkt_find_example(produce_type);
293                         if (!example)
294                                 goto end;
295                         randpkt_example_init(example, extcap_conf->fifo, maxbytes);
296
297                         while (count-- > 0) {
298                                 randpkt_loop(example, 1, packet_delay_ms);
299                                 produce_type = randpkt_parse_type(NULL);
300
301                                 savedump = example->dump;
302
303                                 example = randpkt_find_example(produce_type);
304                                 if (!example)
305                                         goto end;
306                                 example->dump = savedump;
307                         }
308                         randpkt_example_close(example);
309                 }
310                 ret = EXIT_SUCCESS;
311         }
312
313 end:
314         /* clean up stuff */
315         g_free(type);
316         extcap_base_cleanup(&extcap_conf);
317
318         return ret;
319 }
320
321 #ifdef _WIN32
322 int
323 wmain(int argc, wchar_t *wc_argv[])
324 {
325     char **argv;
326
327     argv = arg_list_utf_16to8(argc, wc_argv);
328     return real_main(argc, argv);
329 }
330 #else
331 int
332 main(int argc, char *argv[])
333 {
334     return real_main(argc, argv);
335 }
336 #endif
337
338 /*
339  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
340  *
341  * Local variables:
342  * c-basic-offset: 8
343  * tab-width: 8
344  * indent-tabs-mode: t
345  * End:
346  *
347  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
348  * :indentSize=8:tabSize=8:noTabs=false:
349  */