Linux下C獲取所有可用網絡卡資訊
在Linux下開發網路程式時,經常會遇到需要取本地網路介面名、IP、廣播地址、子網掩碼或者MAC地址等資訊的需求,最常見的辦法是配合巨集SIOCGIFHWADDR、SIOCGIFADDR、SIOCGIFBRDADDR與SIOCGIFNETMASK作為引數呼叫函式ioctl分別獲得MAC地址、IP地址、廣播地址與子網掩碼來實現。一次性獲取此類資訊的C語言程式碼實現如下。
#include <stdio.h> #include <string.h> #include <net/if.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <errno.h> int getLocalInfo(void) { int fd; int interfaceNum = 0; struct ifreq buf[16]; struct ifconf ifc; struct ifreq ifrcopy; char mac[16] = {0}; char ip[32] = {0}; char broadAddr[32] = {0}; char subnetMask[32] = {0}; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); close(fd); return -1; } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc)) { interfaceNum = ifc.ifc_len / sizeof(struct ifreq); printf("interface num = %dn", interfaceNum); while (interfaceNum-- > 0) { printf("ndevice name: %sn", buf[interfaceNum].ifr_name); //ignore the interface that not up or not runing ifrcopy = buf[interfaceNum]; if (ioctl(fd, SIOCGIFFLAGS, &ifrcopy)) { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } //get the mac of this interface if (!ioctl(fd, SIOCGIFHWADDR, (char *)(&buf[interfaceNum]))) { memset(mac, 0, sizeof(mac)); snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x", (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[0], (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[1], (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[2], (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[3], (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[4], (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[5]); printf("device mac: %sn", mac); } else { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } //get the IP of this interface if (!ioctl(fd, SIOCGIFADDR, (char *)&buf[interfaceNum])) { snprintf(ip, sizeof(ip), "%s", (char *)inet_ntoa(((struct sockaddr_in *)&(buf[interfaceNum].ifr_addr))->sin_addr)); printf("device ip: %sn", ip); } else { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } //get the broad address of this interface if (!ioctl(fd, SIOCGIFBRDADDR, &buf[interfaceNum])) { snprintf(broadAddr, sizeof(broadAddr), "%s", (char *)inet_ntoa(((struct sockaddr_in *)&(buf[interfaceNum].ifr_broadaddr))->sin_addr)); printf("device broadAddr: %sn", broadAddr); } else { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } //get the subnet mask of this interface if (!ioctl(fd, SIOCGIFNETMASK, &buf[interfaceNum])) { snprintf(subnetMask, sizeof(subnetMask), "%s", (char *)inet_ntoa(((struct sockaddr_in *)&(buf[interfaceNum].ifr_netmask))->sin_addr)); printf("device subnetMask: %sn", subnetMask); } else { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } } } else { printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__); close(fd); return -1; } close(fd); return 0; } int main(void) { getLocalInfo(); return 0; }
使用ioctl函式雖然可以獲取所有的資訊,但是使用起來比較麻煩,如果不需要獲取MAC地址,那麼使用getifaddrs函式來獲取更加方便與簡潔。值得一提的是,在MacOS或iOS系統上(如iPhone程式開發),上述iotcl函式沒法獲得mac地址跟子網掩碼,這個使用,使用getifaddrs函式便更有優勢了。下面是使用getiaddrs函式獲取網絡卡資訊的C語言程式碼實現。
#include <stdio.h> #include <ifaddrs.h> #include <arpa/inet.h> int getSubnetMask() { struct sockaddr_in *sin = NULL; struct ifaddrs *ifa = NULL, *ifList; if (getifaddrs(&ifList) < 0) { return -1; } for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) { if(ifa->ifa_addr->sa_family == AF_INET) { printf("n>>> interfaceName: %sn", ifa->ifa_name); sin = (struct sockaddr_in *)ifa->ifa_addr; printf(">>> ipAddress: %sn", inet_ntoa(sin->sin_addr)); sin = (struct sockaddr_in *)ifa->ifa_dstaddr; printf(">>> broadcast: %sn", inet_ntoa(sin->sin_addr)); sin = (struct sockaddr_in *)ifa->ifa_netmask; printf(">>> subnetMask: %sn", inet_ntoa(sin->sin_addr)); } } freeifaddrs(ifList); return 0; } int main(void) { getSubnetMask(); return 0; }
ifaddrs結構體定義如下:
struct ifaddrs { struct ifaddrs *ifa_next; /* Next item in list */ char *ifa_name; /* Name of interface */ unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */ struct sockaddr *ifa_addr; /* Address of interface */ struct sockaddr *ifa_netmask; /* Netmask of interface */ union { struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */ struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */ } ifa_ifu; #define ifa_broadaddr ifa_ifu.ifu_broadaddr #define ifa_dstaddr ifa_ifu.ifu_dstaddr void *ifa_data; /* Address-specific data */ };
ifa_next指向連結串列的下一個成員;ifa_name是介面名稱,以0結尾的字串,比如eth0,lo;ifa_flags是介面的標識位(比如當IFF_BROADCAST或IFF_POINTOPOINT設定到此標識位時,影響聯合體變數ifu_broadaddr儲存廣播地址或ifu_dstaddr記錄點對點地址);ifa_netmask儲存該介面的子網掩碼;結構體變數儲存廣播地址或點對點地址(見括弧介紹ifa_flags);ifa_data儲存了該介面協議族的特殊資訊,它通常是NULL(一般不關注他)。
函式getifaddrs(int getifaddrs (struct ifaddrs **__ifap))獲取本地網路介面資訊,將之儲存於連結串列中,連結串列頭結點指標儲存於__ifap中帶回,函式執行成功返回0,失敗返回-1,且為errno賦值。
很顯然,函式getifaddrs用於獲取本機介面資訊,比如最典型的獲取本機IP地址。
相關推薦
Linux下C獲取所有可用網絡卡資訊
在Linux下開發網路程式時,經常會遇到需要取本地網路介面名、IP、廣播地址、子網掩碼或者MAC地址等資訊的需求,最常見的辦法是配合巨集SIOCGIFHWADDR、SIOCGIFADDR、SIOCGIFBRDADDR與SIOCGIFNETMASK作為引數呼叫函式
C# 獲取本機網絡卡資訊、個數、描述資訊、型別、速度等
程式碼比較簡單,直接上圖上碼。實現程式碼有註釋,以下是該例子的完整程式碼。引入名稱空間:using System.Net.NetworkInformation; using System.Net;完整程式碼:namespace NetworkInterfaceExample
c++獲取本機網絡卡資訊(IP,MAC,閘道器,子網掩碼)
int getIP_Mac_GateMac(int adapter, char** ip, int mac[6], int gateMac[6]) //adapter:選擇的網絡卡序號 {//PIP_ADAPTER_INFO結構體指標儲存本機網絡卡資訊PIP_ADAPT
Linux下C語言的socket網絡編程
網絡編程 服務器 enter 編程 scanf 路由 client p s drl Server.c 1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <n
linux程式設計獲取本機網絡卡資訊
轉自:https://blog.csdn.net/shaderdx/article/details/78403437 ifaddrs結構體定義如下: struct ifaddrs { &
linux下如何實現為一個網絡卡繫結多個IP地址
Linux的網路裝置配置檔案存放在/etc/sysconfig/network-scripts裡面,對於乙太網的第一個網路裝置,配置檔名一般為 ifcfg-eth0 如果需要為第一個網路裝置繫結多一個IP地址,只需要在/
Linux 下小米WIFI 的無線網絡卡驅動
在小米的罈子裡看到了大神發的 小米WIFI 驅動 for Linux。於是就下載下來為自己的linux(Fedora 21 , kernel:3.17.8-300 )安裝小米WIFI 驅動。 過程記錄如下(其實也適用於 小度WIFI 和 360 WIFI ,只要用的是晶
linux中使用ifconfig命令檢視網絡卡資訊時顯示為eth1,但是在network-scripts中只有ifcfg-eth0的配置檔案,並且裡面的NAME="eth0"
除了題目中的問題,其實在執行命令:service network restart時,會報錯: 解決辦法: 首先需要修改70-persistent-net.rules檔案: vim /etc/udev/rules.d/70-persistent-net.rules 然
linux中使用ifconfig命令檢視網絡卡資訊時顯示為eth1,但是在network-scripts中只有ifcfg-eth0的配置檔案,並且裡面的NAME="eth0"。
除了題目中的問題,其實在執行命令:service network restart時,會報錯: 解決辦法: 首先需要修改70-persistent-net.rules檔案: vim /etc/udev/rules.d/70-persistent-net.rules 然後修改ifcfg-eth0檔案: v
C/C++:Windows程式設計—程式碼獲取本地所有網絡卡資訊(網絡卡描述,IP地址,子網掩碼,MAC地址)
先看效果 看程式碼 使用 GetAdaptersInfo 函式獲取網絡卡的所有資訊。 MSDN函式說明 https://docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadapters
Linux下利用ioctl函式獲取網絡卡資訊
linux下的ioctl函式原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv]) 函式成功返回0,失敗返回-1. 其相關命令介面如下:
linux通過c語言介面獲取網絡卡資訊
方法一 通過ioctl的SIOCGIFCONF 例項1. 檢查特定的網絡卡是否存在 // ppp、wifi是否正常 static int check_ppp_wifi (int wifi_switch) { struct ifreq ifr
Linux下用netstat查看網絡狀態、端口狀態
服務端 哪些 ipv4 foreign udp協議 nat 進行 ets 當我 在linux一般使用netstat 來查看系統端口使用情況步。 netstat命令是一個監控TCP/IP網絡的非常有用的工具,它可以顯示路由表、實際的網絡連接以及每一個網絡接口設備的
linux下C獲取文件的大小
錯誤代碼 返回 system sys string 文件系統 識別碼 連接 chm 獲取文件大小這裏有兩種方法: 方法一、 範例: unsigned long get_file_size(const char *path) { unsigned lo
c# 多網絡卡 由【網路介面卡名】獲取網絡卡資訊,IP
c# 多網絡卡 由【網路介面卡名】獲取網絡卡資訊,IP 多網絡卡電腦中,網路介面卡的名字 多樣化! 專案中需要,根據網路介面卡 名字 獲取 單個網絡卡的IP: using System.Net.NetworkInformation;
Centos&Redhat下bcm43142博通無線網絡卡linux驅動之二
上次通過更換核心實現成功編譯驅動無線網絡卡,但是啟動到系統原核心下依然沒有bcm43142的驅動,遂準備在原核心下編譯驅動,記錄一下 ps:更推薦這種方法,避免因更換核心出現其他相容性問題 1.準備驅動包 hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz 點我下載
linux下C獲取系統時間的方法
asctime(將時間和日期以字串格式表示) 相關函式 time,ctime,gmtime,localtime 表頭檔案 #include<time.h> 定義函式 char * asctime(const struct tm * ti
linux中讀取網絡卡資訊(ip, mask, mac)以及判斷物理網線是否插好的C程式---我親自試了一下,還不錯!
說明: 我主要轉載如下兩篇文章, 但本文中加入了自己的一些描述 轉載地址一:http://blog.chinaunix.net/uid-20692625-id-3172833.html 轉載地址二:http://blog.chinaun
Linux系統下關閉防火牆和檢視網絡卡的命令
1.關閉防火牆 1)檢視防火牆狀態:service firewalld status 2)臨時關閉防火牆:service firewalld stop 3)檢視防火牆自啟動狀態:chkconfig firewalld 4)關閉防火牆自啟動:chkconfi
Linux 下c獲取當前時間(精確到秒和毫秒或者微秒)
獲取當前的時間的秒數和微秒數本方法需要用到gettimeofday()函式,該函式需要引入的標頭檔案是sys/time.h 。 函式說明int gettimeofday (struct timeval * tv, struct timezone * tz)