struct ifaddrs 与getifaddrs()函数

1,struct ifaddrs结构体:

struct ifaddrs
{
    struct ifaddrs  *ifa_next;    /* Next item in list */
    char            *ifa_name;    /* Name of interface */
    unsigned int     ifa_flags;   /* Flags from SIOCGIFFLAGS */
    struct sockaddr *ifa_addr;    /* Address of interface */
    struct sockaddr *ifa_netmask; /* Netmask of interface */
    union
    {
        struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */
        struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */
    } ifa_ifu;
    #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
    #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
    void            *ifa_data;    /* Address-specific data */
}; 

ifa_next 指向链表中下一个struct ifaddr结构
ifa_name 网络接口名
ifa_flags 网络接口标志,这些标志见下面描述。
ifa_addr 指向一个包含网络地址的sockaddr结构
ifa_netmask 指向一个包含网络掩码的结构
ifu_broadaddr 如果(ifa_flags&IFF_BROADCAST)有效,ifu_broadaddr指向一个包含广播地址的结构。
ifu_dstaddr 如果(ifa_flags&IFF_POINTOPOINT)有效,ifu_dstaddr指向一个包含p2p目的地址的结构。
ifa_addr 指向一个缓冲区,其中包含地址族私有数据。没有私有数据则为NULL。

ifa_flags 标志位:
Device flags
IFF_UP Interface is running.
IFF_BROADCAST Valid broadcast address set.

		              IFF_DEBUG         Internal debugging flag.
		              IFF_LOOPBACK      Interface is a loopback interface.
		              IFF_POINTOPOINT   Interface is a point-to-point link.
		              IFF_RUNNING       Resources allocated.
		              IFF_NOARP         No arp protocol, L2 destination address not
		                                set.
		              IFF_PROMISC       Interface is in promiscuous mode.
		              IFF_NOTRAILERS    Avoid use of trailers.
		              IFF_ALLMULTI      Receive all multicast packets.
		              IFF_MASTER        Master of a load balancing bundle.
		              IFF_SLAVE         Slave of a load balancing bundle.
		              IFF_MULTICAST     Supports multicast
		              IFF_PORTSEL       Is able to select media type via ifmap.
		              IFF_AUTOMEDIA     Auto media selection active.
		              IFF_DYNAMIC       The addresses are lost when the interface
		                                goes down.
		              IFF_LOWER_UP      Driver signals L1 up (since Linux 2.6.17)
		              IFF_DORMANT       Driver signals dormant (since Linux 2.6.17)
		              IFF_ECHO          Echo sent packets (since Linux 2.6.25)

2,getifaddrs()函数
头文件:
#include <sys/types.h>
#include <ifaddrs.h>
函数说明:获取本地网络接口的信息。在路由器上可以用这个接口来获取wan/lan等接口当前的ip地址,广播地址等信息。
int getifaddrs(struct ifaddrs **ifap);
getifaddrs创建一个链表,链表上的每个节点都是一个struct ifaddrs结构,getifaddrs()返回链表第一个元素的指针

返回值:成功返回0, 失败返回-1,同时errno会被赋允相应错误码。
事例:

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>

int
main(int argc, char *argv[])
{
	struct ifaddrs *ifaddr, *ifa;
	int family, s;
	char host[NI_MAXHOST];

	if (getifaddrs(&ifaddr) == -1) {
		perror("getifaddrs");
		exit(EXIT_FAILURE);
	}

	/* Walk through linked list, maintaining head pointer so we
	   can free list later */

	for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
		if (ifa->ifa_addr == NULL)
			continue;
		family = ifa->ifa_addr->sa_family;

		/* Display interface name and family (including symbolic
		   form of the latter for the common families) */

		printf("%s  address family: %d%s\n",
		       ifa->ifa_name, family,
		       (family == AF_PACKET) ? " (AF_PACKET)" :
		       (family == AF_INET) ?   " (AF_INET)" :
		       (family == AF_INET6) ?  " (AF_INET6)" : "");

		if (ifa->ifa_flags & IFF_BROADCAST)

		/* For an AF_INET* interface address, display the address */

		if (family == AF_INET || family == AF_INET6) {
			s = getnameinfo(ifa->ifa_addr,
					(family == AF_INET) ? sizeof(struct sockaddr_in) :
					sizeof(struct sockaddr_in6),
					host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
			if (s != 0) {
				printf("getnameinfo() failed: %s\n", gai_strerror(s));
				exit(EXIT_FAILURE);
			}
			printf("\taddress: <%s>\n", host);

			if (ifa->ifa_flags & IFF_BROADCAST) {
				s = getnameinfo(ifa->ifa_broadaddr,
						(family == AF_INET) ? sizeof(struct sockaddr_in) :
						sizeof(struct sockaddr_in6),
						host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
				printf("\tbroadcast address: <%s>\n", host);
			}
			if (ifa->ifa_flags & IFF_POINTOPOINT) {
				s = getnameinfo(ifa->ifa_dstaddr,
						(family == AF_INET) ? sizeof(struct sockaddr_in) :
						sizeof(struct sockaddr_in6),
						host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
				printf("\tbroadcast address: <%s>\n", host);
			}
		}
	}

	freeifaddrs(ifaddr);
	exit(EXIT_SUCCESS);
}

输出结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路漫漫其远,吾求索

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值