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

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.3k1038142


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/

permanent link

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

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.
permanent link

answered 22 Oct '17, 07:08

cmaynard's gravatar image

cmaynard ♦♦
9.3k1038142
accept rate: 20%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×178
×40
×36
×7

question asked: 22 Oct '17, 03:00

question was seen: 3,629 times

last updated: 22 Oct '17, 07:08

p​o​w​e​r​e​d by O​S​Q​A