Linux环境下获取当前主机的IP/MAC等信息(C/C++)
2017-04-23 10:55
896 查看
本文介绍在unix环境下获取当前主机IP,MAC地址等网络接口信息。在不确定设备网卡类型的情况下,通过预先定义几种可能的网卡类型,然后依次遍历可能的设备如eth0,eth1,借助ioctl函数获取主机的全部网络接口信息。
ioctl函数可以获取所在主机的全部网络接口信息,包括接口地址(IP,MAC,MASK…)、是否支持广播等。ioctl函数的头文件没有标准化,许多系统在“unistd.h中定义,而传统的BSD系统中,通常在 “sys/ioctl.h”中定义 。ioctl的原型为:
int ioctl(int fd,int request, void *arg );
返回:成功返回0,失败返回-1
参数fd通常是获取接口信息所用到的句柄,在本文获取ip等信息时,是socket连接句柄;
参数arg总是一个指针,其类型依赖于request参数;
request类型主要分为6类:套接字操作、文件操作、接口操作、ARP高速缓存操作、路由表操作、流系统
本文要介绍的获取IP地址和MAC等属于接口操作。其中
IP地址的request类型为SIOCGIFADDR
MAC地址的request类型为SIOCGIFHWADDR
其余类型参考文献[1],第17章相关章节。
有关请求参数struct ifreq的定义为位于“net/if.h”
下面是相关代码:
获取MAC地址的代码片段如下:
1.《UNIX网络编程卷1:套接字联网API(第3版)》,ch17(ioctl操作)
ioctl函数可以获取所在主机的全部网络接口信息,包括接口地址(IP,MAC,MASK…)、是否支持广播等。ioctl函数的头文件没有标准化,许多系统在“unistd.h中定义,而传统的BSD系统中,通常在 “sys/ioctl.h”中定义 。ioctl的原型为:
int ioctl(int fd,int request, void *arg );
返回:成功返回0,失败返回-1
参数fd通常是获取接口信息所用到的句柄,在本文获取ip等信息时,是socket连接句柄;
参数arg总是一个指针,其类型依赖于request参数;
request类型主要分为6类:套接字操作、文件操作、接口操作、ARP高速缓存操作、路由表操作、流系统
本文要介绍的获取IP地址和MAC等属于接口操作。其中
IP地址的request类型为SIOCGIFADDR
MAC地址的request类型为SIOCGIFHWADDR
其余类型参考文献[1],第17章相关章节。
有关请求参数struct ifreq的定义为位于“net/if.h”
<net/if.h> /* Interface request structure used for socket ioctl's. All interface ioctl's must have parameter definitions which begin with ifr_name. The remainder may be interface specific. */ struct ifreq { # define IFHWADDRLEN 6 # define IFNAMSIZ IF_NAMESIZE union { char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */ } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short int ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; __caddr_t ifru_data; } ifr_ifru; }; # define ifr_name ifr_ifrn.ifrn_name /* interface name */ # define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC 4000 address */ # define ifr_addr ifr_ifru.ifru_addr /* address */ # define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ # define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ # define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ # define ifr_flags ifr_ifru.ifru_flags /* flags */ # define ifr_metric ifr_ifru.ifru_ivalue /* metric */ # define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ # define ifr_map ifr_ifru.ifru_map /* device map */ # define ifr_slave ifr_ifru.ifru_slave /* slave device */ # define ifr_data ifr_ifru.ifru_data /* for use by interface */ # define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */ # define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */ # define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */ # define ifr_newname ifr_ifru.ifru_newname /* New name */ # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0) # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0) # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
下面是相关代码:
#include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <iostream> #include <string> #include <vector> using namespace std; bool GetIP(const vector<string>& vNetType,string& strip) { for(size_t i=0;i<vNetType.size();i++) { for(char c='0';c<='9';++c) { string strDevice = vNetType[i] + c; //根据网卡类型,遍历设备如eth0,eth1 int fd; struct ifreq ifr; //使用UDP协议建立无连接的服务 fd = socket(AF_INET, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, strDevice.c_str() ); //获取IP地址 if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) { ::close(fd); continue; } // 将一个IP转换成一个互联网标准点分格式的字符串 strip = inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr); if(!strip.empty()) { ::close(fd); return true; } } } return false; } int main() { vector<string> vs;//预先定义了几种可能的网卡类型 vs.push_back("eth"); vs.push_back("em"); vs.push_back("oct"); string str; if( (GetIP(vs,str)) ) { cout<<str<<endl; } return 0; }
获取MAC地址的代码片段如下:
获取MAC地址的代码如下 fd = socket(AF_INET, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, strDevice.c_str() ); if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { ::close(fd); continue; } unsigned char macaddr[6]; memcpy(macaddr,ifr.ifr_hwaddr.sa_data,6); for(int k=0;k<6;k++) { printf("%02x",macaddr[k]); if(k<5) printf(":"); }
1.《UNIX网络编程卷1:套接字联网API(第3版)》,ch17(ioctl操作)
相关文章推荐
- Linux环境下获取当前主机的IP/MAC等信息(C/C++)
- java 获取当前主机IP 主机名 MAC 操作系统信息
- linux 获取本地网络信息 -ip,mac ,等
- Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip 、获取本地主机的名字
- linux 通过Ip获取主机名等信息gethostbyaddr()等。
- linux下libpcap 获取当前主机的网卡信息
- Linux 网络编程之通过IP或者主机名获取信息
- 获取主机MAC IP Mask Gateway的信息
- linux下获取本地IP信息的
- linux通过域名获取主机信息
- linux 环境下 用gethostbyname函数获取 DNS的服务器列表 名称 IP
- linux环境下获取用户基本信息
- C#编程之 如何获取本地和远程主机的IP及MAC地址
- Linux查看环境变量当前信息和查看命令
- WebService获取服务端硬件信息和客户端IP,MAC,浏览器信息,所在城市《转》
- 获取网卡信息(网卡MAC,ip,index,devicename)的一般方法(利用IP HELPER api)
- 获取本地ip,dns 以及 mac等ipconfig/all信息代码
- WebService获取服务端硬件信息和客户端IP,MAC,浏览器信息,所在城市- -
- Linux 下获取LAN中指定IP的网卡的MAC(物理地址)
- ZZ-linux中获取IP和MAC