[x]
Posted via EE Mobile

Search, ask, and monitor your questions on the go with EE Mobile. Visit Experts Exchange from your mobile device and never be out of touch again.

Question
[x]
Attachment Details

TCP Packet checksum calculation error.

Asked by 0x7F in Winsock, Windows ATL / WTL / COM Programming, Network Analysis Software

Hi to all programmers, i have a little problem in the tcp checksum calculation... i don't understand why the checksum is wrong. This is a little code, that don't take the case of tcp or ip options headers... Here is the full code, plz help if you can... need for my self study.

I'm using Wireshark for debugging... he say the checksum must be F136 :/ but is F0FA

NOTE : I use flag  IPPROTO_IP on windows, on unix system IPPROTO_TCP... or give invalid argumnets error.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
typedef struct tagIPV4_HEADER {
	unsigned char ucVersionLength;
	unsigned char ucTypeOfService;
	unsigned short usPacketLength;
	unsigned short usFragmentId;
	unsigned short usFlagsFragmentOffset;
	unsigned char ucTimeToLive;
	unsigned char ucProtocolType;
	unsigned short usChecksum;
	unsigned long ulSourceAddress;
	unsigned long ulDestinationAddress;
} IPV4_HEADER, *PIPV4_HEADER;
 
 
typedef struct tagTCP_HEADER {
	unsigned short usSourcePort;
	unsigned short usDestinationPort;
	unsigned long ulSequenceNumber;
	unsigned long ulAcknowledgmentNumber;
	unsigned short usHeaderLengthFlags;
	unsigned short usWindowSize;
	unsigned short usChecksum;
	unsigned short usUrgentPointer;
} TCP_HEADER, *PTCP_HEADER;
 
#define TCP_FLAG_FINALYZE    0x01
#define TCP_FLAG_SYNCRONIZE  0x02
#define TCP_FLAG_RESET       0x04
#define TCP_FLAG_PUSH        0x08
#define TCP_FLAG_ACKNOW      0x10
#define TCP_FLAG_URGENT      0x20
#define TCP_FLAG_ECNECHO     0x40
#define TCP_FLAG_CWNREDUCED  0x80
 
 
USHORT GetChecksum16(PUSHORT pusBuffer, int iBufferSize) {
	ULONG ulChecksum = 0;
	while (iBufferSize > 1) {
		ulChecksum += *pusBuffer++;
		iBufferSize -= sizeof(USHORT);
	}
	if (iBufferSize) {
		ulChecksum += *(PUCHAR)pusBuffer;
	}
	ulChecksum = (ulChecksum >> 16) + (ulChecksum & 0xFFFF);
	ulChecksum += (ulChecksum >> 16);
	ulChecksum = ~ulChecksum;
	return (USHORT)ulChecksum;
}
 
USHORT GetChecksumTcp(PUSHORT pusTcpHeader, int iDataBufferSize, ULONG ulSourceAddress, 
					  ULONG ulDestinationAddress, USHORT usTcpLength) {
	ULONG ulChecksum = 0;
	int iBufferSize;
	UCHAR ucProtocolType = 0x06;
    ulChecksum += (USHORT)(ulSourceAddress);
    ulChecksum += (USHORT)(ulSourceAddress >> 16);
	ulChecksum += (USHORT)(ulDestinationAddress);
	ulChecksum += (USHORT)(ulDestinationAddress >> 16);
    ulChecksum += (((USHORT)ucProtocolType) << 8);
    ulChecksum += usTcpLength;  //MAIBY HERE???
	iBufferSize = sizeof(TCP_HEADER) + iDataBufferSize;
	while (iBufferSize > 1) {
        ulChecksum += *pusTcpHeader++;
        iBufferSize -= sizeof(USHORT);
	}
	if (iBufferSize) {
		ulChecksum += *(PUCHAR)pusTcpHeader;
	}
	ulChecksum = (ulChecksum >> 16) + (ulChecksum & 0xFFFF);
	ulChecksum += (ulChecksum >> 16);
	ulChecksum = ~ulChecksum;
	return (USHORT)ulChecksum;
}
 
