> I'm getting the packets via the "divert socket" function, which is just a
> raw socket. It looks like it'll be easier to just write the packet out
> myself, using the pcap format (which is what tcpdump uses).
That's what we did here at NetApp - we have a (hidden) command that lets
us log to a file packets coming into or going out of our box, so that we
can get traces of customer problems.
> The pcap format itself is not documented, looks like I'll have to dig
> through the code to figure it out. It might be easier to figure it out via
> ethereal's code.
It'd actually be Wiretap code, but the format isn't that complicated.
The file begins with a header, whose format is described by the
"pcap_file_header" structure declared in "libpcap"s "pcap.h" header
file. The header has:
a 4-byte "magic number", described below
a 2-byte major version number - choose PCAP_VERSION_MAJOR, as
defined in "pcap.h", i.e. 2
a 2-byte minor version number - choose PCAP_VERSION_MINOR, as
defined in "pcap.h", i.e. 4
a 4-byte offset from local time to UTC, in seconds (I'm not sure
whether it's seconds east or west of Greenwich, but I'm not sure
Ethereal cares, so 0 may be good enough - the actual time stamps
for packets are UTC, so all it does is let you display the
packet in local time *at the location where the packet was
captured*, as opposed to local time at the location where you're
reading the file)
a 4-byte figure for time stamp accuracy, but "libpcap" itself
always writes it out as 0, so you can do the same
a 4-byte "snapshot length" - if you're not writing the *entire*
packet out, but are cutting packets off at a fixed size, save
that, otherwise save either the MTU of the interface or some
large number
a 4-byte data link type:
"null" 0
10Mb Ethernet 1
3Mb Ethernet 2
AX.25 3
ProNET 4
Chaos 5
IEEE 802.x 6
ARCNET 7
SLIP 8
PPP 9
FDDI 10
LLC/SNAP-encapsulated ATM 11
"raw IP" 12
alleged BSD/OS SLIP 13
alleged BSD/OS PPP 14
The "magic number" is TCPDUMP_MAGIC, as defined in "savefile.c", i.e.
0xa1b2c3d4.
*ALL* fields in the header are written in the byte order of the machine
writing them out - the reader needs to check whether the magic number is
normal or byte-swapped and, if byte-swapped, needs to swap the header
fields.
Immediately following the file header is a string of packets, each of
which consists of a packet header followed immediately by the raw packet
data.
The packet header is described by the "pcap_pkthdr" structure declared
in "pcap.h"; it has:
a "struct timeval", containing the time when the file was
captured - yes, the format of this may depend on the platform
you're on, with the fields of that "struct timeval" being 32
bits or 64 bits; this may cause problems if it's 64 bits (at
some point I plan to fix Wiretap to be able to read either
32-bit-timestamp or 64-bit-timestamp packets, as, even if
somebody *does* fix "libpcap" to standardize on 32-bit
timestamps, that doesn't mean every single system will
instantaneously switch to doing things that way)
a 32-bit number indicating how many bytes of packet data were
written to the file (that's the raw packet data; it doesn't
include the length of the packet header)
a 32-bit number indicating how many bytes were in the packet,
which may be greater than the number of bytes written to the
file if, as per the above, the packets were cut off at the
"snapshot length".