ifconf和ifreq
http://blog.csdn.net/jasenwan88/article/details/7763689
用ioctl获得本地ip地址时要用到两个结构体ifconf和ifreq,它们对于大多数人来说都是比较陌生的,这里给一种比较简单的理解方法, 仅供参考.
首先先认识一下ifconf和ifreq:
//ifconf通常是用来保存所有接口信息的 //ifreq用来保存某个接口的信息
//if.h
struct ifreq {
char ifr_name[IFNAMSIZ];
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
caddr_t ifru_data;
} ifr_ifru;
};
#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.ifru_broadaddr
上边这两个结构看起来比较复杂,我们现在把它们简单化一些:比如说现在我们向实现获得本地IP的功能。
我们的做法是:1. 先通过ioctl获得本地所有接口的信息,并保存在ifconf中2. 再从ifconf中取出每一个ifreq中表示ip地址的信息
具体使用时我们可以认为ifconf就有两个成员:ifc_len 和 ifc_buf,如图一所示:
ifc_len:表示用来存放所有接口信息的缓冲区长度ifc_buf:表示存放接口信息的缓冲区
所以我们需要在程序开始时对ifconf的ifc_len和ifc_buf进行初始化接下来使用ioctl获取所有接口信息,完成后ifc_len内存放实际获得的接口信息总长度,并且信息被存放在ifc_buf中。如下图示:(假设读到两个接口信息)
接下来我们只需要从一个一个的接口信息获取ip地址信息即可。
下面有一个简单的参考:
#include
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
int i=0;
int sockfd;
struct ifconf ifconf;
unsigned char buf[512];
struct ifreq *ifreq; //初始化ifconf
ifconf.ifc_len = 512;
ifconf.ifc_buf = buf;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0)
{
perror("socket");
exit(1);
}
ioctl(sockfd, SIOCGIFCONF, &ifconf); //获取所有接口信息
//逐个获取IP地址
ifreq = (struct ifreq*)buf;
for(i=(ifconf.ifc_len/sizeof(struct ifreq)); i>0; i--)
{
//if(ifreq->ifr_flags == AF_INET){
//for ipv4
printf("name = [%s]n", ifreq->ifr_name);
printf("local addr = [%s]n",inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr));
ifreq++;
//}
}
return 0;
} 另一种方式(可以获取所有的接口信息,前例子加入有多个网卡的话,信息有可能无法完全获取):
unsigned int buffer_size = 4096; // initial guess
unsigned int last_size = 0;
struct ifconf config;
unsigned char* buffer;
for (;buffesr_size < 65536;) {
buffer = new unsigned char[buffer_size];
config.ifc_len = buffer_size;
config.ifc_buf = (char*)buffer;
if (ioctl(net, SIOCGIFCONF, &config) < 0) {
if (errno != EINVAL || last_size != 0) {
return NPT_ERROR_BASE_UNIX-errno;
}
} else {
if ((unsigned int)config.ifc_len == last_size) {
// same size, we can use the buffer
break;
}
// different size, we need to reallocate
last_size = config.ifc_len;
}
// supply 4096 more bytes more next time around
buffer_size += 4096;
delete[] buffer;
}
struct ifreq
这个结构定义在include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的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;
};
struct ifconf
通常是用来保存所有接口信息的
struct ifconf
{
int ifc_len; /* Size of buffer. */
union
{
__caddr_t ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
};
ifconf和ifreq的更多相关文章
- 两个结构体ifconf和ifreq
用ioctl获得本地ip地址时要用到两个结构体ifconf和ifreq,它们对于大多数人来说都是比较陌生的,这里给大家一种比较简单的理解方法,当然只一种帮助理解的方法,在描述中可能会有一些地方与真实定 ...
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq 结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看 ...
- ifreq、ifconf
网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...
- linux网络接口,struct ifreq struct ifconf结构
网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...
- struct ifreq学习和实例
一.struct ifreq结构体 这个结构定义在/usr/include/net/if.h,用来配置和获取ip地址,掩码,MTU等接口信息的. /* Interface request struct ...
- (十)Linux 网络编程之ioctl函数
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- linux内核数据结构学习总结
目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...
- Linux网络编程实例解析
**************************************************************************************************** ...
- linux编程获取本机网络相关参数
getifaddrs()和struct ifaddrs的使用,获取本机IP 博客分类: Linux C编程 ifaddrs结构体定义如下: struct ifaddrs { struct ifad ...
随机推荐
- .net orm类库 kiss.data 简单文档记录
kiss.data的简单记录 == [github地址](https://github.com/sdming/Kiss.Data) kiss.data是golang的数据库访问类库[kdb](http ...
- JSON在PHP中的基本应用
从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 一.json_encode() 该函数主要用来将数组和对象,转换为json格式 ...
- solaris之cpu
一. Solaris的处理器硬件系统架构 Solaris支持多种处理器系统架构:SPARC.x86和x64.x64即AMD64及EMT64处理器.在版本2.5.1的时候,Solaris曾经一度被移植到 ...
- Assembly类
System.Reflection.Assembly类是一个比较常用到的类,在反射中就经常用到. 由于这个类实在有太多的字段.属性与方法.实在不想将一个个属性方法从MSDN复制出来然后逐个属性.方法敲 ...
- [翻译] 用 ObjectiveSugar 扩展NSArray NSDictionary NSSet NSNumber
source - https://github.com/supermarin/ObjectiveSugar Look like a girl, act like a lady, think like ...
- int to string
int i=9; stringstream stream; stream << i;stream.str()
- MIR Flickr 1M 图像数据集(点击即可下载)
Index of /mirflickr/mirflickr1m Name Last modified Size Description Parent Directory - exif.zip ...
- acd Convex(求面积)
Problem Description We have a special convex that all points have the same distance to origin point. ...
- 解决Ubuntu下的Eclipse打开Windows编写的java代码的中文乱码
其实所有的中文乱码 问题都是编码不同所导致的.这里要想让eclipse能正常显示出汉字,就要修改它的字符编码 步骤如下: 1 ,点击菜单栏中的Window(窗口),选择Preferences(首选项) ...
- Java:字符串类简单的正则表达式
class Test { public static void main(String[] args) { String str = "xia..as....yuan.com"; ...