ldap: assume GSS-SPNEGO as default
[wireshark-sm.git] / extcap / extcap-base.c
blobde753e8e0f2a8a3ba30432f65eda65c5fe61dcad
1 /* extcap-base.c
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
13 #include "config.h"
14 #define WS_LOG_DOMAIN LOG_DOMAIN_EXTCAP
16 #include "extcap-base.h"
18 #include <stdlib.h>
19 #include <stdint.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <wsutil/wslog.h>
24 #include <wsutil/ws_assert.h>
26 #include "ws_attributes.h"
28 enum extcap_options {
29 EXTCAP_BASE_OPTIONS_ENUM
32 typedef struct _extcap_interface
34 char * interface;
35 char * description;
37 uint16_t dlt;
38 char * dltname;
39 char * dltdescription;
40 } extcap_interface;
42 typedef struct _extcap_option {
43 char * optname;
44 char * optdesc;
45 } extcap_option_t;
47 static FILE *custom_log = NULL;
49 /* used to inform to extcap application that end of application is requested */
50 bool extcap_end_application = false;
51 /* graceful shutdown callback, can be null */
52 void (*extcap_graceful_shutdown_cb)(void) = NULL;
54 static void extcap_init_log_file(const char *filename);
56 /* Called from signals */
57 #ifdef _WIN32
58 static BOOL WINAPI
59 extcap_exit_from_loop(DWORD dwCtrlType _U_)
60 #else
61 static void extcap_exit_from_loop(int signo _U_)
62 #endif /* _WIN32 */
64 ws_debug("Exiting from main loop by signal");
65 extcap_end_application = true;
66 if (extcap_graceful_shutdown_cb != NULL) {
67 extcap_graceful_shutdown_cb();
69 #ifdef _WIN32
70 return true;
71 #endif /* _WIN32 */
74 void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription )
76 extcap_base_register_interface_ext(extcap, interface, ifdescription, dlt, NULL, dltdescription );
79 void extcap_base_register_interface_ext(extcap_parameters * extcap,
80 const char * interface, const char * ifdescription,
81 uint16_t dlt, const char * dltname, const char * dltdescription )
83 extcap_interface * iface;
85 if (interface == NULL)
86 return;
88 iface = g_new0(extcap_interface, 1);
90 iface->interface = g_strdup(interface);
91 iface->description = g_strdup(ifdescription);
92 iface->dlt = dlt;
93 iface->dltname = g_strdup(dltname);
94 iface->dltdescription = g_strdup(dltdescription);
96 extcap->interfaces = g_list_append(extcap->interfaces, (void *) iface);
99 bool extcap_base_register_graceful_shutdown_cb(extcap_parameters * extcap _U_, void (*callback)(void))
101 #ifndef _WIN32
102 struct sigaction sig_handler = { .sa_handler = extcap_exit_from_loop };
103 #endif
105 extcap_end_application = false;
106 extcap_graceful_shutdown_cb = callback;
107 #ifdef _WIN32
108 if (!SetConsoleCtrlHandler(extcap_exit_from_loop, true)) {
109 ws_warning("Can't set console handler");
110 return false;
112 #else
113 /* Catch signals to be able to cleanup config later */
114 if (sigaction(SIGINT, &sig_handler, NULL)) {
115 ws_warning("Can't set SIGINT signal handler");
116 return false;
118 if (sigaction(SIGTERM, &sig_handler, NULL)) {
119 ws_warning("Can't set SIGTERM signal handler");
120 return false;
122 if (sigaction(SIGPIPE, &sig_handler, NULL)) {
123 ws_warning("Can't set SIGPIPE signal handler");
124 return false;
126 #endif /* _WIN32 */
128 return true;
131 void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major,
132 const char * minor, const char * release, const char * helppage)
134 extcap->exename = g_path_get_basename(exename);
136 ws_assert(major);
137 if (!minor)
138 ws_assert(!release);
140 extcap->version = ws_strdup_printf("%s%s%s%s%s",
141 major,
142 minor ? "." : "",
143 minor ? minor : "",
144 release ? "." : "",
145 release ? release : "");
146 extcap->helppage = g_strdup(helppage);
149 void extcap_base_set_compiled_with(extcap_parameters * extcap, const char *fmt, ...)
151 va_list ap;
153 va_start(ap, fmt);
154 extcap->compiled_with = ws_strdup_vprintf(fmt, ap);
155 va_end(ap);
158 void extcap_base_set_running_with(extcap_parameters * extcap, const char *fmt, ...)
160 va_list ap;
162 va_start(ap, fmt);
163 extcap->running_with = ws_strdup_vprintf(fmt, ap);
164 va_end(ap);
167 void extcap_log_init(const char *progname)
169 ws_log_init(progname, NULL);
170 /* extcaps cannot write debug information to parent on stderr. */
171 ws_log_console_writer_set_use_stdout(true);
172 ws_noisy("Extcap log initialization finished");
175 uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument)
177 uint8_t ret = 1;
178 enum ws_log_level level;
180 switch (result) {
181 case EXTCAP_OPT_LOG_LEVEL:
182 level = ws_log_set_level_str(optargument);
183 if (level == LOG_LEVEL_NONE) {
184 /* Invalid log level string. */
185 ret = 0;
187 extcap->debug = level;
188 break;
189 case EXTCAP_OPT_LOG_FILE:
190 extcap_init_log_file(optargument);
191 break;
192 case EXTCAP_OPT_LIST_INTERFACES:
193 extcap->do_list_interfaces = 1;
194 break;
195 case EXTCAP_OPT_VERSION:
196 extcap->ws_version = g_strdup(optargument);
197 extcap->do_version = 1;
198 break;
199 case EXTCAP_OPT_LIST_DLTS:
200 extcap->do_list_dlts = 1;
201 break;
202 case EXTCAP_OPT_INTERFACE:
203 extcap->interface = g_strdup(optargument);
204 break;
205 case EXTCAP_OPT_CONFIG:
206 extcap->show_config = 1;
207 break;
208 case EXTCAP_OPT_CAPTURE:
209 extcap->capture = 1;
210 break;
211 case EXTCAP_OPT_CAPTURE_FILTER:
212 extcap->capture_filter = g_strdup(optargument);
213 break;
214 case EXTCAP_OPT_FIFO:
215 extcap->fifo = g_strdup(optargument);
216 break;
217 default:
218 ret = 0;
221 return ret;
224 static void extcap_iface_print(void * data, void * userdata _U_)
226 extcap_interface * iface = (extcap_interface *)data;
228 printf("interface {value=%s}", iface->interface);
229 if (iface->description != NULL)
230 printf ("{display=%s}\n", iface->description);
231 else
232 printf ("\n");
235 static int extcap_iface_compare(gconstpointer a, gconstpointer b)
237 const extcap_interface * iface_a = (const extcap_interface *)a;
239 return (g_strcmp0(iface_a->interface, (const char *) b));
242 static void extcap_print_version(extcap_parameters * extcap)
244 printf("extcap {version=%s}", extcap->version != NULL ? extcap->version : "unknown");
245 if (extcap->helppage != NULL)
246 printf("{help=%s}", extcap->helppage);
247 printf("\n");
250 static int extcap_iface_listall(extcap_parameters * extcap, uint8_t list_ifs)
252 if (list_ifs) {
253 if (g_list_length(extcap->interfaces) > 0) {
254 extcap_print_version(extcap);
255 g_list_foreach(extcap->interfaces, extcap_iface_print, extcap);
257 } else if (extcap->do_version) {
258 extcap_print_version(extcap);
259 } else {
260 GList * element = NULL;
261 extcap_interface * iface = NULL;
262 if ((element = g_list_find_custom(extcap->interfaces, extcap->interface, extcap_iface_compare)) == NULL)
263 return 0;
265 iface = (extcap_interface *) element->data;
266 printf("dlt {number=%u}{name=%s}", iface->dlt, iface->dltname != NULL ? iface->dltname : iface->interface);
267 if (iface->description != NULL)
268 printf ("{display=%s}\n", iface->dltdescription);
269 else
270 printf ("\n");
273 return 1;
276 uint8_t extcap_base_handle_interface(extcap_parameters * extcap)
278 /* A fifo must be provided for capture */
279 if (extcap->capture && (extcap->fifo == NULL || strlen(extcap->fifo) <= 0)) {
280 extcap->capture = 0;
281 ws_error("Extcap Error: No FIFO pipe provided");
282 return 0;
285 if (extcap->do_list_interfaces) {
286 return extcap_iface_listall(extcap, 1);
287 } else if (extcap->do_version || extcap->do_list_dlts) {
288 return extcap_iface_listall(extcap, 0);
291 return 0;
294 static void extcap_iface_free(void * data)
296 extcap_interface * iface = (extcap_interface *)data;
297 g_free(iface->interface);
298 g_free(iface->description);
299 g_free(iface->dltname);
300 g_free(iface->dltdescription);
301 g_free(iface);
304 static void extcap_help_option_free(void * option)
306 extcap_option_t* o = (extcap_option_t*)option;
307 g_free(o->optname);
308 g_free(o->optdesc);
309 g_free(o);
312 void extcap_base_cleanup(extcap_parameters ** extcap)
314 g_list_free_full((*extcap)->interfaces, extcap_iface_free);
315 g_free((*extcap)->exename);
316 g_free((*extcap)->fifo);
317 g_free((*extcap)->interface);
318 g_free((*extcap)->version);
319 g_free((*extcap)->compiled_with);
320 g_free((*extcap)->running_with);
321 g_free((*extcap)->helppage);
322 g_free((*extcap)->help_header);
323 g_free((*extcap)->ws_version);
324 g_list_free_full((*extcap)->help_options, extcap_help_option_free);
325 g_free(*extcap);
326 *extcap = NULL;
329 static void extcap_print_option(void * option, void * user_data _U_)
331 extcap_option_t* o = (extcap_option_t*)option;
332 printf("\t%s: %s\n", o->optname, o->optdesc);
335 void extcap_version_print(extcap_parameters * extcap)
337 printf("%s version %s\n", extcap->exename, extcap->version);
338 if (extcap->compiled_with != NULL)
339 printf("Compiled with %s\n", extcap->compiled_with);
340 if (extcap->running_with != NULL)
341 printf("Running with %s\n", extcap->running_with);
344 void extcap_help_print(extcap_parameters * extcap)
346 printf("\nWireshark - %s v%s\n\n", extcap->exename, extcap->version);
347 printf("Usage:\n");
348 printf("%s", extcap->help_header);
349 printf("\n");
350 printf("Options:\n");
351 g_list_foreach(extcap->help_options, extcap_print_option, NULL);
352 printf("\n");
355 void extcap_help_add_option(extcap_parameters * extcap, const char * help_option_name, const char * help_option_desc)
357 extcap_option_t* o = g_new0(extcap_option_t, 1);
358 o->optname = g_strdup(help_option_name);
359 o->optdesc = g_strdup(help_option_desc);
361 extcap->help_options = g_list_append(extcap->help_options, o);
364 void extcap_help_add_header(extcap_parameters * extcap, char * help_header)
366 extcap->help_header = g_strdup(help_header);
367 extcap_help_add_option(extcap, "--extcap-interfaces", "list the extcap Interfaces");
368 extcap_help_add_option(extcap, "--extcap-dlts", "list the DLTs");
369 extcap_help_add_option(extcap, "--extcap-interface <iface>", "specify the extcap interface");
370 extcap_help_add_option(extcap, "--extcap-config", "list the additional configuration for an interface");
371 extcap_help_add_option(extcap, "--capture", "run the capture");
372 extcap_help_add_option(extcap, "--extcap-capture-filter <filter>", "the capture filter");
373 extcap_help_add_option(extcap, "--fifo <file>", "dump data to file or fifo");
374 extcap_help_add_option(extcap, "--extcap-version", "print tool version");
375 extcap_help_add_option(extcap, "--log-level", "Set the log level");
376 extcap_help_add_option(extcap, "--log-file", "Set a log file to log messages in addition to the console");
379 static void extcap_init_log_file(const char* filename)
381 if (!filename || strlen(filename) == 0)
382 ws_error("Missing log file name");
383 custom_log = fopen(filename, "w");
384 if (!custom_log)
385 ws_error("Can't open custom log file: %s (%s)", filename, strerror(errno));
386 ws_log_add_custom_file(custom_log);
389 void extcap_config_debug(unsigned* count)
391 printf("arg {number=%u}{call=--log-level}{display=Set the log level}"
392 "{type=selector}{tooltip=Set the log level}{required=false}"
393 "{group=Debug}\n", *count);
394 printf("value {arg=%u}{value=message}{display=Message}{default=true}\n", *count);
395 printf("value {arg=%u}{value=info}{display=Info}\n", *count);
396 printf("value {arg=%u}{value=debug}{display=Debug}\n", *count);
397 printf("value {arg=%u}{value=noisy}{display=Noisy}\n", *count);
398 (*count)++;
399 printf("arg {number=%u}{call=--log-file}{display=Use a file for logging}"
400 "{type=fileselect}{tooltip=Set a file where log messages are written}{required=false}"
401 "{group=Debug}\n", (*count)++);
404 void extcap_cmdline_debug(char** ar, const unsigned n)
406 GString* cmdline = g_string_new("cmdline: ");
407 unsigned i;
408 for (i = 0; i < n; i++)
409 g_string_append_printf(cmdline, "%s ", ar[i]);
410 ws_debug("%s", cmdline->str);
411 g_string_free(cmdline, true);
415 * Editor modelines - https://www.wireshark.org/tools/modelines.html
417 * Local variables:
418 * c-basic-offset: 4
419 * tab-width: 8
420 * indent-tabs-mode: nil
421 * End:
423 * vi: set shiftwidth=4 tabstop=8 expandtab:
424 * :indentSize=4:tabSize=8:noTabs=true: