linux检测网口连接状态

时间:2020-12-25 10:42:10

linux下可以用ifconfig命令来查看所有网口的连接状态及其他详细信息。

根据ifconfig的源码,我们可以实现检测网口状态并获取网口的名字和IP地址。


#include <stdio.h>      
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <net/if.h>
#include <time.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <stdlib.h>

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;
}