获取网络上活动IP的列表(Linux)
Get list of alive IP on network (Linux)
我有一个很好的小程序,它给了我一个系统连接到的网络上所有活动ip的向量。。。但仅适用于windows
std::vector<std::string> resultIPList;
PMIB_IPNET_TABLE2 pipTable = NULL;
unsigned long status = GetIpNetTable2(AF_INET, &pipTable);
if(status != NO_ERROR)
{
LOG_ERROR("Error in getting ip Table")
return resultIPList;
}
for(unsigned i = 0; i < pipTable->NumEntries; i++)
{
char* ip = inet_ntoa(pipTable->Table[i].Address.Ipv4.sin_addr);
std::string str = std::string(ip);
resultIPList.push_back(str);
}
FreeMibTable(pipTable);
pipTable = NULL;
return resultIPList;
在Linux中有没有同样的方法(替换GetIpNetTable函数)。我正在使用RHEL
getifaddrs FTW
#include <ifaddrs.h>
#include <net/if.h>
#include <netinet/in.h>
#include <cstdlib>
ifaddrs* pAdapter = NULL;
ifaddrs* pList = NULL;
int result = getifaddrs(&pList);
if (result == -1)
return;
pAdapter = pList;
while (pAdapter)
{
if ((pAdapter->ifa_addr != NULL) && (pAdapter->ifa_flags & IFF_UP))
{
if (pAdapter->ifa_addr->sa_family == AF_INET)
{
sockaddr_in* addr = (sockaddr_in*)(pAdapter->ifa_addr);
}
else if (pAdapter->ifa_addr->sa_family == AF_INET6)
{
sockaddr_in6* addr6 = (sockaddr_in6*)(pAdapter->ifa_addr);
}
}
pAdapter = pAdapter->ifa_next;
}
freeifaddrs(pList);
pList = NULL;
我想看看RHEL上的rtnetlink和getifaddrs,还有NetworkManager,这三者都应该允许您所寻找的东西,但我不认为这三者中的任何一个是特定于windows的API的直接替代品。您还必须有一些方法来破解代码,以便编译相关的函数。我通常使用"#ifndef"来拆分代码,这样你就可以让相同的代码返回相同的东西,但使用不同的代码体,这取决于你编译的目标操作系统。
我最近回答了另一个问题,其中windows/linux编译是一个问题(用于查找boost的运行时版本)这里,原理保持不变,可以轻松地根据您的需求进行定制。
顺便说一句,我怀疑Boost.Asio可能也会在Windows和Linux中为您提供一点帮助。您也可以将其作为与Boost的集成版本或独立版本,以实现更小的占地面积。
让我知道你的进展,或者如果你需要更多信息:)
附录
在Linux上,您可以使用以下内容:
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
void
print_sockaddr(struct sockaddr* addr,const char *name)
{
char addrbuf[128] ;
addrbuf[0] = 0;
if(addr->sa_family == AF_UNSPEC)
return;
switch(addr->sa_family) {
case AF_INET:
inet_ntop(addr->sa_family,&((struct sockaddr_in*)addr)->sin_addr,addrbuf,sizeof(addrbuf));
break;
case AF_INET6:
inet_ntop(addr->sa_family,&((struct sockaddr_in6*)addr)->sin6_addr,addrbuf,sizeof(addrbuf));
break;
default:
sprintf(addrbuf,"Unknown (%d)",(int)addr->sa_family);
break;
}
printf("%-16s %sn",name,addrbuf);
}
void
print_ifaddr(struct ifaddrs *addr)
{
char addrbuf[128] ;
addrbuf[0] = 0;
printf("%-24s %sn","Interface Name:",addr->ifa_name);
if(addr->ifa_addr != NULL)
print_sockaddr(addr->ifa_addr,"Interface Address:");
if(addr->ifa_netmask != NULL)
print_sockaddr(addr->ifa_netmask,"Netmask:");
if(addr->ifa_broadaddr != NULL)
print_sockaddr(addr->ifa_broadaddr,"Broadcast address:");
if(addr->ifa_dstaddr != NULL)
print_sockaddr(addr->ifa_dstaddr,"Peer address:");
puts("");
}
int main(int argc,char *argv[])
{
struct ifaddrs *addrs,*tmp;
if(getifaddrs(&addrs) != 0) {
perror("getifaddrs");
return 1;
}
for(tmp = addrs; tmp ; tmp = tmp->ifa_next) {
print_ifaddr(tmp);
}
freeifaddrs(addrs);
return 0;
}
对于其他衍生产品(Unix、BSD等),这组更基本的代码可能更有用,尽管我模糊地记得BSD下的一些问题(对不起,目前记不清具体是什么,认为这与某些条件会使其无法运行的失败场景有关)
#include <stdio.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#define INT_TO_ADDR(_addr)
(_addr & 0xFF),
(_addr >> 8 & 0xFF),
(_addr >> 16 & 0xFF),
(_addr >> 24 & 0xFF)
int main()
{
struct ifconf ifc;
struct ifreq ifr[10];
int sd, ifc_num, addr, bcast, mask, network, i;
// Create a socket then use ioctl on the file descriptor to retrieve the interface information.
sd = socket(PF_INET, SOCK_DGRAM, 0);
if (sd > 0)
{
ifc.ifc_len = sizeof(ifr);
ifc.ifc_ifcu.ifcu_buf = (caddr_t)ifr;
if (ioctl(sd, SIOCGIFCONF, &ifc) == 0)
{
ifc_num = ifc.ifc_len / sizeof(struct ifreq);
printf("%d interfaces found.n", ifc_num);
for (i = 0; i < ifc_num; ++i)
{
if (ifr[i].ifr_addr.sa_family != AF_INET)
{
continue;
}
/* display the interface name */
printf("%d) Interface Name: %sn", i+1, ifr[i].ifr_name);
/* Retrieve the IP address, broadcast address, and subnet mask. */
if (ioctl(sd, SIOCGIFADDR, &ifr[i]) == 0)
{
addr = ((struct sockaddr_in *)(&ifr[i].ifr_addr))->sin_addr.s_addr;
printf("%d) Interface address: %d.%d.%d.%dn", i+1, INT_TO_ADDR(addr));
}
if (ioctl(sd, SIOCGIFBRDADDR, &ifr[i]) == 0)
{
bcast = ((struct sockaddr_in *)(&ifr[i].ifr_broadaddr))->sin_addr.s_addr;
printf("%d) Broadcast: %d.%d.%d.%dn", i+1, INT_TO_ADDR(bcast));
}
if (ioctl(sd, SIOCGIFNETMASK, &ifr[i]) == 0)
{
mask = ((struct sockaddr_in *)(&ifr[i].ifr_netmask))->sin_addr.s_addr;
printf("%d) Netmask: %d.%d.%d.%dn", i+1, INT_TO_ADDR(mask));
}
/* Compute the current network value from the address and netmask. */
network = addr & mask;
printf("%d) Current Network: %d.%d.%d.%dn", i+1, INT_TO_ADDR(network));
}
}
close(sd);
}
return 0;
}
显然,您需要定制代码以满足您的需求,但这可能会有所帮助:)
相关文章:
- 在C++/Linux中设置单调时钟的一些技巧
- Linux的Cpp上的计时器
- Pybind11:将元组列表从Python传递到C++
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 从链接列表c++中删除一个项目
- 在Linux中哪里可以找到互斥、未来等的源代码
- Linux MinGW:在编译时,他输出了 8 个"nultiple definitions"列表
- 使用C 获取Linux进程列表和状态
- 用C 11 Boost实施的无法处于正常(Win/Linux)的事物列表
- C 链接列表仅在GNU/Linux而非Windows中导致分割故障
- 清除Linux内核链接列表
- 获取网络上活动IP的列表(Linux)
- Execlp()不接受参数列表,只接受命令.UNIX/LINUX编程
- 如何使用智能指针(例如auto_ptr r shared_ptr)在 Linux 上的C++中生成链接列表数据结构
- 在 32 位 Linux 机器中生成的预处理器指令列表与为 64 位 Linux 机器生成的预处理器指令列表之间是否有区
- Linux编译错误-GCC 4.3.4-模板参数列表太少
- 如何在Linux下获得C/C++中SCSI磁盘的列表
- Linux dient:获取目录中所有文件夹的列表
- C++ 分叉子,向子进程询问进程列表,在 Linux 中杀死一个进程
- 是否有一些Linux或gcc的特殊(内存)地址列表