nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23  
24 #include "config.h"
25  
26 #ifdef HAVE_LIBPCAP
27  
28 #include <string.h>
29  
30 #include <glib.h>
31  
32 #include <epan/prefs.h>
33 #include <epan/to_str.h>
34  
35 #include "ui/capture_ui_utils.h"
36 #include "ui/capture_globals.h"
37 #include "ui/iface_lists.h"
38 #include "../log.h"
39  
40 /*
41 * Used when sorting an interface list into alphabetical order by
42 * their friendly names.
43 */
44 gint
45 if_list_comparator_alph(const void *first_arg, const void *second_arg)
46 {
47 const if_info_t *first = (const if_info_t *)first_arg, *second = (const if_info_t *)second_arg;
48  
49 if (first != NULL && first->friendly_name != NULL &&
50 second != NULL && second->friendly_name != NULL) {
51 return g_ascii_strcasecmp(first->friendly_name, second->friendly_name);
52 } else {
53 return 0;
54 }
55 }
56  
57 static void
58 fill_from_ifaces (interface_t *device)
59 {
60 interface_options interface_opts;
61 guint i;
62  
63 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
64 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
65 if (strcmp(interface_opts.name, device->name) != 0) {
66 continue;
67 }
68  
69 #if defined(HAVE_PCAP_CREATE)
70 device->buffer = interface_opts.buffer_size;
71 device->monitor_mode_enabled = interface_opts.monitor_mode;
72 #endif
73 device->pmode = interface_opts.promisc_mode;
74 device->has_snaplen = interface_opts.has_snaplen;
75 device->snaplen = interface_opts.snaplen;
76 g_free(device->cfilter);
77 device->cfilter = g_strdup(interface_opts.cfilter);
78 if (interface_opts.linktype != -1) {
79 device->active_dlt = interface_opts.linktype;
80 }
81 if (!device->selected) {
82 device->selected = TRUE;
83 global_capture_opts.num_selected++;
84 }
85 return;
86 }
87 }
88  
89 /*
90 * Fetch the list of local interfaces with capture_interface_list()
91 * and set the list of "all interfaces" in *capture_opts to include
92 * those interfaces.
93 */
94 void
95 scan_local_interfaces(void (*update_cb)(void))
96 {
97 GList *if_entry, *lt_entry, *if_list;
98 if_info_t *if_info, temp;
99 gchar *descr;
100 if_capabilities_t *caps=NULL;
101 gint linktype_count;
102 gboolean monitor_mode;
103 GSList *curr_addr;
104 int ips = 0, i;
105 guint count = 0, j;
106 if_addr_t *addr, *temp_addr;
107 link_row *link = NULL;
108 data_link_info_t *data_link_info;
109 interface_t device;
110 GString *ip_str;
111 interface_options interface_opts;
112 gboolean found = FALSE;
113  
114  
115 if (global_capture_opts.all_ifaces->len > 0) {
116 for (i = (int)global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
117 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
118 if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
119 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
120  
121 if (device.selected) {
122 global_capture_opts.num_selected--;
123 /* if device was to be used after this statement,
124 we should set device.selected=FALSE here */
125 }
126  
127 /* if we remove an interface from all_interfaces,
128 it must also be removed from ifaces if it is present there
129 otherwise, it would be re-added to all_interfaces below
130 (interfaces set with -i on the command line are initially present in ifaces but not
131 in all_interfaces, but these interfaces are not removed here) */
132 for (j = 0; j < global_capture_opts.ifaces->len; j++) {
133 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
134 if (strcmp(device.name, interface_opts.name) == 0) {
135 /* 2nd param must be the index of ifaces (not all_ifaces) */
136 capture_opts_del_iface(&global_capture_opts, j);
137 }
138 }
139 capture_opts_free_interface_t(&device);
140 }
141 }
142 }
143 /* Scan through the list and build a list of strings to display. */
144 g_free(global_capture_opts.ifaces_err_info);
145 if_list = capture_interface_list(&global_capture_opts.ifaces_err,
146 &global_capture_opts.ifaces_err_info,
147 update_cb);
148 count = 0;
149 for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
150 memset(&device, 0, sizeof(device));
151 if_info = (if_info_t *)if_entry->data;
152 ip_str = g_string_new("");
153 ips = 0;
154 if (strstr(if_info->name, "rpcap:")) {
155 continue;
156 }
157 device.name = g_strdup(if_info->name);
158 if (if_info->friendly_name != NULL) {
159 device.friendly_name = g_strdup(if_info->friendly_name);
160 } else {
161 device.friendly_name = NULL;
162 }
163 device.hidden = FALSE;
164 device.locked = FALSE;
165 memset(&temp, 0, sizeof(temp));
166 temp.name = g_strdup(if_info->name);
167 temp.friendly_name = g_strdup(if_info->friendly_name);
168 temp.vendor_description = g_strdup(if_info->vendor_description);
169 temp.loopback = if_info->loopback;
170 temp.type = if_info->type;
171 #ifdef HAVE_EXTCAP
172 temp.extcap = g_strdup(if_info->extcap);
173 #endif
174 /* Is this interface hidden and, if so, should we include it anyway? */
175  
176 descr = capture_dev_user_descr_find(if_info->name);
177 device.display_name = get_iface_display_name(descr, if_info);
178 g_free(descr);
179 device.selected = FALSE;
180 if (prefs_is_capture_device_hidden(if_info->name)) {
181 device.hidden = TRUE;
182 }
183 device.type = if_info->type;
184 monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
185 caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL, NULL, update_cb);
186 for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
187 temp_addr = (if_addr_t *)g_malloc0(sizeof(if_addr_t));
188 if (ips != 0) {
189 g_string_append(ip_str, "\n");
190 }
191 addr = (if_addr_t *)curr_addr->data;
192 if (addr) {
193 address addr_str;
194 char* temp_addr_str = NULL;
195 temp_addr->ifat_type = addr->ifat_type;
196 switch (addr->ifat_type) {
197 case IF_AT_IPv4:
198 temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
199 set_address(&addr_str, AT_IPv4, 4, &addr->addr.ip4_addr);
200 temp_addr_str = address_to_str(NULL, &addr_str);
201 g_string_append(ip_str, temp_addr_str);
202 break;
203 case IF_AT_IPv6:
204 memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
205 set_address(&addr_str, AT_IPv6, 16, addr->addr.ip6_addr);
206 temp_addr_str = address_to_str(NULL, &addr_str);
207 g_string_append(ip_str, temp_addr_str);
208 break;
209 default:
210 /* In case we add non-IP addresses */
211 break;
212 }
213 wmem_free(NULL, temp_addr_str);
214 } else {
215 g_free(temp_addr);
216 temp_addr = NULL;
217 }
218 if (temp_addr) {
219 temp.addrs = g_slist_append(temp.addrs, temp_addr);
220 }
221 }
222 #ifdef HAVE_PCAP_REMOTE
223 device.local = TRUE;
224 device.remote_opts.src_type = CAPTURE_IFLOCAL;
225 device.remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
226 device.remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
227 device.remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
228 device.remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
229 device.remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
230 device.remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
231 device.remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
232 device.remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
233 #endif
234 #ifdef HAVE_PCAP_SETSAMPLING
235 device.remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
236 device.remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
237 #endif
238 linktype_count = 0;
239 device.links = NULL;
240 if (caps != NULL) {
241 #if defined(HAVE_PCAP_CREATE)
242 device.monitor_mode_enabled = monitor_mode;
243 device.monitor_mode_supported = caps->can_set_rfmon;
244 #endif
245 /*
246 * Process the list of link-layer header types.
247 */
248 for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
249 data_link_info = (data_link_info_t *)lt_entry->data;
250 link = (link_row *)g_malloc(sizeof(link_row));
251 if (data_link_info->description != NULL) {
252 link->dlt = data_link_info->dlt;
253 link->name = g_strdup(data_link_info->description);
254 } else {
255 link->dlt = -1;
256 link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
257 }
258 device.links = g_list_append(device.links, link);
259 linktype_count++;
260 }
261  
262 /*
263 * Set the active DLT for the device appropriately.
264 */
265 set_active_dlt(&device, global_capture_opts.default_options.linktype);
266 } else {
267 #if defined(HAVE_PCAP_CREATE)
268 device.monitor_mode_enabled = FALSE;
269 device.monitor_mode_supported = FALSE;
270 #endif
271 device.active_dlt = -1;
272 }
273 device.addresses = g_strdup(ip_str->str);
274 device.no_addresses = ips;
275 device.local = TRUE;
276 device.if_info = temp;
277 device.last_packets = 0;
278 if (!capture_dev_user_pmode_find(if_info->name, &device.pmode)) {
279 device.pmode = global_capture_opts.default_options.promisc_mode;
280 }
281 if (!capture_dev_user_snaplen_find(if_info->name, &device.has_snaplen,
282 &device.snaplen)) {
283 device.has_snaplen = global_capture_opts.default_options.has_snaplen;
284 device.snaplen = global_capture_opts.default_options.snaplen;
285 }
286 device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
287 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
288 if ((device.buffer = capture_dev_user_buffersize_find(if_info->name)) == -1) {
289 device.buffer = global_capture_opts.default_options.buffer_size;
290 }
291 #endif
292  
293 fill_from_ifaces(&device);
294  
295 #ifdef HAVE_EXTCAP
296 /* Extcap devices start with no cached args */
297 device.external_cap_args_settings = NULL;
298 #endif
299 if (global_capture_opts.all_ifaces->len <= count) {
300 g_array_append_val(global_capture_opts.all_ifaces, device);
301 count = global_capture_opts.all_ifaces->len;
302 } else {
303 g_array_insert_val(global_capture_opts.all_ifaces, count, device);
304 }
305 if (caps != NULL) {
306 free_if_capabilities(caps);
307 }
308  
309 g_string_free(ip_str, TRUE);
310 count++;
311 }
312 free_interface_list(if_list);
313 /* see whether there are additional interfaces in ifaces */
314 for (j = 0; j < global_capture_opts.ifaces->len; j++) {
315 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
316 found = FALSE;
317 for (i = 0; i < (int)global_capture_opts.all_ifaces->len; i++) {
318 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
319 if (strcmp(device.name, interface_opts.name) == 0) {
320 found = TRUE;
321 break;
322 }
323 }
324 if (!found) { /* new interface, maybe a pipe */
325 memset(&device, 0, sizeof(device));
326 device.name = g_strdup(interface_opts.name);
327 device.display_name = interface_opts.descr ?
328 g_strdup_printf("%s: %s", device.name, interface_opts.descr) :
329 g_strdup(device.name);
330 device.hidden = FALSE;
331 device.selected = TRUE;
332 device.type = IF_PIPE;
333 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
334 device.buffer = interface_opts.buffer_size;
335 #endif
336 #if defined(HAVE_PCAP_CREATE)
337 device.monitor_mode_enabled = interface_opts.monitor_mode;
338 device.monitor_mode_supported = FALSE;
339 #endif
340 device.pmode = interface_opts.promisc_mode;
341 device.has_snaplen = interface_opts.has_snaplen;
342 device.snaplen = interface_opts.snaplen;
343 device.cfilter = g_strdup(interface_opts.cfilter);
344 device.active_dlt = interface_opts.linktype;
345 device.addresses = NULL;
346 device.no_addresses = 0;
347 device.last_packets = 0;
348 device.links = NULL;
349 device.local = TRUE;
350 device.locked = FALSE;
351 device.if_info.name = g_strdup(interface_opts.name);
352 device.if_info.friendly_name = NULL;
353 device.if_info.vendor_description = g_strdup(interface_opts.descr);
354 device.if_info.addrs = NULL;
355 device.if_info.loopback = FALSE;
356 #ifdef HAVE_EXTCAP
357 device.if_info.extcap = g_strdup(interface_opts.extcap);
358 #endif
359  
360 g_array_append_val(global_capture_opts.all_ifaces, device);
361 global_capture_opts.num_selected++;
362 }
363 }
364 }
365  
366 /*
367 * Get the global interface list. Generate it if we haven't done so
368 * already. This can be quite time consuming the first time, so
369 * record how long it takes in the info log.
370 */
371 void
372 fill_in_local_interfaces(void(*update_cb)(void))
373 {
374 GTimeVal start_time;
375 GTimeVal end_time;
376 float elapsed;
377 static gboolean initialized = FALSE;
378  
379 /* record the time we started, so we can log total time later */
380 g_get_current_time(&start_time);
381 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "fill_in_local_interfaces() starts");
382  
383 if (!initialized) {
384 /* do the actual work */
385 scan_local_interfaces(update_cb);
386 initialized = TRUE;
387 }
388 /* log how long it took */
389 g_get_current_time(&end_time);
390 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
391 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
392  
393 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "fill_in_local_interfaces() ends, taking %.3fs", elapsed);
394 }
395  
396 void
397 hide_interface(gchar* new_hide)
398 {
399 gchar *tok;
400 guint i;
401 interface_t device;
402 gboolean found = FALSE;
403 GList *hidden_devices = NULL, *entry;
404 if (new_hide != NULL) {
405 for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
406 hidden_devices = g_list_append(hidden_devices, tok);
407 }
408 }
409 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
410 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
411 found = FALSE;
412 for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
413 if (strcmp((char *)entry->data, device.name)==0) {
414 device.hidden = TRUE;
415 if (device.selected) {
416 device.selected = FALSE;
417 global_capture_opts.num_selected--;
418 }
419 found = TRUE;
420 break;
421 }
422 }
423 if (!found) {
424 device.hidden = FALSE;
425 }
426 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
427 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
428 }
429 g_list_free(hidden_devices);
430 g_free(new_hide);
431 }
432  
433 void
434 update_local_interfaces(void)
435 {
436 interface_t device;
437 gchar *descr;
438 guint i;
439  
440 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
441 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
442 device.type = capture_dev_user_linktype_find(device.name);
443 g_free (device.display_name);
444 descr = capture_dev_user_descr_find(device.name);
445 device.display_name = get_iface_display_name(descr, &device.if_info);
446 g_free (descr);
447 device.hidden = prefs_is_capture_device_hidden(device.name);
448 fill_from_ifaces(&device);
449  
450 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
451 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
452 }
453 }
454 #endif /* HAVE_LIBPCAP */
455  
456 /*
457 * Editor modelines
458 *
459 * Local Variables:
460 * c-basic-offset: 4
461 * tab-width: 8
462 * indent-tabs-mode: nil
463 * End:
464 *
465 * ex: set shiftwidth=4 tabstop=8 expandtab:
466 * :indentSize=4:tabSize=8:noTabs=true:
467 */