我有一个很好的小程序,它给我一个系统所连接的网络上所有活动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
答案 0 :(得分:0)
我会看一下RHEL上的rtnetlink和getifaddrs还有NetworkManager所有三个应该允许你想要的但是我不认为这三个中的任何一个是Windows特定API的直接替代品。您还必须有一些方法来编写代码,以便编译相关的函数。我通常使用`#ifndef'来分割代码,这样你可以使用相同的代码返回相同的东西,但使用不同的代码体依赖于你正在编译的目标操作系统。
我最近回答了另一个问题,其中windows / linux编译是一个问题(用于查找boost的运行时版本)here,原则保持不变,可以根据您的需要轻松定制。
另外,我怀疑Boost.Asio可以帮助你在Windows和Linux中进行单点呼叫。您也可以将其设为integrated-with-Boost版本或standalone,以缩小占用空间。
请告诉我您的情况,或者您是否需要更多信息:)
在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 %s\n",name,addrbuf);
}
void
print_ifaddr(struct ifaddrs *addr)
{
char addrbuf[128] ;
addrbuf[0] = 0;
printf("%-24s %s\n","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: %s\n", 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.%d\n", 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.%d\n", 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.%d\n", 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.%d\n", i+1, INT_TO_ADDR(network));
}
}
close(sd);
}
return 0;
}
显然你需要根据自己的需要定制代码,但也许这会有所帮助:)
答案 1 :(得分:0)
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;