If we don't have any of the pcap_datalink_XXX_to_YYY routines,

substitute our own (I wrote them all, so I can steal them from the
BSD-licensed libpcap if I want :-)).  This means that
linktype_name_to_val() and linktype_val_to_name() are always available,
and we don't need to #ifdef use of them.

Use pcap_datalink_val_to_description() to get the description for a
particular DLT_ value, rather than mapping the DLT_ value to a
WTAP_ENCAP_ value and getting the description for the latter.

svn path=/trunk/; revision=27074
This commit is contained in:
Guy Harris 2008-12-21 23:22:12 +00:00
parent 4692f6cae7
commit 44f8cae6ab
6 changed files with 98 additions and 47 deletions

View File

@ -521,6 +521,7 @@ install a newer version of the header file.])
AC_DEFINE(HAVE_PCAP_FINDALLDEVS, 1,
[Define to 1 if you have the `pcap_findalldevs' function and a pcap.h that declares pcap_if_t.])
AC_CHECK_FUNCS(pcap_datalink_val_to_name pcap_datalink_name_to_val)
AC_CHECK_FUNCS(pcap_datalink_val_to_description)
AC_CHECK_FUNCS(pcap_list_datalinks pcap_set_datalink pcap_lib_version)
AC_CHECK_FUNCS(pcap_get_selectable_fd pcap_free_datalinks)
fi

View File

@ -351,6 +351,95 @@ free_interface_list(GList *if_list)
g_list_free(if_list);
}
#if !defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) || !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) || !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION)
struct dlt_choice {
const char *name;
const char *description;
int dlt;
};
#define DLT_CHOICE(code, description) { #code, description, code }
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_NULL, "BSD loopback"),
DLT_CHOICE(DLT_EN10MB, "Ethernet"),
DLT_CHOICE(DLT_IEEE802, "Token ring"),
DLT_CHOICE(DLT_ARCNET, "ARCNET"),
DLT_CHOICE(DLT_SLIP, "SLIP"),
DLT_CHOICE(DLT_PPP, "PPP"),
DLT_CHOICE(DLT_FDDI, "FDDI"),
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
DLT_CHOICE(DLT_RAW, "Raw IP"),
DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
DLT_CHOICE(DLT_IEEE802_11, "802.11"),
DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
DLT_CHOICE(DLT_LTALK, "Localtalk"),
DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"),
DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
DLT_CHOICE_SENTINEL
};
#if !defined(HAVE_PCAP_DATALINK_NAME_TO_VAL)
static int
pcap_datalink_name_to_val(const char *name)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (g_ascii_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
name) == 0)
return (dlt_choices[i].dlt);
}
return (-1);
}
#endif /* defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) */
#if !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME)
static const char *
pcap_datalink_val_to_name(int dlt)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (dlt_choices[i].dlt == dlt)
return (dlt_choices[i].name + sizeof("DLT_") - 1);
}
return (NULL);
}
#endif /* defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) */
#if !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION)
const char *
pcap_datalink_val_to_description(int dlt)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (dlt_choices[i].dlt == dlt)
return (dlt_choices[i].description);
}
return (NULL);
}
#endif /* defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) */
#endif /* !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) || !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) */
/*
* Get the data-link types available for a libpcap device.
*/
@ -358,38 +447,20 @@ 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;
const char *text;
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);
text = pcap_datalink_val_to_name(dlt);
if (text != NULL)
data_link_info->name = g_strdup(text);
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.
*/
text = pcap_datalink_val_to_description(dlt);
if (text != NULL)
data_link_info->description = g_strdup(text);
else
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;
}
@ -510,20 +581,15 @@ set_pcap_linktype(pcap_t *pch, char *devname
#endif
}
#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
const char *
linktype_val_to_name(int dlt)
{
return pcap_datalink_val_to_name(dlt);
}
#endif
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
int linktype_name_to_val(const char *linktype)
{
return pcap_datalink_name_to_val(linktype);
}
#endif
#endif /* HAVE_LIBPCAP */

View File

@ -100,12 +100,8 @@ int get_pcap_linktype(pcap_t *pch, const char *devname);
const char *set_pcap_linktype(pcap_t *pch, char *devname, int dlt);
#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
const char *linktype_val_to_name(int dlt);
#endif
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
int linktype_name_to_val(const char *linktype);
#endif
#ifdef __cplusplus
}

View File

@ -536,17 +536,12 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
return status;
case 'y': /* Set the pcap data link type */
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
capture_opts->linktype = linktype_name_to_val(optarg);
if (capture_opts->linktype == -1) {
cmdarg_err("The specified data link type \"%s\" isn't valid",
optarg);
return 1;
}
#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
/* we can't get the type name, just treat it as a number */
capture_opts->linktype = get_natural_int(optarg, "data link type");
#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
break;
default:
/* the caller is responsible to send us only the right opt's */

View File

@ -305,12 +305,7 @@ sync_pipe_start(capture_options *capture_opts) {
if (capture_opts->linktype != -1) {
argv = sync_pipe_add_arg(argv, &argc, "-y");
#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
#else
/* we can't get the type name, just treat it as a number */
g_snprintf(sdlt, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
#endif
argv = sync_pipe_add_arg(argv, &argc, sdlt);
}

View File

@ -378,13 +378,11 @@ set_link_type(const char *lt_arg) {
spec_ptr++;
if (strncmp(lt_arg, "encap:", strlen("encap:")) == 0) {
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
dlt_val = linktype_name_to_val(spec_ptr);
if (dlt_val >= 0) {
encap = dlt_val;
return TRUE;
}
#endif
dlt_val = strtol(spec_ptr, NULL, 10);
if (errno != EINVAL && dlt_val >= 0) {
encap = wtap_pcap_encap_to_wtap_encap(dlt_val);