linux下可以用ifconfig命令来查看所有网口的连接状态及其他详细信息。
根据ifconfig的源码,我们可以实现检测网口状态并获取网口的名字和IP地址。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct _gEthIfaceInfo
{
unsigned int etherIP;
char etherName[IF_NAMESIZE];
}EtherIfaceInfo_t;
EtherIfaceInfo_t gEtherIfaceInfo;
//
//@usage: get avail iface
//
static bool getAvailIface(EtherIfaceInfo_t &ifaceInfo)
{
int i, flags;
struct ifconf data;
struct ifreq device[IF_NAMESIZE];//16
data.ifc_len = sizeof(device);
data.ifc_req = device;
memset(data.ifc_buf, 0, data.ifc_len);
flags = IFF_UP | IFF_RUNNING | IFF_MULTICAST;
int sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd < 0)
{
perror("socket fails");
return false;
}
/* get list of network interfaces */
if (ioctl(sockfd, SIOCGIFCONF, &data) < 0)
{
ERROR_LOG("failed query network interfaces");
return false;
}
if (data.ifc_len >= sizeof(device))
{
WARN_LOG("device list may exceed allocated space");
}
/* search through interfaces */
for (i = 0; i < data.ifc_len / sizeof(device[0]); ++i)
{
DEBUG_LOG("%d %s %s", i, device[i].ifr_name, inet_ntoa(((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr));
if (ioctl(sockfd, SIOCGIFFLAGS, &device[i]) < 0)
{
ERROR_LOG("failed to get device flags");
continue;
}
else if ((device[i].ifr_flags & flags) != flags)
{
WARN_LOG("does not meet requirements""(%08x, %08x)", device[i].ifr_flags, flags);
continue;
}
else if (ioctl(sockfd, SIOCGIFHWADDR, &device[i]) < 0)
{
ERROR_LOG("failed to get hardware address");
continue;
}
else if (ioctl(sockfd, SIOCGIFADDR, &device[i]) < 0)
{
ERROR_LOG("failed to get ip address");
continue;
}
else
{
DEBUG_LOG("found available interface (%s)", device[i].ifr_name);
ifaceInfo.etherIP = ((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr.s_addr;
memcpy(ifaceInfo.etherName, device[i].ifr_name, IF_NAMESIZE);
return true;
}
}
close(sockfd);
return false;
}