首页 > 代码库 > Linux 获得机器的IP和网卡信息

Linux 获得机器的IP和网卡信息

Linux 获得机器的IP和网卡信息

代码来自于网络, 我改写了, 有美不敢自专, 特分享之.用法很简单,就3个函数.

头文件getmac.h:

/**
 * getmac.h
 *
 * 2014-07-08: init created
 */
#ifndef GETMAC_H_INCLUDED
#define GETMAC_H_INCLUDED

#if defined(__cplusplus)
extern "C" {
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/param.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <unistd.h>


#ifdef SOLARIS
# include <sys/sockio.h>
#endif

#define GETMAC_MAX_INTERFACES   16

#define GETMAC_MAX_MSGLEN      256


#define GETMAC_SUCCESS    0
#define GETMAC_ERROR    (-1)
#define GETMAC_EATTR    (-2)


typedef int GETMAC_BOOL;

#define GETMAC_TRUE    1
#define GETMAC_FALSE   0


typedef struct
{
    int fd;
    struct ifreq buf[GETMAC_MAX_INTERFACES];
    struct arpreq arp;
    int ifaces;
} getmac_info_t;


typedef struct
{
    int errcode;
    char errmsg[GETMAC_MAX_MSGLEN];
} getmac_error_t;

#define GETMAC_ATTR_IFNAME      0
#define GETMAC_ATTR_IS_PROMISC  1
#define GETMAC_ATTR_IS_UP       2
#define GETMAC_ATTR_IPADDR      3
#define GETMAC_ATTR_HDADDR      4


extern int getmac_init (getmac_info_t * mi, getmac_error_t * err);


extern int getmac_attr (getmac_info_t * mi, int i, int attr, void * value, getmac_error_t * err);


extern void getmac_fini (getmac_info_t * mi);


#if defined(__cplusplus)
}
#endif


#endif /* GETMAC_H_INCLUDED */

C文件getmac.c:

/**
 * getmac.c
 *
 * 2014-07-08: init created
 */
#include "getmac.h"


int getmac_init (getmac_info_t * mi, getmac_error_t * err)
{
    int fd;
    struct ifconf ifc;

    bzero (mi, sizeof(getmac_info_t));
    mi->fd = -1;

    fd = socket (AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) {
        err->errcode = errno;
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "socket() error (%d): %s", strerror(errno));
        return GETMAC_ERROR;
    }

    /* prepare to get mac numb */
    ifc.ifc_len = sizeof(mi->buf);
    ifc.ifc_buf = (caddr_t) mi->buf;

    if (ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {
        err->errcode = errno;
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl() error (%d): %s", strerror(errno));
        close (fd);
        return GETMAC_ERROR;
    }

    mi->ifaces = ifc.ifc_len / sizeof (struct ifreq);
    mi->fd = fd;

    /* return numb of mac */
    return mi->ifaces;
}


int getmac_attr (getmac_info_t * mi, int i, int attr, void * value, getmac_error_t * err)
{
    if (mi->fd == -1) {
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "getmac_init should be invoked first");
        return GETMAC_ERROR;
    }

    if (attr == GETMAC_ATTR_IS_PROMISC || attr == GETMAC_ATTR_IS_UP || attr == GETMAC_ATTR_IFNAME) {
        if (! mi->buf[i].ifr_name[0]) {
            if (ioctl (mi->fd, SIOCGIFFLAGS, (char *) & mi->buf[i])) {
                err->errcode = errno;
                snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFFLAGS) error (%d): %s", strerror(errno));  
                return GETMAC_ERROR;
            }
        }

        if (attr == GETMAC_ATTR_IS_PROMISC) {
            /* whether the net card status is promisc */
            if (mi->buf[i].ifr_flags & IFF_PROMISC) {
                * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            } else {
                * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            }
        } else if (attr == GETMAC_ATTR_IS_UP) {
            /* whether the net card status is up */
            if (mi->buf[i].ifr_flags & IFF_UP) {
                * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            } else {
                * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            }
        } else {
            /* device name */
            strcpy (value, mi->buf[i].ifr_name);
        }

        return GETMAC_SUCCESS;
    } else if (attr == GETMAC_ATTR_IPADDR || attr == GETMAC_ATTR_HDADDR) {
        /* get ip address of net card */
        if (ioctl (mi->fd, SIOCGIFADDR, (char *) & mi->buf[i])) {
            err->errcode = errno;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFADDR) error (%d): %s", strerror(errno));  
            return GETMAC_ERROR;
        }

        if (attr == GETMAC_ATTR_IPADDR) {
            strcpy (value, inet_ntoa (((struct sockaddr_in*) (& mi->buf[i].ifr_addr))->sin_addr));
            return GETMAC_SUCCESS;
        } else {
            /* get Hardware Address */
#ifdef SOLARIS

            do {
                mi->arp.arp_pa.sa_family = AF_INET;
                mi->arp.arp_ha.sa_family = AF_INET;
                ((struct sockaddr_in *) & mi->arp.arp_pa)->sin_addr.s_addr = 
                    ((struct sockaddr_in*)(& buf[intrface].ifr_addr))->sin_addr.s_addr;

                if ((ioctl (mi->fd, SIOCGARP, (char *) & mi->arp))) {
                    err->errcode = errno;
                    snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGARP) error (%d): %s", strerror(errno));  
                    return GETMAC_ERROR;
                } else {
                    sprintf (value, "%02x:%02x:%02x:%02x:%02x:%02x",
                        (unsigned char) mi->arp.arp_ha.sa_data[0],
                        (unsigned char) mi->arp.arp_ha.sa_data[1],
                        (unsigned char) mi->arp.arp_ha.sa_data[2],
                        (unsigned char) mi->arp.arp_ha.sa_data[3],
                        (unsigned char) mi->arp.arp_ha.sa_data[4],
                        (unsigned char) mi->arp.arp_ha.sa_data[5] );
                    return GETMAC_SUCCESS;
                }
            } while (0);
#else
    #if 0
            do {
                /* get HW ADDRESS of the net card */
                if (ioctl (mi->fd, SIOCGENADDR, (char *) &buf[i])) {
                    err->errcode = errno;
                    snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGENADDR) error (%d): %s", strerror(errno));  
                    return GETMAC_ERROR;
                }
                
                sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
                    (unsigned char) mi->buf[i].ifr_enaddr[0],
                    (unsigned char) mi->buf[i].ifr_enaddr[1],
                    (unsigned char) mi->buf[i].ifr_enaddr[2],
                    (unsigned char) mi->buf[i].ifr_enaddr[3],
                    (unsigned char) mi->buf[i].ifr_enaddr[4],
                    (unsigned char) mi->buf[i].ifr_enaddr[5]);

                return GETMAC_SUCCESS;
            } while (0);

    #else
            do {
                if (ioctl (mi->fd, SIOCGIFHWADDR, (char *) & mi->buf[i])) {
                    err->errcode = errno;
                    snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFHWADDR) error (%d): %s", strerror(errno));  
                    return GETMAC_ERROR;
                }

                sprintf (value, "%02x:%02x:%02x:%02x:%02x:%02x",
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[0],
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[1],
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[2],
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[3],
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[4],
                    (unsigned char) mi->buf[i].ifr_hwaddr.sa_data[5]);

                return GETMAC_SUCCESS;
        } while (0);

    #endif
#endif
        }
    } else {
        err->errcode = GETMAC_EATTR;
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "error attr specified");
        return GETMAC_EATTR;    
    }
}


void getmac_fini (getmac_info_t * mi)
{
    if (mi->fd != -1) {
        close (mi->fd);
        mi->fd = -1;
    }
}