2 * Base function for extcaps
4 * Copyright 2015, Dario Lombardo
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "extcap-base.h"
26 #ifndef HAVE_GETOPT_LONG
27 #include "wsutil/wsgetopt.h"
29 #include "ws_attributes.h"
32 EXTCAP_BASE_OPTIONS_ENUM
35 typedef struct _extcap_interface
42 char * dltdescription;
45 typedef struct _extcap_option {
50 FILE* custom_log = NULL;
52 void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription )
54 extcap_base_register_interface_ext(extcap, interface, ifdescription, dlt, NULL, dltdescription );
57 void extcap_base_register_interface_ext(extcap_parameters * extcap,
58 const char * interface, const char * ifdescription,
59 uint16_t dlt, const char * dltname, const char * dltdescription )
61 extcap_interface * iface;
63 if (interface == NULL)
66 iface = g_new0(extcap_interface, 1);
68 iface->interface = g_strdup(interface);
69 iface->description = g_strdup(ifdescription);
71 iface->dltname = g_strdup(dltname);
72 iface->dltdescription = g_strdup(dltdescription);
74 extcap->interfaces = g_list_append(extcap->interfaces, (gpointer) iface);
77 void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major, const char * minor, const char * release, const char * helppage)
79 extcap->exename = g_path_get_basename(exename);
85 extcap->version = g_strdup_printf("%s%s%s%s%s",
90 release ? release : "");
91 extcap->helppage = g_strdup(helppage);
94 static void extcap_custom_log(const gchar *log_domain,
95 GLogLevelFlags log_level,
99 if (log_level & G_LOG_LEVEL_DEBUG) {
102 fprintf(custom_log, "%s\n", message);
105 g_log_default_handler(log_domain, log_level, message, user_data);
109 uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument)
112 case EXTCAP_OPT_DEBUG:
114 _putenv_s("G_MESSAGES_DEBUG", "all");
116 setenv("G_MESSAGES_DEBUG", "all", 1);
119 case EXTCAP_OPT_DEBUG_FILE:
120 extcap_init_custom_log(optargument);
121 g_log_set_default_handler(extcap_custom_log, NULL);
123 case EXTCAP_OPT_LIST_INTERFACES:
124 extcap->do_list_interfaces = 1;
126 case EXTCAP_OPT_VERSION:
127 extcap->ws_version = g_strdup(optargument);
128 extcap->do_version = 1;
130 case EXTCAP_OPT_LIST_DLTS:
131 extcap->do_list_dlts = 1;
133 case EXTCAP_OPT_INTERFACE:
134 extcap->interface = g_strdup(optargument);
136 case EXTCAP_OPT_CONFIG:
137 extcap->show_config = 1;
139 case EXTCAP_OPT_CAPTURE:
142 case EXTCAP_OPT_CAPTURE_FILTER:
143 extcap->capture_filter = g_strdup(optargument);
145 case EXTCAP_OPT_FIFO:
146 extcap->fifo = g_strdup(optargument);
153 static void extcap_iface_print(gpointer data, gpointer userdata _U_)
155 extcap_interface * iface = (extcap_interface *)data;
157 printf("interface {value=%s}", iface->interface);
158 if (iface->description != NULL)
159 printf ("{display=%s}\n", iface->description);
164 static gint extcap_iface_compare(gconstpointer a, gconstpointer b)
166 const extcap_interface * iface_a = (const extcap_interface *)a;
168 return (g_strcmp0(iface_a->interface, (const char *) b));
171 static void extcap_print_version(extcap_parameters * extcap)
173 printf("extcap {version=%s}", extcap->version != NULL ? extcap->version : "unknown");
174 if (extcap->helppage != NULL)
175 printf("{help=%s}", extcap->helppage);
179 static gint extcap_iface_listall(extcap_parameters * extcap, uint8_t list_ifs)
182 if (g_list_length(extcap->interfaces) > 0) {
183 extcap_print_version(extcap);
184 g_list_foreach(extcap->interfaces, extcap_iface_print, extcap);
187 if (extcap->do_version) {
188 extcap_print_version(extcap);
190 GList * element = NULL;
191 extcap_interface * iface = NULL;
192 if ((element = g_list_find_custom(extcap->interfaces, extcap->interface, extcap_iface_compare)) == NULL)
195 iface = (extcap_interface *) element->data;
196 printf("dlt {number=%u}{name=%s}", iface->dlt, iface->dltname != NULL ? iface->dltname : iface->interface);
197 if (iface->description != NULL)
198 printf ("{display=%s}\n", iface->dltdescription);
207 uint8_t extcap_base_handle_interface(extcap_parameters * extcap)
209 /* A fifo must be provided for capture */
210 if (extcap->capture && (extcap->fifo == NULL || strlen(extcap->fifo) <= 0)) {
212 g_error("Extcap Error: No FIFO pipe provided");
216 if (extcap->do_list_interfaces) {
217 return extcap_iface_listall(extcap, 1);
218 } else if (extcap->do_version || extcap->do_list_dlts) {
219 return extcap_iface_listall(extcap, 0);
225 static void extcap_iface_free(gpointer data)
227 extcap_interface * iface = (extcap_interface *)data;
228 g_free(iface->interface);
229 g_free(iface->description);
230 g_free(iface->dltname);
231 g_free(iface->dltdescription);
235 static void extcap_help_option_free(gpointer option)
237 extcap_option_t* o = (extcap_option_t*)option;
243 void extcap_base_cleanup(extcap_parameters ** extcap)
245 g_list_free_full((*extcap)->interfaces, extcap_iface_free);
246 g_free((*extcap)->exename);
247 g_free((*extcap)->fifo);
248 g_free((*extcap)->interface);
249 g_free((*extcap)->version);
250 g_free((*extcap)->helppage);
251 g_free((*extcap)->help_header);
252 g_free((*extcap)->ws_version);
253 g_list_free_full((*extcap)->help_options, extcap_help_option_free);
258 static void extcap_print_option(gpointer option, gpointer user_data _U_)
260 extcap_option_t* o = (extcap_option_t*)option;
261 printf("\t%s: %s\n", o->optname, o->optdesc);
264 void extcap_help_print(extcap_parameters * extcap)
266 printf("\nWireshark - %s v%s\n\n", extcap->exename, extcap->version);
268 printf("%s", extcap->help_header);
270 printf("Options:\n");
271 g_list_foreach(extcap->help_options, extcap_print_option, NULL);
275 void extcap_help_add_option(extcap_parameters * extcap, const char * help_option_name, const char * help_option_desc)
277 extcap_option_t* o = g_new0(extcap_option_t, 1);
278 o->optname = g_strdup(help_option_name);
279 o->optdesc = g_strdup(help_option_desc);
281 extcap->help_options = g_list_append(extcap->help_options, o);
284 void extcap_help_add_header(extcap_parameters * extcap, char * help_header)
286 extcap->help_header = g_strdup(help_header);
287 extcap_help_add_option(extcap, "--extcap-interfaces", "list the extcap Interfaces");
288 extcap_help_add_option(extcap, "--extcap-dlts", "list the DLTs");
289 extcap_help_add_option(extcap, "--extcap-interface <iface>", "specify the extcap interface");
290 extcap_help_add_option(extcap, "--extcap-config", "list the additional configuration for an interface");
291 extcap_help_add_option(extcap, "--capture", "run the capture");
292 extcap_help_add_option(extcap, "--extcap-capture-filter <filter>", "the capture filter");
293 extcap_help_add_option(extcap, "--fifo <file>", "dump data to file or fifo");
294 extcap_help_add_option(extcap, "--extcap-version", "print tool version");
295 extcap_help_add_option(extcap, "--debug", "print additional messages");
296 extcap_help_add_option(extcap, "--debug-file", "print debug messages to file");
299 void extcap_init_custom_log(const char* filename)
301 if (!filename || strlen(filename) == 0)
303 custom_log = fopen(filename, "w");
305 g_error("Can't open custom log file: %s (%s)", filename, strerror(errno));
308 void extcap_config_debug(unsigned* count)
310 printf("arg {number=%u}{call=--debug}{display=Run in debug mode}"
311 "{type=boolean}{default=false}{tooltip=Print debug messages}{required=false}"
312 "{group=Debug}\n", (*count)++);
313 printf("arg {number=%u}{call=--debug-file}{display=Use a file for debug}"
314 "{type=string}{tooltip=Set a file where the debug messages are written}{required=false}"
315 "{group=Debug}\n", (*count)++);
318 void extcap_cmdline_debug(char** ar, const unsigned n)
320 GString* cmdline = g_string_new("cmdline: ");
322 for (i = 0; i < n; i++)
323 g_string_append_printf(cmdline, "%s ", ar[i]);
324 g_debug("%s", cmdline->str);
325 g_string_free(cmdline, TRUE);
329 * Editor modelines - https://www.wireshark.org/tools/modelines.html
334 * indent-tabs-mode: nil
337 * vi: set shiftwidth=4 tabstop=4 expandtab:
338 * :indentSize=4:tabSize=4:noTabs=true: