Click here to Skip to main content
15,892,059 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: min-max values Pin
markkuk30-Aug-02 1:16
markkuk30-Aug-02 1:16 
GeneralRe: min-max values Pin
Tomasz Sowinski30-Aug-02 1:29
Tomasz Sowinski30-Aug-02 1:29 
GeneralRe: min-max values Pin
Zizilamoroso30-Aug-02 3:41
Zizilamoroso30-Aug-02 3:41 
GeneralMemory leakages Pin
Anonymous30-Aug-02 0:56
Anonymous30-Aug-02 0:56 
GeneralRe: Memory leakages Pin
Tomasz Sowinski30-Aug-02 1:09
Tomasz Sowinski30-Aug-02 1:09 
GeneralRe: Memory leakages Pin
pépé30-Aug-02 4:11
pépé30-Aug-02 4:11 
GeneralRe: Memory leakages Pin
Anders Molin30-Aug-02 12:40
professionalAnders Molin30-Aug-02 12:40 
GeneralTCP header checksum calculation Pin
AIDS30-Aug-02 0:56
AIDS30-Aug-02 0:56 
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?

<br />
#include <stdio.h><br />
#include <windows.h><br />
<br />
<br />
<br />
// to ensure memory alignment<br />
#include <pshpack1.h><br />
<br />
typedef struct _IP_HEADER<br />
{<br />
	UCHAR  HeaderLength :4;	 // Header length in 32-bit words<br />
	UCHAR  Version      :4;	 // IP version<br />
<br />
	UCHAR  TypeOfService;	 // <br />
	USHORT TotalLength;		 // Total datagram (header + data) length in bytes<br />
	USHORT Identification;	 // <br />
	USHORT FlagsFragment;    // Flags (3 bits) + Fragment position (13bits) in datagram (in 64-bit units)<br />
	UCHAR  TimeToLive;		 //<br />
	UCHAR  Protocol;		 // Next level protocol <br />
	USHORT Checksum;		 // IP header checksum<br />
	ULONG  SourceAddress;	 // Source address<br />
	ULONG  DestAddress;		 // Destination address<br />
} IP_HEADER, *PIP_HEADER;<br />
<br />
<br />
//<br />
// Next level protocol IDs<br />
//<br />
#define IPPROTO_TCP 6<br />
#define IPPROTO_UDP 17<br />
<br />
<br />
//<br />
// TCP Header (rfc 793)<br />
//<br />
<br />
typedef struct _TCP_HEADER<br />
{<br />
	USHORT SourcePort;	//<br />
	USHORT DestPort;	//<br />
	ULONG  SeqNumber;	// Sequence number<br />
	ULONG  AckNumber;	// Acknowledge number<br />
	UCHAR  Reserved :4;	// Reserved must be zero<br />
	UCHAR  Offset   :4;	// TCP Header size in 32-bit words<br />
	UCHAR  FIN      :1;	// No more data from Sender	<br />
	UCHAR  SYN      :1;	// Synchronize sequence number<br />
	UCHAR  RST      :1;	// Reset the connection<br />
	UCHAR  PSH      :1;	// Push function<br />
	UCHAR  ACK      :1;	// Acknowledgment field significant<br />
	UCHAR  URG      :1;	// Urgent pointer field significant<br />
	UCHAR  Reserved1:1;	// <br />
	UCHAR  Reserved2:1;	//<br />
	USHORT Window;		// Number of data octets which the sender of this segment is willing to accept<br />
	USHORT Checksum;	// Checksum of header + data<br />
	USHORT Urgent;		// <br />
} TCP_HEADER, *PTCP_HEADER;<br />
<br />
<br />
//<br />
// TCP pseudo header for checksum calculation<br />
//<br />
<br />
// to ensure memory alignment<br />
typedef struct _TCP_PSEUDOHEADER<br />
{<br />
	ULONG  SourceAddress;	// source IP address<br />
	ULONG  DestAddress;		// destination IP address<br />
	UCHAR  Zero;			// must be 0<br />
	UCHAR  Protocol;		// protocol - always 0x6<br />
	USHORT TcpLength;		// length of TCP header + data<br />
} TCP_PSEUDOHEADER, *PTCP_PSEUDOHEADER;<br />
<br />
#include <poppack.h><br />
<br />
<br />
//<br />
// For debug purposes only. Dumps the Ip header's content<br />
// to the debugger window<br />
//<br />
VOID DumpIPHeader( PIP_HEADER IpHeader )<br />
{<br />
	printf <br />
		(<br />
			"=== IP Header Dump Begin ===\n"<br />
			"Header length (32bit words): %d\n"<br />
			"Version:                     %d\n"<br />
			"TypeOfService:               %d\n"<br />
			"TotalLength:                 %d\n"<br />
			"Identification:            0x%0X\n"<br />
			"Flags/Fragment:            0x%X\n"<br />
			"TimeToLive:                0x%X\n"<br />
			"Protocol:                  0x%X\n"<br />
			"Checksum:                  0x%X\n"<br />
			"Source:                    0x%08X\n"<br />
			"Dest:                      0x%08X\n"<br />
			,<br />
			IpHeader->HeaderLength,<br />
			IpHeader->Version, <br />
			IpHeader->TypeOfService, <br />
			ntohs( IpHeader->TotalLength ), <br />
			IpHeader->Identification, <br />
			IpHeader->FlagsFragment, <br />
			IpHeader->TimeToLive, <br />
			IpHeader->Protocol, <br />
			IpHeader->Checksum, <br />
			IpHeader->SourceAddress, <br />
			IpHeader->DestAddress<br />
	);<br />
}<br />
<br />
VOID DumpTCPHeader( PTCP_HEADER TcpHeader )<br />
{<br />
 <br />
	printf	(<br />
			"=== TCP Header Dump Begin ===\n"<br />
			"Source port: 0x%4X\n"<br />
			"Dest port  : 0x%4X\n"<br />
			"Sequence   : 0x%0X\n"<br />
			"Acknowledge: 0x%0X\n"<br />
			"Offset     : %d\n"<br />
			"SYN        : 0x%X\n"<br />
			"Window     : 0x%X\n"<br />
			"Checksum   : 0x%X\n"<br />
			"Urgent   : 0x%X\n"<br />
			"ACK        : 0x%X\n"<br />
			"PSH        : 0x%X\n"<br />
			,<br />
			TcpHeader->SourcePort, <br />
			TcpHeader->DestPort, <br />
			ntohl(TcpHeader->SeqNumber),<br />
			ntohl(TcpHeader->AckNumber), <br />
			TcpHeader->Offset,<br />
			TcpHeader->SYN, <br />
			TcpHeader->Window, <br />
			TcpHeader->Checksum,<br />
			TcpHeader->Urgent,<br />
			TcpHeader->ACK, <br />
			TcpHeader->PSH<br />
<br />
	);<br />
}<br />
<br />
<br />
UCHAR Packet[478] =<br />
{<br />
	0x45,  0x00, <br />
	0x01,  0xDE,  0x50,  0xA8,  0x40,  0x00,  0x80,  0x06,  0xC5,  0x8E,  0xC0,  0xA8,  0x04,  0x30,  0x14,  0x0A, <br />
	0x0A,  0x01,  0x0B,  0x27,  0x00,  0x50,  0xAC,  0x78,  0xD2,  0x04,  0xB0,  0x9A,  0x29,  0x07,  0x50,  0x18,<br />
	0x44,  0x70,  0xE3,  0x3F,  0x00,  0x00,  0x47,  0x45,  0x54,  0x20,  0x2F,  0x74,  0x65,  0x73,  0x74,  0x20,<br />
	0x48,  0x54,  0x54,  0x50,  0x2F,  0x31,  0x2E,  0x31,  0x0D,  0x0A,  0x41,  0x63,  0x63,  0x65,  0x70,  0x74,<br />
	0x3A,  0x20,  0x69,  0x6D,  0x61,  0x67,  0x65,  0x2F,  0x67,  0x69,  0x66,  0x2C,  0x20,  0x69,  0x6D,  0x61,  <br />
	0x67,  0x65,  0x2F,  0x78,  0x2D,  0x78,  0x62,  0x69,  0x74,  0x6D,  0x61,  0x70,  0x2C,  0x20,  0x69,  0x6D,<br />
	0x61,  0x67,  0x65,  0x2F,  0x6A,  0x70,  0x65,  0x67,  0x2C,  0x20,  0x69,  0x6D,  0x61,  0x67,  0x65,  0x2F,<br />
	0x70,  0x6A,  0x70,  0x65,  0x67,  0x2C,  0x20,  0x61,  0x70,  0x70,  0x6C,  0x69,  0x63,  0x61,  0x74,  0x69,  <br />
	0x6F,  0x6E,  0x2F,  0x76,  0x6E,  0x64,  0x2E,  0x6D,  0x73,  0x2D,  0x65,  0x78,  0x63,  0x65,  0x6C,  0x2C,<br />
	0x20,  0x61,  0x70,  0x70,  0x6C,  0x69,  0x63,  0x61,  0x74,  0x69,  0x6F,  0x6E,  0x2F,  0x6D,  0x73,  0x77,<br />
	0x6F,  0x72,  0x64,  0x2C,  0x20,  0x61,  0x70,  0x70,  0x6C,  0x69,  0x63,  0x61,  0x74,  0x69,  0x6F,  0x6E,<br />
	0x2F,  0x76,  0x6E,  0x64,  0x2E,  0x6D,  0x73,  0x2D,  0x70,  0x6F,  0x77,  0x65,  0x72,  0x70,  0x6F,  0x69,<br />
	0x6E,  0x74,  0x2C,  0x20,  0x2A,  0x2F,  0x2A,  0x0D,  0x0A,  0x41,  0x63,  0x63,  0x65,  0x70,  0x74,  0x2D,<br />
	0x4C,  0x61,  0x6E,  0x67,  0x75,  0x61,  0x67,  0x65,  0x3A,  0x20,  0x65,  0x6E,  0x2D,  0x67,  0x62,  0x0D,<br />
	0x0A,  0x41,  0x63,  0x63,  0x65,  0x70,  0x74,  0x2D,  0x45,  0x6E,  0x63,  0x6F,  0x64,  0x69,  0x6E,  0x67,  <br />
	0x3A,  0x20,  0x67,  0x7A,  0x69,  0x70,  0x2C,  0x20,  0x64,  0x65,  0x66,  0x6C,  0x61,  0x74,  0x65,  0x0D,<br />
	0x0A,  0x55,  0x73,  0x65,  0x72,  0x2D,  0x41,  0x67,  0x65,  0x6E,  0x74,  0x3A,  0x20,  0x4D,  0x6F,  0x7A,<br />
	0x69,  0x6C,  0x6C,  0x61,  0x2F,  0x34,  0x2E,  0x30,  0x20,  0x28,  0x63,  0x6F,  0x6D,  0x70,  0x61,  0x74,  <br />
	0x69,  0x62,  0x6C,  0x65,  0x3B,  0x20,  0x4D,  0x53,  0x49,  0x45,  0x20,  0x35,  0x2E,  0x30,  0x31,  0x3B,<br />
	0x20,  0x57,  0x69,  0x6E,  0x64,  0x6F,  0x77,  0x73,  0x20,  0x4E,  0x54,  0x20,  0x35,  0x2E,  0x30,  0x29,<br />
	0x0D,  0x0A,  0x48,  0x6F,  0x73,  0x74,  0x3A,  0x20,  0x32,  0x30,  0x2E,  0x31,  0x30,  0x2E,  0x31,  0x30,  <br />
	0x2E,  0x31,  0x0D,  0x0A,  0x43,  0x6F,  0x6E,  0x6E,  0x65,  0x63,  0x74,  0x69,  0x6F,  0x6E,  0x3A,  0x20,<br />
	0x4B,  0x65,  0x65,  0x70,  0x2D,  0x41,  0x6C,  0x69,  0x76,  0x65,  0x0D,  0x0A,  0x43,  0x6F,  0x6F,  0x6B,<br />
	0x69,  0x65,  0x3A,  0x20,  0x4D,  0x53,  0x41,  0x53,  0x50,  0x43,  0x6C,  0x69,  0x65,  0x6E,  0x74,  0x53,<br />
	0x69,  0x64,  0x65,  0x43,  0x6F,  0x6C,  0x6F,  0x72,  0x3D,  0x38,  0x30,  0x38,  0x30,  0x30,  0x30,  0x3B,<br />
	0x20,  0x4D,  0x53,  0x41,  0x53,  0x50,  0x48,  0x54,  0x4D,  0x4C,  0x43,  0x6F,  0x6C,  0x6F,  0x72,  0x3D,<br />
	0x25,  0x32,  0x33,  0x46,  0x46,  0x38,  0x30,  0x38,  0x30,  0x3B,  0x20,  0x41,  0x53,  0x50,  0x53,  0x45,<br />
	0x53,  0x53,  0x49,  0x4F,  0x4E,  0x49,  0x44,  0x51,  0x47,  0x47,  0x47,  0x47,  0x52,  0x43,  0x43,  0x3D,  <br />
	0x4D,  0x46,  0x42,  0x4C,  0x49,  0x4C,  0x4D,  0x42,  0x4B,  0x48,  0x4A,  0x41,  0x47,  0x48,  0x47,  0x50,  <br />
	0x4F,  0x46,  0x41,  0x43,  0x47,  0x45,  0x4E,  0x49,  0x0D,  0x0A,  0x0D,  0x0A<br />
};<br />
<br />
<br />
USHORT Checksum( PUCHAR Data, USHORT Length )<br />
{<br />
	ULONG Sum = 0;<br />
	USHORT ShortSum = 0;<br />
	PUSHORT WordData = (PUSHORT) Data;<br />
	USHORT WordCount = Length >> 1;<br />
<br />
	while( WordCount-- )<br />
		Sum += *WordData++;<br />
<br />
	if( Length & 1 )<br />
		Sum += *(PUCHAR)WordData;<br />
<br />
	Sum = (USHORT) Sum + (Sum >> 16) & 0xFFFF;<br />
	ShortSum = (USHORT) Sum + (USHORT)(Sum >> 16);<br />
	<br />
	return (ShortSum != 0xFFFF) ? ~ShortSum : ShortSum;<br />
} <br />
<br />
USHORT ChecksumRFC( PUCHAR Data, USHORT Length )<br />
{<br />
	ULONG Sum = 0;<br />
	PUSHORT WD = (PUSHORT) Data;<br />
<br />
	while( Length > 1 )<br />
	{<br />
		Sum += * WD++;<br />
		Length -= 2;<br />
	}<br />
<br />
	if( Length > 0 )<br />
	{<br />
		Sum += *(PUCHAR)WD;<br />
	}<br />
<br />
	while( Sum >> 16 )<br />
	{<br />
		Sum = (Sum & 0xFFFF) + (Sum >> 16);<br />
	}<br />
<br />
	return (USHORT) ~Sum;<br />
}<br />
<br />
<br />
void main()<br />
{<br />
	PIP_HEADER IpHeader = (PIP_HEADER) Packet;<br />
	PTCP_HEADER TcpHeader = (PTCP_HEADER)( Packet + IpHeader->HeaderLength*4);<br />
	USHORT TcpDataLength = 	ntohs( IpHeader->TotalLength ) - IpHeader->HeaderLength*4;<br />
<br />
	DumpIPHeader( IpHeader );<br />
	DumpTCPHeader( TcpHeader );<br />
	printf( "\nTcpDataLength %d\n", TcpDataLength );<br />
<br />
	USHORT OldChecksum;<br />
<br />
	OldChecksum = IpHeader->Checksum;<br />
	IpHeader->Checksum = 0;<br />
<br />
	printf( "\nIpHeader->Checksum 0x%X\n", Checksum( (PUCHAR) IpHeader, IpHeader->HeaderLength*4) );<br />
	printf( "\nRFC IpHeader->Checksum 0x%X\n", ChecksumRFC( (PUCHAR) IpHeader, IpHeader->HeaderLength*4) );<br />
<br />
	IpHeader->Checksum = OldChecksum;<br />
<br />
	TCP_PSEUDOHEADER TcpPSHeader;<br />
<br />
	TcpPSHeader.SourceAddress = IpHeader->SourceAddress;<br />
	TcpPSHeader.DestAddress   = IpHeader->DestAddress;<br />
	TcpPSHeader.Zero          = 0;<br />
	TcpPSHeader.Protocol      = IpHeader->Protocol;<br />
	TcpPSHeader.TcpLength     = TcpDataLength;<br />
	<br />
	UCHAR tcp[ 478 + 12 ];<br />
<br />
	OldChecksum = TcpHeader->Checksum;<br />
//	TcpHeader->Checksum = 0;<br />
<br />
	memset( tcp, 0, 478 + 12 );<br />
	memcpy( &tcp[ 0 ], &TcpPSHeader, sizeof( TcpPSHeader ) );<br />
	memcpy( &tcp[ 12 ], TcpHeader, TcpDataLength );<br />
<br />
	printf( "\nTCP Checksum 0x%X\n", Checksum( tcp, 478+12 ) );<br />
	printf( "\nRFC TCP Checksum 0x%X\n", ChecksumRFC( tcp, 478+12 ) );<br />
<br />
	TcpHeader->Checksum = OldChecksum;<br />
<br />
	printf( "\n0x%X\n", (USHORT)~OldChecksum );<br />
<br />
}<br />

