MSWSP: WIP: dissect_CPMSetBindings()
[wireshark-wip.git] / ui / iface_lists.c
blobbaefd24f0dcaab583192b73fa92842783bcd4a52
1 /* iface_lists.c
2 * Code to manage the global list of interfaces and to update widgets/windows
3 * displaying items from those lists
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
26 #include "config.h"
28 #ifdef HAVE_LIBPCAP
30 #include <string.h>
32 #include <glib.h>
34 #include <epan/prefs.h>
35 #include <epan/to_str.h>
37 #include "../capture_ui_utils.h"
39 #include "ui/capture_globals.h"
40 #include "ui/iface_lists.h"
41 #include "../log.h"
44 * Used when sorting an interface list into alphabetical order by
45 * their friendly names.
47 gint
48 if_list_comparator_alph(const void *first_arg, const void *second_arg)
50 const if_info_t *first = (const if_info_t *)first_arg, *second = (const if_info_t *)second_arg;
52 if (first != NULL && first->friendly_name != NULL &&
53 second != NULL && second->friendly_name != NULL) {
54 return g_ascii_strcasecmp(first->friendly_name, second->friendly_name);
55 } else {
56 return 0;
61 * Fetch the list of local interfaces with capture_interface_list()
62 * and set the list of "all interfaces" in *capture_opts to include
63 * those interfaces.
65 void
66 scan_local_interfaces(void (*update_cb)(void))
68 GList *if_entry, *lt_entry, *if_list;
69 if_info_t *if_info, *temp;
70 char *if_string;
71 gchar *descr;
72 if_capabilities_t *caps=NULL;
73 gint linktype_count;
74 gboolean monitor_mode;
75 GSList *curr_addr;
76 int ips = 0, i, err;
77 guint count = 0, j;
78 if_addr_t *addr, *temp_addr;
79 link_row *link = NULL;
80 data_link_info_t *data_link_info;
81 interface_t device;
82 GString *ip_str;
83 interface_options interface_opts;
84 gboolean found = FALSE;
87 if (global_capture_opts.all_ifaces->len > 0) {
88 for (i = (int)global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
89 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
90 if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
91 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
96 /* Scan through the list and build a list of strings to display. */
97 if_list = capture_interface_list(&err, NULL, update_cb);
98 count = 0;
99 for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
100 if_info = (if_info_t *)if_entry->data;
101 ip_str = g_string_new("");
102 ips = 0;
103 if (strstr(if_info->name, "rpcap:")) {
104 continue;
106 device.name = g_strdup(if_info->name);
107 if (if_info->friendly_name != NULL) {
108 device.friendly_name = g_strdup(if_info->friendly_name);
109 } else {
110 device.friendly_name = NULL;
112 device.hidden = FALSE;
113 device.locked = FALSE;
114 temp = (if_info_t *)g_malloc0(sizeof(if_info_t));
115 temp->name = g_strdup(if_info->name);
116 temp->friendly_name = g_strdup(if_info->friendly_name);
117 temp->vendor_description = g_strdup(if_info->vendor_description);
118 temp->loopback = if_info->loopback;
119 /* Is this interface hidden and, if so, should we include it anyway? */
121 /* Do we have a user-supplied description? */
122 descr = capture_dev_user_descr_find(if_info->name);
123 if (descr != NULL) {
124 /* Yes, we have a user-supplied description; use it. */
125 if_string = g_strdup_printf("%s: %s", descr, if_info->name);
126 g_free(descr);
127 } else {
128 /* No, we don't have a user-supplied description; did we get
129 one from the OS or libpcap? */
130 if (if_info->friendly_name != NULL) {
131 /* We have a friendly name from the OS, use it */
132 #ifdef _WIN32
134 * On Windows, if we have a friendly name, just show it,
135 * don't show the name, as that's a string made out of
136 * the device GUID, and not at all friendly.
138 if_string = g_strdup_printf("%s", if_info->friendly_name);
139 #else
141 * On UN*X, if we have a friendly name, show it along
142 * with the interface name; the interface name is short
143 * and somewhat friendly, and many UN*X users are used
144 * to interface names, so we should show it.
146 if_string = g_strdup_printf("%s: %s", if_info->friendly_name, if_info->name);
147 #endif
148 } else if (if_info->vendor_description != NULL) {
149 /* We have a device description from libpcap - use it. */
150 if_string = g_strdup_printf("%s: %s", if_info->vendor_description, if_info->name);
151 } else {
152 /* No. */
153 if_string = g_strdup(if_info->name);
156 device.display_name = if_string;
157 device.selected = FALSE;
158 if (prefs_is_capture_device_hidden(if_info->name)) {
159 device.hidden = TRUE;
161 device.type = if_info->type;
162 monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
163 caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL, update_cb);
164 for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
165 temp_addr = (if_addr_t *)g_malloc0(sizeof(if_addr_t));
166 if (ips != 0) {
167 g_string_append(ip_str, "\n");
169 addr = (if_addr_t *)curr_addr->data;
170 if (addr) {
171 temp_addr->ifat_type = addr->ifat_type;
172 switch (addr->ifat_type) {
173 case IF_AT_IPv4:
174 temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
175 g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
176 break;
177 case IF_AT_IPv6:
178 memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
179 g_string_append(ip_str, ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
180 break;
181 default:
182 /* In case we add non-IP addresses */
183 break;
185 } else {
186 g_free(temp_addr);
187 temp_addr = NULL;
189 if (temp_addr) {
190 temp->addrs = g_slist_append(temp->addrs, temp_addr);
193 #ifdef HAVE_PCAP_REMOTE
194 device.local = TRUE;
195 device.remote_opts.src_type = CAPTURE_IFLOCAL;
196 device.remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
197 device.remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
198 device.remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
199 device.remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
200 device.remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
201 device.remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
202 device.remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
203 device.remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
204 #endif
205 #ifdef HAVE_PCAP_SETSAMPLING
206 device.remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
207 device.remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
208 #endif
209 linktype_count = 0;
210 device.links = NULL;
211 if (caps != NULL) {
212 #if defined(HAVE_PCAP_CREATE)
213 device.monitor_mode_enabled = monitor_mode;
214 device.monitor_mode_supported = caps->can_set_rfmon;
215 #endif
216 for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
217 data_link_info = (data_link_info_t *)lt_entry->data;
218 if (linktype_count == 0) {
219 device.active_dlt = data_link_info->dlt;
221 link = (link_row *)g_malloc(sizeof(link_row));
222 if (data_link_info->description != NULL) {
223 link->dlt = data_link_info->dlt;
224 link->name = g_strdup_printf("%s", data_link_info->description);
225 } else {
226 link->dlt = -1;
227 link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
229 device.links = g_list_append(device.links, link);
230 linktype_count++;
232 if (linktype_count > 0) {
233 if ((device.active_dlt = capture_dev_user_linktype_find(if_info->name)) == -1) {
234 device.active_dlt = global_capture_opts.default_options.linktype;
237 } else {
238 #if defined(HAVE_PCAP_CREATE)
239 device.monitor_mode_enabled = FALSE;
240 device.monitor_mode_supported = FALSE;
241 #endif
242 device.active_dlt = -1;
244 device.addresses = g_strdup(ip_str->str);
245 device.no_addresses = ips;
246 device.local = TRUE;
247 device.if_info = *temp;
248 device.last_packets = 0;
249 if ((device.pmode = capture_dev_user_pmode_find(if_info->name)) == -1) {
250 device.pmode = global_capture_opts.default_options.promisc_mode;
252 if ((device.has_snaplen = capture_dev_user_hassnap_find(if_info->name)) == -1) {
253 device.has_snaplen = global_capture_opts.default_options.has_snaplen;
255 if (capture_dev_user_snaplen_find(if_info->name) == -1) {
256 device.snaplen = global_capture_opts.default_options.snaplen;
257 } else {
258 device.snaplen = (guint)capture_dev_user_snaplen_find(if_info->name);
260 device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
261 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
262 if ((device.buffer = capture_dev_user_buffersize_find(if_info->name)) == -1) {
263 device.buffer = global_capture_opts.default_options.buffer_size;
265 #endif
267 if (global_capture_opts.ifaces->len > 0) {
268 for (j = 0; j < global_capture_opts.ifaces->len; j++) {
269 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
270 if (strcmp(interface_opts.name, device.name) == 0) {
271 #if defined(HAVE_PCAP_CREATE)
272 device.buffer = interface_opts.buffer_size;
273 device.monitor_mode_enabled = interface_opts.monitor_mode;
274 #endif
275 device.pmode = interface_opts.promisc_mode;
276 device.has_snaplen = interface_opts.has_snaplen;
277 device.snaplen = interface_opts.snaplen;
278 device.cfilter = g_strdup(interface_opts.cfilter);
279 if (interface_opts.linktype != -1) {
280 device.active_dlt = interface_opts.linktype;
282 device.selected = TRUE;
283 global_capture_opts.num_selected++;
284 break;
288 if (global_capture_opts.all_ifaces->len <= count) {
289 g_array_append_val(global_capture_opts.all_ifaces, device);
290 count = global_capture_opts.all_ifaces->len;
291 } else {
292 g_array_insert_val(global_capture_opts.all_ifaces, count, device);
294 if (caps != NULL) {
295 free_if_capabilities(caps);
298 g_string_free(ip_str, TRUE);
299 count++;
301 free_interface_list(if_list);
302 /* see whether there are additional interfaces in ifaces */
303 for (j = 0; j < global_capture_opts.ifaces->len; j++) {
304 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
305 found = FALSE;
306 for (i = 0; i < (int)global_capture_opts.all_ifaces->len; i++) {
307 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
308 if (strcmp(device.name, interface_opts.name) == 0) {
309 found = TRUE;
310 break;
313 if (!found) { /* new interface, maybe a pipe */
314 device.name = g_strdup(interface_opts.name);
315 device.display_name = g_strdup_printf("%s: %s", device.name, interface_opts.descr);
316 device.hidden = FALSE;
317 device.selected = TRUE;
318 device.type = IF_PIPE;
319 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
320 device.buffer = interface_opts.buffer_size;
321 #endif
322 #if defined(HAVE_PCAP_CREATE)
323 device.monitor_mode_enabled = interface_opts.monitor_mode;
324 device.monitor_mode_supported = FALSE;
325 #endif
326 device.pmode = interface_opts.promisc_mode;
327 device.has_snaplen = interface_opts.has_snaplen;
328 device.snaplen = interface_opts.snaplen;
329 device.cfilter = g_strdup(interface_opts.cfilter);
330 device.active_dlt = interface_opts.linktype;
331 device.addresses = NULL;
332 device.no_addresses = 0;
333 device.last_packets = 0;
334 device.links = NULL;
335 device.local = TRUE;
336 device.locked = FALSE;
337 device.if_info.name = g_strdup(interface_opts.name);
338 device.if_info.friendly_name = NULL;
339 device.if_info.vendor_description = g_strdup(interface_opts.descr);
340 device.if_info.addrs = NULL;
341 device.if_info.loopback = FALSE;
343 g_array_append_val(global_capture_opts.all_ifaces, device);
344 global_capture_opts.num_selected++;
350 * Get the global interface list. Generate it if we haven't done so
351 * already. This can be quite time consuming the first time, so
352 * record how long it takes in the info log.
354 void
355 fill_in_local_interfaces(void(*update_cb)(void))
357 GTimeVal start_time;
358 GTimeVal end_time;
359 float elapsed;
360 static gboolean initialized = FALSE;
362 /* record the time we started, so we can log total time later */
363 g_get_current_time(&start_time);
364 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "fill_in_local_interfaces() starts");
366 if (!initialized) {
367 /* do the actual work */
368 scan_local_interfaces(update_cb);
369 initialized = TRUE;
371 /* log how long it took */
372 g_get_current_time(&end_time);
373 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
374 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
376 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "fill_in_local_interfaces() ends, taking %.3fs", elapsed);
379 void
380 hide_interface(gchar* new_hide)
382 gchar *tok;
383 guint i;
384 interface_t device;
385 gboolean found = FALSE;
386 GList *hidden_devices = NULL, *entry;
387 if (new_hide != NULL) {
388 for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
389 hidden_devices = g_list_append(hidden_devices, tok);
392 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
393 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
394 found = FALSE;
395 for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
396 if (strcmp((char *)entry->data, device.name)==0) {
397 device.hidden = TRUE;
398 if (device.selected) {
399 device.selected = FALSE;
400 global_capture_opts.num_selected--;
402 found = TRUE;
403 break;
406 if (!found) {
407 device.hidden = FALSE;
409 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
410 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
413 #endif /* HAVE_LIBPCAP */
416 * Editor modelines
418 * Local Variables:
419 * c-basic-offset: 4
420 * tab-width: 8
421 * indent-tabs-mode: nil
422 * End:
424 * ex: set shiftwidth=4 tabstop=8 expandtab:
425 * :indentSize=4:tabSize=8:noTabs=true: