I have a small function that tries to print the fragment offset of an IP header.
ParseIpHeader(unsigned char *packet, int len)
{
struct ethhdr *ethernet_header;
struct iphdr *ip_header;
/* First Check if the packet contains an IP header using
the Ethernet header */
ethernet_header = (struct ethhdr *)packet;
if(ntohs(ethernet_header->h_proto) == ETH_P_IP)
{
/* The IP header is after the Ethernet header */
if(len >= (sizeof(struct ethhdr) + sizeof(struct iphdr)))
{
ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));
/* print the Source and Destination IP address */
//printf("Dest IP address: %s\n", inet_ntoa(ip_header->daddr));
//printf("Source IP address: %s\n", inet_ntoa(ip_header->saddr));
printf("protocol %d\n", ip_header->protocol);
printf("Fragment off is %d\n", ntohs(ip_header->frag_off));
}
}
My packets are TCP (the ip_header->protocol is always 6. the problem is that the frag_off
is always 16384. I am sending a lot of data, why the frag_off is always constant?
Thanks.
Fragment offset is shared with flags. You have the “DF” (don’t fragment) bit set.
Which gives you 16384 for the entire 16-bit field, given the fragment offset of 0.
Take a look at the http://www.ietf.org/rfc/rfc791.txt, starting from page 10.
EDIT:
The DF bit in the TCP segments that you are receiving is set by the remote side, to perform the Path MTU discovery – in a nutshell, to try to avoid the fragmentation.
In this case the sending side learns the biggest MTU that the overall path can handle, and chops the TCP segments such that they did not exceed it after the encapsulation into IP.
EDIT2:
regarding the use of recvfrom() and TCP: TCP is a connection-oriented protocol, and all of the segmentation/fragmentation details are already handled by it (fragmentation is obviously handled by the lower layer, IP) – so you do not need to deal with it. Anything you write() on the sending side will be eventually read() on the other side – possibly not in the same chunks though – i.e. two 4K writes may result in a single 8K read sometimes, and sometimes in two 4K reads – depending on the behaviour of the media inbetween concerning reordering/losses.
IP Fragmentation and reassembly is handled transparently by the operating system, so you do not need to worry about it, same as about packets out of order, etc. (you will just see the decreased performance as the effect on the application).
One good read I could recommend is this one: UNIX network programming. Given Steven’s involvement with the TCP, it’s a good book no matter which OS you use.
EDIT3:
And if you are doing something to be a “man in the middle” (assuming you have good and legitimate reasons for doing so 🙂 – then you can assess the upcoming work by looking at the prior art: chaosreader (one-script approach that works on pcap files, but adaptable to something else), or LibNIDS – that does emulate the IP defragmentation and the TCP stream reassembly; and maybe just reuse them for your purposes.