zoukankan      html  css  js  c++  java
  • ICMP(Ping)扫描

    //--------------------------------------------------------------------//
    //					ICMP(Ping)扫描                 //
    //						Rrouned		    //
    //--------------------------------------------------------------------//
    #include "stdio.h"
    #include "Winsock2.h"
    #pragma comment( lib, "ws2_32.lib" ) ;
    typedef struct IpHeader
    {
        unsigned char Version_HLen;
        unsigned char TOS;
        unsigned short Length;
        unsigned short Ident;
        unsigned short Flags_Offset;
        unsigned char TTL;
        unsigned char Protocol;
        unsigned short Checksum;
        unsigned int SourceAddr;
        unsigned int DestinationAddr;
    } Ip_Header;
    //类型和代码一起决定了ICMP报文的类型
    //类型8、代码0:回射请求。
    //类型0、代码0:回射应答。
    //类型11、代码0:超时。
    //ICMP回射请求和应答报文,标识本ICMP进程
    typedef struct IcmpHeader
    {
        BYTE Type;		//类型
        BYTE Code;		//代码
        USHORT Checksum;//校验和
        USHORT ID;
        USHORT Sequence;
    } Icmp_Header;
    USHORT checksum(USHORT *buff, int size)
    {
        unsigned long cksum = 0;
        while (size > 1)
        {
            cksum +=  *buff++;
            size -= sizeof(USHORT);
        }
        if (size)
        {
            cksum += *(UCHAR*)(buff);
        }
        cksum = (cksum >> 16) + (cksum &0xffff);
        cksum += (cksum >> 16);
        return (USHORT)(~cksum);
    }
    
    int main(int argc, char *argv[])
    {
        WSADATA wsaData;
        sockaddr_in DestAddr;
        Ip_Header *ip;
        Icmp_Header *icmp;
        Icmp_Header *SendIcmp;
        int Timeout = 100;
        char DestIpAddr[100] = "192.168.1.10";
        char IcmpBuffer[8] = "";
        SOCKET IcmpSocket;
        char RecvBuffer[1024];
        sockaddr_in addr;
        int Len = sizeof(addr);
        int Result;
        if ((Result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
        {
            printf("WSAStartup failed with error %d
    ", Result);
            return 0;
        }
        IcmpSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
        if (IcmpSocket == INVALID_SOCKET)
        {
            printf("socket failed with error %d
    ", WSAGetLastError());
            return 0;
        }
    	//设置超时
        Result = setsockopt(IcmpSocket, SOL_SOCKET, SO_RCVTIMEO, (char*) &Timeout, sizeof(Timeout));
        if (Result == SOCKET_ERROR)
        {
            printf("setsockopt failed with error %d 
    ", WSAGetLastError());
            return 0;
        }
    
    	//构造数据包
        memset(&DestAddr, 0, sizeof(DestAddr));
        DestAddr.sin_addr.s_addr = inet_addr(DestIpAddr);
        DestAddr.sin_port = htons(0);
        DestAddr.sin_family = AF_INET;
        SendIcmp = (Icmp_Header*)IcmpBuffer;
        SendIcmp->Type = 8;
        SendIcmp->Code = 0;
        SendIcmp->ID = (USHORT)GetCurrentProcessId();
        SendIcmp->Sequence = htons(1);
        SendIcmp->Checksum = 0;
        SendIcmp->Checksum = checksum((USHORT*)IcmpBuffer, sizeof(IcmpBuffer));
        Result = sendto(IcmpSocket, IcmpBuffer, sizeof(IcmpBuffer), 0, (SOCKADDR*) &DestAddr, sizeof(DestAddr));
        if (Result == SOCKET_ERROR)
        {
            printf("sendto failed with error %d 
    ", WSAGetLastError());
            return 0;
        }
    
    	//recvform是阻塞的,一直等到数据的到达
    	//设置了超时之后如果在超时前没有数据到达就返回
        Result = recvfrom(IcmpSocket, RecvBuffer, 1024, 0, (sockaddr*) &addr, &Len);
        if (Result == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSAETIMEDOUT)
            {
                printf("recvfrom failed with error %d 
    ", WSAGetLastError());
                return 0;
            }
            else
            {
                printf("Host %s may be down.
    ", DestIpAddr);
            }
        }
        if (Result < sizeof(Ip_Header) + sizeof(Icmp_Header))
        {
            printf("data error from %d
    ", inet_ntoa(addr.sin_addr));
        }
        ip = (Ip_Header*)RecvBuffer;
    
    
    
    	//检查返回的数据包
    	//IP的目标地址,协议类型
        if ((ip->SourceAddr == inet_addr(DestIpAddr)) && (ip->Protocol == IPPROTO_ICMP))
        {
            icmp = (Icmp_Header*)(RecvBuffer + sizeof(Ip_Header));
            //ICMP类型
    		if (icmp->Type != 0)
            {
                printf("type error %d ", icmp->Type);
                return 0;
            }
    
    		//ICMP的进程ID
            if (icmp->ID != GetCurrentProcessId())
            {
                printf("id error %d
    ", icmp->ID);
                return 0;
            }
            else if ((icmp->Type == 0) && (icmp->ID == GetCurrentProcessId()))
            {
                printf("Host %s is up.
    ", DestIpAddr);
            }
        }
    
    
    
    
    
    	//收尾操作。。
        if (closesocket(IcmpSocket) == SOCKET_ERROR)
        {
            printf("closesocket failed with error %d
    ", WSAGetLastError());
            return 0;
        }
        if (WSACleanup() == SOCKET_ERROR)
        {
            printf("WSACleanup failed with error %d
    ", WSAGetLastError());
            return 0;
        }
        return 1;
    }
    

      

  • 相关阅读:
    PreparedStatementUpdateTest.java
    JDBCUtils.java
    StringTest.java
    创建线程的方式四:使用线程池
    用递归实现解决斐波那契数列。
    反射的用处。Class对象的介绍,怎么通过反射创建实例和调用方法。
    基于jenkins+docker+git 持续化自动部署项目(详细版一));
    git常用命令,linus的神作之一。
    电话号码的字母组合。(每天一道,防止痴呆)
    编写一个函数来查找字符串数组中的最长公共前缀。(每天一道防止痴呆)
  • 原文地址:https://www.cnblogs.com/Rrouned/p/3440633.html
Copyright © 2011-2022 走看看