Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285099
  • 博文数量: 65
  • 博客积分: 3091
  • 博客等级: 中校
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2005-01-25 09:44
文章存档

2013年(2)

2012年(11)

2011年(12)

2010年(13)

2009年(15)

2008年(12)

分类: LINUX

2012-08-24 11:20:27

/*
 * 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) |
给主人留下些什么吧!~~