Пример #1
0
/*
 * Fetch the list of local interfaces with capture_interface_list()
 * and set the list of "all interfaces" in *capture_opts to include
 * those interfaces.
 */
void
scan_local_interfaces(void)
{
    GList             *if_entry, *lt_entry, *if_list;
    if_info_t         *if_info, *temp;
    char              *if_string;
    gchar             *descr;
    if_capabilities_t *caps=NULL;
    gint              linktype_count;
    gboolean          monitor_mode;
    GSList            *curr_addr;
    int               ips = 0, i, err;
    guint             count = 0, j;
    if_addr_t         *addr, *temp_addr;
    link_row          *link = NULL;
    data_link_info_t  *data_link_info;
    interface_t       device;
    GString           *ip_str;
    interface_options interface_opts;
    gboolean          found = FALSE;


    if (global_capture_opts.all_ifaces->len > 0) {
        for (i = (int)global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
            if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
                global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
            }
        }
    }

    /* Scan through the list and build a list of strings to display. */
    if_list = capture_interface_list(&err, NULL);
    count = 0;
    for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
        if_info = (if_info_t *)if_entry->data;
        ip_str = g_string_new("");
        ips = 0;
        if (strstr(if_info->name, "rpcap:")) {
            continue;
        }
        device.name = g_strdup(if_info->name);
        if (if_info->friendly_name != NULL) {
            device.friendly_name = g_strdup(if_info->friendly_name);
        } else {
            device.friendly_name = NULL;
        }
        device.hidden = FALSE;
        device.locked = FALSE;
        temp = (if_info_t *)g_malloc0(sizeof(if_info_t));
        temp->name = g_strdup(if_info->name);
        temp->friendly_name = g_strdup(if_info->friendly_name);
        temp->vendor_description = g_strdup(if_info->vendor_description);
        temp->loopback = if_info->loopback;
        /* Is this interface hidden and, if so, should we include it anyway? */

        /* Do we have a user-supplied description? */
        descr = capture_dev_user_descr_find(if_info->name);
        if (descr != NULL) {
            /* Yes, we have a user-supplied description; use it. */
            if_string = g_strdup_printf("%s: %s", descr, if_info->name);
            g_free(descr);
        } else {
            /* No, we don't have a user-supplied description; did we get
            one from the OS or libpcap? */
            if (if_info->friendly_name != NULL) {
                /* We have a friendly name from the OS, use it */
#ifdef _WIN32
                /*
                 * On Windows, if we have a friendly name, just show it,
                 * don't show the name, as that's a string made out of
                 * the device GUID, and not at all friendly.
                 */
                if_string = g_strdup_printf("%s", if_info->friendly_name);
#else
		/*
		 * On UN*X, if we have a friendly name, show it along
		 * with the interface name; the interface name is short
		 * and somewhat friendly, and many UN*X users are used
		 * to interface names, so we should show it.
		 */
                if_string = g_strdup_printf("%s: %s", if_info->friendly_name, if_info->name);
#endif
            } else if (if_info->vendor_description != NULL) {
                /* We have a device description from libpcap - use it. */
                if_string = g_strdup_printf("%s: %s", if_info->vendor_description, if_info->name);
            } else {
                /* No. */
                if_string = g_strdup(if_info->name);
            }
        }
        device.display_name = if_string;
        device.selected = FALSE;
        if (prefs_is_capture_device_hidden(if_info->name)) {
            device.hidden = TRUE;
        }
        device.type = if_info->type;
        monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
        caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL);
        for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
            temp_addr = (if_addr_t *)g_malloc0(sizeof(if_addr_t));
            if (ips != 0) {
                g_string_append(ip_str, "\n");
            }
            addr = (if_addr_t *)curr_addr->data;
            if (addr) {
                temp_addr->ifat_type = addr->ifat_type;
                switch (addr->ifat_type) {
                    case IF_AT_IPv4:
                        temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
                        g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
                        break;
                    case IF_AT_IPv6:
                        memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
                        g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
                        break;
                    default:
                        /* In case we add non-IP addresses */
                        break;
                }
            } else {
                g_free(temp_addr);
                temp_addr = NULL;
            }
            if (temp_addr) {
                temp->addrs = g_slist_append(temp->addrs, temp_addr);
            }
        }
#ifdef HAVE_PCAP_REMOTE
        device.local = TRUE;
        device.remote_opts.src_type = CAPTURE_IFLOCAL;
        device.remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
        device.remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
        device.remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
        device.remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
        device.remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
        device.remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
        device.remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
        device.remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
#endif
#ifdef HAVE_PCAP_SETSAMPLING
        device.remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
        device.remote_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
