Linux C编程获取本地网卡设备信息以及域名解析DNS

来源:互联网 发布:taptap是什么软件 编辑:程序博客网 时间:2024/05/22 10:23

一、Linux 中ifreq 结构体原型:

struct ifreq {#define IFHWADDRLEN 6 union {  char ifrn_name[IFNAMSIZ];  /* if 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 ifru_flags;  int ifru_ivalue;  int ifru_mtu;  struct  ifmap ifru_map;  char ifru_slave[IFNAMSIZ]; /* Just fits the size */  char ifru_newname[IFNAMSIZ];  void __user * ifru_data;  struct if_settings ifru_settings; } ifr_ifru;};#define ifr_name ifr_ifrn.ifrn_name   /* interface name  */#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC 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 ifr_settings ifr_ifru.ifru_settings/* Device/proto settings*/
基本介绍:

ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。

举例说明:

在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:

        ifconfig eth0 mtu 1250

ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。

struct ifreq data;fd = socket(PF_INET, SOCK_DGRAM, 0);<... initialize "data" ...>err = ioctl(fd, SIOCSIFMTU, &data);

二、获取本地ip,netmask和mac地址

#include <stdio.h>#include <netdb.h>        //gethostbyaddr,gethostbyname//#include <unistd.h>       //比如read,write函数#include <netinet/in.h>   //地址簇相关,比如sockaddr_in#include <arpa/inet.h>    //inet_ntoa#include <net/if.h>#include <net/if_arp.h>#include <sys/types.h>   //比如文件描述符fd_set#include <sys/socket.h>#include <sys/ioctl.h>struct in_addr myip,mymask;int fd_arp;     //socket fd for receive packetsstruct ifreq ifr;//ifr structint main(){char device[32];  //ethernet device namestruct sockaddr from,to;struct sockaddr_in *sin_ptr;u_char *ptr;if((fd_arp=socket(AF_INET,SOCK_DGRAM,0))<0){perror("arp socket error");exit(-1);}strcpy(device,"eth0");strcpy(ifr.ifr_name,device);/**** get ip address of my interface****/if(ioctl(fd_arp,SIOCGIFADDR,&ifr)<0){perror("ioctl SIOCGIFADDR error");exit(-1);}sin_ptr = (struct sockaddr_in *)&ifr.ifr_addr;myip = sin_ptr->sin_addr;printf("request IP  %s\n",inet_ntoa(myip));/**** get network mask of my interface****/if(ioctl(fd_arp,SIOCGIFNETMASK,&ifr)<0){perror("ioctl SIOCGIFNETMASK error");exit(-1);}sin_ptr = (struct sockaddr_in *)&ifr.ifr_addr;mymask = sin_ptr->sin_addr;printf("request netmask  %s\n",inet_ntoa(mymask));/**** get mac address of my interface****/if(ioctl(fd_arp,SIOCGIFHWADDR,&ifr)<0){perror("ioctl SIOCGIFHWADDR error");exit(-1);}ptr = (u_char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];printf("request mac %02x:%02x:%02x:%02x:%02x:%02x\n",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));/**** ---end--- ****/return 0;}
三、域名解析 DNS

 gethostbyname()gethostbyaddr():这两个函数可以获得DNS 信息。

使用gethostbyname()函数,不能使用perror() 来输出错误信息,因为错误代码存储在h_error中而不是error中。所以,需要调用herror()函数。