取本机所有的 IP
代码修改自 qmail 的 ipme.c , 要点是对于 struct ifreq 里定义了 ifr_addr.sa_len 的系统(比如 FreeBSD),是和 Linux 不太一样的。
在 CentOS 3 和 FreeBSD 4.7 上测试通过
-
/* ipme.c from qmail */
-
#include "sys/types.h"
-
#include "sys/ioctl.h"
-
#include "sys/socket.h"
-
#include "netinet/in.h"
-
#include "net/if.h"
-
-
int main(int argc, char *argv[])
-
{
-
struct ifconf ifc;
-
int sockfd;
-
char buf[20000];
-
char *ptr;
-
-
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-
return -1;
-
}
-
-
ifc.ifc_buf = buf;
-
ifc.ifc_len = sizeof(buf);
-
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
-
return -1;
-
}
-
-
ptr = buf;
-
while (ptr < buf + ifc.ifc_len) {
-
struct ifreq *ifr;
-
struct sockaddr_in *sin;
-
int len;
-
-
ifr = (struct ifreq *)ptr;
-
#ifdef __FreeBSD__
-
len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
-
-
if (ifr->ifr_addr.sa_family == AF_INET) {
-
printf("%s", ifr->ifr_name);
-
sin = (struct sockaddr_in *)&ifr->ifr_addr;
-
printf("\t%s", inet_ntoa(sin->sin_addr));
-
if (ioctl(sockfd, SIOCGIFFLAGS, ifr) == 0) {
-
if (ifr->ifr_flags & IFF_UP) {
-
printf("\tUP\n");
-
} else {
-
printf("\tDOWN\n");
-
}
-
}
-
}
-
-
// 这段代码来自 qmail 的 ipme.c, 在 FreeBSD 上实测中没有出现过 len 小的情况
-
if (len < sizeof(struct ifreq))
-
#else
-
if (ioctl(sockfd, SIOCGIFFLAGS, ifr) == 0) {
-
if (ifr->ifr_flags & IFF_UP) {
-
if (ioctl(sockfd, SIOCGIFADDR, ifr) == 0) {
-
if (ifr->ifr_addr.sa_family == AF_INET) {
-
sin = (struct sockaddr_in *)&ifr->ifr_addr;
-
printf("%s\t%s\n", ifr->ifr_name, inet_ntoa(sin->sin_addr));
-
}
-
}
-
}
-
}
-
#endif
-
len = sizeof(struct ifreq);
-
ptr += len;
-
}
-
}
最新评论