+ microtime(&tv);
+ if (d->bd_flags & BPF_EXTENDED_HDR) {
+ ehp = (struct bpf_hdr_ext *)(void *)(d->bd_sbuf + curlen);
+ memset(ehp, 0, sizeof(*ehp));
+ ehp->bh_tstamp.tv_sec = tv.tv_sec;
+ ehp->bh_tstamp.tv_usec = tv.tv_usec;
+ ehp->bh_datalen = pktlen;
+ ehp->bh_hdrlen = hdrlen;
+ ehp->bh_caplen = totlen - hdrlen;
+ mt = m_tag_locate(m, bpf_mtag_id, 0, NULL);
+ if (mt && mt->m_tag_len >= sizeof(*bt)) {
+ bt = (struct bpf_mtag *)(mt + 1);
+ ehp->bh_pid = bt->bt_pid;
+ strlcpy(ehp->bh_comm, bt->bt_comm,
+ sizeof(ehp->bh_comm));
+ ehp->bh_svc = so_svc2tc(bt->bt_svc);
+ if (bt->bt_direction == BPF_MTAG_DIR_OUT)
+ ehp->bh_flags |= BPF_HDR_EXT_FLAGS_DIR_OUT;
+ else
+ ehp->bh_flags |= BPF_HDR_EXT_FLAGS_DIR_IN;
+ m_tag_delete(m, mt);
+ } else if (outbound) {
+ /* only do lookups on non-raw INPCB */
+ if ((m->m_pkthdr.pkt_flags & (PKTF_FLOW_ID|
+ PKTF_FLOW_LOCALSRC|PKTF_FLOW_RAWSOCK)) ==
+ (PKTF_FLOW_ID|PKTF_FLOW_LOCALSRC) &&
+ m->m_pkthdr.pkt_flowsrc == FLOWSRC_INPCB) {
+ ehp->bh_flowid = m->m_pkthdr.pkt_flowid;
+ ehp->bh_proto = m->m_pkthdr.pkt_proto;
+ }
+ ehp->bh_svc = so_svc2tc(m->m_pkthdr.pkt_svc);
+ ehp->bh_flags |= BPF_HDR_EXT_FLAGS_DIR_OUT;
+ if (m->m_pkthdr.pkt_flags & PKTF_TCP_REXMT)
+ ehp->bh_pktflags |= BPF_PKTFLAGS_TCP_REXMT;
+ if (m->m_pkthdr.pkt_flags & PKTF_START_SEQ)
+ ehp->bh_pktflags |= BPF_PKTFLAGS_START_SEQ;
+ if (m->m_pkthdr.pkt_flags & PKTF_LAST_PKT)
+ ehp->bh_pktflags |= BPF_PKTFLAGS_LAST_PKT;
+ if (m->m_pkthdr.pkt_flags & PKTF_VALID_UNSENT_DATA) {
+ ehp->bh_unsent_bytes =
+ m->m_pkthdr.bufstatus_if;
+ ehp->bh_unsent_snd =
+ m->m_pkthdr.bufstatus_sndbuf;
+ }
+ } else
+ ehp->bh_flags |= BPF_HDR_EXT_FLAGS_DIR_IN;
+ payload = (u_char *)ehp + hdrlen;
+ caplen = ehp->bh_caplen;
+ } else {
+ hp = (struct bpf_hdr *)(void *)(d->bd_sbuf + curlen);
+ hp->bh_tstamp.tv_sec = tv.tv_sec;
+ hp->bh_tstamp.tv_usec = tv.tv_usec;
+ hp->bh_datalen = pktlen;
+ hp->bh_hdrlen = hdrlen;
+ hp->bh_caplen = totlen - hdrlen;
+ payload = (u_char *)hp + hdrlen;
+ caplen = hp->bh_caplen;
+ }