我最近要写一个程序,用到要写一个自己的ping程序,而且要改变发出去的数据报的原地址,参看的csdn里不少文章,但由于我水品有限,现在实现起来还是有困难,第一次写文章求救,希望大家帮忙!谢谢!
在我不自己填写ip头时,程序还能正常ping通,但是我尝试着自己填充ip头后,就ping不了了!
ip头的数据结构
typedef struct ip_hdr
{
unsigned char ip_verlen;
unsigned char ip_tos;
unsigned short ip_totallength;
unsigned short ip_id;
unsigned short ip_offset;
unsigned char ip_ttl;
unsigned char ip_protocol;
unsigned short ip_checksum;
unsigned int ip_srcaddr;
unsigned int ip_destaddr;
}IPHDR, *PIPHDR;
icmp数据结构
typedef struct tagICMPHDR
{
unsigned char Type; // Type
unsigned char Code; // Code
u_short Checksum; // Checksum
u_short ID; // Identification
u_short Seq; // Sequence
unsigned char Data; // Data
}ICMPHDR, *PICMPHDR;
#define REQ_DATASIZE 32 // Echo Request Data size
// ICMP Echo Request
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;
DWORD dwTime;
unsigned char cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;
// ICMP Echo Reply
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
unsigned char cFiller[256];
}ECHOREPLY, *PECHOREPLY;
我就不全放上程序了,选重要的。
bool bOpt=true;
setsockopt(rawSocket, IPPROTO_IP, IP_HDRINCL, (char*)bOpt, sizeof(bOpt));//选择自己填充ip头
我这样填充
myIPHead.ip_totallength=htons(sizeof(IPHDR)+sizeof(ECHOREQUEST));
int ipsize=sizeof(IPHDR)/sizeof(unsigned long);
myIPHead.ip_verlen=ipsize;
myIPHead.ip_tos=0;
myIPHead.ip_id=0;
myIPHead.ip_offset=0;
myIPHead.ip_ttl=128;
myIPHead.ip_protocol=IPPROTO_ICMP;
myIPHead.ip_checksum=0;
myIPHead.ip_srcaddr=inet_addr("211.65.86.107");
myIPHead.ip_destaddr=inet_addr("211.65.86.105");
然后计算ip的校验和
myIPHead.ip_checksum=in_cksum((u_short *)&myIPHead, sizeof(myIPHead));
icmp部分是用了一个现成的,不会有问题的
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum = 0;
echoReq.icmpHdr.ID = nId++;
echoReq.icmpHdr.Seq = nSeq++;
// Fill in some data to send
for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
echoReq.cData[nRet] = ' '+nRet;
// Save tick count when sent
echoReq.dwTime = GetTickCount();
// Put data in packet and compute checksum
echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));
填充一个buffer,准备发送。
memcpy(szSendBuf,&myIPHead,sizeof(myIPHead));
memcpy(szSendBuf+sizeof(myIPHead),&echoReq,sizeof(ECHOREQUEST));
sendSize=sizeof(myIPHead)+sizeof(echoReq);
nRet = sendto(s, /* socket */
(LPSTR)szSendBuf, /* buffer */
sendSize,
0, /* flags */
(LPSOCKADDR)lpstToAddr, /* destination */
sizeof(SOCKADDR_IN)); /* address length */
但是不行,根本受不到回应,而且我查看arp表,根本没有对方机子的ip mac记录,希望大家帮我看看源代码,指出错误,不胜感激!