Linux C获取本机IP和Mac

       通常在Linux下查看本机网卡相关信息常用命令是ifconfig,或者想要更详细点在后面加上“-a”选项,但如果想要在代码上实现获取本机IP地址、Mac地址,或者是其他网络配置信息,可以怎么做呢?

       其实方法有很多,但自我感觉这个算是比较通俗易懂的,也不需要调用一些不常用的函数。思路很简单,就是通过 ifconfig 命令查找出对应字段,把字段值保存到文件里,使用时再从文件读取出来即可。具体步骤如下:

获取IP地址

 1. ifconfig eth0 | grep 'inet addr' | awk '{ print $2}' | awk -F: '{print $2}' > /tmp/debug.txt ;                   ifconfig eth0 :只显示网卡0的相关信息   

     grep 'inet addr':从网卡0信息里查找'inet addr'字符串,因为该字符后跟着的就是IP地址;

     awk '{ print $2}' :使用awk命令打印eth0信息带有'inet addr'的第二个字段(文章结尾再补充)

     awk -F: '{print $2}':指定域分隔符为":",打印第二个字段值,如果不指定默认是空格或者tab键,每个字段通过分隔符区分(后面一起补充)

    > /tmp/debug.txt :将打印的内容重定向输出到/tmp/debug.txt 文件(文件不存在则自动创建)

 2. 调用system()函数执行以上指令

 3. open()打开文件,read()读取文件内容

 4. 读取后的是字符串格式IP地址,如果需要的是整型或者其他格式,则要转换格式,这里使用sscanf()函数,以"."作为分割格式切割字符串,存到对应整型数组里

 5. 将存好的数值进行移位处理,组装成一个32bit的数值,因为从字符串里获取的每个IP值都只占8bit,所以要组装成32bit

具体代码如下:

U32 GetLocalIP(void)
{
    U8   u8Cmd[256] = {0};
    char readBuf[256] = {0};
    U32  u32IP[4] = {0};
    U32  u32SrcIP = 0;

    snprintf((char *)u8Cmd, sizeof(u8Cmd),"ifconfig eth0 | grep 'inet addr' | awk '{ print $2}' | awk -F: '{print $2}' > /tmp/debug.txt");
    //获取本机IP
    system((char *)u8Cmd);

    int fd = open("/tmp/debug.txt", O_RDONLY);
    if(fd < 0)
    {
        printf("[%s] open debug.txt fail...\n", __func__);
        return 1;
    }

    read(fd, readBuf, sizeof(readBuf));

    sscanf(readBuf, "%u.%u.%u.%u", &u32IP[0], &u32IP[1], &u32IP[2], &u32IP[3]);

    u32SrcIP = (u32IP[0] << 24) | (u32IP[1] << 16) | (u32IP[2] << 8) | u32IP[3] ;

    return u32SrcIP;

}

获取Mac地址,跟IP地址类似,基本就是awk命令获取字段值不同,还有就是Mac地址所占字节大小是6字节,这里我们需要的Mac地址对应值在第五字段,使用的命令是:ifconfig eth0|grep eth0|awk '{print $5}'  ,即在eth0信息里过滤eth0当前行的第五个字段

具体代码如下:

U64 GetLocalMac(void)
{
    U8   u8Cmd[256] = {0};
    char readBuf[256] = {0};
    U64  u64Mac[6] = {0};
    U64  u64SrcMac = 0;

    snprintf((char *)u8Cmd, sizeof(u8Cmd),"ifconfig eth0|grep eth0|awk '{print $5}' > /tmp/debug.txt");
    //获取本机MAC
    system((char *)u8Cmd);

    int fd = open("/tmp/debug.txt", O_RDONLY);
    if(fd < 0)
    {
        printf("[%s] open debug.txt fail...\n", __func__);
        return 1;
    }

    read(fd, readBuf, sizeof(readBuf));

    sscanf(readBuf, "%02x:%02x:%02x:%02x:%02x:%02x", &u64Mac[0], &u64Mac[1], &u64Mac[2], &u64Mac[3], &u64Mac[4], &u64Mac[5]);

    u64SrcMac = (u64Mac[0] << 40) | (u64Mac[1] << 32) | (u64Mac[2] << 24) | (u64Mac[3] << 16) | (u64Mac[4] << 8) | u64Mac[5];

    return u64SrcMac;

}


补充:可能有同学疑惑上面说的 “字段” 怎么看,怎么知道自己需要的值在哪个字段,别慌,简单滴很!我们可以在linux终端下执行 ifconfig 命令,可以看到类似以下的信息:

 之前也提到字段区分默认分隔符是空格/tab,而且awk命令是按行解析的,例如第一行 HWaddr 后跟的就是Mac地址,eth0为第一个字段$1,Link就是第二个字段$2,encap:Ethernet第三个字段$3,HWaddr第四个字段$4,00:0A:35:00:01:22第五个字段$5,也是我们需要的Mac值;

如果需要指定分隔符,则在awk 后加 -F + 分隔符,例如:awk -F: '{print $2}' ,就是指定":" (冒号)作为分割符,看第二行,inet addr 为第一个字段,因为其后跟的是":",第二个字段就是IP地址。但是如果不加过滤条件和和指定分隔符是怎样的呢?如下图所示,执行 ifconfig eth0 | awk '{print $2}' ,其效果就是打印了每行的第二个字段值,因为每行字段都是从 $1开始,所以我们才需要目标字段做一些过滤处理。

 


总结:其实也没有太难的点,主要就是awk命令用法可能比较少见,其实这个还有很多用法,网上很多都讲得挺详细的。以上写的比较啰嗦(没办法,咱也是第一次写这个),主要目的是为了让每位看官都清楚写的是什么,有什么用法,怎么用的,哪怕不是这行的也能看懂,要是能达到这种效果就很不错!!!(如果以上讲得有不正确的地方可以帮忙指出)

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值