通过getifaddrs获取网络接口的名称、mac地址、子网掩码、ip地址、网关,请写出C程序
时间: 2023-08-06 10:10:10 浏览: 321
好的,以下是一个使用getifaddrs函数获取网络接口信息的C程序,包括名称、MAC地址、子网掩码、IP地址和网关信息。请注意,获取网关信息需要使用系统调用来实现,因此这个程序只能在类Unix系统上运行。
```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
char gateway[NI_MAXHOST];
char mac[18];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
return EXIT_FAILURE;
}
/* Walk through linked list, maintaining head pointer so we
can free list later */
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL) {
continue;
}
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
form of the latter for the common families) */
printf("%-8s %s (%d)\n",
ifa->ifa_name,
(family == AF_PACKET) ? "AF_PACKET" :
(family == AF_INET) ? "AF_INET" :
(family == AF_INET6) ? "AF_INET6" : "???",
family);
/* For an AF_PACKET interface, display the MAC address. */
if (family == AF_PACKET && ifa->ifa_data != NULL) {
struct sockaddr_ll *s = (struct sockaddr_ll*)ifa->ifa_addr;
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
s->sll_addr[0], s->sll_addr[1], s->sll_addr[2],
s->sll_addr[3], s->sll_addr[4], s->sll_addr[5]);
printf("\t\tAddress: %s\n", mac);
}
/* For an AF_INET or AF_INET6 interface, display the
address and subnet mask */
else if (family == AF_INET || family == AF_INET6) {
s = socket(family, SOCK_DGRAM, 0);
if (s == -1) {
perror("socket");
return EXIT_FAILURE;
}
if (getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST) == 0) {
printf("\t\tAddress: <%s>\n", host);
}
if (getnameinfo(ifa->ifa_netmask,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST) == 0) {
printf("\t\tNetmask: <%s>\n", host);
}
/*Get the gateway address*/
if (family == AF_INET) {
struct rtentry *route;
memset(&route, 0, sizeof(route));
route->rt_dst.sa_family = AF_INET;
((struct sockaddr_in *) &route->rt_dst)->sin_addr.s_addr = 0;
route->rt_flags = RTF_UP;
if (ioctl(s, SIOCADDRT, &route) < 0) {
perror("SIOCADDRT failed");
return EXIT_FAILURE;
}
struct sockaddr_in *addr;
for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
addr = (struct sockaddr_in *) ifa->ifa_addr;
if (ifa->ifa_flags & IFF_LOOPBACK) {
continue;
}
if (addr->sin_addr.s_addr == ((struct sockaddr_in *) &route->rt_dst)->sin_addr.s_addr) {
continue;
}
if (ioctl(s, SIOCGIFHWADDR, ifa) == -1) {
perror("ioctl failed");
return EXIT_FAILURE;
}
if (ifa->ifa_addr) {
inet_ntop(AF_INET, &addr->sin_addr, gateway, NI_MAXHOST);
printf("\t\tGateway: %s\n", gateway);
}
}
}
if (ioctl(s, SIOCDELRT, &route) < 0) {
perror("SIOCDELRT failed");
return EXIT_FAILURE;
}
}
close(s);
}
}
freeifaddrs(ifaddr);
return EXIT_SUCCESS;
}
```
这个程序将会打印出每个网络接口的名称、MAC地址、IP地址、子网掩码和网关信息。如果某个接口没有网关,它将不会打印网关信息。
阅读全文