PCHAR TcpCreatePacket(const PCHAR pcSourceAddress, const PCHAR pcDestinationAddress, 
					  USHORT usSourcePort, USHORT usDestinationPort, PCHAR pcDataBuffer,
					  USHORT usDataBufferSize, UCHAR ucTos, UCHAR ucTtl, USHORT usTcpFlags, 
					  PUSHORT pusPacketLength) 
{
    USHORT usPacketLength;
	PCHAR pcPacketDataBuffer = NULL;
	PIPV4_HEADER ptagIpv4Header = NULL;
	PTCP_HEADER ptagTcpHeader = NULL;
	USHORT usTcpLength;
	usPacketLength = sizeof(IPV4_HEADER) + sizeof(TCP_HEADER) + usDataBufferSize;
	pcPacketDataBuffer = (PCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, usPacketLength);
	if (!pcPacketDataBuffer) {
		*pusPacketLength = 0x0000;
		return NULL;
	}
	*pusPacketLength = usPacketLength;
	ptagIpv4Header = (PIPV4_HEADER)pcPacketDataBuffer;
	ptagIpv4Header->ucVersionLength = (0x04 << 4 | (sizeof(IPV4_HEADER) / sizeof(unsigned long)));
	ptagIpv4Header->ucTypeOfService = ucTos;
	ptagIpv4Header->usPacketLength = htons(usPacketLength);
	ptagIpv4Header->usFragmentId = 0x0000;
	ptagIpv4Header->usFlagsFragmentOffset = 0x0000;
	ptagIpv4Header->ucTimeToLive = ucTtl;
	ptagIpv4Header->ucProtocolType = 0x06;
	ptagIpv4Header->ulSourceAddress = inet_addr(pcSourceAddress);
	ptagIpv4Header->ulDestinationAddress = inet_addr(pcDestinationAddress);
	ptagIpv4Header->usChecksum = GetChecksum16((PUSHORT)ptagIpv4Header, sizeof(IPV4_HEADER));  //PERFECT!
	pcPacketDataBuffer += sizeof(IPV4_HEADER);
	ptagTcpHeader = (PTCP_HEADER)pcPacketDataBuffer;
	ptagTcpHeader->usSourcePort = htons(usSourcePort);
	ptagTcpHeader->usDestinationPort = htons(usDestinationPort);
	ptagTcpHeader->ulSequenceNumber = 0x00000000;
	ptagTcpHeader->ulAcknowledgmentNumber = 0x00000000;
	usTcpLength = (sizeof(TCP_HEADER) + usDataBufferSize) / sizeof(ULONG) << 4;
    ptagTcpHeader->usHeaderLengthFlags = usTcpLength;
	ptagTcpHeader->usHeaderLengthFlags |= htons(usTcpFlags);
	ptagTcpHeader->usWindowSize = htons(65535);
	ptagTcpHeader->usUrgentPointer = 0x00000;
	if (usDataBufferSize) {
	    pcPacketDataBuffer += sizeof(TCP_HEADER);
	    CopyMemory(pcPacketDataBuffer, pcDataBuffer, usDataBufferSize);
	}
	pcPacketDataBuffer = (PCHAR)ptagIpv4Header;
    ptagTcpHeader->usChecksum = GetChecksumTcp((PUSHORT)ptagTcpHeader, usDataBufferSize,
		                                       ptagIpv4Header->ulSourceAddress,
											   ptagIpv4Header->ulDestinationAddress,
											   htons(ptagTcpHeader->usHeaderLengthFlags) & 0xFF00);  //WRONG WRONG WRONG :/
	return pcPacketDataBuffer;
}
 
 
int _tmain(int argc, TCHAR **argv) {
 
	WSADATA tagWsaData = {0};
	PCHAR pcPacketDataBuffer = NULL;
	PTCP_HEADER ptagTcpHeader = NULL;
	USHORT usPacketLength = 0;
    int iReturn;
	PIPV4_HEADER ptagIpv4Header;
	SOCKADDR_IN tagSockAddrIn;
	SOCKET iSocket;
	BOOL bIpHeaderInclude = TRUE;
 
	ZeroMemory(&tagSockAddrIn, sizeof(SOCKADDR_IN));
 
	if (WSAStartup(MAKEWORD(2, 2), &tagWsaData)) {
		return FALSE;
	}
 
	iSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
 
	if (iSocket == INVALID_SOCKET) {
		goto CleanAndExit;
	}
 
	iReturn = setsockopt(iSocket, IPPROTO_IP, IP_HDRINCL, 
		                 (const PCHAR)&bIpHeaderInclude, 
						 sizeof(bIpHeaderInclude));
	if (iReturn == SOCKET_ERROR) {
		goto CleanAndExit;
	}
 
/*ONLY FOR TRY*/
	pcPacketDataBuffer = TcpCreatePacket("192.168.1.2", "74.125.45.100", 34000, 80, 
		                                 NULL, NULL, NULL, 128, TCP_FLAG_SYNCRONIZE, &usPacketLength);
	if (!pcPacketDataBuffer) {
		goto CleanAndExit;
	}
	ptagIpv4Header = (PIPV4_HEADER)pcPacketDataBuffer;
	tagSockAddrIn.sin_family = AF_INET;
	tagSockAddrIn.sin_addr.s_addr = ptagIpv4Header->ulDestinationAddress;
    ptagTcpHeader = (PTCP_HEADER)(pcPacketDataBuffer + sizeof(IPV4_HEADER));
	tagSockAddrIn.sin_port = ptagTcpHeader->usDestinationPort;
	
	iReturn = sendto(iSocket, pcPacketDataBuffer, usPacketLength, NULL, 
		             (LPSOCKADDR)&tagSockAddrIn, sizeof(tagSockAddrIn));
 
	if (iReturn == SOCKET_ERROR) {
        goto CleanAndExit;
	}
	
CleanAndExit:
 
	if (pcPacketDataBuffer) {
		HeapFree(GetProcessHeap(), NULL, pcPacketDataBuffer);
	}
 
	WSACleanup();
 
	return TRUE;
}
[+][-]06/23/09 04:27 AM, ID: 24690738Expert Comment

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 30-day free trial to view this Expert Comment or ask the Experts your question.

 
 
Loading Advertisement...
20091021-EE-VQP-81 - Hierarchy / EE_QW_3_20080625