【Goood转】Linux netlink socket使用总结
作者:左手码农
来源:CSDN
原文:https://blog.csdn.net/liuruiqun/article/details/50404210?utm_source=copy
1. netlink 地址格式
struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */
__u32 nl_pid; /* port ID */
__u32 nl_groups; /* multicast groups mask */
};
nl_pad 当前没有使用,因此要总是设置为 0,
nl_pid就是一个约定的通信端口,用户态使用的时候需要用一个非0的数字,一般来说可以直接采用上层应用的进程ID(未必是进程 ID,它只是用于区分不同的接收者或发送者的一个标识,用户可以根据自己需要设置该字段,只要是系统中不冲突的一个数字即可)。对于内核的地址,该值必须用0,即上层通过sendto向内核发送netlink消息,peer addr中nl_pid必须填写0。
nl_groups用于一个消息同时分发给不同的接收者,是一种组播应用。绑定时用于指定绑定者所要加入的多播组,这样绑定者就可以接收多播消息,发送 消息时可以用于指定多播组,这样就可以将消息发给多个接收者。这里nl_groups 为32位的无符号整形,所以可以指定32个多播组,每个进程可以加入多个多播组, 因为多播组是通过“或”操作,如果设置为 0,表示调用者不加入任何多播组。
本质上,nl_pid就是netlink的通信地址。除了通信地址,netlink还提供“协议”来标示通信实体,在创建socket的时候,需要指定netlink的通信协议号。每个协议号代表一种“应用”,上层可以用内核已经定义的协议和内核进行通信,获得内核已经提供的信息。netlink采用“协议号 + 通信端口”的方式构建自己的地址体系。
2. netlink 头部信息
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 port ID */
};
nlmsg_len 指定消息的总长度,包括紧跟该结构的数据部分长度以及该结构的大小。
nlmsg_type 用于应用内部定义消息的类型,它对netlink 内核实现是透明的,因此大部分情况下设置为 0。
nlmsg_seq 和 nlmsg_pid 用于应用追踪消息,前者表示顺序号,后者为消息来源进程 ID。其中pid是Netlink分配的一个ID,不同的值代表不同的socket通道,默认的值是进程PID。在某些情况下,这个值被设置为0,比如消息来自内核空间,或者想要Netlink来设置这个值。
nlmsg_flags 用于设置消息标志,可用的标志包括: