linux通过c语言接口获取网卡信息
程序员文章站
2022-06-03 08:17:58
...
方法一 通过ioctl的SIOCGIFCONF
实例1. 检查特定的网卡是否存在
// ppp、wifi是否正常
static int check_ppp_wifi (int wifi_switch)
{
struct ifreq ifr;
struct ifconf ifc;
char buf[256];
int success = 0;
int wifi_exist = 0;
int ppp_exist = 0;
int ret = -1;
int sock = -1;
int count = 0;
if (wifi_switch == 0)
wifi_exist = 1;
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock == -1) {
APP_LogPrintf(ALM_ERROR, "socket error\n");
goto out;
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
APP_LogPrintf(ALM_ERROR,"ioctl error\n");
goto out;
}
struct ifreq* it = ifc.ifc_req;
const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
for (; it != end; ++it) {
strcpy(ifr.ifr_name, it->ifr_name);
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
// don't count loopback
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
count ++ ;
unsigned char * ptr ;
ptr = (unsigned char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
if (strncmp("ppp0", ifr.ifr_name, 4) == 0) {
ppp_exist = 1;
if (wifi_exist) {
ret = 0;
goto out;
}
} else if (strncmp("uap0", ifr.ifr_name, 4) == 0) {
wifi_exist = 1;
if (wifi_exist) {
ret = 0;
goto out;
}
}
}
}
} else {
APP_LogPrintf(ALM_ERROR,"get mac info error\n");
goto out;
}
}
out:
if (-1 != sock)
close(sock);
return ret;
}
实例2 列举系统所有的网卡信息
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
int main()
{
struct ifreq ifr;
struct ifconf ifc;
char buf[2048];
int success = 0;
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock == -1) {
printf("socket error\n");
return -1;
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
printf("ioctl error\n");
return -1;
}
struct ifreq* it = ifc.ifc_req;
const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
char szMac[64];
int count = 0;
for (; it != end; ++it) {
strcpy(ifr.ifr_name, it->ifr_name);
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
count ++ ;
unsigned char * ptr ;
ptr = (unsigned char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
snprintf(szMac,64,"%02X:%02X:%02X:%02X:%02X:%02X",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
printf("%d,Interface name : %s , Mac address : %s \n",count,ifr.ifr_name,szMac);
}
}
}else{
printf("get mac info error\n");
return -1;
}
}
}
注意:使用的时候一定要记得关闭socket,不然可能会导致打开文件过多,程序崩溃。
方案二:通过getifaddrs()来实现
实例1 检查特定网卡
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
int c_ifaddrs_netlink_status(const char *if_name )
{
struct ifaddrs *ifa = NULL, *ifList;
if (getifaddrs(&ifList) < 0) {
return -1;
}
for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_INET) {
if (strcmp(ifa->ifa_name, if_name) ==0) {
if (!(ifa->ifa_flags & IFF_UP)) {
printf("DEVICE_DOWN\r\n");
freeifaddrs(ifList);
return 1;
}
if (!(ifa->ifa_flags & IFF_RUNNING)) {
printf("DEVICE_UNPLUGGED\r\n");
freeifaddrs(ifList);
return 2;
}
printf("DEVICE_LINKED\r\n");
freeifaddrs(ifList);
return 3;
}
}
}
printf(stderr, "DEVICE_NONE\r\n");
freeifaddrs(ifList);
return 0;
}
int main(int argc, char* argv[])
{
int i=0;
if (argc != 2) {
fprintf(stderr, "usage: %s <ethname>\r\n", argv[0]);
return -1;
}
i = c_ifaddrs_netlink_status(argv[1]);
fprintf(stderr,"c_ifaddrs_netlink_status if_status = %d\n", i );
return 0;
}
实例2 列举系统所有网卡信息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
int main(int argc, char* argv[]) {
struct ifaddrs *ifc, *ifc1;
char ip[64] = {};
char nm[64] = {};
if(0 != getifaddrs(&ifc)) return -1;
ifc1 = ifc;
printf("iface\tIP address\tNetmask\n");
for (; NULL != ifc; ifc = (*ifc).ifa_next) {
printf("%s", (*ifc).ifa_name);
if (NULL != (*ifc).ifa_addr) {
inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_addr))->sin_addr), ip, 64);
printf("\t%s", ip);
} else {
printf("\t\t");
}
if (NULL != (*ifc).ifa_netmask) {
inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_netmask))->sin_addr), nm, 64);
printf("\t%s", nm);
} else {
printf("\t\t");
}
printf("\n");
}
freeifaddrs(ifc1);
return 0;
}
上一篇: route和router 解惑
下一篇: 编程以获取/设置Linux系统的网络信息