tcpdump mailing list archives

[RFC PATCH 1/2] libpcap: linux hw timestamp support


From: "Mcmillan, Scott A" <scott.a.mcmillan () intel com>
Date: Mon, 24 May 2010 07:26:30 -0700

[My apologies if this double posts.  The mail server didn't care for the first submission.]

This patch adds the general infrastructure needed to select the packet timestamp source as well as specific support for 
the PACKET_TIMESTAMP Linux kernel setting.  

Signed-off-by: Scott McMillan <scott.a.mcmillan () intel com>

--- a/libpcap-1.1.1/pcap/pcap.h 2010-03-11 19:56:54.000000000 -0600
+++ b/libpcap-1.1.1/pcap/pcap.h 2010-05-18 14:07:43.000000000 -0500
@@ -259,6 +259,7 @@
  */
 #define PCAP_WARNING                   1       /* generic warning code */
 #define PCAP_WARNING_PROMISC_NOTSUP    2       /* this device doesn't support promiscuous mode */
+#define PCAP_WARNING_HWTSTAMP_NOTSUP   3       /* hardware timestamps are not supported */
 
 /*
  * Value to pass to pcap_compile() as the netmask if you don't know what
--- a/libpcap-1.1.1/pcap-int.h  2010-03-11 19:56:54.000000000 -0600
+++ b/libpcap-1.1.1/pcap-int.h  2010-05-18 14:07:43.000000000 -0500
@@ -265,6 +265,10 @@
 
        int break_loop;         /* flag set to force break from packet-reading loop */
 
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+       int timesource;   /* select the timesource for the packet timestamp */
+#endif /* HAVE_LINUX_NET_TSTAMP_H */
+
 #ifdef PCAP_FDDIPAD
        int fddipad;
 #endif
--- a/libpcap-1.1.1/pcap-linux.c        2010-03-11 19:56:54.000000000 -0600
+++ b/libpcap-1.1.1/pcap-linux.c        2010-05-18 16:44:45.000000000 -0500
@@ -138,6 +138,11 @@
 #include <poll.h>
 #include <dirent.h>
 
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+#include <linux/net_tstamp.h>
+#include <linux/sockios.h>
+#endif
+
 /*
  * Got Wireless Extensions?
  */
@@ -3078,6 +3083,48 @@
 
        frames_per_block = req.tp_block_size/req.tp_frame_size;
 
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+       /* ask the kernel to use hardware timestamps */
+       if (handle->timesource != 0) {
+#ifdef SIOCSHWTSTAMP
+               struct hwtstamp_config hwconfig;
+               struct ifreq ifr;
+
+               memset(&hwconfig, 0, sizeof(hwconfig));
+               hwconfig.tx_type = HWTSTAMP_TX_ON;
+               hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
+
+               memset(&ifr, 0, sizeof(ifr));
+               strcpy(ifr.ifr_name, handle->opt.source);
+               ifr.ifr_data = (void *)&hwconfig;
+
+               if(ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                               "can't set SIOCSHWTSTAMP %d: %d-%s",
+                               handle->fd, errno, pcap_strerror(errno));
+               }
+#else
+               snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                       "SIOCSHWTSTAMP not supported %d: %d-%s",
+                       handle->fd, errno, pcap_strerror(errno));
+#endif /* SIOCSHWTSTAMP */
+
+#ifdef PACKET_TIMESTAMP
+               if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP,
+                       (void *)&handle->timesource, 
+                       sizeof(handle->timesource))) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 
+                               "can't set PACKET_TIMESTAMP %d: %d-%s", 
+                               handle->fd, errno, pcap_strerror(errno));
+               }
+#else
+               snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                       "PACKET_TIMESTAMP not supported: %d: %d-%s",
+                       handle->fd, errno, pcap_strerror(errno));
+#endif
+       }
+#endif /* HAVE_LINUX_NET_TSTAMP_H */
+
        /* ask the kernel to create the ring */
 retry:
        req.tp_block_nr = req.tp_frame_nr / frames_per_block;
--- a/libpcap-1.1.1/pcap.c      2010-03-11 19:56:54.000000000 -0600
+++ b/libpcap-1.1.1/pcap.c      2010-05-18 14:07:43.000000000 -0500
@@ -309,6 +309,19 @@
 }
 
 int
+pcap_set_timesource(pcap_t *p, int timesource)
+{
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+       if (pcap_check_activated(p))
+               return PCAP_ERROR_ACTIVATED;
+       p->timesource = timesource;
+       return 0;
+#else
+       return PCAP_WARNING_HWTSTAMP_NOTSUP;
+#endif /* HAVE_LINUX_NET_TSTAMP_H */
+}
+
+int
 pcap_set_buffer_size(pcap_t *p, int buffer_size)
 {
        if (pcap_check_activated(p))
@@ -979,6 +992,9 @@
        case PCAP_WARNING_PROMISC_NOTSUP:
                return ("That device doesn't support promiscuous mode");
 
+       case PCAP_WARNING_HWTSTAMP_NOTSUP:
+               return ("Hardware timestamps are not supported");
+
        case PCAP_ERROR:
                return("Generic error");
 
--- a/libpcap-1.1.1/configure.in        2010-03-11 19:56:53.000000000 -0600
+++ b/libpcap-1.1.1/configure.in        2010-05-18 14:07:43.000000000 -0500
@@ -1416,6 +1416,16 @@
        AC_SUBST(CAN_SRC)
 fi
 
+dnl check for hardware timestamp support
+case "$host_os" in
+linux*)
+       AC_CHECK_HEADERS([linux/net_tstamp.h])
+       ;;
+*)
+       AC_MSG_NOTICE(no hardware timestamp support)
+       ;;
+esac
+
 AC_PROG_INSTALL
 
 AC_CONFIG_HEADER(config.h)
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: