diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 4f1a0afbe69..36f4444c6d6 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -441,7 +441,7 @@ pcap_ack_zbuf(pcap_t *p) #endif /* HAVE_ZEROCOPY_BPF */ pcap_t * -pcap_create_interface(const char *device _U_, char *ebuf) +pcap_create_interface(const char *device, char *ebuf) { pcap_t *p; @@ -451,6 +451,26 @@ pcap_create_interface(const char *device _U_, char *ebuf) p->activate_op = pcap_activate_bpf; p->can_set_rfmon_op = pcap_can_set_rfmon_bpf; + +#ifdef __FreeBSD__ + if (strcmp(device, "any") != 0) { + struct ifreq ifr; + int fd; + + fd = socket(AF_LOCAL, SOCK_DGRAM, 0); + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFCAP, (caddr_t)&ifr) == 0 && ( + ifr.ifr_curcap & IFCAP_HWRXTSTMP) != 0) { + p->tstamp_type_count = 2; + p->tstamp_type_list = malloc(2 * sizeof(u_int)); + p->tstamp_type_list[0] = PCAP_TSTAMP_HOST; + p->tstamp_type_list[1] = PCAP_TSTAMP_ADAPTER; + } + close(fd); + } +#endif /* __FreeBSD__ */ + #ifdef BIOCSTSTAMP /* * We claim that we support microsecond and nanosecond time @@ -2445,7 +2465,8 @@ pcap_activate_bpf(pcap_t *p) } #ifdef BIOCSTSTAMP - v = BPF_T_BINTIME; + v = BPF_T_BINTIME | ( + p->opt.tstamp_type == PCAP_TSTAMP_ADAPTER ? BPF_T_ADAPTER: BPF_T_HOST); if (ioctl(p->fd, BIOCSTSTAMP, &v) < 0) { pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, errno, "BIOCSTSTAMP"); diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 605e7aa39fd..25958f9924b 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2204,20 +2204,31 @@ bpf_ts_quality(int tstype) static int bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m) { - struct m_tag *tag; int quality; quality = bpf_ts_quality(tstype); if (quality == BPF_TSTAMP_NONE) return (quality); + if ((tstype & BPF_T_ADAPTER) != 0 && m != NULL && + m_rcvif(m) != NULL) { + if (m->m_flags & M_TSTMP) { + bt->sec = m->m_pkthdr.rcv_tstmp / 1000000000; + bt->frac = m->m_pkthdr.rcv_tstmp % 1000000000; + return (BPF_TSTAMP_FAST); + } + } +#if 0 if (m != NULL) { + struct m_tag *tag; + tag = m_tag_locate(m, MTAG_BPF, MTAG_BPF_TIMESTAMP, NULL); if (tag != NULL) { *bt = *(struct bintime *)(tag + 1); return (BPF_TSTAMP_EXTERN); } } +#endif if (quality == BPF_TSTAMP_NORMAL) binuptime(bt); else @@ -2328,7 +2339,8 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m) BPFD_LOCK(d); counter_u64_add(d->bd_fcount, 1); - if (gottime < bpf_ts_quality(d->bd_tstamp)) + if (gottime < bpf_ts_quality(d->bd_tstamp) || ( + d->bd_tstamp & BPF_T_ADAPTER)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) @@ -2385,7 +2397,8 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m) BPFD_LOCK(d); counter_u64_add(d->bd_fcount, 1); - if (gottime < bpf_ts_quality(d->bd_tstamp)) + if (gottime < bpf_ts_quality(d->bd_tstamp) || ( + d->bd_tstamp & BPF_T_ADAPTER)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) diff --git a/sys/net/bpf.h b/sys/net/bpf.h index 54bbfd23bba..1108b84f89b 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -166,11 +166,16 @@ enum bpf_direction { }; /* Time stamping functions */ +#define BPF_T_HOST 0x0000 +#define BPF_T_ADAPTER 0x0010 +#define BPF_T_SOURCE_MASK (BPF_T_ADAPTER) + #define BPF_T_MICROTIME 0x0000 #define BPF_T_NANOTIME 0x0001 #define BPF_T_BINTIME 0x0002 #define BPF_T_NONE 0x0003 #define BPF_T_FORMAT_MASK 0x0003 + #define BPF_T_NORMAL 0x0000 #define BPF_T_FAST 0x0100 #define BPF_T_MONOTONIC 0x0200 @@ -180,7 +185,7 @@ enum bpf_direction { #define BPF_T_FLAG(t) ((t) & BPF_T_FLAG_MASK) #define BPF_T_VALID(t) \ ((t) == BPF_T_NONE || (BPF_T_FORMAT(t) != BPF_T_NONE && \ - ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK)) == 0)) + ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK | BPF_T_SOURCE_MASK)) == 0)) #define BPF_T_MICROTIME_FAST (BPF_T_MICROTIME | BPF_T_FAST) #define BPF_T_NANOTIME_FAST (BPF_T_NANOTIME | BPF_T_FAST)