当前位置:编程学习 > VC++ >>

vc++Ping命令模拟进阶----如何嗅探某个IP段

这次我将代码整合后,做一个实战的练习,扫描一个IP段,返回所有活动的IP

要完成这个练习,以下有几个步骤,作为程序员的我们就用代码说话
首先要做到如何证明一个IP是否在活动,代码如下
Java代码 
BOOL IpCheck::IsIPActive(char *addr) 

    // 目的IP地址,即要Ping的IP地址     
    char *szDestIp = addr;  // 127.0.0.1     
 
    // 创建原始套节字     
    WSADATA wsaData;   
    WSAStartup(MAKEWORD(2, 2), &wsaData);   
    SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);     
 
    // 设置接收超时     
    SetTimeout(sRaw, 100, TRUE);     
 
    // 设置目的地址     
    SOCKADDR_IN dest;     
    dest.sin_family = AF_INET;     
    dest.sin_port = htons(0);     
    dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);     
 
    // 创建ICMP封包     
    char buff[sizeof(ICMP_HDR) + 32];     
    ICMP_HDR* pIcmp = (ICMP_HDR*)buff;     
 
    // 填写ICMP封包数据,请求一个ICMP回显     
    pIcmp->icmp_type = 8;         
    pIcmp->icmp_code = 0;     
    pIcmp->icmp_id = (USHORT)GetCurrentProcessId();     
    pIcmp->icmp_checksum = 0;     
    pIcmp->icmp_sequence = 0;     
 
    // 填充数据部分,可以为任意     
    memset(&buff[sizeof(ICMP_HDR)], 'E', 32);     
 
    // 开始发送和接收ICMP封包     
    USHORT  nSeq = 0;     
    char recvBuf[1024];     
    SOCKADDR_IN from;     
    int nLen = sizeof(from);     
 
    static int nCount = 0;     
    int nRet;     
 
    pIcmp->icmp_checksum = 0;     
    pIcmp->icmp_timestamp = GetTickCount();     
    pIcmp->icmp_sequence = nSeq++;     
    pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32);     
    nRet = sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *)&dest, sizeof(dest));     
    if(nRet == SOCKET_ERROR)     
    {     
        printf(" sendto() failed: %d \n", ::WSAGetLastError());     
        return -1;     
    }   
    nRet = recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);   
    if(nRet == SOCKET_ERROR)   
    {     
        if(WSAGetLastError() == WSAETIMEDOUT)     
        {     
            printf("%s timed out\n", addr);     
            return FALSE;     
        } 
        printf("recvfrom() failed: %d\n", WSAGetLastError());     
        return FALSE; 
    }     
 
    // 下面开始解析接收到的ICMP封包     
    int nTick = ::GetTickCount();     
    if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR))     
    {     
        printf(" Too few bytes from %s \n", inet_ntoa(from.sin_addr));     
    }     
 
    // 接收到的数据中包含IP头,IP头大小为20个字节,所以加20得到ICMP头     
    // (ICMP_HDR*)(recvBuf + sizeof(IPHeader));     
    ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + 20);      
    if(pRecvIcmp->icmp_type == ICMP_TYPE_REACH_FAIL)    // 回显     
    {     
        printf("%s reach fail, type %d recvd \n", addr, pRecvIcmp->icmp_type);     
        return FALSE;     
    }   
 
    if(pRecvIcmp->icmp_id != GetCurrentProcessId())     
    {     
        printf(" someone else's packet! \n");     
        return FALSE;     
    }     
 
    printf("从 %s 返回 %d 字节:", addr,nRet);     
    printf(" 数据包序列号 = %d. \t", pRecvIcmp->icmp_sequence);     
    printf(" 延时大小: %d ms", nTick - pRecvIcmp->icmp_timestamp);     
    printf(" \n"); 
 
    s_array->Insert(addr); 
 
    WSACleanup();   
    closesocket(sRaw); 
 
    return TRUE; 


这个是扫描一个指定的IP地址,但是我们想要扫描多个IP地址的话,必须对IP地址进行转化,转化为整数就可以进行累加操作
Java代码 
unsigned long __fastcall IpCheck::InvertIp(unsigned long NormalIp)  
{  
    unsigned   char   b1,b2,b3,b4;  
 

补充:软件开发 , Vc ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,