/* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
-/* define if we can use nanosecond timestamps */
-#undef HAVE_LINUX_TSTAMP_NANO
-
/* Define to 1 if you have the <linux/types.h> header file. */
#undef HAVE_LINUX_TYPES_H
fi
fi
- # Do we have support for nanosecond timestamps in kernel?
- { echo "$as_me:$LINENO: checking whether the system supports timestamps with nanosecond resolution" >&5
-echo $ECHO_N "checking whether the system supports timestamps with nanosecond resolution... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
- #include <linux/sockios.h>
- #include <linux/net.h>
-int
-main ()
-{
-return SIOCGSTAMPNS && SO_TIMESTAMPNS
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LINUX_TSTAMP_NANO 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
for ac_header in linux/ethtool.h
do
fi
fi
- # Do we have support for nanosecond timestamps in kernel?
- AC_MSG_CHECKING(whether the system supports timestamps with nanosecond resolution)
- AC_TRY_COMPILE([
- #include <linux/sockios.h>
- #include <linux/net.h>],
- [return SIOCGSTAMPNS && SO_TIMESTAMPNS],
- [AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_LINUX_TSTAMP_NANO], 1, [define if we can use nanosecond timestamps])],
- AC_MSG_RESULT(no))
-
AC_CHECK_HEADERS(linux/ethtool.h,,,
[
AC_INCLUDES_DEFAULT
u_int *dlt_list;
int tstamp_type_count;
u_int *tstamp_type_list;
+ int tstamp_precision_count;
+ u_int *tstamp_precision_list;
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
#include <sys/mman.h>
#include <linux/if.h>
#include <linux/if_packet.h>
+#include <linux/sockios.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if_arp.h>
#include <linux/filter.h>
#endif
-/*
- * We need linux/sockios.h if we have linux/net_tstamp.h (for time stamp
- * specification) or linux/ethtool.h (for ethtool ioctls to get offloading
- * information).
- */
-#if defined(HAVE_LINUX_NET_TSTAMP_H) || defined(HAVE_LINUX_ETHTOOL_H)
-#include <linux/sockios.h>
-#endif
-
#ifdef HAVE_LINUX_NET_TSTAMP_H
#include <linux/net_tstamp.h>
#endif
handle->tstamp_type_list[2] = PCAP_TSTAMP_ADAPTER_UNSYNCED;
#endif
+#if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
+ /*
+ * We claim that we support microsecond and nanosecond time
+ * stamps.
+ *
+ * XXX - with adapter-supplied time stamps, can we choose
+ * microsecond or nanosecond time stamps on arbitrary
+ * adapters?
+ */
+ handle->tstamp_precision_count = 2;
+ handle->tstamp_type_list = malloc(2 * sizeof(u_int));
+ if (handle->tstamp_type_list == NULL) {
+ if (handle->tstamp_type_list != NULL)
+ free(handle->tstamp_type_list);
+ free(handle);
+ return NULL;
+ }
+ handle->tstamp_type_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
+ handle->tstamp_type_list[1] = PCAP_TSTAMP_PRECISION_NANO;
+#endif /* defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS) */
+
return handle;
}
/* Fill in our own header data */
/* get timestamp for this packet */
+#if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
if (ioctl(handle->fd, SIOCGSTAMPNS, &pcap_header.ts) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SIOCGSTAMPNS: %s", pcap_strerror(errno));
return PCAP_ERROR;
}
- } else {
+ } else
+#endif
+ {
if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SIOCGSTAMP: %s", pcap_strerror(errno));
/* Save the socket FD in the pcap structure */
handle->fd = sock_fd;
+#if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
int nsec_tstamps = 1;
return PCAP_ERROR;
}
}
+#endif /* defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS) */
return 1;
-#else
+#else /* HAVE_PF_PACKET_SOCKETS */
strncpy(ebuf,
"New packet capturing interface not supported by build "
"environment", PCAP_ERRBUF_SIZE);
return 0;
-#endif
+#endif /* HAVE_PF_PACKET_SOCKETS */
}
#ifdef HAVE_PACKET_RING
return (PCAP_ERROR_ACTIVATED);
/*
- * If p->tstamp_type_count is 0, we don't support setting
- * the time stamp type at all.
+ * If p->tstamp_type_count is 0, we only support PCAP_TSTAMP_HOST;
+ * the default time stamp type is PCAP_TSTAMP_HOST.
*/
- if (p->tstamp_type_count == 0)
- return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
-
- /*
- * Check whether we claim to support this type of time stamp.
- */
- for (i = 0; i < p->tstamp_type_count; i++) {
- if (p->tstamp_type_list[i] == tstamp_type) {
- /*
- * Yes.
- */
+ if (p->tstamp_type_count == 0) {
+ if (tstamp_type == PCAP_TSTAMP_HOST) {
p->opt.tstamp_type = tstamp_type;
return (0);
}
+ } else {
+ /*
+ * Check whether we claim to support this type of time stamp.
+ */
+ for (i = 0; i < p->tstamp_type_count; i++) {
+ if (p->tstamp_type_list[i] == tstamp_type) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_type = tstamp_type;
+ return (0);
+ }
+ }
}
/*
- * No. We support setting the time stamp type, but not to this
- * particular value.
+ * We don't support this type of time stamp.
*/
return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
}
}
int
-pcap_set_tstamp_precision(pcap_t *p, int precision)
+pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision)
{
+ int i;
+
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
- if (precision == PCAP_TSTAMP_PRECISION_NANO) {
-#ifdef HAVE_LINUX_TSTAMP_NANO
- /* We should be able to get timestamp with nanosecond precision */
- p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_NANO;
-#else
- /* TODO: We don't know anything about other platforms yet */
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "nanosecond timestamps are not supported");
- return PCAP_WARNING_TSTAMP_PRECISION_NOTSUP;
-#endif
- } else if (precision == PCAP_TSTAMP_PRECISION_MICRO) {
- p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+ /*
+ * If p->tstamp_precision_count is 0, we only support setting
+ * the time stamp precision to microsecond precision; every
+ * pcap module *MUST* support microsecond precision, even if
+ * it does so by converting the native precision to
+ * microseconds.
+ */
+ if (p->tstamp_precision_count == 0) {
+ if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO) {
+ p->opt.tstamp_precision = tstamp_precision;
+ return (0);
+ }
} else {
- /* unknown precision requested */
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "nanosecond timestamps are not supported");
- return PCAP_WARNING_TSTAMP_PRECISION_NOTSUP;
+ /*
+ * Check whether we claim to support this precision of
+ * time stamp.
+ */
+ for (i = 0; i < p->tstamp_precision_count; i++) {
+ if (p->tstamp_precision_list[i] == tstamp_precision) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_precision = tstamp_precision;
+ return (0);
+ }
+ }
}
- return 0;
+ /*
+ * We don't support this time stamp precision.
+ */
+ return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP);
}
int
case PCAP_ERROR_PROMISC_PERM_DENIED:
return ("You don't have permission to capture in promiscuous mode on that device");
+
+ case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:
+ return ("That device doesn't support that time stamp precision");
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
p->tstamp_type_list = NULL;
p->tstamp_type_count = 0;
}
+ if (p->tstamp_precision_list != NULL) {
+ free(p->tstamp_precision_list);
+ p->tstamp_precision_list = NULL;
+ p->tstamp_precision_count = 0;
+ }
pcap_freecode(&p->fcode);
#if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0) {
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
+#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */
/*
* Warning codes for the pcap API.
#define PCAP_WARNING 1 /* generic warning code */
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */
-#define PCAP_WARNING_TSTAMP_PRECISION_NOTSUP 4 /* the requested time stamp precision is not supported */
/*
* Value to pass to pcap_compile() as the netmask if you don't know what