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