ping 程序(vc6.0 原始套接字实现)

#include 
#include 
#include 


#include  //IP_TTL
#pragma comment(lib,"ws2_32.lib")
//ICMP首部结构体
typedef struct tagICMPHEADER
{
 unsigned char type;//类型
 unsigned char code;//代码
 unsigned short checknum;//检验和
 unsigned short id;//标识符
 unsigned short seq_num;//序列号
}ICMPHEADER;
//IP首部结构体
typedef struct _ip_hdr
{
 unsigned char ihl:4;   //首部长度
 unsigned char version:4, //版本 
 unsigned char tos;   //服务类型
 unsigned short tot_len; //总长度
 unsigned short id;    //标志
 unsigned short frag_off; //分片偏移
 unsigned char ttl;   //生存时间
 unsigned char protocol; //协议
 unsigned short chk_sum; //检验和
 struct in_addr srcaddr; //源IP地址
 struct in_addr dstaddr; //目的IP地址
}IPHEADER;


//计算检验和
unsigned short checksum(unsigned short *buffer, int size) 
{ 
 unsigned long cksum = 0; // 将所有的16数相加 
 while (size > 1) 
 { 
  cksum += *buffer++;
  size -= sizeof(unsigned short); 
 }
 if (size) //加上最后一个BYTE 
 {
  cksum += *(unsigned char*)buffer;
 } 
 while (cksum>>16)
 {
  cksum = (cksum & 0xffff) + (cksum >> 16);
 } 
 return (unsigned short)~cksum;
} 
 
 
int main()
{
 WSADATA wsadata;
 if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
 {
  printf("初始化socket dll失败\n");
  return 1;
 }
 //设置ICMP首部内容
 ICMPHEADER icmp_hdr;
 icmp_hdr.type=8;
 icmp_hdr.code=0;
 icmp_hdr.checknum=0;
 icmp_hdr.id=(unsigned short)GetCurrentProcessId();
 icmp_hdr.seq_num=0;
 //计算检验和
 icmp_hdr.checknum=checksum((unsigned short*)&icmp_hdr,sizeof(icmp_hdr));
 //设置原始套接字
 SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
 if(INVALID_SOCKET==sock)
 {
  printf("创建socket失败\n");
  WSACleanup();
  return 1;
 }
 int ttl=255;
 //设置TTL为255
 if(setsockopt(sock,IPPROTO_IP,IP_TTL,(const char*)&ttl,sizeof(ttl))==SOCKET_ERROR)
 {
  printf("set TTL error!\n");
  WSACleanup();
  return 2;
 }
 //目标地址
 SOCKADDR_IN Dest_addr;
 memset(&Dest_addr,0,sizeof(Dest_addr));
 Dest_addr.sin_family=AF_INET;
 Dest_addr.sin_addr.S_un.S_addr=inet_addr("192.168.1.1");
 //发送ICMP请求报文
 int status=sendto(sock,(const char*)&icmp_hdr,sizeof(icmp_hdr),0,(SOCKADDR*)&Dest_addr,sizeof(Dest_addr));
 if(SOCKET_ERROR==status)
 {
  printf("sent error!\n");
  shutdown(sock,SD_BOTH);
  closesocket(sock);
  WSACleanup();
  return 3;
 }
 int size=60+sizeof(ICMPHEADER);
 char *buffer=(char*)malloc(size);
 memset(buffer,0,size);
 int des=sizeof(SOCKADDR_IN);
 //接受ICMP回应报文并分析
 while (true)
 {
  recvfrom(sock,buffer,size,0,(SOCKADDR*)&Dest_addr,&des);
  ICMPHEADER *p=(ICMPHEADER*)((char*)buffer+((IPHEADER*)buffer)->ihl*4);
  if(p->type==0)
  {
   if(p->id==icmp_hdr.id)
   {
    printf("ping %s成功\n",inet_ntoa(Dest_addr.sin_addr));
    break;
   }
  }
  else
  {
   printf("ping %s不成功\n",inet_ntoa(Dest_addr.sin_addr));
   break;
  }
 }
 shutdown(sock,SD_BOTH);
 closesocket(sock);
 WSACleanup();
 return 0;
} 


你可能感兴趣的:(网络编程)