想改ping的原地址

来源:互联网 发布:淘宝客查不到佣金 编辑:程序博客网 时间:2024/05/05 17:57

我最近要写一个程序,用到要写一个自己的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记录,希望大家帮我看看源代码,指出错误,不胜感激!

原创粉丝点击