1,317
社区成员
发帖
与我相关
我的任务
分享
u_short CheckSum(u_short *pBuffer, int nSize)
{
u_long dwChecksum = 0;
int cnt = nSize;
while (cnt > 1)
{
dwChecksum += *pBuffer++;
cnt -= sizeof(u_short);
}
if (cnt)
{
dwChecksum += *(u_char*)pBuffer;
}
while (dwChecksum >> 16)
{
dwChecksum = (dwChecksum >> 16) + (dwChecksum & 0xFFFF);
}
return (u_short)~dwChecksum;
}
void TcpCheckSum(tcp_packet *packet)
{
unsigned short attachsize = 0; //传输层协议头以及附加数据的总长度
_tcp_hdr *ptcp_header = NULL; //TCP头指针
FakeHead_t *ptcp_psd_header = NULL;
ptcp_header = (_tcp_hdr *)(packet + 14 + ((packet->ip.ip.ucVersionAndHeadLength) & 15) * 4);
attachsize = ntohs(packet->ip.ip.usTotalLength) - ((packet->ip.ip.ucVersionAndHeadLength) & 15) * 4;
ptcp_psd_header = (FakeHead_t *)malloc(attachsize + sizeof(FakeHead_t));
if (!ptcp_psd_header)
{
return;
}
memset(ptcp_psd_header, 0, attachsize + sizeof(FakeHead_t));
//填充伪TCP头
ptcp_psd_header->dest_address = packet->ip.ip.dest_ip;
ptcp_psd_header->source_address = packet->ip.ip.sour_ip;
ptcp_psd_header->placeholder = 0;
ptcp_psd_header->protocol = 0x06;
ptcp_psd_header->tcp_length = htons(attachsize);
//计算TCP校验和
ptcp_header->usCheckSum = 0;
memcpy((unsigned char *)ptcp_psd_header + sizeof(FakeHead_t), (unsigned char *)ptcp_header, attachsize);
ptcp_header->usCheckSum = CheckSum((unsigned short *)ptcp_psd_header, attachsize + sizeof(FakeHead_t));
free(ptcp_psd_header);
}
struct FakeHead_t
{
u_int source_address;
u_int dest_address;
u_char placeholder;
u_char protocol;
u_short tcp_length;
};
struct tcp_packet
{
ip_packet ip;
_tcp_hdr tcp;
};
struct ip_head
{
u_char ucVersionAndHeadLength;
u_char ucTos;
u_short usTotalLength;
u_short usIdentification;
u_short usFlagsAndFragmentOffset;
u_char ucTtl;
u_char ucProtocol;
u_short usCheckSum;
unsigned long sour_ip;
unsigned long dest_ip;
};
struct ip_packet
{
ethernet_head eth;
ip_head ip;
};
struct _tcp_hdr
{
u_short usSourcePort;
u_short usDestPort;
DWORD dwSeq;
DWORD dwAck;
u_char ucLength;
u_char ucFlag;
u_short usWindow;
u_short usCheckSum;
u_short usUrgent;
u_int unMssOpt;
u_short usNopOpt;
u_short usSackOpt;
};
struct ethernet_head
{
unsigned char dest_mac[6]; //目标主机MAC地址
unsigned char source_mac[6]; //源端MAC地址
unsigned short eh_type; //以太网类型
};