读书人

netlink跟rtnetlink(一)

发布时间: 2012-10-17 10:25:47 作者: rapoo

netlink和rtnetlink(一)

转到:http://blogold.chinaunix.net/u/15993/showart.php?id=89359

我们先从netlink说起,netlink其实就是一组宏,这组宏用来访问和创建netlink数据报,其实和其他套结字一样,只不过它是用来给用户进程和内核模块之间进行通信的,它的宏定义有:
?????? ?#include <asm/types.h>
?????? ?#include <linux/netlink.h>
?????? ?int NLMSG_ALIGN(size_t len);
?????? ?int NLMSG_LENGTH(size_t len);
?????? ?int NLMSG_SPACE(size_t len);
?????? ?void *NLMSG_DATA(struct nlmsghdr *nlh);
?????? ?struct nlmsghdr *NLMSG_NEXT(struct nlmsghdr *nlh, int len);
?????? ?int NLMSG_OK(struct nlmsghdr *nlh, int len);
?????? ?int NLMSG_PAYLOAD(struct nlmsghdr *nlh, int len);这些宏的含义我就不多说了,大家可以man 3 netlink。这里要说的是netlink的用法,netlink的用法在初始化的时候和一般的socket相似,如下:
?????? ?#include <asm/types.h>
?????? ?#include <sys/socket.h>
?????? ?#include <linux/netlink.h>?????? ?netlink_socket = socket(PF_NETLINK, socket_type, netlink_family);
?
socket_type为SOCK_RAW或者SOCK_DGRAM都可以,因为netlink本身是基于数据报的。
netlink_family有下面几种:
NETLINK_ROUTE
?????? 用来修改和读取路由表的,这是我们后面要讨论的关键问题.NETLINK_FIREWALL
?????? 接收IPv4防火墙代码发送的信息。NETLINK_ARPD
?????? 在用户空间中管理ARP表.NETLINK_ROUTE6
?????? 接收和发送路由表更新.NETLINK_IP6_FW
?????? to? receive? packets? that failed the IPv6 firewall
?????? checks (currently not implemented).NETLINK_TAPBASE...NETLINK_TAPBASE+15
?????? are the instances of the ethertap device.? Ethertap
?????? is? a? pseudo? network tunnel device that allows an
?????? ethernet driver to be simulated from user space.NETLINK_SKIP
?????? Reserved for ENskip.NETLINK_USERSOCK
?????? is reserved for future user space protocols.Netlink消息是一个含有一个或者多个nlmsghdr头和相关载荷组成的字节流。除了最后一个nlmsghdr头的类型是NLMSG_DONE,其他的nlmsghdr头都是NLM_F_MULTI类型。这个字节流只能被上面描述过的标准NLMSG_*宏来访问。Netlink是一个不可靠的协议。如果出现内存用尽或者其他错误,它就会丢包。如果需要可靠传输。发送者可以通过设置NLM_F_ACK标志来向接收端要求一个ACK。一个ACK其实就是一个NLMSG_ERROR包,只不过它的error field设置为0。应用程序需要为接收的消息自己产生ACK。内核尽力为每个失败的包产生NLMSG_ERROR消息。用户进程也要遵守这个规范。struct nlmsghdr
?????? {
??? __u32??? nlmsg_len;? /* Length of message including header */
??? __u16??? nlmsg_type; /* Message content */
??? __u16??? nlmsg_flags;/* Additional flags */
??? __u32??? nlmsg_seq;? /* Sequence number */
??? __u32??? nlmsg_pid;? /* Sending process PID */
?????? };
???struct nlmsgerr
???{
??? int??? error;????? /* negative errno or 0 for acks. */
??? struct nlmsghdr msg; /* message header that caused the error */
???};? nlmsg_flag的标准flag
?????? ?NLM_F_REQUEST?? set on all request messages
?????? ?NLM_F_MULTI???? the message is part of a multipart mes-
???????? sage terminated by NLMSG_DONE
?????? ?NLM_F_ACK?????? reply with an acknowledgment on success
?????? ?NLM_F_ECHO????? echo this request?????? ?GET请求的附加标志位
?????? ?NLM_F_ROOT???? Return the complete table instead of a single entry.
?????? ?NLM_F_MATCH??? Not implemented yet.
?????? ?NLM_F_ATOMIC?? Return an atomic snapshot of the table.
?????? ?NLM_F_DUMP???? not documented yet.?????? ?NEW请求的附加标志位
?????? ?NLM_F_REPLACE?? Override existing object.
?????? ?NLM_F_EXCL????? Don't replace if the object already exists.
?????? ?NLM_F_CREATE??? Create object if it doesn't already exist.
?????? ?NLM_F_APPEND??? Add to the end of the object list.
?
?sockaddr_nl结构描述了一个用户空间或者内核空间里面的netlink客户端。一个sockaddr_nl可以为单播也可以为组播。
?struct sockaddr_nl
?????? {
??? sa_family_t nl_family;??? /* AF_NETLINK */
??? unsigned short nl_pad;??? /* zero */
??? pid_t?????? nl_pid;???? /* process pid */
??? __u32?????? nl_groups;??? /* multicast groups mask */
?????? };
?nl_pid是用户空间netlink的pid,如果为0,就代表是内核空间。nl_groups是一个位掩码,每个bit代表了一个组号。如果是0就是单播。(未完待续)

读书人网 >编程

热点推荐