/*
* getifnet.c
* socket, sockaddr, sockaddr_in, sockaddr_in6, in_addr, in6_addr, ioctl
* Auth: saodrin
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXINTERFACES 16
//struct ifreq {
// char ifr_name[IFNAMSIZ]; // Interface name
// union {
// struct sockaddr ifr_addr; // Interface address (we use this)
// struct sockaddr ifr_dstaddr;
// struct sockaddr ifr_broadaddr;
// struct sockaddr ifr_netmask;
// struct sockaddr ifr_hwaddr;
// short ifr_flags;
// int ifr_ifindex;
// int ifr_metric;
// int ifr_mtu;
// struct ifmap ifr_map;
// char ifr_slave[IFNAMSIZ];
// char ifr_newname[IFNAMSIZ];
// char *ifr_data;
// };
//};
//struct ifconf {
// int ifc_len; // length of ifc_req buffer
// union {
// char *ifc_buf; // buffer address (we use this)
// struct ifreq *ifc_req;
// };
//};
/* This operating system-specific header file defines the SOCK_*, PF_*,
AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr',
`struct msghdr', and `struct linger' types. */
//#include
/* POSIX.1g specifies this type name for the `sa_family' member. */
//typedef unsigned short int sa_family_t;
//#define __SOCKADDR_COMMON(sa_prefix) \
// sa_family_t sa_prefix##family
/* Structure describing a generic socket address. */
//struct sockaddr
//{
// __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
// char sa_data[14]; /* Address data. */
//};
//#ifdef __USE_BSD
/* This is the 4.3 BSD `struct sockaddr' format, which is used as wire
format in the grotty old 4.3 `talk' protocol. */
//struct osockaddr
// {
// unsigned short int sa_family;
// unsigned char sa_data[14];
// };
//#endif
//struct in_addr {
// __be32 s_addr;
//};
//struct sockaddr_in {
// sa_family_t sin_family; /* Address family */
// __be16 sin_port; /* Port number */
// struct in_addr sin_addr; /* Internet address */
//
// /* Pad to size of `struct sockaddr'. */
// unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
// sizeof(unsigned short int) - sizeof(struct in_addr)];
//};
//struct in6_addr
//{
// union
// {
// __u8 u6_addr8[16];
// __be16 u6_addr16[8];
// __be32 u6_addr32[4];
// } in6_u;
//#define s6_addr in6_u.u6_addr8
//#define s6_addr16 in6_u.u6_addr16
//#define s6_addr32 in6_u.u6_addr32
//};
//struct sockaddr_in6 {
// unsigned short int sin6_family; /* AF_INET6 */
// __be16 sin6_port; /* Transport layer port # */
// __be32 sin6_flowinfo; /* IPv6 flow information */
// struct in6_addr sin6_addr; /* IPv6 address */
// __u32 sin6_scope_id; /* scope id (new in RFC2553) */
//};
int main(int argc, char *argv[])
{
int sockfd;
int interfaces;
int i;
char ifstr[64]; /* INET_ADDRSTRLEN or INET6_ADDRSTRLEN */
struct sockaddr *saddr;
struct sockaddr_in *i4saddr;
struct sockaddr_in6 *i6saddr;
struct ifconf ifc;
struct ifreq ifr[MAXINTERFACES];
struct ifreq ifdata;
//if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
if ((sockfd = socket(PF_INET, SOCK_DGRAM /* SOCK_STREAM */, 0)) == -1)
{
perror("socket");
return (-1);
}
ifc.ifc_len = sizeof(ifr);
ifc.ifc_buf = (char *)ifr;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1)
{
perror("ioctl");
return (-1);
}
interfaces = ifc.ifc_len / sizeof(ifr[0]);
// Print a heading that includes the total # of interfaces.
printf("IF(%d)\tIP\n", interfaces);
// Loop through the array of interfaces, printing each one's name and IP.
for (i = 0; i < interfaces; i++)
{
i4saddr = (struct sockaddr_in *) &ifr[i].ifr_addr;
// Convert the binary IP address into a readable string.
if (0 == inet_ntop(AF_INET, &i4saddr->sin_addr, ifstr, sizeof(ifstr)))
{
perror("inet_ntop");
continue;
}
printf("%s\t%s\n", ifr[i].ifr_name, ifstr);
strcpy(ifdata.ifr_name, ifr[i].ifr_name);
ioctl(sockfd, SIOCGIFFLAGS, &ifdata); /* 获取接口的状态参数 */
if (ifdata.ifr_flags & IFF_UP)
printf("Status:\tUP");
else
printf("status:\tDOWN");
strcpy(ifdata.ifr_name, ifr[i].ifr_name);
ioctl(sockfd, SIOCGIFBRDADDR, &ifdata); /* 获取接口的广播地址 */
i4saddr = (struct sockaddr_in *) &ifdata.ifr_addr;
if (0 == inet_ntop(AF_INET, &i4saddr->sin_addr, ifstr, sizeof(ifstr)))
{
perror("inet_ntop");
continue;
}
printf("broad addr:\t%s\n", ifstr);
ioctl(sockfd, SIOCGIFNETMASK, &ifdata); /* 获取接口的子网掩码 */
i4saddr = (struct sockaddr_in *) &ifdata.ifr_addr;
if (0 == inet_ntop(AF_INET, &i4saddr->sin_addr, ifstr, sizeof(ifstr)))
{
perror("inet_ntop");
continue;
}
printf("net mask:\t%s\n", ifstr);
ioctl(sockfd, SIOCGIFHWADDR, &ifdata); /* 获取接口的物理地址 */
printf("phy addr:\t%02X:%02X:%02X:%02X:%02X:%02X\n", \
(unsigned char)ifdata.ifr_hwaddr.sa_data[0], \
(unsigned char)ifdata.ifr_hwaddr.sa_data[1], \
(unsigned char)ifdata.ifr_hwaddr.sa_data[2], \
(unsigned char)ifdata.ifr_hwaddr.sa_data[3], \
(unsigned char)ifdata.ifr_hwaddr.sa_data[4], \
(unsigned char)ifdata.ifr_hwaddr.sa_data[5]);
printf("\n");
}
close(sockfd);
#ifdef __linux__
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
return (-1);
}
/* Walk through linked list, maintaining head pointer so we
can free list later */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
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("%s address family: %d%s\n",
ifa->ifa_name, family,
(family == AF_PACKET) ? " (AF_PACKET)" :
(family == AF_INET) ? " (AF_INET)" :
(family == AF_INET6) ? " (AF_INET6)" : "");
/* For an AF_INET* interface address, display the address */
if (family == AF_INET || family == AF_INET6)
{
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("address: \t%s\n", host);
}
}
freeifaddrs(ifaddr); //一定要释放
#else /* not Linux */
if ((sockfd = socket(PF_INET6, SOCK_DGRAM /* SOCK_STREAM */, 0)) == -1)
{
perror("socket");
return (-1);
}
ifc.ifc_len = sizeof(ifr);
ifc.ifc_buf = (char *)ifr;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1)
{
perror("ioctl");
return (-1);
}
interfaces = ifc.ifc_len / sizeof(ifr[0]);
// Print a heading that includes the total # of interfaces.
printf("IF(%d)\tIPv6\n", interfaces);
// Loop through the array of interfaces, printing each one's name and IP.
for (i = 0; i < interfaces; i++)
{
saddr = (struct sockaddr *)&(ifr[i].ifr_addr);
/* Convert the binary IP address into a readable string. */
if (0 == inet_ntop(AF_INET6, (struct in6_addr *)&(((struct sockaddr_in6 *)saddr)->sin6_addr),
ifstr, INET6_ADDRSTRLEN))
{
perror("inet_ntop");
continue;
}
printf("%s\t%s\n", ifr[i].ifr_name, ifstr);
/* 使用 SIOCGIFADDR 获取特定接口的地址 */
strcpy(ifdata.ifr_name, ifr[i].ifr_name);
ioctl(sockfd, SIOCGIFADDR, &ifdata); /* 获取接口的地址参数 */
saddr = (struct sockaddr *)&(ifdata.ifr_addr);
i6saddr = (struct sockaddr_in6 *)saddr;
if (0 == inet_ntop(AF_INET6, &(i6saddr->sin6_addr), ifstr, INET6_ADDRSTRLEN))
{
perror("inet_ntop");
continue;
}
printf("%s\t%s\n", ifr[i].ifr_name, ifstr);
}
printf("\n");
#endif
return (0);
}
阅读(894) | 评论(0) | 转发(0) |