2 * Code to manage the global list of interfaces and to update widgets/windows
3 * displaying items from those lists
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.
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"
44 * Used when sorting an interface list into alphabetical order by
45 * their friendly names.
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
);
61 * Fetch the list of local interfaces with capture_interface_list()
62 * and set the list of "all interfaces" in *capture_opts to include
66 scan_local_interfaces(void (*update_cb
)(void))
68 GList
*if_entry
, *lt_entry
, *if_list
;
69 if_info_t
*if_info
, *temp
;
72 if_capabilities_t
*caps
=NULL
;
74 gboolean monitor_mode
;
78 if_addr_t
*addr
, *temp_addr
;
79 link_row
*link
= NULL
;
80 data_link_info_t
*data_link_info
;
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
);
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("");
103 if (strstr(if_info
->name
, "rpcap:")) {
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
);
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
);
124 /* Yes, we have a user-supplied description; use it. */
125 if_string
= g_strdup_printf("%s: %s", descr
, if_info
->name
);
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 */
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
);
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
);
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
);
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
));
167 g_string_append(ip_str
, "\n");
169 addr
= (if_addr_t
*)curr_addr
->data
;
171 temp_addr
->ifat_type
= addr
->ifat_type
;
172 switch (addr
->ifat_type
) {
174 temp_addr
->addr
.ip4_addr
= addr
->addr
.ip4_addr
;
175 g_string_append(ip_str
, ip_to_str((guint8
*)&addr
->addr
.ip4_addr
));
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
));
182 /* In case we add non-IP addresses */
190 temp
->addrs
= g_slist_append(temp
->addrs
, temp_addr
);
193 #ifdef HAVE_PCAP_REMOTE
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
;
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
;
212 #if defined(HAVE_PCAP_CREATE)
213 device
.monitor_mode_enabled
= monitor_mode
;
214 device
.monitor_mode_supported
= caps
->can_set_rfmon
;
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
);
227 link
->name
= g_strdup_printf("%s (not supported)", data_link_info
->name
);
229 device
.links
= g_list_append(device
.links
, link
);
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
;
238 #if defined(HAVE_PCAP_CREATE)
239 device
.monitor_mode_enabled
= FALSE
;
240 device
.monitor_mode_supported
= FALSE
;
242 device
.active_dlt
= -1;
244 device
.addresses
= g_strdup(ip_str
->str
);
245 device
.no_addresses
= ips
;
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
;
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
;
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
;
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
++;
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
;
292 g_array_insert_val(global_capture_opts
.all_ifaces
, count
, device
);
295 free_if_capabilities(caps
);
298 g_string_free(ip_str
, TRUE
);
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
);
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) {
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
;
322 #if defined(HAVE_PCAP_CREATE)
323 device
.monitor_mode_enabled
= interface_opts
.monitor_mode
;
324 device
.monitor_mode_supported
= FALSE
;
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;
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.
355 fill_in_local_interfaces(void(*update_cb
)(void))
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");
367 /* do the actual work */
368 scan_local_interfaces(update_cb
);
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
);
380 hide_interface(gchar
* new_hide
)
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
);
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
--;
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 */
421 * indent-tabs-mode: nil
424 * ex: set shiftwidth=4 tabstop=8 expandtab:
425 * :indentSize=4:tabSize=8:noTabs=true: