This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

What is the IP header checksum used for and how to calculate it?

0

Solved
I have a udp packet captured through multicast channel and I found that there is a Header checksum under Internet Protocol Version 4.
alt text

I would like to ask

  1. What is it used for?
  2. How to calculate it?

I have tried to search on the web but what I found is the check sum calculation for the whole UDP packet which seems not the same checksum that I am asking for on the above.

Here is what I do for IP Header checksum:

void ReCalculateCheckSum_IPHeader(u_char* pData)
{
    // reset checksum
    pData[24] = 0;
    pData[25] = 0;
uint32_t unChecksum = 0;
const uint16_t* pD16;
pD16 = reinterpret_cast<const uint16_t*>(pData + CommonHelper::IP_HEADER_OFFSET);

// adding checksum for scr IP and dst IP
for (int i = 0; i < 10; i++)
{
    unChecksum += _byteswap_ushort(*pD16++);
}
while (unChecksum >> 16)
{
    unChecksum = (unChecksum & 0xffff) + (unChecksum >> 16);
}

// set checksum back to data
uint16_t un16TempChecksum = static_cast<uint16_t>(~unChecksum);
un16TempChecksum = _byteswap_ushort(un16TempChecksum);
memcpy((char*)(pData + 24), &un16TempChecksum, sizeof(uint16_t));

}

Here is what I do for the UDP checksum:

void ReCalculateCheckSum_UDP_Pkt(u_char* pData, unsigned int unDataLen)
{
// reset checksum
pData[40] = 0;
pData[41] = 0;

uint32_t unChecksum = 0;
const uint16_t* pD16;
const uint8_t* pD8;
// handle IP layer
//      handle src IP
pD16 = reinterpret_cast<const uint16_t*>(pData + 26);
unChecksum += _byteswap_ushort(*pD16++); // since wireshark file is big-endian, but c++ in PC is little-endian
unChecksum += _byteswap_ushort(*pD16);
//      handle dst IP
pD16 = reinterpret_cast<const uint16_t*>(pData + 30);
unChecksum += _byteswap_ushort(*pD16++); // since wireshark file is big-endian, but c++ in PC is little-endian
unChecksum += _byteswap_ushort(*pD16);
//      handle portocol
pD8 = reinterpret_cast<const uint8_t*>(pData + 23);
unChecksum += *pD8;
//      handle data lenght, from IP layer to udp data layer
pD16 = reinterpret_cast<const uint16_t*>(pData + 38);
unChecksum += _byteswap_ushort(*pD16);


// handle UDP layer
//      handle src Port
pD16 = reinterpret_cast<const uint16_t*>(pData + 34);
unChecksum += _byteswap_ushort(*pD16);
//      handle dst Port
pD16 = reinterpret_cast<const uint16_t*>(pData + 36);
unChecksum += _byteswap_ushort(*pD16);
//      handle data lenght, from IP layer to udp data layer
pD16 = reinterpret_cast<const uint16_t*>(pData + 38);
unChecksum += _byteswap_ushort(*pD16);

// handle udp data
size_t len = unDataLen - CommonHelper::DATAGRAME_DATA_OFFSET; // 42 is the Ethernet header
pD16 = reinterpret_cast<const uint16_t*>(pData + CommonHelper::DATAGRAME_DATA_OFFSET);
while (len > 1)
{
    unChecksum += _byteswap_ushort(*pD16++); // since wireshark file is big-endian, but c++ in PC is little-endian
    len -= sizeof(uint16_t);
}
if (len) // if total lenght the data is odd
{
    unChecksum += *reinterpret_cast<const uint8_t*>(pD16);
}


while (unChecksum >> 16)
{
    unChecksum = (unChecksum & 0xffff) + (unChecksum >> 16);
}

// set checksum back to data
uint16_t un16TempChecksum = static_cast<uint16_t>(~unChecksum);
un16TempChecksum = _byteswap_ushort(un16TempChecksum);
memcpy((char*)(pData + 40), &un16TempChecksum, sizeof(uint16_t));

}

asked 22 Oct ‘17, 03:00

SulfredLee's gravatar image

SulfredLee
26448
accept rate: 0%

edited 22 Oct ‘17, 06:12

cmaynard's gravatar image

cmaynard ♦♦
9.4k1038142


2 Answers:

1

The picture shows the IP header and its header checksum. The IP header checksum is used to protect it against errors, same as all the other checksums in a packet for their various parts.

