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无法初始化!\n");
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
: 查看路由表信息,可以看到网关信息
上述的两段代码调试信息(程序中为了精简,没有打印出)
:
QT---Winsocket获取网关(Gateway) 主机IP等信息的更多相关文章
- shell 获取网关 以及修改ip 启用网卡
shell 获取网关 以及修改ip 启用网卡 #!/bin/bash #autho freefei #script is a init computer eth #data 2014 10 09 19 ...
- GetAdaptersInfo获取网卡配置和Ip地址信息
一台机器上可能不只有一个网卡,但每一个网卡只有一个MAC地址,而每一个网卡可能配置有多个IP地址:如平常的笔记本电脑中,就会有无线网卡和有线网卡(网线接口)两种:因此,如果要获得本机所有网卡的IP和M ...
- [源码]K8 Cscan模块 C#获取内网主机IP/机器名/Banner/网页标题源码
[原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器?其实也是插件化,但C ...
- PHP利用纯真IP数据库在本地实现IP地址信息查询
https://blog.csdn.net/myweishanli/article/details/45098693 准备工作: 建议本地IP地址数据库,请到http://www.cz88.net/这 ...
- Qt之获取本机网络信息(MAC, IP等等,很全)
经常使用命令行来查看一些计算机的配置信息. 1.首先按住键盘上的“开始键+R键”,然后在弹出的对话框中输入“CMD”,回车 另外,还可以依次点击 开始>所有程序>附件>命令提示符 2 ...
- 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
package com.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.htt ...
- pythond的icmp广播报获取局域网主机IP
icmp广播报获取局域网四川特产IP from scapy.all import *import randomimport threading def scan(sip,dip): pkt = Eth ...
- Java如何获取本地计算机的IP地址和主机名?
在Java编程中,如何获取本地计算机的IP地址和主机名? 以下示例显示如何使用InetAddress类的getLocalAddress()方法获取系统的本地IP地址和主机名. package com. ...
- java Socket 获取本地主机ip
package cn.itcast.net.p1.ip; import java.net.InetAddress;import java.net.UnknownHostException; publi ...
随机推荐
- Windows 平台下 LiteIDE 的安装和使用
1. 安装 Go 语言并设置环境变量 参考博客<Windows 平台下 Go 语言的安装和环境变量设置>. 2. MinGW 的下载和安装 Windows 下的 Go 调试还需要安装 Mi ...
- Swift下CoreData的使用
我之前的随笔中有写过一些iOS持久化存储的方法,包含了sqlite.解归档.沙盒存放等等.这些方式中,能够大规模存储,并保持性能的只有使用sqlite了.而这里将记录下Cocoa自身继承的数据库的存储 ...
- 打造开发React Native的Sublime
之前一年多一直用Sublime Text做前端开发,最近做React开发,发现不太好用,就尝试其他编辑器.WebStorm和VS Code都用过,WebStorm基本不用装插件,可以直接用,但用习惯 ...
- Call、Apply和Bind
首先说一下bind,灵活的通过bind来改变this指针 bind方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入bind方法的第一个参数作为this, 传入bind ...
- 2.RabbitMQ的quick start
1.首先要安装 RabbitMQ Client 2.创建一个控制台项目 取名 Publisher代码如下: using RabbitMQ.Client; using System; using Sys ...
- TCP 报文段结构
源端口.目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信.源端口.目标端口是用 ...
- [MVVM Light]Messenger 的使用
原文:[MVVM Light]Messenger 的使用 当我们使用MVVM开发模式进行开发时,ViewModel之间的通信常常是很头疼的事情,好在MVVM Light提供了Messenger类可以轻 ...
- NYOJ 24 素数的距离问题
素数的距离问题 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描写叙述 如今给出你一些数.要求你写出一个程序,输出这些整数相邻近期的素数,并输出其相距长度.假设左右有等距离长 ...
- delphi的bpl、dcp 、dcu文件意义(BPL相当于C++中的DLL,DCP相当于C++中的Lib,编译时需要)
BPL 英文全称 Borland Package library ,是一种特殊的DLL文件,用于代码重用和减少可执行文件.编译bpl时,仅需要添加相应功能的pas文件,如果有窗体,则需要添加dfm文 ...
- PHP中间uniqid在高并发重复问题
在公用事业最近项目生成token检查问题.首先考虑php中间uniqid()函数生成一个随机字符串,但因为该函数的良好似基于微秒的水平.在高并发的情况下,,也能够产生相同的值. 解1:uniqid(r ...