netlink的使用方法(2)

发布时间:2021-06-08

netlink的使用方法

__u32 nl_groups;

};

成员 nl_family 为协议簇 AF_NETLINK,成员 nl_pad 当前没有使用,因此要总是设置为 0,成员 nl_pid 为接收或发送消息的进程的 ID,如果希望内核处理消息或多播消息,就把该字段设置为 0,否则设置为处理消息的进程 ID。成员 nl_groups 用于指定多播组,bind 函数用于把调用进程加入到该字段指定的多播组,如果设置为 0,表示调用者不加入任何多播组:

struct sockaddr_nl local;

memset(&local, 0, sizeof(local));

local.nl_family = AF_NETLINK;

local.nl_pid = getpid(); /*设置pid 为自己的pid 值*/

local.nl_groups = 0;

if(bind(skfd, (struct sockaddr*)&local, sizeof(local)) != 0) /*绑定套接字*/

{

printf("bind() error\n");

return -1;

}

用户空间可以调用send 函数簇向内核发送消息,如sendto、sendmsg 等,同样地,也可以使用struct sockaddr_nl 来描述一个对端地址,以待send 函数来调用,与本地地址稍不同的是,因为对端为内核,所以nl_pid 成员需要设置为0:

struct sockaddr_nl kpeer;

memset(&kpeer, 0, sizeof(kpeer));

kpeer.nl_family = AF_NETLINK;

kpeer.nl_pid = 0;

kpeer.nl_groups = 0;

另一个问题就是发内核发送的消息的组成,使用我们发送一个IP 网络数据包的话,则数据包结构为“IP 包头+IP 数据”,同样地,netlink 的消息结构是“netlink 消息头部+数据”。Netlink 消息头部使用struct nlmsghdr 结构来描述:

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 指定消息的总长度,包括紧跟该结构的数据部分长度以及该结构的大小,一般地,我们使用netlink 提供的宏NLMSG_LENGTH 来计算这个长度,仅需向NLMSG_LENGTH宏提供要发送的数据的长度,它会自动计算对齐后的总长度:

/*计算包含报头的数据报长度*/

#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr)))

/*字节对齐*/

#define NLMSG_ALIGN(len) (((len)+NLMSG_ALIGNTO-1)& ~(NLMSG_ALIGNTO-1) )

后面还可以看到很多netlink 提供的宏,这些宏可以为我们编写netlink 宏提供很大的方便。

字段 nlmsg_type 用于应用内部定义消息的类型,它对 netlink 内核实现是透明的,因此大部分情况下设置为 0,字段 nlmsg_flags 用于设置消息标志,对于一般的使用,用户把它设置为 0 就可以,只是一些高级应用(如 netfilter 和路由 daemon 需要它进行一些复杂的操作),字段nlmsg_seq 和 nlmsg_pid 用于应用追踪消息,前者表示顺序号,后者为消息来源进程 ID。

struct msg_to_kernel /*自定义消息首部,它仅包含了netlink 的消息首部*/

{

struct nlmsghdr hdr;

netlink的使用方法(2).doc 将本文的Word文档下载到电脑

精彩图片

热门精选

大家正在看

× 游客快捷下载通道(下载后可以自由复制和排版)

限时特价:7 元/份 原价:20元

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219