9

If we use ICMP's ping, we know the TTL and round-trip time are stored in the IP header. In the below IP header map we know TTL's location, but where is the round-trip time?

Enter image description here

Is it stored in Options?

2 Answers 2

23

The round trip time is not actually stored anywhere. The sending host remembers the time it sends each ICMP Echo Request message, using ICMP's 16-bit identifier and sequence fields. When it gets the ICMP Echo Reply, it notes the current time, finds the time it sent the matching Request packet identified by the reply, calculates the difference, and reports it.

Typically ping uses ICMP's identification field to differentiate multiple simultaneous pings, and the sequence field to differentiate individual packets.

It is up to the implementation to decide where to store the outgoing time for a given packet: instead of storing it on the host in a table, it typically sends it in the outgoing request and uses the copy in the reply to calculate the time. (Thanks commenters for pointing this out.) It's sent in whatever way is convenient for the implementation, and of course has to trust the far end, and any intervening equipment, to properly copy the data. Some systems are known to represent the time in 16 bytes with resolution of microseconds, some as 8 bytes with resolution of milliseconds.

The format inside the data portion of the IP packet is the ICMP Echo Request/Reply message, copied here from RFC 792 "Internet Control Message Format" (p14).

Type is 8 for Request, 0 for Reply; Code is 0.

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |     Code      |          Checksum             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Identifier          |        Sequence Number        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Data ...
   +-+-+-+-+-

PS. Just to be clear, the identification field of the IP header is normally set to an arbitrary value, different for each outgoing packet, used for reassembly of any fragmentation, and doesn't have the same value as anything in the ICMP body.

Also, although there is a mechanism defined for putting timestamps into the IP header as an option, this is not the normal mechanism for ping because very many routers are configured not to pass certain IP options. See RFC 781 Specification of the Internet Protocol Timestamp Option.

Finally, although everything here was written from an IPv4 perspective, per the original question; but ping in IPv6 is extremely similar, see ICMPv6 RFC 4443.

4
  • 3
    AIUI the "identification" field is used to identify packets for fragment reassembly. Echo requests are matched to echo replies by the id and seq fields in the ICMP header. Sep 14, 2018 at 15:14
  • Thanks for pointing it out: I clarified it's the ICMP not IP id (and seq, as you say).
    – jonathanjo
    Sep 14, 2018 at 18:33
  • I'm pretty sure there is at least one implementation of ping on Linux which stores the timestamp in the Data section of the ICMP payload. That lead to some quite interesting error message when the echo replies traversed an internet exchange which was corrupting a bit in that location in every packet.
    – kasperd
    Sep 14, 2018 at 20:13
  • You're right of course, and I updated the answer to say this; though naturally it's the sending absolute time according to sender's clock that's stored, not RTT itself.
    – jonathanjo
    Sep 15, 2018 at 13:02
3

At least with the common ping utility on Linux, the time when the packet was sent is stored in the data part of the echo request packet, i.e. after the IP and ICMP headers. The data part is kept intact when the receiver replies with an echo reply, so the sender can calculate the round-trip time.

This is described in the man page for the ping utility (under "ICMP PACKET DETAILS"):

If the data space is at least of size of struct timeval ping uses the beginning bytes of this space to include a timestamp which it uses in the computation of round trip times. If the data space is shorter, no round trip times are given.

On my machine sizeof(struct timeval) is 16, so setting the packet data size to 15 prevents ping from showing the round-trip times:

$ ping -s 15 8.8.8.8 
PING 8.8.8.8 (8.8.8.8) 15(43) bytes of data.
23 bytes from 8.8.8.8: icmp_seq=1 ttl=121

Of course, storing the send timestamp within the utility, as @jonathanjo's answer describes, would also be a possible implementation. Even the Linux utility needs some internal bookkeeping, since it detects duplicate packets.

4
  • 1
    It feels like it is a program bug that they cannot display the RTT when you set the data size to be less than 16. But good points.
    – canadadry
    Sep 14, 2018 at 20:32
  • @canadadry, Well, putting the timestamp in the packet itself is just obvious: the only situation it's needed is when the reply packet comes, so there's no use in storing it locally. Of course, the program appears to be derived from the '80s BSD original, so it may have something to do with the times, too. Anyway, I'm not exactly sure why anyone would want to use such extra-small packets. Note that even the minimum Ethernet frame size is large enough to fit the Ethernet, IP, and ICMP headers, and a 16-byte timestamp. (Though with 2 bytes left over, so not much room for any further extension.)
    – ilkkachu
    Sep 15, 2018 at 2:15
  • @ilkkachu thanks for reminding me where the time often stored; I updated my answer. Re tiny packets: many network problems are differentiated on packet size.
    – jonathanjo
    Sep 15, 2018 at 13:04
  • @ikkachu I took a look at Cisco's ping packets: they also have the time, as 64-bit count of milliseconds.
    – jonathanjo
    Sep 15, 2018 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.