/* XXX - We parse simple text output to get our interface list. Should * we use "real" data serialization instead, e.g. via XML? */ GList * capture_interface_list(int *err, char **err_str, void (*update_cb)(void)) { int ret; GList *if_list = NULL; int i, j; gchar *data, *primary_msg, *secondary_msg; gchar **raw_list, **if_parts, **addr_parts; gchar *name; if_info_t *if_info; if_addr_t *if_addr; g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ..."); *err = 0; /* Try to get our interface list */ ret = sync_interface_list_open(&data, &primary_msg, &secondary_msg, update_cb); if (ret != 0) { #ifdef HAVE_EXTCAP /* Add the extcap interfaces that can exist, even if no native interfaces have been found */ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Loading External Capture Interface List ..."); if_list = append_extcap_interface_list(if_list, err_str); /* err_str is ignored, as the error for the interface loading list will take precedence */ if ( g_list_length(if_list) == 0 ) { #endif g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed. Error %d, %s (%s)", *err, primary_msg ? primary_msg : "no message", secondary_msg ? secondary_msg : "no secondary message"); if (err_str) { *err_str = primary_msg; } else { g_free(primary_msg); } g_free(secondary_msg); *err = CANT_GET_INTERFACE_LIST; #ifdef HAVE_EXTCAP } #endif return if_list; } /* Split our lines */ #ifdef _WIN32 raw_list = g_strsplit(data, "\r\n", 0); #else raw_list = g_strsplit(data, "\n", 0); #endif g_free(data); for (i = 0; raw_list[i] != NULL; i++) { #ifdef HAVE_EXTCAP if_parts = g_strsplit(raw_list[i], "\t", 7); if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || if_parts[3] == NULL || if_parts[4] == NULL || if_parts[5] == NULL || if_parts[6] == NULL) { g_strfreev(if_parts); continue; } #else if_parts = g_strsplit(raw_list[i], "\t", 6); if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || if_parts[3] == NULL || if_parts[4] == NULL || if_parts[5] == NULL) { g_strfreev(if_parts); continue; } #endif /* Number followed by the name, e.g "1. eth0" */ name = strchr(if_parts[0], ' '); if (name) { name++; } else { g_strfreev(if_parts); continue; } if_info = g_new0(if_info_t,1); if_info->name = g_strdup(name); if (strlen(if_parts[1]) > 0) if_info->vendor_description = g_strdup(if_parts[1]); if (strlen(if_parts[2]) > 0) if_info->friendly_name = g_strdup(if_parts[2]); if_info->type = (interface_type)(int)strtol(if_parts[3], NULL, 10); addr_parts = g_strsplit(if_parts[4], ",", 0); for (j = 0; addr_parts[j] != NULL; j++) { if_addr = g_new0(if_addr_t,1); if (ws_inet_pton4(addr_parts[j], &if_addr->addr.ip4_addr)) { if_addr->ifat_type = IF_AT_IPv4; } else if (ws_inet_pton6(addr_parts[j], (ws_in6_addr *)&if_addr->addr.ip6_addr)) { if_addr->ifat_type = IF_AT_IPv6; } else { g_free(if_addr); if_addr = NULL; } if (if_addr) { if_info->addrs = g_slist_append(if_info->addrs, if_addr); } } if (strcmp(if_parts[5], "loopback") == 0) if_info->loopback = TRUE; #ifdef HAVE_EXTCAP if_info->extcap = g_strdup(if_parts[6]); #endif g_strfreev(if_parts); g_strfreev(addr_parts); if_list = g_list_append(if_list, if_info); } g_strfreev(raw_list); #ifdef HAVE_PCAP_REMOTE if (remote_interface_list && g_list_length(remote_interface_list) > 0) { if_list = append_remote_list(if_list); } #endif #ifdef HAVE_EXTCAP /* Add the extcap interfaces after the native and remote interfaces */ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Loading External Capture Interface List ..."); if_list = append_extcap_interface_list(if_list, err_str); #endif return if_list; }
/* XXX - We parse simple text output to get our interface list. Should * we use "real" data serialization instead, e.g. via XML? */ GList * capture_interface_list(int *err, char **err_str) { int ret; GList *if_list = NULL; int i, j; gchar *data, *primary_msg, *secondary_msg; gchar **raw_list, **if_parts, **addr_parts; gchar *name; if_info_t *if_info; if_addr_t *if_addr; g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ..."); /* Try to get our interface list */ ret = sync_interface_list_open(&data, &primary_msg, &secondary_msg); if (ret != 0) { g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!"); if (err_str) { *err_str = primary_msg; } else { g_free(primary_msg); } g_free(secondary_msg); *err = CANT_GET_INTERFACE_LIST; return NULL; } /* Split our lines */ #ifdef _WIN32 raw_list = g_strsplit(data, "\r\n", 0); #else raw_list = g_strsplit(data, "\n", 0); #endif g_free(data); for (i = 0; raw_list[i] != NULL; i++) { if_parts = g_strsplit(raw_list[i], "\t", 5); if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || if_parts[3] == NULL || if_parts[4] == NULL) { g_strfreev(if_parts); continue; } /* Number followed by the name, e.g "1. eth0" */ name = strchr(if_parts[0], ' '); if (name) { name++; } else { g_strfreev(if_parts); continue; } if_info = g_malloc0(sizeof(if_info_t)); if_info->name = g_strdup(name); if (strlen(if_parts[1]) > 0) if_info->vendor_description = g_strdup(if_parts[1]); if (strlen(if_parts[2]) > 0) if_info->friendly_name = g_strdup(if_parts[2]); addr_parts = g_strsplit(if_parts[3], ",", 0); for (j = 0; addr_parts[j] != NULL; j++) { if_addr = g_malloc0(sizeof(if_addr_t)); if (inet_pton(AF_INET, addr_parts[j], &if_addr->addr.ip4_addr)) { if_addr->ifat_type = IF_AT_IPv4; } else if (inet_pton(AF_INET6, addr_parts[j], &if_addr->addr.ip6_addr)) { if_addr->ifat_type = IF_AT_IPv6; } else { g_free(if_addr); if_addr = NULL; } if (if_addr) { if_info->addrs = g_slist_append(if_info->addrs, if_addr); } } if (strcmp(if_parts[4], "loopback") == 0) if_info->loopback = TRUE; g_strfreev(if_parts); g_strfreev(addr_parts); if_list = g_list_append(if_list, if_info); } g_strfreev(raw_list); /* Check to see if we built a list */ if (if_list == NULL) { *err = NO_INTERFACES_FOUND; if (err_str) *err_str = g_strdup("No interfaces found"); } #ifdef HAVE_PCAP_REMOTE if (remote_interface_list && g_list_length(remote_interface_list) > 0) { append_remote_list(if_list); } #endif return if_list; }