Chinaunix

标题: netlink 编程介绍(V0.2) [打印本页]

作者: 哦,呀呀    时间: 2010-01-27 10:19
标题: netlink 编程介绍(V0.2)
在socket程序中,如果我们要求接收报文则要求调用bind,表示我们期望接收什么样的报文。对于netlink也一样,我们要求指定我们期望接收的地址信息,不过同传统的sockaddr不同,这个地方是一个sockaddr_nl的结构:
struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* 用来填充的字段,赋值为0 */
pid_t nl_pid; /* 进程标识号pid */
__u32 nl_groups; /* 多址广播组掩码*/
};
每一个 netlink 数据类都有一个32位广播分组,当对套接字调用 bind(2) 时, sockaddr_nl 中的 nl_groups 字段设置成所要侦听的广播组的位掩码。其默认值为 0,表示不接收任何广播,我们会在后面中看到如何使用这个广播组的例子。
NETLINK_ROUTE协议介绍
netlink目前使用最广泛的是通过这个选项来获取网络设备或者网址的一些信息。在使用这个协议时候支持的类型有:
RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK 创建,删除或者获取网络设备的信息
RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR 创建,删除或者获取网络设备的IP信息
RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE 创建,删除或者获取网络设备的路由信息
RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH 创建,删除或者获取网络设备的相邻信息
RTM_NEWRULE, RTM_DELRULE, RTM_GETRULE 创建,删除或者获取路由规则信息
RTM_NEWQDISC, RTM_DELQDISC, RTM_GETQDISC 创建,删除或者获取队列的原则
RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS 创建,删除或者获取流量的类别
RTM_NEWTFILTER, RTM_DELTFILTER, RTM_GETTFILTER 创建,删除或者获取流量的过虑
由于NETLINK_ROUTE支持的类型实在太多了,我们这个地方只重点介绍一下RTM_GETLINK这个类型,然后通过一个例子介绍如何同内核进行通讯。关于其它类型的用法大家可以参考rtnetlink(7)的man手册。
按照rtnetlink的说法,在获取设备信息的时候我们要求首先发送一个报文给内核表示我们的请求,这个报文的格式是1个nlmsghdr头部机构+1个ifinfomsg接口结构+多个rtattr属性机构。其中后面两个结构的定义是:
struct ifinfomsg
{
unsigned char ifi_family; /* AF_UNSPEC */
unsigned short ifi_type; /* Device type */
int ifi_index; /* Interface index */
unsigned int ifi_flags; /* Device flags */
unsigned int ifi_change; /* change mask */
};
struct rtattr
{
unsigned short rta_len; /* Length of option */
unsigned short rta_type; /* Type of option */
/* Data follows */
};
ifi_type:这个字段包含了硬件的类型,可以参考比较常见的是 ARPHRD_ETHER 10M以太网
ARPHRD_PPP PPP拨号
ARPHRD_LOOPBACK 环路设备
ifi_flags:这个字段包含了设备的一些标志,相应的值为: IFF_UP 接口正在运行.
IFF_BROADCAST 有效的广播地址集.
IFF_DEBUG 内部调试标志.
IFF_LOOPBACK 这是自环接口.
IFF_POINTOPOINT 这是点到点的链路接口.
IFF_RUNNING 资源已分配.
IFF_NOARP 无arp协议, 没有设置第二层目的地址.
IFF_PROMISC 接口为杂凑(promiscuous)模式.
IFF_NOTRAILERS 避免使用trailer .
IFF_ALLMULTI 接收所有组播(multicast)报文.
IFF_MASTER 主负载平衡群(bundle).
IFF_SLAVE 从负载平衡群(bundle).
IFF_MULTICAST 支持组播(multicast).
IFF_PORTSEL 可以通过ifmap选择介质(media)类型.
IFF_AUTOMEDIA 自动选择介质.
IFF_DYNAMIC 接口关闭时丢弃地址.
rta_type:这个字段指定属性的类型,相应的值为: IFLA_UNSPEC 后面的数据格式未指定
IFLA_ADDRESS 后面的数据是一个硬件地址
IFLA_BROADCAST 后面的数据是一个硬件广播地址
IFLA_IFNAME 后面的数据是一个char型的设备名称
IFLA_MTU unsigned int型的设备MTU值
IFLA_LINK int型的链路类型
IFLA_QDISC 字符串型的队列规则
IFLA_STATS struct net_device_stats型的设备信息
在我们接收和发送数据的时候为了我们获取属性的方便,rtnetlink提供了一个宏供我们取获取其中的结构,这些宏的定义为: #include
#include
#include
#include
int RTA_OK(struct rtattr *rta, int rtabuflen);
void *RTA_DATA(struct rtattr *rta);
unsigned int RTA_PAYLOAD(struct rtattr *rta);
struct rtattr *RTA_NEXT(struct rtattr *rta, unsigned int rtabuflen);
unsigned int RTA_LENGTH(unsigned int length);
unsigned int RTA_SPACE(unsigned int length);
文章出处:DIY部落(
http://www.diybl.com/course/6_system/linux/Linuxjs/200876/130650_2.html
)

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/111204/showart_2161826.html




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2