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
#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