Linux下如何获取网卡信息

本文介绍如何在Linux系统中获取网络信息,包括网卡数量、IP地址、掩码、MAC地址、网关及DNS等。通过解析/proc文件系统和使用ioctl函数实现。

有时候,写程序的时候需要获取计算机的网络信息,比如IP地址、电脑名称、DNS等信息。IP地址和电脑名称是比较容易获取到的,而要想获取地址掩码、DNS、网关等信息就有些麻烦了。

在Windows下我们一般都是通过从注册表读取这些信息。在Linux怎么做呢?其实,Linux下更加容易一些。因为我们可以拿现成的程序看它的源代码。通过阅读其源代码找到解决该问题的方法。那么,看哪个程序的源代码呢?如果你使用过Linux,并且比较熟悉的话就肯定知道一个命令ifconfig。这个命令和Windows下的ipconfig差不多,都可以输出网卡的信息,其中就包含DNS、掩码等信息。所以,我们可以通过看它的源代码来找到解决该问题的方法。

获取系统中的网卡数量

并没有那个系统调用提供网卡数量的获取。但是,我们可以通过强大的proc文件系统获取网卡数量的信息。实际上,ifconfig也是这样做的,请看示例代码如下:
0001 #include <stdio.h>
0002 #include <string.h>
0003 #include <errno.h>
0004
0005 int GetNetCardCount()
0006 {
0007     int nCount = 0;
0008     FILE* f = fopen("/proc/net/dev", "r");
0009     if (!f)
0010     {
0011         fprintf(stderr, "Open /proc/net/dev failed!errno:%d\n", errno);
0012         return nCount;
0013     }
0014
0015     char szLine[512];
0016
0017     fgets(szLine, sizeof(szLine), f);    /* eat line */
0018     fgets(szLine, sizeof(szLine), f);
0019
0020     while(fgets(szLine, sizeof(szLine), f))
0021     {
0022         char szName[128] = {0};
0023         sscanf(szLine, "%s", szName);
0024         int nLen = strlen(szName);
0025         if (nLen <= 0)continue;
0026         if (szName[nLen - 1] == ':') szName[nLen - 1] = 0;
0027         if (strcmp(szName, "lo") == 0)continue;
0028         nCount++;
0029     }
0030
0031     fclose(f);
0032     f = NULL;
0033     return nCount;
0034 }
0035
0036 int main(int argc, char* argv[])
0037 {
0038     printf("NetCardCount: %d\n", GetNetCardCount());
0039     return 0;
0040 }

获取IP、掩码、MAC及网关

获取IP、掩码、MAC和广播地址是比较容易的,只需要调用对应的IOCTL即可。只是大家对Linux下的IOCTL可能不太熟悉。却看示例代码:

 

0001 void DispNetInfo(const char* szDevName)
0002 {
0003     int s = socket(AF_INET, SOCK_DGRAM, 0);
0004     if (s < 0)
0005     {
0006         fprintf(stderr, "Create socket failed!errno=%d", errno);
0007         return;
0008     }
0009
0010     struct ifreq ifr;
0011     unsigned char mac[6];
0012     unsigned long nIP, nNetmask, nBroadIP;
0013
0014     printf("%s:\n", szDevName);
0015
0016     strcpy(ifr.ifr_name, szDevName);
0017     if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0)
0018     {
0019         return;
0020     }
0021     memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
0022     printf("\tMAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
0023             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
0024
0025     strcpy(ifr.ifr_name, szDevName);
0026     if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
0027     {
0028         nIP = 0;
0029     }
0030     else
0031     {
0032         nIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
0033     }
0034     printf("\tIP: %s\n", inet_ntoa(*(in_addr*)&nIP));
0035
0036     strcpy(ifr.ifr_name, szDevName);
0037     if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
0038     {
0039         nBroadIP = 0;
0040     }
0041     else
0042     {
0043         nBroadIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
0044     }
0045     printf("\tBroadIP: %s\n", inet_ntoa(*(in_addr*)&nBroadIP));
0046
0047     strcpy(ifr.ifr_name, szDevName);
0048     if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
0049     {
0050         nNetmask = 0;
0051     }
0052     else
0053     {
0054         nNetmask = *(unsigned long*)&ifr.ifr_netmask.sa_data[2];
0055     }
0056     printf("\tNetmask: %s\n", inet_ntoa(*(in_addr*)&nNetmask));
0057     close(s);
0058 }

 

       那么如何获取网关地址呢?更加容易,但是,好像很少有人知道。反正我在网上没有找到有人知道。最后看了nslookup的源代码以后才知道正确的做法。代码如下:

       res_init();      

       for (int i = 0; i < _res.nscount; i++)

       {

              struct sockaddr* server = (structsockaddr*)&_res.nsaddr_list[i];

              printf("Server:  %s\n", inet_ntoa(*(in_addr*)&(server->sa_data[2])));

       }

代码很简单,就不做解释了。

 

怎么获取网关呢?这个稍微有点麻烦一些,不过和获取网卡数量相似,都是通过proc文件系统。这次分析的/proc/net/route文件。我就不再贴出示例代码了。

最后,我把运行示例程序获取到的信息附上,以供大家有个直观的认识:

eth0:

       MAC: 08-00-27-98-bf-f3

       IP: 192.168.1.106

       BroadIP: 255.255.255.255

       Netmask: 255.255.255.0

Gateway: 192.168.1.1

eth1:

       MAC: 08-00-27-16-f4-bf

       IP: 192.168.1.108

       BroadIP: 192.168.1.255

       Netmask: 255.255.255.0

Gateway: 0.0.0.0

eth2:

       MAC: 08-00-27-37-9c-91

       IP: 0.0.0.0

       BroadIP: 0.0.0.0

       Netmask: 0.0.0.0

Gateway: 0.0.0.0

eth3:

       MAC: 08-00-27-5a-d2-39

       IP: 0.0.0.0

       BroadIP: 0.0.0.0

       Netmask: 0.0.0.0

Gateway: 0.0.0.0

NetCardCount: 4

DNS 0:  218.2.135.1

DNS 1:  61.147.37.1


====

http://www.360doc.com/content/12/0222/10/1317564_188554876.shtml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值