netlink的使用方法(3)
发布时间:2021-06-08
发布时间:2021-06-08
netlink的使用方法
};
struct msg_to_kernel message;
memset(&message, 0, sizeof(message));
message.hdr.nlmsg_len = NLMSG_LENGTH(0); /*计算消息,因为这里只是发送一个请求消息,没
有多余的数据,所以,数据长度为0*/
message.hdr.nlmsg_flags = 0;
message.hdr.nlmsg_type = IMP2_U_PID; /*设置自定义消息类型*/
message.hdr.nlmsg_pid = local.nl_pid; /*设置发送者的PID*/
这样,有了本地地址、对端地址和发送的数据,就可以调用发送函数将消息发送给内核了:
sendto(skfd, &message, message.hdr.nlmsg_len, 0, /*发送一个请求*/
(struct sockaddr*)&kpeer, sizeof(kpeer));
当发送完请求后,就可以调用recv 函数簇从内核接收数据了,接收到的数据包含了netlink
消息首部和要传输的数据:
/*接收的数据包含了netlink 消息首部和自定义数据结构*/
struct u_packet_info
{
struct nlmsghdr hdr;
struct packet_info icmp_info;
};
struct u_packet_info info;
while(1)
{
kpeerlen = sizeof(struct sockaddr_nl);
rcvlen = recvfrom(skfd, &info, sizeof(struct u_packet_info),0, (struct sockaddr*)&kpeer, &kpeerlen); /*接收内核空间返回的数据;处理接收到的数据*/
}
同样地,函数close 用于关闭打开的netlink socket。程序中,因为程序一直循环接收处理内核的消息,需要收到用户的关闭信号才会退出,所以关闭套接字的工作放在了自定义的信号函数sig_int 中处理: /*这个信号函数,处理一些程序退出时的动作*/
static void sig_int(int signo)
{
struct sockaddr_nl kpeer;
struct msg_to_kernel message;
memset(&kpeer, 0, sizeof(kpeer));
kpeer.nl_family = AF_NETLINK;
kpeer.nl_pid = 0;
kpeer.nl_groups = 0;
memset(&message, 0, sizeof(message));
message.hdr.nlmsg_len = NLMSG_LENGTH(0);
message.hdr.nlmsg_flags = 0;
message.hdr.nlmsg_type = IMP2_CLOSE;
message.hdr.nlmsg_pid = getpid();
/*向内核发送一个消息,由nlmsg_type 表明,应用程序将关闭*/
sendto(skfd, &message, message.hdr.nlmsg_len, 0, (struct sockaddr *)(&kpeer), sizeof(kpeer));
close(skfd);
exit(0);
}
这个结束函数中,向内核发送一个“我已经退出了”的消息,然后调用close 函数关闭netlink套接字,退出程序。
下一篇:测控电路课后答案