Linux下利用ioctl函數獲取網卡信息

linux下的ioctl函數原型以下:linux

#include <sys/ioctl.h>緩存

int ioctl(int handle, int cmd, [int *argc, int argv])異步

函數成功返回0,失敗返回-1.socket

其相關命令接口以下:函數

 

類別
Request
說明
數據類型
SIOCATMARK
SIOCSPGRP
SIOCGPGRP
是否位於帶外標記
設置套接口的進程ID 或進程組ID
獲取套接口的進程ID 或進程組ID
int
int
int
FIONBIO
FIOASYNC
FIONREAD
FIOSETOWN
FIOGETOWN
設置/ 清除非阻塞I/O 標誌
設置/ 清除信號驅動異步I/O 標誌
獲取接收緩存區中的字節數
設置文件的進程ID 或進程組ID
獲取文件的進程ID 或進程組ID
int
int
int
int
int
SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
SIOCxxx
獲取全部接口的清單
設置接口地址
獲取接口地址
設置接口標誌
獲取接口標誌
設置點到點地址
獲取點到點地址
獲取廣播地址
設置廣播地址
獲取子網掩碼
設置子網掩碼
獲取接口的測度
設置接口的測度
獲取接口MTU
(還有不少取決於系統的實現)
struct ifconf
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
ARP
SIOCSARP
SIOCGARP
SIOCDARP
建立/ 修改ARP 表項
獲取ARP 表項
刪除ARP 表項
struct arpreq
struct arpreq
struct arpreq
SIOCADDRT
SIOCDELRT
增長路徑
刪除路徑
struct rtentry
struct rtentry
       

 

 

在這裏咱們須要用到的結構體測試

#include<netinet/in.h>.net

struct sockaddr_in {
short sin_family; /* Address family */
unsigned short sin_port; /* Port number */
struct  in_addr sin_addr; /* Internet address */
unsigned char sin_zero[8]; /* Same size as struct sockaddr */
};

#include <net/if.h>server

struct ifreq
{
#define IFHWADDRLEN 6
union
{
charifrn_name[IFNAMSIZ]; 
} ifr_ifrn;

union {
structsockaddr ifru_addr;
structsockaddr ifru_dstaddr;
structsockaddr ifru_broadaddr;
structsockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
shortifru_flags;
intifru_ivalue;
intifru_mtu;
struct ifmap ifru_map;
charifru_slave[IFNAMSIZ]; 
charifru_newname[IFNAMSIZ];
void __user * ifru_data;
structif_settings ifru_settings;
} ifr_ifru;
};htm

#define ifr_name ifr_ifrn.ifrn_name 
#define ifr_hwaddr ifr_ifru.ifru_hwaddr 
#defineifr_addr ifr_ifru.ifru_addr 
#defineifr_dstaddr ifr_ifru.ifru_dstaddr 
#defineifr_broadaddr ifr_ifru.ifru_broadaddr 
#defineifr_netmask ifr_ifru.ifru_netmask
#defineifr_flags ifr_ifru.ifru_flags 
#defineifr_metric ifr_ifru.ifru_ivalue
#defineifr_mtu ifr_ifru.ifru_mtu
#define ifr_map ifr_ifru.ifru_map
#define ifr_slave ifr_ifru.ifru_slave
#defineifr_data ifr_ifru.ifru_data 
#define ifr_ifindex ifr_ifru.ifru_ivalue
#define ifr_bandwidth ifr_ifru.ifru_ivalue 
#define ifr_qlen ifr_ifru.ifru_ivalue
#define ifr_newname ifr_ifru.ifru_newname
#define ifr_settings ifr_ifru.ifru_settingblog

ioctl函數能獲取到IP地址、子網掩碼、廣播地址、硬件MAC地址等信息,至於網關及路由表比較複雜,在此不討論。

具體代碼以下:(測試經過)

#include <stdio.h>

#include <stdlib.h>

#include <net/if.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <arpa/inet.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <errno.h>

#include <fcntl.h>

#include <netinet/in.h>

#include <net/route.h>

#include <string.h>

#include <net/if_arp.h>

 

int main()

{

   struct sockaddr_in *sin;

   struct ifreq ifr;

   FILE *dns;

   FILE *gw;

   char *ip = new char(16);

   char *netmask = new char(16);

   char *broadcast = new char(16);

   //char *ip = (char *)malloc(16);

   char *mac = new  char(32);

   //char *mac = (char *)malloc(32);

   int socket_fd;

 

       if((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){

               perror("socket");

               exit(1);

       }

 

       memset(&ifr, 0, sizeof(ifr));

       strcpy(ifr.ifr_name, "eth0");

       memset(&sin, 0, sizeof(sin));

//獲取IP地址

       if(ioctl(socket_fd, SIOCGIFADDR, &ifr) != -1){

               sin = (struct sockaddr_in *)&ifr.ifr_addr;

               strcpy(ip, inet_ntoa(sin->sin_addr));

               printf("IP address is %s\n", ip);

       }

//獲取廣播地址

 

       if(ioctl(socket_fd, SIOCGIFBRDADDR, &ifr) != -1){

               sin = (struct sockaddr_in *)&ifr.ifr_broadaddr;

               strcpy(broadcast, inet_ntoa(sin->sin_addr));

               printf("Broadcast is %s\n", broadcast);

       }

//獲取子網掩碼

 

       if(ioctl(socket_fd, SIOCGIFNETMASK, &ifr) != -1){

               sin = (struct sockaddr_in *)&ifr.ifr_broadaddr;

               strcpy(netmask, inet_ntoa(sin->sin_addr));

               printf("Net-mask is %s\n", netmask);

       }

//獲取硬件MAC地址

 

       if(ioctl(socket_fd, SIOCGIFHWADDR, &ifr) != -1){

               sin = (struct sockaddr_in *)&ifr.ifr_netmask;

               sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",

               (unsigned char)ifr.ifr_netmask.sa_data[0],

               (unsigned char)ifr.ifr_netmask.sa_data[1],

               (unsigned char)ifr.ifr_netmask.sa_data[2],

               (unsigned char)ifr.ifr_netmask.sa_data[3],

               (unsigned char)ifr.ifr_netmask.sa_data[4],

               (unsigned char)ifr.ifr_netmask.sa_data[5]);

               printf("Mac address is %s\n", mac);

       }

   return 0;

}

 

至於獲取網關以及DNS,我是經過相關命令得到的。

主要代碼以下:

//獲取網關,利用route -n 命令能夠看到相關的網關。鏈接標誌是‘UG’

if(gw_fd = popen("route -n | grep 'UG'", "r")){

   fread(temp,1,128, gw_fd);

   sscanf(temp, "%*s%s", szNetGate);

   printf("Gateway is %s\n", szNetGate);

}

//獲取DNS;通常DNS保存在/etc/reslov.conf文件中。具體得到方法要根據實際狀況而定。

個人配置文件中是這樣的

root@nill:/home/arm-none-linux# cat /etc/resolv.conf

 

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)

#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 202.96.134.133  

上面的202.96.134.133就是我須要獲取的主DNS,沒有備用DNS

if(dns_fd = popen("cat /etc/reslov.conf | grep 'nameserver'", "r")){

   fread(temp,1,128, gw_fd);

   sscanf(temp, "%*s%s%*s%s", szDNS1,szDNS2);

   printf("DNS1 is %s",szDNS1);

   printf("DNS2is %s", szDNS2);

}

 

轉載地址:http://5375342.blog.51cto.com/5365342/1209335

相關地址:http://blog.csdn.net/bailyzheng/article/details/7489656

相關文章
相關標籤/搜索