zoukankan      html  css  js  c++  java
  • QT---Winsocket获取网关(Gateway) 主机IP等信息

      基于WinPcap库做开发,需要利用到局域网的默认网关地址和Mac地址,但是WinPcap实现获取网关IP地址没有很好的思路,可以知道的是网关的接收和发出的数据包数量一般是比局域网内的各主机要多的,可以抓包,判断,根据这个来获取网关的IP地址和Mac地址。不过,这不可靠。 
      很快就知道利用WinSocket里面的库可以获取网关的IP地址,实验前包含必要的头文件(

    // 获取Host IP(通过winsock2)
    QString PcapCommon::getHostIpByWinSock()
    {
        char hostname[256] = {0};
        WSADATA wsaData;
        char ip[128] = {0};
    
        // 调用Windows Sockets DLL
        if (WSAStartup(MAKEWORD(2,1),&wsaData)){
            printf("Winsock无法初始化!
    ");
            WSACleanup();
            return 0;
        }
    
        if(gethostname(hostname, sizeof(hostname)) == 0){
            // 结构
            struct hostent * pHost;
            pHost = gethostbyname(hostname);
            // 只取主网卡 ip
            BYTE *p;
            p =(BYTE *)pHost->h_addr;
            sprintf(ip,"%d.%d.%d.%d", p[0], p[1],p[2], p[3]);
        }
    
        return QString(ip);
    }
    获取完主机IP地址后,再获取网关(Gateway)的IP地址
    
    // 获取本机网关(通过winsock2)
    QString PcapCommon::getGateway()
    {
        PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
        unsigned long stSize = sizeof(IP_ADAPTER_INFO);
        int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);
        if (ERROR_BUFFER_OVERFLOW == nRel){
            // ERROR_BUFFER_OVERFLOW:内存空间不够
            // 释放原来的内存空间
            delete pIpAdapterInfo;
            // 重新申请内存空间用来存储所有网卡信息
            pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
            // 再次调用GetAdaptersInfo
            nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);
        }
        if (ERROR_SUCCESS == nRel){
            while (pIpAdapterInfo){
                switch(pIpAdapterInfo->Type){
                case MIB_IF_TYPE_OTHER:
                    break;
                case MIB_IF_TYPE_ETHERNET:
                    break;
                case MIB_IF_TYPE_TOKENRING:
                    break;
                case MIB_IF_TYPE_FDDI:
                    break;
                case MIB_IF_TYPE_PPP:
                    break;
                case MIB_IF_TYPE_LOOPBACK:
                    break;
                case MIB_IF_TYPE_SLIP:
                    break;
                default:
                    break;
                }
                for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++)
                    if (i < pIpAdapterInfo->AddressLength-1){
                    }
                    else{                    
                    }                
                    // 多个网卡、多个IP
                    IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);
                    do{                    
                        if(QString(pIpAddrString->IpAddress.String) == getHostIpByWinSock()){                        
                            return QString(pIpAdapterInfo->GatewayList.IpAddress.String);
                        }                    
                        pIpAddrString=pIpAddrString->Next;
                    } while (pIpAddrString);
                    pIpAdapterInfo = pIpAdapterInfo->Next;               
            }
    
        }
        //释放内存空间
        if (pIpAdapterInfo){
            delete pIpAdapterInfo;
        }
    
        return "0.0.0.0";
    }

      上面的循环是因为有多个网卡,循环列出各个网卡,思路是找到其中的一个网卡的IP地址是跟主机的IP地址是一样的,那么就将该网卡中的网关信息返回,在这里,还可以获取该网卡其他的信息,比如本机Mac地址,掩码地址等,但是这里是不能获取网关的Mac地址的,接下来就通过WinPcap来获取IP地址是网关的IP地址的包,并得到网关的Mac地址,这样就得到了网关的IP地址和Mac地址

      怎么用WinPcap去抓包,这里就不介绍了。可以参考WinPcap中文技术文档:

    http://www.ferrisxu.com/WinPcap/html/

    测试帮助:
    

    route print : 查看路由表信息,可以看到网关信息

    这里写图片描述

    上述的两段代码调试信息(程序中为了精简,没有打印出):

    这里写图片描述

     
     
    http://blog.csdn.net/freeape/article/details/50908911
  • 相关阅读:
    linux常用命令
    mysql 开发基础系列20 事务控制和锁定语句(上)
    sql server 性能调优之 资源等待 CXPACKET
    mysql 开发基础系列19 触发器
    mysql 开发基础系列18 存储过程和函数(下)
    mysql 开发基础系列17 存储过程和函数(上)
    sql server 性能调优之 资源等待PAGEIOLATCH
    mysql 开发基础系列16 视图
    mysql 开发基础系列15 索引的设计和使用
    sql server 性能调优之 当前用户请求分析 (1)
  • 原文地址:https://www.cnblogs.com/findumars/p/6294208.html
Copyright © 2011-2022 走看看