#endif
        linktype_count = 0;
        device.links = NULL;
        if (caps != NULL) {
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = monitor_mode;
            device.monitor_mode_supported = caps->can_set_rfmon;
#endif
            for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
                data_link_info = (data_link_info_t *)lt_entry->data;
                if (linktype_count == 0) {
                    device.active_dlt = data_link_info->dlt;
                }
                link = (link_row *)g_malloc(sizeof(link_row));
                if (data_link_info->description != NULL) {
                    link->dlt = data_link_info->dlt;
                    link->name = g_strdup_printf("%s", data_link_info->description);
                } else {
                    link->dlt = -1;
                    link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
                }
                device.links = g_list_append(device.links, link);
                linktype_count++;
            }
        } else {
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = FALSE;
            device.monitor_mode_supported = FALSE;
#endif
            device.active_dlt = -1;
        }
        device.addresses = g_strdup(ip_str->str);
        device.no_addresses = ips;
        device.local = TRUE;
        device.if_info = *temp;
        device.last_packets = 0;
        if ((device.pmode = capture_dev_user_pmode_find(if_info->name)) == -1) {
            device.pmode = global_capture_opts.default_options.promisc_mode;
        }
        if ((device.has_snaplen = capture_dev_user_hassnap_find(if_info->name)) == -1) {
            device.has_snaplen = global_capture_opts.default_options.has_snaplen;
        }
        if (capture_dev_user_snaplen_find(if_info->name) == -1) {
            device.snaplen = global_capture_opts.default_options.snaplen;
        } else {
            device.snaplen = (guint)capture_dev_user_snaplen_find(if_info->name);
        }
        device.cfilter      = g_strdup(global_capture_opts.default_options.cfilter);
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
        if ((device.buffer = capture_dev_user_buffersize_find(if_info->name)) == -1) {
            device.buffer = global_capture_opts.default_options.buffer_size;
        }
#endif

        if (global_capture_opts.ifaces->len > 0) {
            for (j = 0; j < global_capture_opts.ifaces->len; j++) {
                interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
                if (strcmp(interface_opts.name, device.name) == 0) {
#if defined(HAVE_PCAP_CREATE)
                    device.buffer = interface_opts.buffer_size;
                    device.monitor_mode_enabled = interface_opts.monitor_mode;
#endif
                    device.pmode = interface_opts.promisc_mode;
                    device.has_snaplen = interface_opts.has_snaplen;
                    device.snaplen = interface_opts.snaplen;
                    device.cfilter = g_strdup(interface_opts.cfilter);
                    if (interface_opts.linktype != -1) {
                        device.active_dlt = interface_opts.linktype;
                    }
                    device.selected = TRUE;
                    global_capture_opts.num_selected++;
                    break;
                }
            }
        }
        if (global_capture_opts.all_ifaces->len <= count) {
            g_array_append_val(global_capture_opts.all_ifaces, device);
            count = global_capture_opts.all_ifaces->len;
        } else {
            g_array_insert_val(global_capture_opts.all_ifaces, count, device);
        }
        if (caps != NULL) {
            free_if_capabilities(caps);
        }

        g_string_free(ip_str, TRUE);
        count++;
    }
    free_interface_list(if_list);
    /* see whether there are additional interfaces in ifaces */
    for (j = 0; j < global_capture_opts.ifaces->len; j++) {
        interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
        found = FALSE;
        for (i = 0; i < (int)global_capture_opts.all_ifaces->len; i++) {
            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
            if (strcmp(device.name, interface_opts.name) == 0) {
                found = TRUE;
                break;
            }
        }
        if (!found) {  /* new interface, maybe a pipe */
            device.name         = g_strdup(interface_opts.name);
            device.display_name = g_strdup_printf("%s: %s", device.name, interface_opts.descr);
            device.hidden       = FALSE;
            device.selected     = TRUE;
            device.type         = IF_PIPE;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
            device.buffer = interface_opts.buffer_size;
#endif
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = interface_opts.monitor_mode;
            device.monitor_mode_supported = FALSE;
#endif
            device.pmode = interface_opts.promisc_mode;
            device.has_snaplen = interface_opts.has_snaplen;
            device.snaplen = interface_opts.snaplen;
            device.cfilter = g_strdup(interface_opts.cfilter);
            device.active_dlt = interface_opts.linktype;
            device.addresses    = NULL;
            device.no_addresses = 0;
            device.last_packets = 0;
            device.links        = NULL;
            device.local        = TRUE;
            device.locked       = FALSE;
            device.if_info.name = g_strdup(interface_opts.name);
            device.if_info.friendly_name = NULL;
            device.if_info.vendor_description = g_strdup(interface_opts.descr);
            device.if_info.addrs = NULL;
            device.if_info.loopback = FALSE;

            g_array_append_val(global_capture_opts.all_ifaces, device);
            global_capture_opts.num_selected++;
        }
    }
}
Пример #2
0
/*
 * Fetch the list of local interfaces with capture_interface_list()
 * and set the list of "all interfaces" in *capture_opts to include
 * those interfaces.
 */