GeneralRe: TCP header checksum calculation Pin
Koep30-Aug-02 1:02
Koep30-Aug-02 1:02 
GeneralRe: TCP header checksum calculation Pin
AIDS30-Aug-02 1:40
AIDS30-Aug-02 1:40 
GeneralRe: TCP header checksum calculation Pin
Stephen C. Steel30-Aug-02 12:30
Stephen C. Steel30-Aug-02 12:30 
GeneralProblems with CArray Updated Pin
Koep30-Aug-02 0:50
Koep30-Aug-02 0:50 
GeneralRe: Problems with CArray Updated Pin
Tomasz Sowinski30-Aug-02 0:56
Tomasz Sowinski30-Aug-02 0:56 
GeneralRe: Problems with CArray Updated Pin
Koep30-Aug-02 1:00
Koep30-Aug-02 1:00 
GeneralRe: Problems with CArray Updated Pin
Tomasz Sowinski30-Aug-02 1:12
Tomasz Sowinski30-Aug-02 1:12 
GeneralRe: Problems with CArray Updated Pin
jhwurmbach30-Aug-02 3:20
jhwurmbach30-Aug-02 3:20 
GeneralRe: Problems with CArray Updated Pin
Tomasz Sowinski30-Aug-02 3:21
Tomasz Sowinski30-Aug-02 3:21 
GeneralRe: Problems with CArray Updated Pin
jhwurmbach30-Aug-02 3:48
jhwurmbach30-Aug-02 3:48 
GeneralProblems with CArray Pin
Koep30-Aug-02 0:48
Koep30-Aug-02 0:48 
GeneralRe: Problems with CArray Pin
mishgun30-Aug-02 1:35
mishgun30-Aug-02 1:35 
GeneralRe: Problems with CArray Pin
Koep30-Aug-02 1:43
Koep30-Aug-02 1:43 
GeneralCPrintDialog problem Pin
Wouter Dhondt29-Aug-02 23:58
Wouter Dhondt29-Aug-02 23:58 
GeneralRecompiler Engine Pin
Joel Holdsworth29-Aug-02 23:55
Joel Holdsworth29-Aug-02 23:55 
GeneralRe: Recompiler Engine Pin
Tomasz Sowinski30-Aug-02 0:03
Tomasz Sowinski30-Aug-02 0:03 
GeneralRe: Recompiler Engine Pin
Joel Holdsworth30-Aug-02 0:26
Joel Holdsworth30-Aug-02 0:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.