netlink注意的几个地方

netlink是个功能强大的socket,可以很方便的应用在用户态程序和内核态的通信,具体可以在内核态使用netlink通信,然后在用户态可以使用普通套接字,也可以使用netlink套接字接收消息。最近在使用netlink时发现几点问题,在这里记录下来:

 

1.netlink消息头是一个nlmsghdr的结构体结构,也被称做netlink控制块,每次发送数据都要把这个消息头放在数据头部:
struct nlmsghdr
{
  __u32 nlmsg_len;   /* Length of message */
  __u16 nlmsg_type;  /* Message type*/
  __u16 nlmsg_flags; /* Additional flags */
  __u32 nlmsg_seq;   /* Sequence number */
  __u32 nlmsg_pid;   /* Sending process PID */
};
其中字段 nlmsg_len 指定消息的总长度,包括紧跟该结构的数据部分长度以及该结构的大小,字段 nlmsg_type 用于应用内部定义消息的类型,它对
netlink内核实现是透明的,因此大部分情况下设置为 0,字段 nlmsg_flags 用于设置消息标志对于一般的使用,用户把它设置为 0 就可以,只是一些高
级应用(如 netfilter 和路由 daemon 需要它进行一些复杂的操作),字段 nlmsg_seq 和 nlmsg_pid 用于应用追踪消息,前者表示顺序号,后者为消息
来源进程 ID
2. netlink发送的数据会包装成为一个sk_buff的结构体, sk_buff的意思是socket buff,在sk_buff中包含了很多信息,其中有指向前一个和后一个要发
送的buffer的指针、数据长度、指向数据的指针等,其中有个tail的元素为记录发送数据结尾的变量,这个元素的类型是sk_buff_data_t,而这个类型的定
义是:
#if BITS_PER_LONG > 32
#define NET_SKBUFF_DATA_USES_OFFSET 1
#endif

#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;
#else
typedef unsigned char *sk_buff_data_t;
#endif
相信大家已经很清楚了,在32位系统上,是unsigned char*类型,在64位系统上是unsigned int类型,所以要注意这个地方,使用tail这个变量一个好处是
很容易得到发送数据的长度,如下:
old_tail = skb_send->tail;
memcpy(NLMSG_DATA(nlh), data, n);
nlh->nlmsg_len = skb_send->tail - old_tail;
3.在发送和接收时如何往消息中放入真正的数据和取出真正的数据呢?在上面其实已经用到了,没错,就是使用NLMSG_DATA这个宏定义了,发送端上面已经有
例子了,再举个接收端的吧,其中data为客户端接收到的数据:
message = (struct nlmsghdr *)data;
msghdr = (struct ct_msghdr *)NLMSG_DATA(message);

当然这些都是netlink最基本的东西,netlink包含有路由 daemon(NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态 socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM),SELinux 事件通知(NETLINK_SELINUX),iSCSI 子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询 (NETLINK_FIB_LOOKUP),netlink connector(NETLINK_CONNECTOR),netfilter 子系统(NETLINK_NETFILTER),IPv6 防火墙NETLINK_IP6_FW),DECnet 路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用 netlink(NETLINK_GENERIC)等多种方式。
可参考网站:http://www.infradead.org/~tgr/libnl/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据