关于构造tcp报文出现的问题
主要代码如下:
//ip header
struct iphdr
{
unsigned short h_ver:4; //版本
unsigned short hl:4;//首部长度
unsigned short tos:8; //服务类型
unsigned short total_len; //总长度
unsigned short ident; //标识
unsigned short frag_and_flags; //标志和片偏移
unsigned short ttl:8; //生存时间
unsigned short proto:8; //协议
unsigned short checksum; //校验和
unsigned int sourceIP; //源端IP地址
unsigned int destIP; //目的地址
};
//TCP header
struct tcphdr
{
unsigned short source;
unsigned short dest;
unsigned int seq;
unsigned int ack_seq;
# if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned short res1:4;
unsigned short doff:4;
unsigned short fin:1;
unsigned short syn:1;
unsigned short rst:1;
unsigned short psh:1;
unsigned short ack:1;
unsigned short urg:1;
unsigned short res2:2;
# elif __BYTE_ORDER == __BIG_ENDIAN
unsigned short doff:4;
unsigned short res1:4;
unsigned short res2:2;
unsigned short urg:1;
unsigned short ack:1;
unsigned short psh:1;
unsigned short rst:1;
unsigned short syn:1;
unsigned short fin:1;
# else
# error "Adjust your <bits/endian.h> defines"
# endif
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
};
//TCP 伪首部
//伪首部
struct psehdr{ //伪首部
unsigned long saddr; //源IP地址
unsigned long daddr; //目的IP地址
unsigned char reserved;
unsigned char proto; //协议号
unsigned short len; //TCP长度
};
int SendTCPRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr,unsigned short sport,unsigned short dport)
{
int nRet;
long PACKLEN;
char buf[50] = {0};
PACKLEN = sizeof(struct iphdr) + sizeof(struct tcphdr);
//填充IP
struct iphdr ipH;
// ipH.h_verlen=(4<<4|sizeof(struct iphdr)/sizeof(unsigned long));
ipH.h_ver = 4;//版本号
ipH.hl = 5;
ipH.tos = 0;
ipH.total_len = htons(PACKLEN);//整个数据报总长度
ipH.frag_and_flags = 0x40;//不分段
ipH.ident = 13;
ipH.ttl = 255;
ipH.proto = IPPROTO_TCP;
ipH.sourceIP = inet_addr(ip1);//这里IP只是一个代号
ipH.destIP = inet_addr(ip2);
ipH.checksum = 0;
//填充TCP伪首部
struct psehdr pseuhdr;
pseuhdr.saddr = ipH.sourceIP;
pseuhdr.daddr = ipH.destIP;
pseuhdr.reserved = 0 ;
pseuhdr.proto = ipH.proto;
pseuhdr.len = htons( sizeof(struct tcphdr) );
//填充TCP数据。
struct tcphdr tcpH;
tcpH.dest = dport;
tcpH.source = sport;//发送端口号可以随便
tcpH.seq = 0;
tcpH.ack_seq = 0;
tcpH.doff = 5;
tcpH.res1 = 0;
tcpH.res2 = 0;
tcpH.ack = TRUE;
tcpH.fin = false;
tcpH.psh = false;
tcpH.rst = false;
tcpH.urg = false;
tcpH.syn = false;
tcpH.window = 1024;
tcpH.check = 0;
tcpH.urg_ptr = 0;
//
//memcpy(buf,&ipH,sizeof(struct iphdr));
memcpy(buf,&pseuhdr,sizeof(struct psehdr));
memcpy(buf + sizeof(struct psehdr),&tcpH,sizeof(struct tcphdr));
tcpH.check = in_cksum((u_short *)buf,sizeof(buf));
memset(buf,'\0',sizeof(buf));
memcpy(buf,&ipH,sizeof(struct iphdr));
memcpy(buf + sizeof(struct iphdr),&tcpH,sizeof(struct tcphdr));
nRet = sendto(s,
buf,
sizeof(buf),
0,
(LPSOCKADDR)lpstToAddr,
sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
printf("%d\n",errno);
printf("sendto()");0
}
return nRet;
}
//校验和代码
unsigned short in_cksum(unsigned short * addr,int len)
{
register int sum = 0;
u_short answer = 0;
register u_short * w = addr;
register int nleft = len;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *)(&answer) = *(u_char *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
程序一直出错在sendto。errno=0。我反复看了,我TCP,IP构造错了吗?还是怎么了?希望能有大侠指点一二。 TCP报文 C语言编程
[解决办法]
建议你sendto之前把报文打出来,你的ip头里写的长度是PACKLEN。但是实际发送的时候又用的sizeof(buff[50]),报文这样就不正确了。你的PACKLEN只有ip,tcp头的长度,,没有数据的长度加上,不知道你真实是想发送多少数据,还是就是想构造一个tcp的syn报文,或者啥的。