no krb5_cksumtype_to_string
[metze/wireshark/wip.git] / extcap / extcap-base.c
1 /* extcap-base.c
2  * Base function for extcaps
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 <stdlib.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include <errno.h>
21
22 #ifdef HAVE_GETOPT_H
23     #include <getopt.h>
24 #endif
25
26 #ifndef HAVE_GETOPT_LONG
27     #include "wsutil/wsgetopt.h"
28 #endif
29 #include "ws_attributes.h"
30
31 enum extcap_options {
32     EXTCAP_BASE_OPTIONS_ENUM
33 };
34
35 typedef struct _extcap_interface
36 {
37     char * interface;
38     char * description;
39
40     uint16_t dlt;
41     char * dltname;
42     char * dltdescription;
43 } extcap_interface;
44
45 typedef struct _extcap_option {
46     char * optname;
47     char * optdesc;
48 } extcap_option_t;
49
50 FILE* custom_log = NULL;
51
52 void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription )
53 {
54     extcap_base_register_interface_ext(extcap, interface, ifdescription, dlt, NULL, dltdescription );
55 }
56
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 )
60 {
61     extcap_interface * iface;
62
63     if (interface == NULL)
64     return;
65
66     iface = g_new0(extcap_interface, 1);
67
68     iface->interface = g_strdup(interface);
69     iface->description = g_strdup(ifdescription);
70     iface->dlt = dlt;
71     iface->dltname = g_strdup(dltname);
72     iface->dltdescription = g_strdup(dltdescription);
73
74     extcap->interfaces = g_list_append(extcap->interfaces, (gpointer) iface);
75 }
76
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)
78 {
79     extcap->exename = g_path_get_basename(exename);
80
81     g_assert(major);
82     if (!minor)
83         g_assert(!release);
84
85     extcap->version = g_strdup_printf("%s%s%s%s%s",
86         major,
87         minor ? "." : "",
88         minor ? minor : "",
89         release ? "." : "",
90         release ? release : "");
91     extcap->helppage = g_strdup(helppage);
92 }
93
94 static void extcap_custom_log(const gchar *log_domain,
95              GLogLevelFlags log_level,
96              const gchar *message,
97              gpointer user_data)
98 {
99     if (log_level & G_LOG_LEVEL_DEBUG) {
100         if (!custom_log)
101             return;
102         fprintf(custom_log, "%s\n", message);
103         fflush(custom_log);
104     } else {
105         g_log_default_handler(log_domain, log_level, message, user_data);
106     }
107 }
108
109 uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument)
110 {
111     switch (result) {
112         case EXTCAP_OPT_DEBUG:
113 #ifdef _WIN32
114             _putenv_s("G_MESSAGES_DEBUG", "all");
115 #else
116             setenv("G_MESSAGES_DEBUG", "all", 1);
117 #endif
118             break;
119         case EXTCAP_OPT_DEBUG_FILE:
120             extcap_init_custom_log(optargument);
121             g_log_set_default_handler(extcap_custom_log, NULL);
122             break;
123         case EXTCAP_OPT_LIST_INTERFACES:
124             extcap->do_list_interfaces = 1;
125             break;
126         case EXTCAP_OPT_VERSION:
127             extcap->ws_version = g_strdup(optargument);
128             extcap->do_version = 1;
129             break;
130         case EXTCAP_OPT_LIST_DLTS:
131             extcap->do_list_dlts = 1;
132             break;
133         case EXTCAP_OPT_INTERFACE:
134             extcap->interface = g_strdup(optargument);
135             break;
136         case EXTCAP_OPT_CONFIG:
137             extcap->show_config = 1;
138             break;
139         case EXTCAP_OPT_CAPTURE:
140             extcap->capture = 1;
141             break;
142         case EXTCAP_OPT_CAPTURE_FILTER:
143             extcap->capture_filter = g_strdup(optargument);
144             break;
145         case EXTCAP_OPT_FIFO:
146             extcap->fifo = g_strdup(optargument);
147             break;
148     }
149
150     return 1;
151 }
152
153 static void extcap_iface_print(gpointer data, gpointer userdata _U_)
154 {
155     extcap_interface * iface = (extcap_interface *)data;
156
157     printf("interface {value=%s}", iface->interface);
158     if (iface->description != NULL)
159         printf ("{display=%s}\n", iface->description);
160     else
161         printf ("\n");
162 }
163
164 static gint extcap_iface_compare(gconstpointer  a, gconstpointer  b)
165 {
166     const extcap_interface * iface_a = (const extcap_interface *)a;
167
168     return (g_strcmp0(iface_a->interface, (const char *) b));
169 }
170
171 static void extcap_print_version(extcap_parameters * extcap)
172 {
173     printf("extcap {version=%s}", extcap->version != NULL ? extcap->version : "unknown");
174     if (extcap->helppage != NULL)
175         printf("{help=%s}", extcap->helppage);
176     printf("\n");
177 }
178
179 static gint extcap_iface_listall(extcap_parameters * extcap, uint8_t list_ifs)
180 {
181     if (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);
185         }
186     } else {
187         if (extcap->do_version) {
188             extcap_print_version(extcap);
189     } else {
190         GList * element = NULL;
191         extcap_interface * iface = NULL;
192         if ((element = g_list_find_custom(extcap->interfaces, extcap->interface, extcap_iface_compare)) == NULL)
193             return 0;
194
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);
199         else
200             printf ("\n");
201         }
202     }
203
204     return 1;
205 }
206
207 uint8_t extcap_base_handle_interface(extcap_parameters * extcap)
208 {
209     /* A fifo must be provided for capture */
210     if (extcap->capture && (extcap->fifo == NULL || strlen(extcap->fifo) <= 0)) {
211         extcap->capture = 0;
212         g_error("Extcap Error: No FIFO pipe provided");
213         return 0;
214     }
215
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);
220     }
221
222     return 0;
223 }
224
225 static void extcap_iface_free(gpointer data)
226 {
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);
232     g_free(iface);
233 }
234
235 static void extcap_help_option_free(gpointer option)
236 {
237     extcap_option_t* o = (extcap_option_t*)option;
238     g_free(o->optname);
239     g_free(o->optdesc);
240     g_free(o);
241 }
242
243 void extcap_base_cleanup(extcap_parameters ** extcap)
244 {
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);
254     g_free(*extcap);
255     *extcap = NULL;
256 }
257
258 static void extcap_print_option(gpointer option, gpointer user_data _U_)
259 {
260     extcap_option_t* o = (extcap_option_t*)option;
261     printf("\t%s: %s\n", o->optname, o->optdesc);
262 }
263
264 void extcap_help_print(extcap_parameters * extcap)
265 {
266     printf("\nWireshark - %s v%s\n\n", extcap->exename, extcap->version);
267     printf("Usage:\n");
268     printf("%s", extcap->help_header);
269     printf("\n");
270     printf("Options:\n");
271     g_list_foreach(extcap->help_options, extcap_print_option, NULL);
272     printf("\n");
273 }
274
275 void extcap_help_add_option(extcap_parameters * extcap, const char * help_option_name, const char * help_option_desc)
276 {
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);
280
281     extcap->help_options = g_list_append(extcap->help_options, o);
282 }
283
284 void extcap_help_add_header(extcap_parameters * extcap, char * help_header)
285 {
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");
297 }
298
299 void extcap_init_custom_log(const char* filename)
300 {
301     if (!filename || strlen(filename) == 0)
302         return;
303     custom_log = fopen(filename, "w");
304     if (!custom_log)
305         g_error("Can't open custom log file: %s (%s)", filename, strerror(errno));
306 }
307
308 void extcap_config_debug(unsigned* count)
309 {
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)++);
316 }
317
318 void extcap_cmdline_debug(char** ar, const unsigned n)
319 {
320     GString* cmdline = g_string_new("cmdline: ");
321     unsigned i;
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);
326 }
327
328 /*
329  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
330  *
331  * Local variables:
332  * c-basic-offset: 4
333  * tab-width: 4
334  * indent-tabs-mode: nil
335  * End:
336  *
337  * vi: set shiftwidth=4 tabstop=4 expandtab:
338  * :indentSize=4:tabSize=4:noTabs=true:
339  */