Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. TCP header checksum calculation

TCP header checksum calculation

Scheduled Pinned Locked Moved C / C++ / MFC
sysadminalgorithmsperformancehelpquestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AIDS
    wrote on last edited by
    #1

    Hi All, I got stuck with TCP header checksum calculation. RFC 793 says checksum is calculated using the same algorithm as IP header checksum and includes 96-bit pseudo header + data. I have written a checksum calculation function, and it works well for IP headers, but when I apply it to the TCP packet the function produces wrong results. I have captured a TCP packet from my network, and put it into my test program. There are 2 checksum functions in the code: Checksum and ChecksumRFC. The last one is taken from RFC1071. The code is for Windows 2000, VC6.0 Could anyone explain me what I do wrong? #include <stdio.h> #include <windows.h> // to ensure memory alignment #include <pshpack1.h> typedef struct _IP_HEADER { UCHAR HeaderLength :4; // Header length in 32-bit words UCHAR Version :4; // IP version UCHAR TypeOfService; // USHORT TotalLength; // Total datagram (header + data) length in bytes USHORT Identification; // USHORT FlagsFragment; // Flags (3 bits) + Fragment position (13bits) in datagram (in 64-bit units) UCHAR TimeToLive; // UCHAR Protocol; // Next level protocol USHORT Checksum; // IP header checksum ULONG SourceAddress; // Source address ULONG DestAddress; // Destination address } IP_HEADER, *PIP_HEADER; // // Next level protocol IDs // #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 // // TCP Header (rfc 793) // typedef struct _TCP_HEADER { USHORT SourcePort; // USHORT DestPort; // ULONG SeqNumber; // Sequence number ULONG AckNumber; // Acknowledge number UCHAR Reserved :4; // Reserved must be zero UCHAR Offset :4; // TCP Header size in 32-bit words UCHAR FIN :1; // No more data from Sender UCHAR SYN :1; // Synchronize sequence number UCHAR RST :1; // Reset the connection UCHAR PSH :1; // Push function UCHAR ACK :1; // Acknowledgment field significant UCHAR URG :1; // Urgent pointer field significant UCHAR Reserved1:1; // UCHAR Reserved2:1; // USHORT Window; // Number of data octets which the sender of this segment is willing to accept USHORT Checksum; // Checksum of header + data USHORT Urgent; // } TCP_HEADER, *PTCP_HEADER; // // TCP pseudo header for checksum calculation // // to ensure memory alignment typedef struct _TCP_PSEUDOHEADER { ULONG SourceAddress; // source IP address ULONG DestAddress; // destination IP address UCHAR Zero; // must be 0 UCHAR Protocol;

    K S 2 Replies Last reply
    0
    • A AIDS

      Hi All, I got stuck with TCP header checksum calculation. RFC 793 says checksum is calculated using the same algorithm as IP header checksum and includes 96-bit pseudo header + data. I have written a checksum calculation function, and it works well for IP headers, but when I apply it to the TCP packet the function produces wrong results. I have captured a TCP packet from my network, and put it into my test program. There are 2 checksum functions in the code: Checksum and ChecksumRFC. The last one is taken from RFC1071. The code is for Windows 2000, VC6.0 Could anyone explain me what I do wrong? #include <stdio.h> #include <windows.h> // to ensure memory alignment #include <pshpack1.h> typedef struct _IP_HEADER { UCHAR HeaderLength :4; // Header length in 32-bit words UCHAR Version :4; // IP version UCHAR TypeOfService; // USHORT TotalLength; // Total datagram (header + data) length in bytes USHORT Identification; // USHORT FlagsFragment; // Flags (3 bits) + Fragment position (13bits) in datagram (in 64-bit units) UCHAR TimeToLive; // UCHAR Protocol; // Next level protocol USHORT Checksum; // IP header checksum ULONG SourceAddress; // Source address ULONG DestAddress; // Destination address } IP_HEADER, *PIP_HEADER; // // Next level protocol IDs // #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 // // TCP Header (rfc 793) // typedef struct _TCP_HEADER { USHORT SourcePort; // USHORT DestPort; // ULONG SeqNumber; // Sequence number ULONG AckNumber; // Acknowledge number UCHAR Reserved :4; // Reserved must be zero UCHAR Offset :4; // TCP Header size in 32-bit words UCHAR FIN :1; // No more data from Sender UCHAR SYN :1; // Synchronize sequence number UCHAR RST :1; // Reset the connection UCHAR PSH :1; // Push function UCHAR ACK :1; // Acknowledgment field significant UCHAR URG :1; // Urgent pointer field significant UCHAR Reserved1:1; // UCHAR Reserved2:1; // USHORT Window; // Number of data octets which the sender of this segment is willing to accept USHORT Checksum; // Checksum of header + data USHORT Urgent; // } TCP_HEADER, *PTCP_HEADER; // // TCP pseudo header for checksum calculation // // to ensure memory alignment typedef struct _TCP_PSEUDOHEADER { ULONG SourceAddress; // source IP address ULONG DestAddress; // destination IP address UCHAR Zero; // must be 0 UCHAR Protocol;

      K Offline
      K Offline
      Koep
      wrote on last edited by
      #2

      I can't help you. But which Packet driver do you use, i have a similar project, but not with TCP. Marco

      A 1 Reply Last reply
      0
      • K Koep

        I can't help you. But which Packet driver do you use, i have a similar project, but not with TCP. Marco

        A Offline
        A Offline
        AIDS
        wrote on last edited by
        #3

        I do not use any Packet driver. I have captured the packet using Windows 2000 Network Monitor. And I need to calculate checksums in my driver, which is NDIS intermediate driver.

        1 Reply Last reply
        0
        • A AIDS

          Hi All, I got stuck with TCP header checksum calculation. RFC 793 says checksum is calculated using the same algorithm as IP header checksum and includes 96-bit pseudo header + data. I have written a checksum calculation function, and it works well for IP headers, but when I apply it to the TCP packet the function produces wrong results. I have captured a TCP packet from my network, and put it into my test program. There are 2 checksum functions in the code: Checksum and ChecksumRFC. The last one is taken from RFC1071. The code is for Windows 2000, VC6.0 Could anyone explain me what I do wrong? #include <stdio.h> #include <windows.h> // to ensure memory alignment #include <pshpack1.h> typedef struct _IP_HEADER { UCHAR HeaderLength :4; // Header length in 32-bit words UCHAR Version :4; // IP version UCHAR TypeOfService; // USHORT TotalLength; // Total datagram (header + data) length in bytes USHORT Identification; // USHORT FlagsFragment; // Flags (3 bits) + Fragment position (13bits) in datagram (in 64-bit units) UCHAR TimeToLive; // UCHAR Protocol; // Next level protocol USHORT Checksum; // IP header checksum ULONG SourceAddress; // Source address ULONG DestAddress; // Destination address } IP_HEADER, *PIP_HEADER; // // Next level protocol IDs // #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 // // TCP Header (rfc 793) // typedef struct _TCP_HEADER { USHORT SourcePort; // USHORT DestPort; // ULONG SeqNumber; // Sequence number ULONG AckNumber; // Acknowledge number UCHAR Reserved :4; // Reserved must be zero UCHAR Offset :4; // TCP Header size in 32-bit words UCHAR FIN :1; // No more data from Sender UCHAR SYN :1; // Synchronize sequence number UCHAR RST :1; // Reset the connection UCHAR PSH :1; // Push function UCHAR ACK :1; // Acknowledgment field significant UCHAR URG :1; // Urgent pointer field significant UCHAR Reserved1:1; // UCHAR Reserved2:1; // USHORT Window; // Number of data octets which the sender of this segment is willing to accept USHORT Checksum; // Checksum of header + data USHORT Urgent; // } TCP_HEADER, *PTCP_HEADER; // // TCP pseudo header for checksum calculation // // to ensure memory alignment typedef struct _TCP_PSEUDOHEADER { ULONG SourceAddress; // source IP address ULONG DestAddress; // destination IP address UCHAR Zero; // must be 0 UCHAR Protocol;

          S Offline
          S Offline
          Stephen C Steel
          wrote on last edited by
          #4

          It may not be the problem, but you should be suspicous of any cross platform code using bitfields to pick out bits like this. The C standard does not define whether bitfields are allocated starting from the most or least significant bits of the variable. Different compilers may interpret this code differently!

          UCHAR HeaderLength :4; // Header length in 32-bit words

          Some compilers will use the high nibble, others the lower nibble. Its much safer to use masks and shifts:

          Either
          HeaderLength = (uchar_var & 0xF0) >> 4
          or
          HeaderLength = (uchar_var & 0x0F)
          as appropriate. Stephen C. Steel Kerr Vayne Systems Ltd.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups