*
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
#include <glib.h>
#ifdef HAVE_LIBPCAP
+#ifdef HAVE_PCAP_FINDALLDEVS
+
+#include <pcap.h>
+
+#else /* HAVE_PCAP_FINDALLDEVS */
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
#endif
-#include <pcap.h>
-
/*
* Keep Digital UNIX happy when including <net/if.h>.
*/
# include <sys/sockio.h>
#endif
+#include "capture-pcap-util.h"
+
+#endif /* HAVE_PCAP_FINDALLDEVS */
+
+#include "capture_ifinfo.h"
#include "capture-pcap-util.h"
#include "capture-pcap-util-int.h"
-#ifndef HAVE_PCAP_FINDALLDEVS
+#ifdef HAVE_PCAP_REMOTE
+GList *
+get_remote_interface_list(const char *hostname, const char *port,
+ int auth_type, const char *username,
+ const char *passwd, int *err, char **err_str)
+{
+ struct pcap_rmtauth auth;
+ char source[PCAP_BUF_SIZE];
+ char errbuf[PCAP_ERRBUF_SIZE];
+ GList *result;
+
+ if (pcap_createsrcstr(source, PCAP_SRC_IFREMOTE, hostname, port,
+ NULL, errbuf) == -1) {
+ *err = CANT_GET_INTERFACE_LIST;
+ if (err_str != NULL)
+ *err_str = cant_get_if_list_error_message(errbuf);
+ return NULL;
+ }
+
+ auth.type = auth_type;
+ auth.username = g_strdup(username);
+ auth.password = g_strdup(passwd);
+
+ result = get_interface_list_findalldevs_ex(source, &auth, err, err_str);
+ g_free(auth.username);
+ g_free(auth.password);
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+GList *
+get_interface_list(int *err, char **err_str)
+{
+ return get_interface_list_findalldevs(err, err_str);
+}
+#else /* HAVE_PCAP_FINDALLDEVS */
struct search_user_data {
char *name;
if_info_t *if_info;
};
static void
-search_for_if_cb(gpointer data, gpointer user_data);
-#endif
+search_for_if_cb(gpointer data, gpointer user_data)
+{
+ struct search_user_data *search_user_data = user_data;
+ if_info_t *if_info = data;
+
+ if (strcmp(if_info->name, search_user_data->name) == 0)
+ search_user_data->if_info = if_info;
+}
GList *
-get_interface_list(int *err, char *err_str)
+get_interface_list(int *err, char **err_str)
{
-#ifdef HAVE_PCAP_FINDALLDEVS
- return get_interface_list_findalldevs(err, err_str);
-#else
GList *il = NULL;
gint nonloopback_pos = 0;
struct ifreq *ifr, *last;
int len, lastlen;
char *buf;
if_info_t *if_info;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ gboolean loopback;
if (sock < 0) {
*err = CANT_GET_INTERFACE_LIST;
- g_snprintf(err_str, PCAP_ERRBUF_SIZE, "Error opening socket: %s",
- strerror(errno));
+ if (err_str != NULL) {
+ *err_str = g_strdup_printf(
+ "Can't get list of interfaces: error opening socket: %s",
+ g_strerror(errno));
+ }
return NULL;
}
memset (buf, 0, len);
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
if (errno != EINVAL || lastlen != 0) {
- g_snprintf(err_str, PCAP_ERRBUF_SIZE,
- "SIOCGIFCONF ioctl error getting list of interfaces: %s",
- strerror(errno));
+ if (err_str != NULL) {
+ *err_str = g_strdup_printf(
+ "Can't get list of interfaces: SIOCGIFCONF ioctl error: %s",
+ g_strerror(errno));
+ }
goto fail;
}
} else {
- if ((unsigned) ifc.ifc_len < sizeof(struct ifreq)) {
- g_snprintf(err_str, PCAP_ERRBUF_SIZE,
- "SIOCGIFCONF ioctl gave too small return buffer");
+ if ((unsigned int) ifc.ifc_len < sizeof(struct ifreq)) {
+ if (err_str != NULL) {
+ *err_str = g_strdup(
+ "Can't get list of interfaces: SIOCGIFCONF ioctl gave too small return buffer");
+ }
goto fail;
}
if (ifc.ifc_len == lastlen)
* Get the interface flags.
*/
memset(&ifrflags, 0, sizeof ifrflags);
- strncpy(ifrflags.ifr_name, ifr->ifr_name,
+ g_strlcpy(ifrflags.ifr_name, ifr->ifr_name,
sizeof ifrflags.ifr_name);
if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
goto next;
- g_snprintf(err_str, PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS error getting flags for interface %s: %s",
- ifr->ifr_name, strerror(errno));
+ if (err_str != NULL) {
+ *err_str = g_strdup_printf(
+ "Can't get list of interfaces: SIOCGIFFLAGS error getting flags for interface %s: %s",
+ ifr->ifr_name, g_strerror(errno));
+ }
goto fail;
}
* supplied is too large, rather than just truncating it.
*/
pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
- err_str);
+ errbuf);
if (pch == NULL)
goto next;
pcap_close(pch);
* don't want a loopback interface to be the default capture
* device unless there are no non-loopback devices.
*/
- if_info = if_info_new(ifr->ifr_name, NULL);
+ loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
+ strncmp(ifr->ifr_name, "lo", 2) == 0);
+ if_info = if_info_new(ifr->ifr_name, NULL, loopback);
if_info_add_address(if_info, &ifr->ifr_addr);
- if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
- strncmp(ifr->ifr_name, "lo", 2) == 0) {
- if_info->loopback = TRUE;
+ if (loopback)
il = g_list_append(il, if_info);
- } else {
- if_info->loopback = FALSE;
+ else {
il = g_list_insert(il, if_info, nonloopback_pos);
/*
* Insert the next non-loopback interface after this
* Try opening it and, if that succeeds, add it to the end of
* the list of interfaces.
*/
- pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str);
+ pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, errbuf);
if (pch != NULL) {
/*
* It worked; we can use the "any" device.
*/
if_info = if_info_new("any",
- "Pseudo-device that captures on all interfaces");
+ "Pseudo-device that captures on all interfaces", FALSE);
il = g_list_insert(il, if_info, -1);
pcap_close(pch);
}
* No interfaces found.
*/
*err = NO_INTERFACES_FOUND;
+ if (err_str != NULL)
+ *err_str = NULL;
}
return il;
close(sock);
*err = CANT_GET_INTERFACE_LIST;
return NULL;
-#endif /* HAVE_PCAP_FINDALLDEVS */
-}
-
-#ifndef HAVE_PCAP_FINDALLDEVS
-static void
-search_for_if_cb(gpointer data, gpointer user_data)
-{
- struct search_user_data *search_user_data = user_data;
- if_info_t *if_info = data;
-
- if (strcmp(if_info->name, search_user_data->name) == 0)
- search_user_data->if_info = if_info;
}
#endif /* HAVE_PCAP_FINDALLDEVS */
void
get_compiled_pcap_version(GString *str)
{
-#ifdef HAVE_PCAP_VERSION
- extern char pcap_version[];
-
- g_string_sprintfa(str, "with libpcap %s", pcap_version);
-#else
- g_string_append(str, "with libpcap (version unknown)");
-#endif
+ /*
+ * NOTE: in *some* flavors of UN*X, the data from a shared
+ * library might be linked into executable images that are
+ * linked with that shared library, in which case you could
+ * look at pcap_version[] to get the version with which
+ * the program was compiled.
+ *
+ * In other flavors of UN*X, that doesn't happen, so
+ * pcap_version[] gives you the version the program is
+ * running with, not the version it was built with, and,
+ * in at least some of them, if the length of a data item
+ * referred to by the executable - such as the pcap_version[]
+ * string - isn't the same in the version of the library
+ * with which the program was built and the version with
+ * which it was run, the run-time linker will complain,
+ * which is Not Good.
+ *
+ * So, for now, we just give up on reporting the version
+ * of libpcap with which we were compiled.
+ */
+ g_string_append(str, "with libpcap");
}
/*
void
get_runtime_pcap_version(GString *str)
{
- g_string_sprintfa(str, "with ");
+ g_string_append_printf(str, "with ");
#ifdef HAVE_PCAP_LIB_VERSION
- g_string_sprintfa(str, pcap_lib_version());
+ g_string_append(str, pcap_lib_version());
#else
g_string_append(str, "libpcap (version unknown)");
#endif
- g_string_append(str, " ");
}
#else /* HAVE_LIBPCAP */