Put all the capture dissector structures into epan/capture_dissectors.h.
[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  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 #include "extcap-base.h"
28
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <string.h>
32
33 #ifdef HAVE_GETOPT_H
34     #include <getopt.h>
35 #endif
36
37 #ifndef HAVE_GETOPT_LONG
38     #include "wsutil/wsgetopt.h"
39 #endif
40
41 enum extcap_options {
42     EXTCAP_BASE_OPTIONS_ENUM
43 };
44
45 typedef struct _extcap_interface
46 {
47     char * interface;
48     char * description;
49
50     uint16_t dlt;
51     char * dltname;
52     char * dltdescription;
53 } extcap_interface;
54
55 typedef struct _extcap_option {
56     char * optname;
57     char * optdesc;
58 } extcap_option_t;
59
60 #ifdef _WIN32
61 BOOLEAN IsHandleRedirected(DWORD handle)
62 {
63     HANDLE h = GetStdHandle(handle);
64     if (h) {
65         BY_HANDLE_FILE_INFORMATION fi;
66         if (GetFileInformationByHandle(h, &fi)) {
67             return TRUE;
68         }
69     }
70     return FALSE;
71 }
72
73 void attach_parent_console()
74 {
75     BOOL outRedirected, errRedirected;
76
77     outRedirected = IsHandleRedirected(STD_OUTPUT_HANDLE);
78     errRedirected = IsHandleRedirected(STD_ERROR_HANDLE);
79
80     if (outRedirected && errRedirected) {
81         /* Both standard output and error handles are redirected.
82          * There is no point in attaching to parent process console.
83          */
84         return;
85     }
86
87     if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) {
88         /* Console attach failed. */
89         return;
90     }
91
92     /* Console attach succeeded */
93     if (outRedirected == FALSE) {
94         if (!freopen("CONOUT$", "w", stdout)) {
95             g_warning("Cannot redirect to stdout.");
96         }
97     }
98
99     if (errRedirected == FALSE) {
100         if (!freopen("CONOUT$", "w", stderr)) {
101             g_warning("Cannot redirect to strerr.");
102         }
103     }
104 }
105 #endif
106
107 void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription )
108 {
109     extcap_base_register_interface_ext(extcap, interface, ifdescription, dlt, NULL, dltdescription );
110 }
111
112 void extcap_base_register_interface_ext(extcap_parameters * extcap,
113         const char * interface, const char * ifdescription,
114         uint16_t dlt, const char * dltname, const char * dltdescription )
115 {
116     extcap_interface * iface;
117
118     if (interface == NULL)
119     return;
120
121     iface = g_new0(extcap_interface, 1);
122
123     iface->interface = g_strdup(interface);
124     iface->description = g_strdup(ifdescription);
125     iface->dlt = dlt;
126     iface->dltname = g_strdup(dltname);
127     iface->dltdescription = g_strdup(dltdescription);
128
129     extcap->interfaces = g_list_append(extcap->interfaces, (gpointer) iface);
130 }
131
132 void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major, const char * minor, const char * release, const char * helppage)
133 {
134     extcap->exename = g_path_get_basename(exename);
135
136     g_assert(major);
137     if (!minor)
138         g_assert(!release);
139
140     extcap->version = g_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);
147 }
148
149 uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument )
150 {
151     switch (result) {
152         case EXTCAP_OPT_DEBUG:
153 #ifdef _WIN32
154             _putenv_s("G_MESSAGES_DEBUG", "all");
155 #else
156             setenv("G_MESSAGES_DEBUG", "all", 1);
157 #endif
158             break;
159         case EXTCAP_OPT_LIST_INTERFACES:
160             extcap->do_list_interfaces = 1;
161             break;
162         case EXTCAP_OPT_VERSION:
163             extcap->do_version = 1;
164             break;
165         case EXTCAP_OPT_LIST_DLTS:
166             extcap->do_list_dlts = 1;
167             break;
168         case EXTCAP_OPT_INTERFACE:
169             extcap->interface = g_strdup(optargument);
170             break;
171         case EXTCAP_OPT_CONFIG:
172             extcap->show_config = 1;
173             break;
174         case EXTCAP_OPT_CAPTURE:
175             extcap->capture = 1;
176             break;
177         case EXTCAP_OPT_CAPTURE_FILTER:
178             extcap->capture_filter = g_strdup(optargument);
179             break;
180         case EXTCAP_OPT_FIFO:
181             extcap->fifo = g_strdup(optargument);
182             break;
183     }
184
185     return 1;
186 }
187
188 static void extcap_iface_print(gpointer data, gpointer userdata _U_)
189 {
190     extcap_interface * iface = (extcap_interface *)data;
191
192     printf("interface {value=%s}", iface->interface);
193     if (iface->description != NULL)
194         printf ("{display=%s}\n", iface->description);
195     else
196         printf ("\n");
197 }
198
199 static gint extcap_iface_compare(gconstpointer  a, gconstpointer  b)
200 {
201     const extcap_interface * iface_a = (const extcap_interface *)a;
202
203     return (g_strcmp0(iface_a->interface, (const char *) b));
204 }
205
206 static void extcap_print_version(extcap_parameters * extcap)
207 {
208     printf("extcap {version=%s}", extcap->version != NULL ? extcap->version : "unknown");
209     if (extcap->helppage != NULL)
210         printf("{help=%s}", extcap->helppage);
211     printf("\n");
212 }
213
214 static gint extcap_iface_listall(extcap_parameters * extcap, uint8_t list_ifs)
215 {
216     if (list_ifs) {
217         if (g_list_length(extcap->interfaces) > 0) {
218             extcap_print_version(extcap);
219             g_list_foreach(extcap->interfaces, extcap_iface_print, extcap);
220         }
221     } else {
222         if (extcap->do_version) {
223             extcap_print_version(extcap);
224     } else {
225         GList * element = NULL;
226         extcap_interface * iface = NULL;
227         if ((element = g_list_find_custom(extcap->interfaces, extcap->interface, extcap_iface_compare)) == NULL)
228             return 0;
229
230         iface = (extcap_interface *) element->data;
231         printf("dlt {number=%u}{name=%s}", iface->dlt, iface->dltname != NULL ? iface->dltname : iface->interface);
232         if (iface->description != NULL)
233             printf ("{display=%s}\n", iface->dltdescription);
234         else
235             printf ("\n");
236         }
237     }
238
239     return 1;
240 }
241
242 uint8_t extcap_base_handle_interface(extcap_parameters * extcap)
243 {
244     /* A fifo must be provided for capture */
245     if (extcap->capture && (extcap->fifo == NULL || strlen(extcap->fifo) <= 0)) {
246         extcap->capture = 0;
247         g_error("Extcap Error: No FIFO pipe provided");
248         return 0;
249     }
250
251     if (extcap->do_list_interfaces) {
252         return extcap_iface_listall(extcap, 1);
253     } else if (extcap->do_version || extcap->do_list_dlts) {
254         return extcap_iface_listall(extcap, 0);
255     }
256
257     return 0;
258 }
259
260 static void extcap_iface_free(gpointer data)
261 {
262     extcap_interface * iface = (extcap_interface *)data;
263     g_free(iface->interface);
264     g_free(iface->description);
265     g_free(iface->dltname);
266     g_free(iface->dltdescription);
267     g_free(iface);
268 }
269
270 static void extcap_help_option_free(gpointer option)
271 {
272     extcap_option_t* o = (extcap_option_t*)option;
273     g_free(o->optname);
274     g_free(o->optdesc);
275     g_free(o);
276 }
277
278 void extcap_base_cleanup(extcap_parameters ** extcap)
279 {
280     /* g_list_free_full() only exists since 2.28. g_list_free_full((*extcap)->interfaces, extcap_iface_free);*/
281     g_list_foreach((*extcap)->interfaces, (GFunc)extcap_iface_free, NULL);
282     g_list_free((*extcap)->interfaces);
283     g_free((*extcap)->exename);
284     g_free((*extcap)->fifo);
285     g_free((*extcap)->interface);
286     g_free((*extcap)->version);
287     g_free((*extcap)->helppage);
288     g_free((*extcap)->help_header);
289     g_list_foreach((*extcap)->help_options, (GFunc)extcap_help_option_free, NULL);
290     g_list_free((*extcap)->help_options);
291     g_free(*extcap);
292     *extcap = NULL;
293 }
294
295 static void extcap_print_option(gpointer option)
296 {
297     extcap_option_t* o = (extcap_option_t*)option;
298     printf("\t%s: %s\n", o->optname, o->optdesc);
299 }
300
301 void extcap_help_print(extcap_parameters * extcap)
302 {
303     printf("\nWireshark - %s v%s\n\n", extcap->exename, extcap->version);
304     printf("Usage:\n");
305     printf("%s", extcap->help_header);
306     printf("\n");
307     printf("Options:\n");
308     g_list_foreach(extcap->help_options, (GFunc)extcap_print_option, NULL);
309     printf("\n");
310 }
311
312 void extcap_help_add_option(extcap_parameters * extcap, const char * help_option_name, const char * help_option_desc)
313 {
314     extcap_option_t* o = g_new0(extcap_option_t, 1);
315     o->optname = g_strdup(help_option_name);
316     o->optdesc = g_strdup(help_option_desc);
317
318     extcap->help_options = g_list_append(extcap->help_options, o);
319 }
320
321 void extcap_help_add_header(extcap_parameters * extcap, char * help_header)
322 {
323     extcap->help_header = g_strdup(help_header);
324     extcap_help_add_option(extcap, "--extcap-interfaces", "list the extcap Interfaces");
325     extcap_help_add_option(extcap, "--extcap-dlts", "list the DLTs");
326     extcap_help_add_option(extcap, "--extcap-interface <iface>", "specify the extcap interface");
327     extcap_help_add_option(extcap, "--extcap-config", "list the additional configuration for an interface");
328     extcap_help_add_option(extcap, "--capture", "run the capture");
329     extcap_help_add_option(extcap, "--extcap-capture-filter <filter>", "the capture filter");
330     extcap_help_add_option(extcap, "--fifo <file>", "dump data to file or fifo");
331     extcap_help_add_option(extcap, "--extcap-version", "print tool version");
332     extcap_help_add_option(extcap, "--debug", "print additional messages");
333 }
334
335 /*
336  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
337  *
338  * Local variables:
339  * c-basic-offset: 4
340  * tab-width: 4
341  * indent-tabs-mode: nil
342  * End:
343  *
344  * vi: set shiftwidth=4 tabstop=4 expandtab:
345  * :indentSize=4:tabSize=4:noTabs=true:
346  */