« 前一篇:2005,放弃&遗忘
后一篇:MacAddr »

ping @ 2/10/2006

技术类
用Raw Socket来实现ICMP_ECHO协议。
#include <windows.h>
#include <winsock.h>

#pragma comment(lib, "ws2_32")

typedef struct _ihdr {
    u_char i_type, i_code;
    u_short i_cksum,i_id, i_seq;
} IcmpHeader;

u_short checksum(u_short *buffer, int size) {
    unsigned long cksum=0;
    while(size >1) {
        cksum+=*buffer++;
        size -=sizeof(USHORT);
    }
    if(size) {
        cksum += *(UCHAR*)buffer;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
}

int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int) {
    WSADATA wsaData;
    SOCKET sockRaw = INVALID_SOCKET;
    struct sockaddr_in dest,from;
    char icmp_data[10], recvbuf[1024];
    unsigned int addr=0;
    int fromlen = sizeof(from);
    int timeout = 3000; //ms
    int count = 3;
    struct hostent* host;
    char szDestHost[] = "www.sinzy.net";

    WSAStartup(MAKEWORD(2,1),&wsaData) ;
    if(inet_addr(szDestHost)==INADDR_NONE) {
        host=gethostbyname(szDestHost);
    } else {
        addr=inet_addr(szDestHost);
        host=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
    }
   
    if(host == NULL) {
        MessageBox(NULL, "Not Resolved!", szDestHost, MB_OK);
    } else {
        sockRaw = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
        setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));

        memset(&dest,0,sizeof(dest));
        dest.sin_family = AF_INET;
        dest.sin_addr.s_addr = *((unsigned long*)host->h_addr);
        memset(icmp_data,0,sizeof(icmp_data)); //clear icmp_data.
        ((IcmpHeader*)icmp_data)->i_type = 8; //ICMP_ECHO
        ((IcmpHeader*)icmp_data)->i_code = 0;
        ((IcmpHeader*)icmp_data)->i_id = (u_short)GetCurrentProcessId();
        ((IcmpHeader*)icmp_data)->i_seq = 0;

        for(int k=0; k < count; k ++) {
            ((IcmpHeader*)icmp_data)->i_cksum = 0;
            ((IcmpHeader*)icmp_data)->i_seq ++;
            ((IcmpHeader*)icmp_data)->i_cksum=checksum((u_short*)icmp_data,8);
           
            sendto(sockRaw,icmp_data,8,0,(struct sockaddr*)&dest,sizeof(dest));
            int bread=recvfrom(sockRaw,recvbuf,1024,0,(struct sockaddr*)&from, &fromlen);
            if(bread != SOCKET_ERROR){
                break;
            }
        }
        closesocket(sockRaw);
        sockRaw = INVALID_SOCKET;
       
        MessageBox(NULL, (k==count)?"Failed!":"Succeeded!", szDestHost, MB_OK);
    }

    WSACleanup();
    return 0;
}
发布于 2/10/2006 11:02:53 | 评论:0

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1168
  • 评论数:2011