在Windows下我們一般都是通過從註冊表讀取這些信息。在Linux怎麼做呢?其實,Linux下更加容易一些。因爲我們可以拿現成的程序看它的源代碼。通過閱讀其源代碼找到解決該問題的方法。那麼,看哪個程序的源代碼呢?如果你使用過Linux,並且比較熟悉的話就肯定知道一個命令ifconfig。這個命令和Windows下的ipconfig差不多,都可以輸出網卡的信息,其中就包含DNS、掩碼等信息。所以,我們可以通過看它的源代碼來找到解決該問題的方法。
獲取系統中的網卡數量
並沒有那個系統調用提供網卡數量的獲取。但是,我們可以通過強大的proc文件系統獲取網卡數量的信息。實際上,ifconfig也是這樣做的,請看示例代碼如下:#include <stdio.h>
#include <string.h>
#include <errno.h>
int GetNetCardCount()
{
int nCount = 0;
FILE* f = fopen("/proc/net/dev", "r");
if (!f)
{
fprintf(stderr, "Open /proc/net/dev failed!errno:%d\n", errno);
return nCount;
}
char szLine[512];
fgets(szLine, sizeof(szLine), f); /* eat line */
fgets(szLine, sizeof(szLine), f);
while(fgets(szLine, sizeof(szLine), f))
{
char szName[128] = {0};
sscanf(szLine, "%s", szName);
int nLen = strlen(szName);
if (nLen <= 0)continue;
if (szName[nLen - 1] == ':') szName[nLen - 1] = 0;
if (strcmp(szName, "lo") == 0)continue;
nCount++;
}
fclose(f);
f = NULL;
return nCount;
}
int main(int argc, char* argv[])
{
printf("NetCardCount: %d\n", GetNetCardCount());
return 0;
}
獲取IP、掩碼、MAC及網關
獲取IP、掩碼、MAC和廣播地址是比較容易的,只需要調用對應的IOCTL即可。只是大家對Linux下的IOCTL可能不太熟悉。卻看示例代碼:void DispNetInfo(const char* szDevName)
{
int s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
{
fprintf(stderr, "Create socket failed!errno=%d", errno);
return;
}
struct ifreq ifr;
unsigned char mac[6];
unsigned long nIP, nNetmask, nBroadIP;
printf("%s:\n", szDevName);
strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0)
{
return;
}
memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
printf("\tMAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
{
nIP = 0;
}
else
{
nIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
}
printf("\tIP: %s\n", inet_ntoa(*(in_addr*)&nIP));
strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
{
nBroadIP = 0;
}
else
{
nBroadIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
}
printf("\tBroadIP: %s\n", inet_ntoa(*(in_addr*)&nBroadIP));
strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
{
nNetmask = 0;
}
else
{
nNetmask = *(unsigned long*)&ifr.ifr_netmask.sa_data[2];
}
printf("\tNetmask: %s\n", inet_ntoa(*(in_addr*)&nNetmask));
close(s);
}
那麼如何獲取網關地址呢?更加容易,但是,好像很少有人知道。反正我在網上沒有找到有人知道。最後看了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