void
scan_local_interfaces(void (*update_cb)(void))
{
    GList             *if_entry, *lt_entry, *if_list;
    if_info_t         *if_info, temp;
    gchar             *descr;
    if_capabilities_t *caps=NULL;
    gint              linktype_count;
    gboolean          monitor_mode;
    GSList            *curr_addr;
    int               ips = 0, i;
    guint             count = 0, j;
    if_addr_t         *addr, *temp_addr;
    link_row          *link = NULL;
    data_link_info_t  *data_link_info;
    interface_t       device;
    GString           *ip_str;
    interface_options interface_opts;
    gboolean          found = FALSE;


    if (global_capture_opts.all_ifaces->len > 0) {
        for (i = (int)global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
            if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
                global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);

                if (device.selected) {
                    global_capture_opts.num_selected--;
                    /* if device was to be used after this statement,
                       we should set device.selected=FALSE here */
                }

                /* if we remove an interface from all_interfaces,
                   it must also be removed from ifaces if it is present there
                   otherwise, it would be re-added to all_interfaces below
                   (interfaces set with -i on the command line are initially present in ifaces but not
                   in all_interfaces, but these interfaces are not removed here) */
                for (j = 0; j < global_capture_opts.ifaces->len; j++) {
                    interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
                    if (strcmp(device.name, interface_opts.name) == 0) {
                        /* 2nd param must be the index of ifaces (not all_ifaces) */
                        capture_opts_del_iface(&global_capture_opts, j);
                    }
                }
                capture_opts_free_interface_t(&device);
            }
        }
    }
    /* Scan through the list and build a list of strings to display. */
    g_free(global_capture_opts.ifaces_err_info);
    if_list = capture_interface_list(&global_capture_opts.ifaces_err,
                                     &global_capture_opts.ifaces_err_info,
                                     update_cb);
    count = 0;
    for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
        memset(&device, 0, sizeof(device));
        if_info = (if_info_t *)if_entry->data;
        ip_str = g_string_new("");
        ips = 0;
        if (strstr(if_info->name, "rpcap:")) {
            continue;
        }
        device.name = g_strdup(if_info->name);
        if (if_info->friendly_name != NULL) {
            device.friendly_name = g_strdup(if_info->friendly_name);
        } else {
            device.friendly_name = NULL;
        }
        device.hidden = FALSE;
        device.locked = FALSE;
        memset(&temp, 0, sizeof(temp));
        temp.name = g_strdup(if_info->name);
        temp.friendly_name = g_strdup(if_info->friendly_name);
        temp.vendor_description = g_strdup(if_info->vendor_description);
        temp.loopback = if_info->loopback;
        temp.type = if_info->type;
#ifdef HAVE_EXTCAP
        temp.extcap = g_strdup(if_info->extcap);
#endif
        /* Is this interface hidden and, if so, should we include it anyway? */

        descr = capture_dev_user_descr_find(if_info->name);
        device.display_name = get_iface_display_name(descr, if_info);
        g_free(descr);
        device.selected = FALSE;
        if (prefs_is_capture_device_hidden(if_info->name)) {
            device.hidden = TRUE;
        }
        device.type = if_info->type;
        monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
        caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL, NULL, update_cb);
        for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
            temp_addr = (if_addr_t *)g_malloc0(sizeof(if_addr_t));
            if (ips != 0) {
                g_string_append(ip_str, "\n");
            }
            addr = (if_addr_t *)curr_addr->data;
            if (addr) {
                address addr_str;
                char* temp_addr_str = NULL;
                temp_addr->ifat_type = addr->ifat_type;
                switch (addr->ifat_type) {
                    case IF_AT_IPv4:
                        temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
                        set_address(&addr_str, AT_IPv4, 4, &addr->addr.ip4_addr);
                        temp_addr_str = address_to_str(NULL, &addr_str);
                        g_string_append(ip_str, temp_addr_str);
                        break;
                    case IF_AT_IPv6:
                        memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
                        set_address(&addr_str, AT_IPv6, 16, addr->addr.ip6_addr);
                        temp_addr_str = address_to_str(NULL, &addr_str);
                        g_string_append(ip_str, temp_addr_str);
                        break;
                    default:
                        /* In case we add non-IP addresses */
                        break;
                }
                wmem_free(NULL, temp_addr_str);
            } else {
                g_free(temp_addr);
                temp_addr = NULL;
            }
            if (temp_addr) {
                temp.addrs = g_slist_append(temp.addrs, temp_addr);
            }
        }
#ifdef HAVE_PCAP_REMOTE
        device.local = TRUE;
        device.remote_opts.src_type = CAPTURE_IFLOCAL;
        device.remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
        device.remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
        device.remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
        device.remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
        device.remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
        device.remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
        device.remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
        device.remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
#endif
#ifdef HAVE_PCAP_SETSAMPLING
        device.remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
        device.remote_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
#endif
        linktype_count = 0;
        device.links = NULL;
        if (caps != NULL) {
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = monitor_mode;
            device.monitor_mode_supported = caps->can_set_rfmon;
#endif
            /*
             * Process the list of link-layer header types.
             */
            for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
                data_link_info = (data_link_info_t *)lt_entry->data;
                link = (link_row *)g_malloc(sizeof(link_row));
                if (data_link_info->description != NULL) {
                    link->dlt = data_link_info->dlt;
                    link->name = g_strdup_printf("%s", data_link_info->description);
                } else {
                    link->dlt = -1;
                    link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
                }
                device.links = g_list_append(device.links, link);
                linktype_count++;
            }

            /*
             * Set the active DLT for the device appropriately.
             */
            set_active_dlt(&device, global_capture_opts.default_options.linktype);
        } else {
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = FALSE;
            device.monitor_mode_supported = FALSE;
#endif
            device.active_dlt = -1;
        }
        device.addresses = g_strdup(ip_str->str);
        device.no_addresses = ips;
        device.local = TRUE;
        device.if_info = temp;
        device.last_packets = 0;
        if (!capture_dev_user_pmode_find(if_info->name, &device.pmode)) {
            device.pmode = global_capture_opts.default_options.promisc_mode;
        }
        if (!capture_dev_user_snaplen_find(if_info->name, &device.has_snaplen,
                                           &device.snaplen)) {
            device.has_snaplen = global_capture_opts.default_options.has_snaplen;
            device.snaplen = global_capture_opts.default_options.snaplen;
        }
        device.cfilter      = g_strdup(global_capture_opts.default_options.cfilter);
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
        if ((device.buffer = capture_dev_user_buffersize_find(if_info->name)) == -1) {
            device.buffer = global_capture_opts.default_options.buffer_size;
        }
#endif

        fill_from_ifaces(&device);

#ifdef HAVE_EXTCAP
        /* Extcap devices start with no cached args */
        device.external_cap_args_settings = NULL;
#endif
        if (global_capture_opts.all_ifaces->len <= count) {
            g_array_append_val(global_capture_opts.all_ifaces, device);
            count = global_capture_opts.all_ifaces->len;
        } else {
            g_array_insert_val(global_capture_opts.all_ifaces, count, device);
        }
        if (caps != NULL) {
            free_if_capabilities(caps);
        }

        g_string_free(ip_str, TRUE);
        count++;
    }
    free_interface_list(if_list);
    /* see whether there are additional interfaces in ifaces */
    for (j = 0; j < global_capture_opts.ifaces->len; j++) {
        interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
        found = FALSE;
        for (i = 0; i < (int)global_capture_opts.all_ifaces->len; i++) {
            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
            if (strcmp(device.name, interface_opts.name) == 0) {
                found = TRUE;
                break;
            }
        }
        if (!found) {  /* new interface, maybe a pipe */
            memset(&device, 0, sizeof(device));
            device.name         = g_strdup(interface_opts.name);
            device.display_name = interface_opts.descr ?
                g_strdup_printf("%s: %s", device.name, interface_opts.descr) :
                g_strdup_printf("%s", device.name);
            device.hidden       = FALSE;
            device.selected     = TRUE;
            device.type         = IF_PIPE;
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
            device.buffer = interface_opts.buffer_size;
#endif
#if defined(HAVE_PCAP_CREATE)
            device.monitor_mode_enabled = interface_opts.monitor_mode;
            device.monitor_mode_supported = FALSE;
#endif
            device.pmode = interface_opts.promisc_mode;
            device.has_snaplen = interface_opts.has_snaplen;
            device.snaplen = interface_opts.snaplen;
            device.cfilter = g_strdup(interface_opts.cfilter);
            device.active_dlt = interface_opts.linktype;
            device.addresses    = NULL;
            device.no_addresses = 0;
            device.last_packets = 0;
            device.links        = NULL;
            device.local        = TRUE;
            device.locked       = FALSE;
            device.if_info.name = g_strdup(interface_opts.name);
            device.if_info.friendly_name = NULL;
            device.if_info.vendor_description = g_strdup(interface_opts.descr);
            device.if_info.addrs = NULL;
            device.if_info.loopback = FALSE;
#ifdef HAVE_EXTCAP
            device.if_info.extcap = g_strdup(interface_opts.extcap);
#endif

            g_array_append_val(global_capture_opts.all_ifaces, device);
            global_capture_opts.num_selected++;
        }
    }
}