取本机所有的 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;
    }
}

Debian lenny测试通过

/* ADD #include <stdio.h> */

在我的debian上测试通过,博主能否再写一个获取本机外部IP?
脚本也行啊!

什么叫本机外部IP ?

什么叫本机外部IP ?

如: 我的本机内部IP:192.168.1.2

如:
我的本机内部IP:192.168.1.2
我的外部IP:221.221.0.11

上面的代码能得到192.168.1.2,但我想得到221.221.0.11
我现在的方法是wget一个IP的网站,然后cron给我的gmail,这样我在家或外地也可以ssh到公司的机器上,因为IP是动态的!

这种方法就是只能取到本地配置的,可以用 ifconfig

这种方法就是只能取到本地配置的,可以用 ifconfig 看到的 IP 啊.

debian

debian 上装一个facter
hmy@luna:~$facter |grep -i ipadd
ipaddress => 192.168.2.10
ipaddress_eth0 => 192.168.2.10
ipaddress_eth0:0 => 10.0.1.10
ipaddress_eth1 => 192.168.0.103
ipaddress_vmnet1 => 10.0.35.1