We always HAVE_CONFIG_H so don't bother checking whether we have it or not.
[gd/wireshark/.git] / ui / iface_lists.c
1 /* iface_lists.c
2  * Code to manage the global list of interfaces and to update widgets/windows
3  * displaying items from those lists
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include "config.h"
27
28 #ifdef HAVE_LIBPCAP
29
30 #include <string.h>
31
32 #include <glib.h>
33
34 #include <epan/prefs.h>
35 #include <epan/to_str.h>
36
37 #include "../capture_ui_utils.h"
38
39 #include "ui/capture_globals.h"
40 #include "ui/iface_lists.h"
41
42 capture_options global_capture_opts;
43
44 /*
45  * Used when sorting an interface list into alphabetical order by
46  * their descriptions.
47  */
48 gint
49 if_list_comparator_alph(const void *first_arg, const void *second_arg)
50 {
51     const if_info_t *first = first_arg, *second = second_arg;
52
53     if (first != NULL && first->description != NULL &&
54         second != NULL && second->description != NULL) {
55         return g_ascii_strcasecmp(first->description, second->description);
56     } else {
57         return 0;
58     }
59 }
60
61 /*
62  * Fetch the list of local interfaces with capture_interface_list()
63  * and set the list of "all interfaces" in *capture_opts to include
64  * those interfaces.
65  */
66 void
67 scan_local_interfaces(void)
68 {
69     GList             *if_entry, *lt_entry, *if_list;
70     if_info_t         *if_info, *temp;
71     char              *if_string;
72     gchar             *descr;
73     if_capabilities_t *caps=NULL;
74     gint              linktype_count;
75     gboolean          monitor_mode;
76     GSList            *curr_addr;
77     int               ips = 0, i, err;
78     guint             count = 0, j;
79     if_addr_t         *addr, *temp_addr;
80     link_row          *link = NULL;
81     data_link_info_t  *data_link_info;
82     interface_t       device;
83     GString           *ip_str;
84     interface_options interface_opts;
85     gboolean          found = FALSE;
86
87
88     if (global_capture_opts.all_ifaces->len > 0) {
89         for (i = (int)global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
90             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
91             if (device.local) {
92                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
93             }
94         }
95     }
96     /* Scan through the list and build a list of strings to display. */
97     if_list = capture_interface_list(&err, NULL);
98     count = 0;
99     for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
100         if_info = if_entry->data;
101         ip_str = g_string_new("");
102         ips = 0;
103         if (strstr(if_info->name, "rpcap:")) {
104             continue;
105         }
106         device.name = g_strdup(if_info->name);
107         device.hidden = FALSE;
108         device.locked = FALSE;
109         temp = g_malloc0(sizeof(if_info_t));
110         temp->name = g_strdup(if_info->name);
111         temp->description = g_strdup(if_info->description);
112         temp->loopback = if_info->loopback;
113         /* Is this interface hidden and, if so, should we include it anyway? */
114
115         /* Do we have a user-supplied description? */
116         descr = capture_dev_user_descr_find(if_info->name);
117         if (descr != NULL) {
118             /* Yes, we have a user-supplied description; use it. */
119             if_string = g_strdup_printf("%s: %s", descr, if_info->name);
120             g_free(descr);
121         } else {
122             /* No, we don't have a user-supplied description; did we get
123             one from the OS or libpcap? */
124             if (if_info->description != NULL) {
125                 /* Yes - use it. */
126                 if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
127             } else {
128                 /* No. */
129                 if_string = g_strdup(if_info->name);
130             }
131         }
132         if (if_info->loopback) {
133             device.display_name = g_strdup_printf("%s (loopback)", if_string);
134         } else {
135             device.display_name = g_strdup(if_string);
136         }
137         g_free(if_string);
138         device.selected = FALSE;
139         if (prefs_is_capture_device_hidden(if_info->name)) {
140             device.hidden = TRUE;
141         }
142         device.type = get_interface_type(if_info->name, if_info->description);
143         monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
144         caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL);
145         for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
146             temp_addr = g_malloc0(sizeof(if_addr_t));
147             if (ips != 0) {
148                 g_string_append(ip_str, "\n");
149             }
150             addr = (if_addr_t *)curr_addr->data;
151             if (addr) {
152                 temp_addr->ifat_type = addr->ifat_type;
153                 switch (addr->ifat_type) {
154                     case IF_AT_IPv4:
155                         temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
156                         g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
157                         break;
158                     case IF_AT_IPv6:
159                         memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
160                         g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
161                         break;
162                     default:
163                         /* In case we add non-IP addresses */
164                         break;
165                 }
166             } else {
167                 g_free(temp_addr);
168                 temp_addr = NULL;
169             }
170             if (temp_addr) {
171                 temp->addrs = g_slist_append(temp->addrs, temp_addr);
172             }
173         }
174 #ifdef HAVE_PCAP_REMOTE
175         device.local = TRUE;
176         device.remote_opts.src_type = CAPTURE_IFLOCAL;
177         device.remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
178         device.remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
179         device.remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
180         device.remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
181         device.remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
182         device.remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
183         device.remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
184         device.remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
185 #endif
186 #ifdef HAVE_PCAP_SETSAMPLING
187         device.remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
188         device.remote_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
189 #endif
190         linktype_count = 0;
191         device.links = NULL;
192         if (caps != NULL) {
193 #if defined(HAVE_PCAP_CREATE)
194             device.monitor_mode_enabled = monitor_mode;
195             device.monitor_mode_supported = caps->can_set_rfmon;
196 #endif
197             for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
198                 data_link_info = lt_entry->data;
199                 if (linktype_count == 0) {
200                     device.active_dlt = data_link_info->dlt;
201                 }
202                 link = (link_row *)g_malloc(sizeof(link_row));
203                 if (data_link_info->description != NULL) {
204                     link->dlt = data_link_info->dlt;
205                     link->name = g_strdup_printf("%s", data_link_info->description);
206                 } else {
207                     link->dlt = -1;
208                     link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
209                 }
210                 device.links = g_list_append(device.links, link);
211                 linktype_count++;
212             }
213         } else {
214 #if defined(HAVE_PCAP_CREATE)
215             device.monitor_mode_enabled = FALSE;
216             device.monitor_mode_supported = FALSE;
217 #endif
218             device.active_dlt = -1;
219         }
220         device.addresses = g_strdup(ip_str->str);
221         device.no_addresses = ips;
222         device.local = TRUE;
223         device.if_info = *temp;
224         device.last_packets = 0;
225         device.pmode        = global_capture_opts.default_options.promisc_mode;
226         device.has_snaplen  = global_capture_opts.default_options.has_snaplen;
227         device.snaplen      = global_capture_opts.default_options.snaplen;
228         device.cfilter      = g_strdup(global_capture_opts.default_options.cfilter);
229 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
230         device.buffer = 1;
231 #endif
232
233         if (global_capture_opts.ifaces->len > 0) {
234             for (j = 0; j < global_capture_opts.ifaces->len; j++) {
235                 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
236                 if (strcmp(interface_opts.name, device.name) == 0) {
237 #if defined(HAVE_PCAP_CREATE)
238                     device.buffer = interface_opts.buffer_size;
239                     device.monitor_mode_enabled = interface_opts.monitor_mode;
240 #endif
241                     device.pmode = interface_opts.promisc_mode;
242                     device.has_snaplen = interface_opts.has_snaplen;
243                     device.snaplen = interface_opts.snaplen;
244                     device.cfilter = g_strdup(interface_opts.cfilter);
245                     device.active_dlt = interface_opts.linktype;
246                     device.selected = TRUE;
247                     global_capture_opts.num_selected++;
248                     break;
249                 }
250             }
251         }
252         if (global_capture_opts.all_ifaces->len <= count) {
253             g_array_append_val(global_capture_opts.all_ifaces, device);
254             count = global_capture_opts.all_ifaces->len;
255         } else {
256             g_array_insert_val(global_capture_opts.all_ifaces, count, device);
257         }
258         if (caps != NULL) {
259             free_if_capabilities(caps);
260         }
261
262         g_string_free(ip_str, TRUE);
263         count++;
264     }
265     free_interface_list(if_list);
266     /* see whether there are additional interfaces in ifaces */
267     for (j = 0; j < global_capture_opts.ifaces->len; j++) {
268         interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
269         found = FALSE;
270         for (i = 0; i < (int)global_capture_opts.all_ifaces->len; i++) {
271             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
272             if (strcmp(device.name, interface_opts.name) == 0) {
273                 found = TRUE;
274                 break;
275             }
276         }
277         if (!found) {  /* new interface, maybe a pipe */
278             device.name         = g_strdup(interface_opts.name);
279             device.display_name = g_strdup_printf("%s", device.name);
280             device.hidden       = FALSE;
281             device.selected     = TRUE;
282             device.type         = IF_PIPE;
283 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
284             device.buffer = interface_opts.buffer_size;
285 #endif
286 #if defined(HAVE_PCAP_CREATE)
287             device.monitor_mode_enabled = interface_opts.monitor_mode;
288             device.monitor_mode_supported = FALSE;
289 #endif
290             device.pmode = interface_opts.promisc_mode;
291             device.has_snaplen = interface_opts.has_snaplen;
292             device.snaplen = interface_opts.snaplen;
293             device.cfilter = g_strdup(interface_opts.cfilter);
294             device.active_dlt = interface_opts.linktype;
295             device.addresses    = NULL;
296             device.no_addresses = 0;
297             device.last_packets = 0;
298             device.links        = NULL;
299             device.local        = TRUE;
300             device.locked       = FALSE;
301             device.if_info.name = g_strdup(interface_opts.name);
302             device.if_info.description = g_strdup(interface_opts.descr);
303             device.if_info.addrs = NULL;
304             device.if_info.loopback = FALSE;
305
306             g_array_append_val(global_capture_opts.all_ifaces, device);
307             global_capture_opts.num_selected++;
308         }
309     }
310 }
311
312 /*
313  * Get the global interface list.  Generate it if we haven't
314  * done so already.
315  */
316 void
317 fill_in_local_interfaces(void)
318 {
319     static gboolean initialized = FALSE;
320
321     if (!initialized) {
322         scan_local_interfaces();
323         initialized = TRUE;
324     }
325 }
326
327 void
328 hide_interface(gchar* new_hide)
329 {
330     gchar       *tok;
331     guint       i;
332     interface_t device;
333     gboolean    found = FALSE;
334     GList       *hidden_devices = NULL, *entry;
335     if (new_hide != NULL) {
336         for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
337             hidden_devices = g_list_append(hidden_devices, tok);
338         }
339     }
340     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
341         device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
342         found = FALSE;
343         for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
344             if (strcmp(entry->data, device.name)==0) {
345                 device.hidden = TRUE;
346                 if (device.selected) {
347                     device.selected = FALSE;
348                     global_capture_opts.num_selected--;
349                 }
350                 found = TRUE;
351                 break;
352             }
353         }
354         if (!found) {
355             device.hidden = FALSE;
356         }
357         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
358         g_array_insert_val(global_capture_opts.all_ifaces, i, device);
359     }
360 }
361 #endif /* HAVE_LIBPCAP */