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_NOERROR    0
#define GETMAC_SUCCESS  GETMAC_NOERROR
#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_IFF_UP          1       /* Interface is up */
#define GETMAC_ATTR_IFF_BROADCAST   2       /* Broadcast address valid */
#define GETMAC_ATTR_IFF_DEBUG       3       /* Turn on debugging */
#define GETMAC_ATTR_IFF_LOOPBACK    4       /* Is a loopback net */
#define GETMAC_ATTR_IFF_POINTOPOINT 5       /* Interface is point-to-point link */
#define GETMAC_ATTR_IFF_NOTRAILERS  6       /* Avoid use of trailers */
#define GETMAC_ATTR_IFF_RUNNING     7       /* Resources allocated */
#define GETMAC_ATTR_IFF_NOARP       8       /* No address resolution protocol */
#define GETMAC_ATTR_IFF_PROMISC     9       /* Receive all packets */

#define GETMAC_ATTR_IFNAME         10       /* Interface name, e.g. "en0".  */
#define GETMAC_ATTR_IPADDR         11       /* Address of interface */
#define GETMAC_ATTR_HWADDR         12       /* MAC address */

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;
    }

    /* initialize if not a valid name */
    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 (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;
        }

        /* 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[i].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;
            }
        } 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;
            }
        } 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;
            }
        } while (0);
    #endif
#endif
    }

    err->errcode = GETMAC_NOERROR;

    /* get net attribute */
    switch (attr) {
    case GETMAC_ATTR_IFF_UP:    /* Interface is up */
        if (mi->buf[i].ifr_flags & IFF_UP) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is up");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is not up");
        }
        break;

    case GETMAC_ATTR_IFF_BROADCAST:    /* Broadcast address valid */
        if (mi->buf[i].ifr_flags & IFF_BROADCAST) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Broadcast address valid");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Broadcast address invalid");
        }
        break;

    case GETMAC_ATTR_IFF_DEBUG:    /* Turn on debugging */
        if (mi->buf[i].ifr_flags & IFF_DEBUG) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Turn on debugging");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Turn off debugging");
        }
        break;

    case GETMAC_ATTR_IFF_LOOPBACK:    /* Is a loopback net */
        if (mi->buf[i].ifr_flags & IFF_LOOPBACK) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Is a loopback net");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not a loopback net");
        }
        break;

    case GETMAC_ATTR_IFF_POINTOPOINT:    /* Interface is point-to-point link */
        if (mi->buf[i].ifr_flags & IFF_POINTOPOINT) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is point-to-point link");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is not point-to-point link");
        }
        break;

    case GETMAC_ATTR_IFF_NOTRAILERS:    /* Avoid use of trailers */
        if (mi->buf[i].ifr_flags & IFF_NOTRAILERS) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Avoid use of trailers");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not Avoid use of trailers");
        }
        break;

    case GETMAC_ATTR_IFF_RUNNING:    /* Resources allocated */
        if (mi->buf[i].ifr_flags & IFF_RUNNING) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Resources allocated");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Resources not allocated");
        }
        break;

    case GETMAC_ATTR_IFF_NOARP:    /* No address resolution protocol */
        if (mi->buf[i].ifr_flags & IFF_NOARP) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "No address resolution protocol");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Has address resolution protocol");
        }
        break;

    case GETMAC_ATTR_IFF_PROMISC:    /* Receive all packets */
        if (mi->buf[i].ifr_flags & IFF_PROMISC) {
            * ((GETMAC_BOOL *) value) = GETMAC_TRUE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Receive all packets");
        } else {
            * ((GETMAC_BOOL *) value) = GETMAC_FALSE;
            snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not a promisc mode");
        }
        break;

    case GETMAC_ATTR_IFNAME:    /* Interface name, e.g. "en0" */
        strcpy (value, mi->buf[i].ifr_name);
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface name");
        break;

    case GETMAC_ATTR_IPADDR:    /* Interface address */
        strcpy (value, inet_ntoa (((struct sockaddr_in*) (& mi->buf[i].ifr_addr))->sin_addr));
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface address");
        break;

    case GETMAC_ATTR_HWADDR:
#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[i].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] );
            }
        } while (0);
#else
    #if 0
        do {
            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]);
        } while (0);
    #else
        do {
            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]);
        } while (0);
    #endif
#endif
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "MAC address");
        break;

    default:
        err->errcode = GETMAC_EATTR;
        snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "error attr specified");
        return GETMAC_EATTR;
    }

    return GETMAC_SUCCESS;
}

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

