diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-11-01 02:30:18 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-11-01 02:30:18 +0000 |
commit | 219b6cefa2380d726788967886907b9aa751dfdc (patch) | |
tree | 8cfd28761860f069df6b8e3ebe81a3dbee7dd825 /pcap-util.c | |
parent | 9ac0cce997ff284748ba351ab6abcfffce0eede4 (diff) | |
download | wireshark-219b6cefa2380d726788967886907b9aa751dfdc.tar.gz wireshark-219b6cefa2380d726788967886907b9aa751dfdc.tar.bz2 wireshark-219b6cefa2380d726788967886907b9aa751dfdc.zip |
Based on a patch from Brian Fundakowski Feldman, add support for setting
link-layer type when capturing, using the "pcap_set_datalink()" and
related APIs.
svn path=/trunk/; revision=8848
Diffstat (limited to 'pcap-util.c')
-rw-r--r-- | pcap-util.c | 127 |
1 files changed, 126 insertions, 1 deletions
diff --git a/pcap-util.c b/pcap-util.c index 2a2615b10f..064e8097a0 100644 --- a/pcap-util.c +++ b/pcap-util.c @@ -1,7 +1,7 @@ /* pcap-util.c * Utility routines for packet capture * - * $Id: pcap-util.c,v 1.18 2003/10/10 03:00:10 guy Exp $ + * $Id: pcap-util.c,v 1.19 2003/11/01 02:30:14 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -31,6 +31,7 @@ #include <glib.h> #include <stdlib.h> +#include <limits.h> #include <string.h> #ifdef HAVE_SYS_TYPES_H @@ -43,6 +44,9 @@ #include <pcap.h> +#include <wtap.h> +#include <wtap-capture.h> + #include "pcap-util.h" #include "pcap-util-int.h" @@ -231,4 +235,125 @@ free_interface_list(GList *if_list) g_list_free(if_list); } +/* + * Get the data-link types available for a libpcap device. + */ +static data_link_info_t * +create_data_link_info(int dlt) +{ + data_link_info_t *data_link_info; +#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME + const char *typename; +#endif + int wtap_encap; + + data_link_info = g_malloc(sizeof (data_link_info_t)); + data_link_info->dlt = dlt; +#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME + typename = pcap_datalink_val_to_name(dlt); + if (typename != NULL) + data_link_info->name = g_strdup(typename); + else +#endif + data_link_info->name = g_strdup_printf("DLT %d", dlt); + wtap_encap = wtap_pcap_encap_to_wtap_encap(dlt); + if (wtap_encap == WTAP_ENCAP_UNKNOWN) { + /* + * We don't support this in Wiretap. + * However, we should, so you can capture on it. + * Put in an entry for it, with no description. + */ + data_link_info->description = NULL; + } else { + /* + * If this is null, that's a bug in + * "wtap_pcap_encap_to_wtap_encap()" - it should always + * return a valid encapsulation type - so we assume it's + * not null. + */ + data_link_info->description = + g_strdup(wtap_encap_string(wtap_encap)); + } + return data_link_info; +} + +GList * +get_pcap_linktype_list(char *devname, char *err_buf) +{ + GList *linktype_list = NULL; + pcap_t *pch; + int deflt; +#ifdef HAVE_PCAP_SET_DATALINK + int *linktypes; + int i, nlt; +#endif + data_link_info_t *data_link_info; + + pch = pcap_open_live(devname, MIN_PACKET_SIZE, 0, 0, err_buf); + if (pch == NULL) + return NULL; + err_buf[0] = '\0'; /* an empty list doesn't mean an error */ + deflt = get_pcap_linktype(pch, devname); +#ifdef HAVE_PCAP_LIST_DATALINKS + nlt = pcap_list_datalinks(pch, &linktypes); + if (nlt == 0 || linktypes == NULL) + return NULL; + for (i = 0; i < nlt; i++) { + data_link_info = create_data_link_info(linktypes[i]); + + /* + * XXX - for 802.11, make the most detailed 802.11 + * version the default, rather than the one the + * device has as the default? + */ + if (linktypes[i] == deflt) + linktype_list = g_list_prepend(linktype_list, + data_link_info); + else + linktype_list = g_list_append(linktype_list, + data_link_info); + } + free(linktypes); +#else + data_link_info = create_data_link_info(deflt); + linktype_list = g_list_append(linktype_list, data_link_info); +#endif + + pcap_close(pch); + return linktype_list; +} + +static void +free_linktype_cb(gpointer data, gpointer user_data _U_) +{ + data_link_info_t *linktype_info = data; + + g_free(linktype_info->name); + if (linktype_info->description != NULL) + g_free(linktype_info->description); +} + +void +free_pcap_linktype_list(GList *linktype_list) +{ + g_list_foreach(linktype_list, free_linktype_cb, NULL); + g_list_free(linktype_list); +} + +/* Set the data link type on a pcap. */ +const char * +set_pcap_linktype(pcap_t *pch, char *devname, int dlt) +{ +#ifdef HAVE_PCAP_SET_DATALINK + if (pcap_set_datalink(pch, dlt) == 0) + return NULL; /* no error */ + return pcap_geterr(pch); +#else + /* Let them set it to the type it is; reject any other request. */ + if (get_pcap_linktype(pch, devname) == dlt) + return NULL; /* no error */ + return "That DLT is not one of the DLTs supported by this device"; +#endif +} + #endif /* HAVE_LIBPCAP */ |