android ioctl ipv6,ioctl及getifaddrs读取IPv4,IPv6网卡信息

使用ioctl的SIOCGIFCONF可以读取所有网卡信息。ioctl调用后返回指向ifconf的结构链表,其中包含了指向ifreq的结构指针。ifconf及ifreq定义在net/if.h中。

《UNIX网络编程》中提供了get_ifi_info函数的实现方法,使用这种方式来获取网络信息。在LINUX下,这种方式不能获得IPV6的网卡信息。《UNIX网络编程》中有如下描述:

在支持IPV6的系统中,没有关于对SIOCGIFCONF请求是否返回IPV6地址的标准。我们给支持IPV6的新系统增加了一个case语句, 这是为了预防万一。问题在于ifreq中的联合把返回的地址定义成一个通用的16字节套接口地址结构,适合16字节的IPV4 socket_in结构,但对于24字节的IPV6 socket_in6结构太小了。如果返回IPV6地址,将可能破环现有的在每个ifreq结构中采用固定大小的套接口地址结构的代码。

经测试,在fedor6-2.6.18kernel中无法返回ipv6地址,事实上,返回的地址簇总是AF_INET,而并非AF_INET6。

这种方法的实现代码如下:

trans.gif

net_if.h

#ifndef __NET_INF_H

#define __NET_INF_H

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define IFI_NAME 16

#define IFI_HADDR 8

typedef struct ifi_info

{

char ifi_name[IFI_NAME];

u_char ifi_haddr[IFI_HADDR];

u_short ifi_hlen;

short ifi_flags;

short ifi_myflags;

struct sockaddr *ifi_addr;

struct sockaddr *ifi_brdaddr;

struct sockaddr *ifi_dstaddr;

struct ifi_info *ifi_next;

}ifi_info;

#define IFI_ALIAS 1

struct ifi_info *get_ifi_info(int, int);

void free_ifi_info(struct ifi_info *);

#endif

net_if.c

#include "net_if.h"

ifi_info *get_ifi_info(int family, int doaliases)

{

ifi_info *ifi, *ifihead, **ifipnext;

int sockfd, len, lastlen, flags, myflags;

char *ptr, *buf, lastname[IFNAMSIZ], *cptr;

struct ifconf ifc;

struct ifreq *ifr, ifrcopy;

struct sockaddr_in *sinptr;

if ((sockfd=socket(family, SOCK_DGRAM, 0))<0)

{

printf("socket error.\n");

exit(1);

}

lastlen = 0;

len = 10*sizeof(struct ifreq);

while (1)

{

buf = (char*)malloc(len);

ifc.ifc_len = len;

ifc.ifc_buf = buf;

if (ioctl(sockfd, SIOCGIFCONF, &ifc)<0)

{

if (errno!=EINVAL||lastlen!=0)

{

printf("ioctl error.\n");

}

}

else

{

if (ifc.ifc_len == lastlen)

break;

lastlen = ifc.ifc_len;

}

len += 10*sizeof(struct ifreq);

free(buf);

}

ifihead = NULL;

ifipnext = &ifihead;

lastname[0] = 0;

for (ptr = buf; ptrifr->ifr_addr.sa_len?sizeof(struct sockaddr):ifr->ifr_addr.sa_len;

#else

switch (ifr->ifr_addr.sa_family)

{

#ifdef IPV6

case AF_INET6:

len = sizeof(struct sockaddr_in6);

break;

#endif

case AF_INET:

default:

len = sizeof(struct socka

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值