bpf writes on tun device

Charles Swiger cswiger at mac.com
Tue Jun 7 20:47:13 GMT 2005


On Jun 7, 2005, at 3:54 PM, Matthew Luckie wrote:
>> I'd be wary of changing the definition of DLT_NULL however -- it  
>> literally
>> means 'there's nothing here apart from raw data', and changing  
>> this notion
>> would mean that we have to change it everywhere, including bpf  
>> clients,
>> because the change being proposed would make DLT_NULL mean  
>> 'there's a 32-bit
>> integer in front of everything else which is raw data', which is  
>> something
>> else.
>
> this was the behaviour expected of most DLT_NULL bpf devices  
> already (passing a 32bit int when writing).  It is important to  
> note that the behaviour of BPF writers does not change in these  
> cases, and my patch is merely a bug fix.

Agreed.  When you use BPF or PCAP to capture packets, for the  
DTL_NULL case there is a 4-byte offset between where PCAP says the  
packet starts and where the actual raw IP packet starts.

If you want BPF/PCAP to return packets without the 4-byte offset, the  
associated datalink type is actually called DLT_RAW.  Note that the  
behavior of DLT_NULL is useful in practice, since you can find out  
what the "ether type" of the packet was per <net/ethernet.h>:

#define ETHERTYPE_IP            0x0800  /* IP protocol */
#define ETHERTYPE_ARP           0x0806  /* Addr. resolution protocol */
#define ETHERTYPE_REVARP        0x8035  /* reverse Addr. resolution  
protocol */
#define ETHERTYPE_VLAN          0x8100  /* IEEE 802.1Q VLAN tagging */
#define ETHERTYPE_IPV6          0x86dd  /* IPv6 */
#define ETHERTYPE_LOOPBACK      0x9000  /* used to test interfaces */

...to distinguish between IPv4, IPv6, ARP traffic, and so forth.

I've written some code that needed to do packet capture and run on a  
range of platforms-- FreeBSD, NetBSD, Linux, Darwin, Solaris.   I  
haven't tested all of the datalink types, so I won't promise that the  
offsets below are entirely correct, but this might still be helpful:

/* some platforms define ETHER_HDR_LEN, but not all of them do */
#define DLH_EN (14)

int
datalink_offset(int dltype) {
     switch (dltype) {
       case DLT_NULL:    return 4;
       case DLT_EN10MB:  return DLH_EN;
       case DLT_IEEE802: return 22;
       case DLT_ARCNET:  return 4; /* not sure */
       case DLT_SLIP:    return 16;
       case DLT_PPP:     return 24;
       case DLT_FDDI:    return 21;
       case DLT_ATM_RFC1483: return 8; /* not sure */
       case DLT_RAW:     return 0;
#if !defined(__NetBSD__)
       case DLT_LOOP:    return 4;
       case DLT_LINUX_SLL: return 16;
#endif
       default:
         logwarn("unknown/unsupported PCAP datalink type\n");
         return 0;
     }
}

-- 
-Chuck



More information about the freebsd-net mailing list