Sample trace of a HTTP session

Ooi Chuin Nee C.Ooi@etc.com.au

3 February 1998
© Xamax Consultancy Pty Ltd, 1997, 1998


A dump of the TCP packets in a brief HTTP session was taken to illustrate the steps taken when a client requests a page from a HTTP server. A step by step explanation of the output is provided to guide the reader through the steps taken.


1. Session setup

The following is a sample dump (using tcpdump) of a HTTP request and response. The setup used when the session was captured is as follows:

  1. The HTTP server is running on hal (192.168.0.102). Server software is Apache 1.2.4.
  2. The WWW browser is running on deep-thought (192.168.0.103). Browser software is Netscape Navigator 4.01.
  3. hal is also running a DNS server, and deep-thought has been configured to use hal to resolve hostnames.
  4. hal and deep-thought are both on the same subnet of an ethernet LAN.
  5. The WWW browser is told (by the user) to fetch the document at the URL http://hal.etc.com.au/documentation/apache/ (which consists of a HTML page with 2 images).
  6. The WWW browser has got the "Automatically load images" parameter turned on.

2. Session dump

2.1 Output format

The output from tcpdump has been reformatted for clarity. It is in the format:

[line #]  [timestamp]  [arp/tcp packet details]

The timestamps are in the format hh:mm:ss.frac.

The TCP segment details are in the form:

[originating host IP address].[originating port] > [destination host IP address].[destination port]: TCP header, e.g. 192.168.0.103.1045 > 192.168.0.102.53 indicates a packet going from port 1045 on 192.168.0.103 to port 53 on 192.168.0.102

The TCP header is shown in the following format:

[header flag] [initial sequence number]:[ending sequence number (implied)] ([size in bytes]) [acknowledgement number] [advertised window size] ([other flags])

2.2 tcpdump output


1   14:52:49.463851  arp who-has 192.168.0.102 tell 192.168.0.103
2   14:52:49.463851  arp reply 192.168.0.102 is-at 0:a0:c9:65:14:80
3   14:52:49.463851  192.168.0.103.1045 > 192.168.0.102.53: 7+ A? hal.etc.com.au. (32)
4   14:52:49.463851  192.168.0.102.53 > 192.168.0.103.1045: 7* 1/1/1 A 192.168.0.102 (88)
5   14:52:49.543851  192.168.0.103.1046 > 192.168.0.102.80: S 7861110:7861110(0) win 8192 <mss 1460> (DF)
6   14:52:49.543851  192.168.0.102.80 > 192.168.0.103.1046: S 3595122238:3595122238(0) ack 7861111 win 32736 <mss 1460>
7   14:52:49.543851  192.168.0.103.1046 > 192.168.0.102.80: . ack 3595122239 win 8760 (DF)
8   14:52:49.653851  192.168.0.103.1046 > 192.168.0.102.80: P 7861111:7861361(250) ack 3595122239 win 8760 (DF)
9   14:52:49.663851  192.168.0.102.80 > 192.168.0.103.1046: . 3595122239:3595123699(1460) ack 7861361 win 32736 (DF)
10  14:52:49.663851  192.168.0.102.80 > 192.168.0.103.1046: P 3595123699:3595124724(1025) ack 7861361 win 32736 (DF)
11  14:52:49.663851  192.168.0.103.1046 > 192.168.0.102.80: . ack 3595124724 win 8760 (DF)
12  14:52:50.803851  192.168.0.103.1047 > 192.168.0.102.80: S 7862363:7862363(0) win 8192 <mss 1460> (DF)
13  14:52:50.803851  192.168.0.102.80 > 192.168.0.103.1047: S 3701480536:3701480536(0) ack 7862364 win 32736 <mss 1460>
14  14:52:50.803851  192.168.0.103.1047 > 192.168.0.102.80: . ack 3701480537 win 8760 (DF)
15  14:52:50.873851  192.168.0.103.1048 > 192.168.0.102.80: S 7862437:7862437(0) win 8192 <mss 1460> (DF)
16  14:52:50.873851  192.168.0.102.80 > 192.168.0.103.1048: S 2553725067:2553725067(0) ack 7862438 win 32736 <mss 1460>
17  14:52:50.873851  192.168.0.103.1048 > 192.168.0.102.80: . ack 2553725068 win 8760 (DF)
18  14:52:50.973851  192.168.0.103.1048 > 192.168.0.102.80: P 7862438:7862753(315) ack 2553725068 win 8760 (DF)
19  14:52:50.993851  192.168.0.102.80 > 192.168.0.103.1048: . ack 7862753 win 32736 (DF)
20  14:52:50.993851  192.168.0.102.80 > 192.168.0.103.1048: . 2553725068:2553726528(1460) ack 7862753 win 32736 (DF)
21  14:52:50.993851  192.168.0.102.80 > 192.168.0.103.1048: P 2553726528:2553726886(358) ack 7862753 win 32736 (DF)
22  14:52:50.993851  192.168.0.103.1048 > 192.168.0.102.80: . ack 2553726886 win 8760 (DF)
23  14:52:51.023851  192.168.0.103.1047 > 192.168.0.102.80: P 7862364:7862677(313) ack 3701480537 win 8760 (DF)
24  14:52:51.023851  192.168.0.102.80 > 192.168.0.103.1047: . 3701480537:3701481997(1460) ack 7862677 win 32736 (DF)
25  14:52:51.023851  192.168.0.102.80 > 192.168.0.103.1047: . 3701481997:3701483457(1460) ack 7862677 win 32736 (DF)
26  14:52:51.033851  192.168.0.103.1047 > 192.168.0.102.80: . ack 3701483457 win 8760 (DF)
27  14:52:51.033851  192.168.0.102.80 > 192.168.0.103.1047: P 3701483457:3701484633(1176) ack 7862677 win 32736 (DF)
28  14:52:51.033851  192.168.0.102.80 > 192.168.0.103.1047: . 3701484633:3701486093(1460) ack 7862677 win 32736
29  14:52:51.033851  192.168.0.102.80 > 192.168.0.103.1047: P 3701486093:3701486899(806) ack 7862677 win 32736 (DF)
30  14:52:51.033851  192.168.0.103.1047 > 192.168.0.102.80: . ack 3701486899 win 8760 (DF)
31  14:53:04.663851  192.168.0.102.80 > 192.168.0.103.1046: F 3595124724:3595124724(0) ack 7861361 win 32736
32  14:53:04.663851  192.168.0.103.1046 > 192.168.0.102.80: . ack 3595124725 win 8760 (DF)
33  14:53:05.993851  192.168.0.102.80 > 192.168.0.103.1048: F 2553726886:2553726886(0) ack 7862753 win 32736
34  14:53:05.993851  192.168.0.103.1048 > 192.168.0.102.80: . ack 2553726887 win 8760 (DF)
35  14:53:06.023851  192.168.0.102.80 > 192.168.0.103.1047: F 3701486899:3701486899(0) ack 7862677 win 32736
36  14:53:06.023851  192.168.0.103.1047 > 192.168.0.102.80: . ack 3701486900 win 8760 (DF)

3. Explanation of the output

The first thing that the WWW browser needs to do is resolve the IP address for the hostname in the URL, which is hal.etc.com.au. To do so, it sends an ARP query to resolve the ethernet address for the configured name server (which is 192.168.0.102). It then sends a DNS query to 192.168.0.102 to resolve the hostname to an IP address and subsequently sends a HTTP request for the document to hal.

The HTTP server on hal responds with the appropriate document, which was a HTML file in this case. As the HTML file was parsed by the WWW browser, it finds that two images have been linked in on that page. The WWW browser then automatically sends another two HTTP requests to hal to retrieve these two images.

3.1 ARP query

Line 1

ARP broadcast query from deep-thought to resolve the ethernet address for 192.168.0.102.

Line 2

192.168.0.102 responds with the ethernet address 00:a0:c9:65:14:80.

3.2 DNS host address query

Line 3

deep-thought sends a DNS query to 192.168.0.102 (port 53 is the 'well-known' port for DNS). The request identification field is set to 7, the query is of type A (a query for host address), and the query name is "hal.etc.com.au"

Line 4

The response to the host address query. 7* indicates that it is responding to the request for which the request identification field was 7 and that the response was authoritative. The host address for hal.etc.com.au is 192.168.0.102.

Additional notes

The DNS query and response was sent over UDP, which is the recommended method for queries. UDP is a connectionless protocol so no handshaking is necessary to establish the connection.

3.3 Initial HTTP request and response

TCP connection establishment

Line 5

deep-thought sends a TCP packet with the SYN flag set and sequence number 7861110 with 0 bytes in the data segment to port 80 on hal (port 80 is the 'well-known' port for HTTP).

Line 6

hal responds with a TCP packet with the sequence number 3595122238 with 0 bytes in the data segment. Additionally, that TCP packet has the acknowledgement number set to 7861111 to acknowledge the receipt of the packet previously sent to hal by deep-thought (7861111 is derived from the sequence number of that packet = 7861110 + 1).

Line 7

deep-thought to hal, acknowledgement number 3595122239 (3595122238 + 1), which completes the TCP handshake.

HTTP request

Line 8

deep-thought sends a 250 byte request to hal. The contents of the request (which is not shown in the tcpdump output above) is as follows:
(<crlf> is used to indicate the carriage return and line feed characters)


GET /documentation/apache/ HTTP/1.0<crlf>
Connection: Keep-Alive<crlf>
User-Agent: Mozilla/4.01 [en] (Win95; I)<crlf>
Host: hal.etc.com.au<crlf>
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*<crlf>
Accept-Language: en<crlf>
Accept-Charset: iso-8859-1,*,utf-8<crlf>
<crlf>

HTTP response

Lines 9 and 10

hal sends a total of (1460 + 1025 = ) 2485 bytes to deep-thought, and the acknowledgement number is set to the sequence number of the last segment received (7861361). The response (contents not shown in the tcpdump output above) consists of the following HTTP headers (278 bytes) and the HTML document requested (2207 bytes, omitted for brevity):


HTTP/1.1 200 OK<crlf>
Date: Mon, 19 Jan 1998 03:52:49 GMT<crlf>
Server: Apache/1.2.4<crlf>
Last-Modified: Wed, 08 Oct 1997 04:15:24 GMT<crlf>
ETag: "2ce0b-89f-343b08dc"<crlf>
Content-Length: 2207<crlf>
Accept-Ranges: bytes<crlf>
Keep-Alive: timeout=15, max=100<crlf>
Connection: Keep-Alive<crlf>
Content-Type: text/html<crlf>
<crlf>
[  2207 byte HTML document deleted  ]

The response was broken up into two segments because the amount of data to be transferred was greater than the maximum segment size (MSS), which was negotiated in the handshake as 1460 bytes.

Line 11

deep-thought acknowledges the receipt of the last two segments, the last finishing with the sequence number 3595124724.

TCP connection termination

Line 31

hal closes the connection approximately 15 seconds after the receipt of the previous GET on this TCP connection.

Line 32

deep-thought acknowledges receipt of the FIN.

Additional notes

Only a half-closure of the connection was captured. TCP is a full duplex protocol, so a proper closure requires the sending 4 messages - i.e. each end must send a segment with the FIN flag set and an ACK of the other end's FIN.

Previous versions of the HTTP protocol required that separate TCP connections be used to fetch each URL. In order to improve performance of the protocol, the latest versions of HTTP allow persistent connections (keep-alive) - multiple HTTP requests and responses can be sent on the same TCP connection. Therefore, a FIN segment is not immediately sent after the transmission of the data is completed. In this case, Apache has been configured to keep the connection alive for 15 seconds after the receipt of last request from the client, after which the connection will be terminated. Hence, it sent a FIN segment which was acknowledged by the client. The client still has not closed the connection on its end.

3.4 Subsequent HTTP requests and reponses

As the browser parses the HTML document received from the hal, it finds that it has to load two images, and thus, spawns requests for those images.

Image 1

Lines 12-14

TCP 3 way handshake to establish the connection, as per explanation above. This time, the request originates from port 1047 on deep-thought to port 80 on hal.

Line 23

deep-thought sends a 313 byte request to hal for the image http://hal.etc.com.au/documentation/apache/images/sub.gif


GET /documentation/apache/images/sub.gif HTTP/1.0<crlf>
Referer: http://hal.etc.com.au/documentation/apache/<crlf>
Connection: Keep-Alive<crlf>
User-Agent: Mozilla/4.01 [en] (Win95; I)<crlf>
Host: hal.etc.com.au<crlf>
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg<crlf>
Accept-Language: en<crlf>
Accept-Charset: iso-8859-1,*,utf-8<crlf>

Lines 24-25, 27-29

hal sends a total of (1460 + 1460 + 1176 + 1460 + 806 = ) 6362 bytes, which consists of 279 bytes of header (as shown below) and 6083 bytes of binary data (the GIF image)


HTTP/1.1 200 OK<crlf>
Date: Mon, 19 Jan 1998 03:52:51 GMT<crlf>
Server: Apache/1.2.4<crlf>
Last-Modified: Wed, 08 Oct 1997 04:15:24 GMT<crlf>
ETag: "61a85-17c3-343b08dc"<crlf>
Content-Length: 6083<crlf>
Accept-Ranges: bytes<crlf>
Keep-Alive: timeout=15, max=100<crlf>
Connection: Keep-Alive<crlf>
Content-Type: image/gif<crlf>
<crlf>

Lines 26 and 30

deep-thought to hal, acknowledgement of TCP segments sent.

Line 35 and 36

See TCP connection termination explanation above.

Image 2

Lines 15-17:

TCP 3 way handshake, as per explanation above. The request originates from port 1048 on deep-thought to port 80 on hal.

Line 18

deep-thought sends a 315 byte request to hal for the image http://hal.etc.com.au/documentation/apache/images/index.gif.


GET /documentation/apache/images/index.gif HTTP/1.0<crlf>
Referer: http://hal.etc.com.au/documentation/apache/<crlf>
Connection: Keep-Alive<crlf>
User-Agent: Mozilla/4.01 [en] (Win95; I)<crlf>
Host: hal.etc.com.au<crlf>
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg<crlf>
Accept-Language: en<crlf>
Accept-Charset: iso-8859-1,*,utf-8<crlf>
<crlf>

Line 19

hal acknowledges the receipt of the TCP segment

Lines 20 and 21:

hal sends a total of (1460 + 358 = ) 1818 bytes to deep-thought, which consists of a 278 byte header (shown below) followed by 1540 bytes of binary data (the GIF image).


HTTP/1.1 200 OK<crlf>
Date: Mon, 19 Jan 1998 03:52:50 GMT<crlf>
Server: Apache/1.2.4<crlf>
Last-Modified: Wed, 08 Oct 1997 04:15:24 GMT<crlf>
ETag: "61a84-604-343b08dc"<crlf>
Content-Length: 1540<crlf>
Accept-Ranges: bytes<crlf>
Keep-Alive: timeout=15, max=100<crlf>
Connection: Keep-Alive<crlf>
Content-Type: image/gif<crlf>
<crlf>

Line 22

deep-thought acknowledges the receipt of the 1818 bytes sent.

Lines 33 and 34

See TCP connection termination explanation above.