Analysis of HTTP message #1
I am going to analyse a simple HTTP request response at packet level from application layer down to data link layer in this post. I took a sample packet capture by connecting to my web page which displays only “Hello World!” on an Apache web server. There are 10 ethernet frames captured and I will try to examine each frame by referencing the time value in each row. Below is the list of each packet in order. Let’s start analyzing each:
1) 0.000000 TCP connection request (SYN segment)
a) Ethernet header
This the ethernet header of our first frame. My PC’s MAC address (a8:d0:e5:b3:99:c1) and web server’s MAC address ( 00:0c:29:c0:c6:df) are clearly shown. Header also contains an EtherType field which indicates the type of the payload in the upper layer. In our example 0x0800 stands for IPv4 protocol.
b) IP Header
Header length: This contains the entire IP header size 4+4 of which is occupied by source and destination addresses only. In our example it is 20 bytes in total.
Total length: This is the entire packet size.For example you can easily say that total size of the layers above IP layer is 48-20=28 bytes.
Identification: This identification number helps to identify fragments of an IP packet if fragmentation has occurred. It is set even though there is no fragmentation!
DF (Don’t fragment) flag: If a packet is marked with DF bit, network devices shouldn’t fragment the packet under any circumstances. Instead they are supposed to send an ICMP notification message back “Destination unreachable (Fragmentation needed)”
Fragment Offset: it specifies the offset of the current fragment to the beginning. As our more-fragment bit is 0 and like fragment offset field, this is not a fragmented packet.
Time to live: This is the number which is decremented at each hop. My client PC (sender) is in the same segment with the web server (receiver) which means there is no intermediate host. My PC sends the packet with TTL=128 and receiving host decrements it by 1 because of which we see 127 in the packet capture on the receiving side.
Protocol: This indicates what is our payload. In our capture, payload is a TCP segment whose protocol number is 6. If the payload was UDP then it would be 17. Check wikipedia
or associated RFC for more info.
Source & Destination: These fields are self explanatory indeed. Source IP address and Destination IP addresses.
Source port & Destination port: These are two obvious fields indeed. Source port is randomly assigned (2371) and 80 is the web server port.
Sequence number: 2215066426 is the sender’s Initial Sequence Number (ISN) and it is sent by two sides of this communication arbitrarily. Sequence number represents the number of bytes sent from each nodes in order. Therefore either nodes can reconstruct the data when they receive. As this is the first segment of this communication, sender introduces it is starting sequence number to the other node and this is the only segment without any ACK bit set!
Header length: TCP header length is 28 bytes in this initial segment. A normal TCP header is 20 bytes but we have additional options in this segment. Let’s go back and take a look at the IP total length = 48 and IP header length=20 fields. IP total – IP header = 28 which is our TCP segment. In this initial segment, it is also equal to the TCP header. The reason is we don’t have any data on this initial TCP segment. That is why we end up finding the header length after this subtraction.
Flags:
Syn :As this is the initial connection request only the Syn (Synchronize) bit is set which is used to initialize the connection.
Ack: Ack bit isn’t set. Why? Because we don’t expect anything as we haven’t received anything. It indicates that we have received some data let’s say 4 bytes and we set it to 5 which means “I have got 4 bytes already” and send me the 5th.
Reset: This is the bit of unexpected events e.g if you try to connect to a port which isn’t listened or an invalid sequence number is received.
Push: I like this bit:) as it helps me to see what I type in my ssh,telnet sessions. I can’t image internet without this bit:) TCP segment is like a truck. You must fill the truck completely to benefit the bandwidth but what if your message is urgent? Then you can’t use a truck as you can’t wait that long. Than you should use micro truck or a ferrari to send your message as quickly as possible.
Window Size: This field indicates how many bytes we are willing to receive at one time. It is all related to the buffers and capacity. Only this field itself is the topic of a post indeed. So I will leave it here.
Maximum Segment Size: This is an optional field and you can only see it during the initial communication not later. It is indicates the maximum size of the TCP segment data which means excluding headers that can be accepted on this specific connection. As RFC 879 says “The MSS counts only data octets in the segment, it does not count the TCP header or the IP header.” It isn’t a negotiation but an announcement. For details you can check the RFC
TCP SACK: As you might now TCP acknowledgements are cumulative. Receiver doesn’t acknowledge every byte it receives one by one but acks them in total. There are situations where you may need to acknowledge a particular segment. To me it seems a controversial option though. For details RFC2018
This is the end of the first post. I will have a few more posts until I finish this whole conversation. We have finished the first SYN request yet. Stay tuned!