My best bet would be to use something like:
tcpdump -ieth0 -s96 -w traffic.dump 'ip or icmp or tcp or udp'
Where the "tricky" part will be to chose a correct value for the "-s" (snaplen) parameter (snaplen is the maximum length of the packet tcpdump will capture).
From the tcpdump man pages:
Snarf snaplen bytes of data from each
packet rather than the default of 68
(with NIT, the minimum is actually
96). 68 bytes is adequate for IP,
ICMP, TCP and UDP but may truncate
protocol information from name server
and NFS packets (see below). Packets
truncated because of a limited
snapshot are indicated in the output
with ``[|proto]'', where proto is the
name of the protocol level at which
the truncation has occurred. Note that
taking larger snapshots both increases
the amount of time it takes to process
packets and, effectively, decreases
the amount of packet buffering. This
may cause packets to be lost. You
should limit snaplen to the smallest
number that will capture the protocol
information you're interested in.
In this example i'm using 96 to be "almost" sure that I would capture 100% of ethernet+ip+(icmp || udp || tcp) header values.
In case your traffic have IP or TCP options (i.e. timestamps) and you want to also capture this info, then you will have to play with the snaplen parameter (i.e. increase/decrease it).
In case the length of the headers of your packet is less than snaplen, you may also capture part of the payload.
Finally, to read the traffic captured, I would use something like:
tcpdump -e -nn -vv -r traffic.dump
Where the important part is to use the "-e" option so you can get the ethernet headers printed.
This page gives you an idea about the size of the ethernet/tcp/udp headers under different circumstances and may help you to arrive to a "correct" value for the snaplen parameter.
If an IP packet is bigger than the MTU of the network link on which the packet is being sent, IP will fragment it into IP packets that can fit on the network; that's done by the IP layer, not the UDP layer.
The MTU of an Ethernet is normally 1500 bytes (the maximum Ethernet packet size is 1518, which includes 14 bytes of header, 1500 bytes of payload, and 4 bytes of FCS). An IPv4 header is 20 bytes if it has no options, and a UDP header is 8 bytes, so the maximum UDP payload size is 1500-28 = 1472.
So IP splits the packet into two or more fragments, and reassembles them on the receiving machine.
See the related question for a discussion of why tcpdump isn't capturing any fragments other than the first fragment.
Best Answer
My first choose would be wireshark. If you must do it from a terminal you can also try ngrep, it gives a more readable output than tcpdump. You can probably filter out the header info with a simple bash script.
http://ngrep.sourceforge.net/usage.html#http