version 1.1, 2012/02/21 16:57:34
|
version 1.1.1.2, 2016/10/18 14:04:50
|
Line 18
|
Line 18
|
#include <net/if.h> |
#include <net/if.h> |
#include <netinet/in.h> |
#include <netinet/in.h> |
|
|
#if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ | #if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ \ |
| || ( defined __GLIBC__ && ! defined __linux__ ) |
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/sysctl.h> |
#include <sys/sysctl.h> |
#include <net/if_dl.h> |
#include <net/if_dl.h> |
#endif |
#endif |
|
|
|
#ifdef USE_GETIFADDRS |
|
#include <ifaddrs.h> |
|
#endif |
|
|
#include "iftop.h" |
#include "iftop.h" |
|
|
/* |
/* |
Line 40
|
Line 45
|
*/ |
*/ |
|
|
int |
int |
get_addrs_ioctl(char *interface, char if_hw_addr[], struct in_addr *if_ip_addr) | get_addrs_ioctl(char *interface, char if_hw_addr[], struct in_addr *if_ip_addr, struct in6_addr *if_ip6_addr) |
{ |
{ |
int s; |
int s; |
struct ifreq ifr = {}; |
struct ifreq ifr = {}; |
int got_hw_addr = 0; |
int got_hw_addr = 0; |
int got_ip_addr = 0; |
int got_ip_addr = 0; |
|
int got_ip6_addr = 0; |
|
#ifdef USE_GETIFADDRS |
|
struct ifaddrs *ifa, *ifas; |
|
#endif |
|
|
/* -- */ |
/* -- */ |
|
|
s = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */ | s = socket(AF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */ |
|
|
if (s == -1) { |
if (s == -1) { |
perror("socket"); |
perror("socket"); |
Line 71 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
Line 80 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
got_hw_addr = 1; |
got_hw_addr = 1; |
} |
} |
#else |
#else |
#if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ | #if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ \ |
| || ( defined __GLIBC__ && ! defined __linux__ ) |
{ |
{ |
int sysctlparam[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; |
int sysctlparam[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; |
size_t needed = 0; |
size_t needed = 0; |
Line 80 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
Line 90 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
sysctlparam[5] = if_nametoindex(interface); |
sysctlparam[5] = if_nametoindex(interface); |
if (sysctlparam[5] == 0) { |
if (sysctlparam[5] == 0) { |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
goto ENDHWADDR; |
|
} |
} |
if (sysctl(sysctlparam, 6, NULL, &needed, NULL, 0) < 0) { | else if (sysctl(sysctlparam, 6, NULL, &needed, NULL, 0) < 0) { |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
goto ENDHWADDR; |
|
} |
} |
if ((buf = malloc(needed)) == NULL) { | else if ((buf = malloc(needed)) == NULL) { |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
goto ENDHWADDR; |
|
} |
} |
if (sysctl(sysctlparam, 6, buf, &needed, NULL, 0) < 0) { | else if (sysctl(sysctlparam, 6, buf, &needed, NULL, 0) < 0) { |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface); |
free(buf); |
free(buf); |
goto ENDHWADDR; |
|
} |
} |
msghdr = (struct if_msghdr *) buf; | else { |
memcpy(if_hw_addr, LLADDR((struct sockaddr_dl *)(buf + sizeof(struct if_msghdr) - sizeof(struct if_data) + sizeof(struct if_data))), 6); | msghdr = (struct if_msghdr *) buf; |
free(buf); | memcpy(if_hw_addr, LLADDR((struct sockaddr_dl *)(buf + sizeof(struct if_msghdr) - sizeof(struct if_data) + sizeof(struct if_data))), 6); |
got_hw_addr = 1; | free(buf); |
| got_hw_addr = 1; |
ENDHWADDR: | } |
1; /* compiler whines if there is a label at the end of a block...*/ | |
} |
} |
#else |
#else |
fprintf(stderr, "Cannot obtain hardware address on this platform\n"); |
fprintf(stderr, "Cannot obtain hardware address on this platform\n"); |
Line 109 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
Line 114 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
#endif |
#endif |
|
|
/* Get the IP address of the interface */ |
/* Get the IP address of the interface */ |
#ifdef SIOCGIFADDR | #ifdef USE_GETIFADDRS |
| if (getifaddrs(&ifas) == -1) { |
| fprintf(stderr, "Unable to get IP address for interface: %s\n", interface); |
| perror("getifaddrs()"); |
| } |
| else { |
| for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) { |
| if (got_ip_addr && got_ip6_addr) |
| break; /* Search is already complete. */ |
| |
| if (strcmp(ifa->ifa_name, interface)) |
| continue; /* Not our interface. */ |
| |
| if (ifa->ifa_addr == NULL) |
| continue; /* Skip NULL interface address. */ |
| |
| if ( (ifa->ifa_addr->sa_family != AF_INET) |
| && (ifa->ifa_addr->sa_family != AF_INET6) ) |
| continue; /* AF_PACKET is beyond our scope. */ |
| |
| if ( (ifa->ifa_addr->sa_family == AF_INET) |
| && !got_ip_addr ) { |
| got_ip_addr = 2; |
| memcpy(if_ip_addr, |
| &(((struct sockaddr_in *) ifa->ifa_addr)->sin_addr), |
| sizeof(*if_ip_addr)); |
| continue; |
| } |
| /* Must be a IPv6 address at this point. */ |
| struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) ifa->ifa_addr; |
| |
| if ( IN6_IS_ADDR_LINKLOCAL(&(sa6->sin6_addr)) |
| || IN6_IS_ADDR_SITELOCAL(&(sa6->sin6_addr)) ) |
| continue; |
| |
| /* A useful IPv6 address. */ |
| memcpy(if_ip6_addr, &(sa6->sin6_addr), sizeof(*if_ip6_addr)); |
| got_ip6_addr = 4; |
| } |
| freeifaddrs(ifas); |
| } /* getifaddrs() */ |
| #elif defined(SIOCGIFADDR) |
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET; |
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET; |
if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { |
if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { |
fprintf(stderr, "Unable to get IP address for interface: %s\n", interface); |
fprintf(stderr, "Unable to get IP address for interface: %s\n", interface); |
Line 125 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
Line 171 get_addrs_ioctl(char *interface, char if_hw_addr[], st
|
|
|
close(s); |
close(s); |
|
|
return got_hw_addr + got_ip_addr; | return got_hw_addr + got_ip_addr + got_ip6_addr; |
} |
} |