Linux 获得机器的IP和网卡信息的更多相关文章

  1. Linux查询一台机器的IP地址和其对应的域名

    Linux查询一台机器的IP地址和其对应的域名 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ nslookup > 127.0.0.1 Server: ...

  2. java获取本机器的IP(linux和windows)

    目录 描述 方案描述 获取Windows下的IP 获取linux下的IP 判断操作系统的类型 最后将上面三个方法进行整合 参考 描述 由于项目是部署在集群上的,需要项目能够自动采集各机器的信息.jav ...

  3. 修改ip 在linux上永久修改IP地址 子网掩码

    小结: 1. 子网掩码.子网IP计算 2. linux centos 修改ip地址细节介绍_LINUX_操作系统_脚本之家 http://www.jb51.net/LINUXjishu/66509.h ...

  4. Linux 单网卡多 IP 的配置方法

     Linux 单网卡多 IP 的配置方法 1 .永久配置的方法: 知道在 Linux 下网卡被称为 eth0,eth1,eth2..... ,所有网卡的配置文件都存储在 /etc/sysconfi ...

  5. Linux 高性能服务器编程——IP协议详解

    1 IP服务特点 IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. 无状态:IP通信双方不同步传输数据的状态信息,因此IP数据包的发送.传输和接收都是无序的.     ...

  6. linux操作系统-设置静态ip

    在使用linux虚拟机的时候因为经常有关机的需求,然后重新开机后可能面临这上一次获取的ip被改变,在这里我分享一下在linux 下设置静态ip的经验 1.查看路由状态 [root@localhost ...

  7. VMWare中Linux虚拟机设置静态IP上网的设置方法

    VMWare中Linux虚拟机设置静态IP上网的设置方法 标签: vmwareLinux虚拟机securecrt静态IP上网 2016-05-18 02:30 702人阅读 评论(0) 收藏 举报   ...

  8. linux常用命令:ip 命令

    ip命令是Linux下较新的功能强大的网络配置工具. 1.命令格式: ip  [OPTIONS]  OBJECT  [COMMAND [ARGUMENTS]] 2.命令功能: ip命令用来显示或操纵L ...

  9. linux命令总结之ip命令

    Linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者.使用ip命令,只需一个命令,你就能很轻松地执行一些网络管理任务.ifconfig是net-tools中已被废弃使用的一个命 ...

随机推荐

  1. Android开发学习之路--Drawable mutations

      时间过得很快,明天终于可以拿到房子了,交完这次房租,也可以成为房东了,看看博客也好久没有更新了,最近一直在整机器人,也没有太多时间整理博客.   今天下午和同事一起遇到了一个问题,就是明明没有改变 ...

  2. Java安全管理器——SecurityManager

    总的来说,Java安全应该包括两方面的内容,一是Java平台(即是Java运行环境)的安全性:二是Java语言开发的应用程序的安全性.由于我们不是Java本身语言的制定开发者,所以第一个安全性不需要我 ...

  3. windows下安装nginx (转载自:http://blog.163.com/njut_wangjian/blog/static/1657964252013327103716818/)

    1.  到nginx官网上下载相应的安装包,http://nginx.org/en/download.html:下载进行解压,将解压后的文件放到自己心仪的目录下,我的解压文件放在了d盘根目录下,如下图 ...

  4. Cocos2D添加精灵纹理滤镜实现图像复古效果的转换

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家知道Cocos2d本身是一个非常强悍的2d游戏引擎,其中自 ...

  5. iOS中 UITableViewCell cell划线那些事 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang 在开发中经常遇到cell分割线显示不全或者想自定义线的宽高等; 最近总结了一下,希望帮到大家: 1.不想划线怎么办? Table ...

  6. Android初级教程理论知识(第九章多媒体编程)

    多媒体概念 文字.图片.音频.视频 计算机图片大小的计算 图片大小 = 图片的总像素 * 每个像素占用的大小 单色图:每个像素占用1/8个字节 16色图:每个像素占用1/2个字节 256色图:每个像素 ...

  7. Java EE 之 过滤器入门学习与总结(2)

    今天就对使用Filter技术能做什么来个小小的归纳.也为了方便今后的复习. 控制浏览器不进行对jsp页面的缓存 //在doFilter方法中添加这样的代码 HttpServletRequest req ...

  8. Cookie 进阶

    Cookie作为一个客户端技术被广泛的应用着.我今天也来谈一谈我对Cookie的理解. 先来一个小菜(实现"上次登录时间") 具体的思路如下: 通过request.getCooki ...

  9. HTML5 Web Storage 特性

    原文地址: Using HTML5 Web Storage 原文日期: 2010年06月28日 翻译日期: 2013年08月12日 当下Web开发领域最火爆的词语当属 HTML5.HTML5标准的新特 ...

  10. C++ Primer 有感(标准库set类型)

    set容器只是单纯的键的集合,键必须为一.set容器不支持下标操作,而且没有定义maped_type类型.在set容器中,value_type不是pair类型,而是与key_type类型相同的类型. ...