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;
}
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:
by: Infinity08Posted on 2009-06-23 at 04:27:10ID: 24690738
>> ulChecksum += *(PUCHAR)pusBuffer;
rfc793.txt
The zero padding is added to the right, not to the left, so :
ulChecksum += ((USHORT) *((PUCHAR)pusBuffer)) << 8;
>> ulChecksum += (((USHORT)ucProtocolType) << 8);
The zero byte is on the left of the protocol, so :
ulChecksum += ((USHORT)ucProtocolType);
>> ulChecksum += usTcpLength; //MAIBY HERE???
The TCP length is a 16bit value calculated is the sum of the TCP header length (in bytes) and the data length (in bytes).
>> if (iBufferSize) {
>> ulChecksum += *(PUCHAR)pusTcpHeader;
>> }
Same here as above. The zero padding is added to the right, not to the left.
And finally : did you set the checksum field to 0 before calculating the checksum ?
Check the RFC for more information :
http://tools.ietf.org/rfc/