Here's one example of how to calculate it: http://www.thegeekstuff.com/2012/05/ip-header-checksum/

answered 22 Oct '17, 03:08

Jasper's gravatar image

Jasper ♦♦
23.8k551284
accept rate: 18%

Thank you very much. It works.

(22 Oct '17, 05:30) SulfredLee

0

To be clear, the IP Header Checksum helps protect against errors in the IP header only, and not with errors in the payload. This is by design. For further reading, refer to RFC 791 INTERNET PROTOCOL:

1.4. Operation

The Header Checksum provides a verification that the information used
in processing internet datagram has been transmitted correctly.  The
data may contain errors.  If the header checksum fails, the internet
datagram is discarded at once by the entity which detects the error.

3.1. Internet Header Format

Header Checksum:  16 bits

A checksum on the header only. Since some header fields change (e.g., time to live), this is recomputed and verified at each point that the internet header is processed.

The checksum algorithm is:

The checksum field is the 16 bit one's complement of the one's
complement sum of all 16 bit words in the header.  For purposes of
computing the checksum, the value of the checksum field is zero.

This is a simple to compute checksum and experimental evidence indicates it is adequate, but it is provisional and may be replaced by a CRC procedure, depending on further experience.

3.2. Discussion

Checksum

The internet header checksum is recomputed if the internet header is changed. For example, a reduction of the time to live, additions or changes to internet options, or due to fragmentation. This checksum at the internet level is intended to protect the internet header fields from transmission errors.

There are some applications where a few data bit errors are acceptable while retransmission delays are not. If the internet protocol enforced data correctness such applications could not be supported.

For implementations of the Internet Checksum, refer to RFC 1071 Computing the Internet Checksum along with its Errata, RFC 1141 Incremental Updating of the Internet Checksum and RFC 1624 Computation of the Internet Checksum via Incremental Update, which corrects a mistake made in RFC 1141.

If you’re interested in the UDP Checksum, refer to RFC 768 User Datagram Protocol, where you’ll find:

Checksum is the 16-bit one's complement of the one's complement sum of a
pseudo header of information from the IP header, the UDP header, and the
data,  padded  with zero octets  at the end (if  necessary)  to  make  a
multiple of two octets.

The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length. This information gives protection against misrouted datagrams. This checksum procedure is the same as is used in TCP.

              0      7 8     15 16    23 24    31
             +--------+--------+--------+--------+
             |          source address           |
             +--------+--------+--------+--------+
             |        destination address        |
             +--------+--------+--------+--------+
             |  zero  |protocol|   UDP length    |
             +--------+--------+--------+--------+

If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care).

Since RFC 768 indicates that, “This checksum procedure is the same as is used in TCP.", you might also want to have a look at RFC 793 TRANSMISSION CONTROL PROTOCOL, where the Checksum field is described as follows:

Checksum:  16 bits

The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header and text. If a segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a 16 bit word for checksum purposes. The pad is not transmitted as part of the segment. While computing the checksum, the checksum field itself is replaced with zeros.

The checksum also covers a 96 bit pseudo header conceptually prefixed to the TCP header. This pseudo header contains the Source Address, the Destination Address, the Protocol, and TCP length. This gives the TCP protection against misrouted segments. This information is carried in the Internet Protocol and is transferred across the TCP/Network interface in the arguments or results of calls by the TCP on the IP.

               +--------+--------+--------+--------+
               |           Source Address          |
               +--------+--------+--------+--------+
               |         Destination Address       |
               +--------+--------+--------+--------+
               |  zero  |  PTCL  |    TCP Length   |
               +--------+--------+--------+--------+

The TCP Length is the TCP header length plus the data length in
octets (this is not an explicitly transmitted quantity, but is
computed), and it does not count the 12 octets of the pseudo
header.</code></pre></div><div class="answer-controls post-controls"></div><div class="post-update-info-container"><div class="post-update-info post-update-info-user"><p>answered <strong>22 Oct '17, 07:08</strong></p><img src="https://secure.gravatar.com/avatar/55158e2322c4e365a5e0a4a0ac3fbcef?s=32&amp;d=identicon&amp;r=g" class="gravatar" width="32" height="32" alt="cmaynard&#39;s gravatar image" /><p><span>cmaynard ♦♦</span><br />

9.4k1038142
accept rate: 20%