手机版

netlink的使用方法(5)

发布时间:2021-06-08   来源:未知    
字号:

netlink的使用方法

user_proc.pid = nlh->nlmsg_pid;

write_unlock_bh(&user_proc.pid);

}

else if(nlh->nlmsg_type == IMP2_CLOSE) /*应用程序关闭*/

{

write_lock_bh(&user_proc.pid);

if(nlh->nlmsg_pid == user_proc.pid)

user_proc.pid = 0;

write_unlock_bh(&user_proc.pid);

}

}

}

}

kfree_skb(skb);

}

up(&receive_sem); /*返回信号量*/

}while(nlfd && nlfd->receive_queue.qlen);

}

因为内核模块可能同时被多个进程同时调用,所以函数中使用了信号量和锁来进行互斥。

skb = skb_dequeue(&sk->receive_queue)用于取得socket sk 的接收队列上的消息,返回为一个struct sk_buff 的结构,skb->data 指向实际的netlink 消息。

程序中注册了一个Netfilter 钩子,钩子函数是get_icmp,它截获ICMP 数据包,然后调用send_to_user 函数将数据发送给应用空间进程。发送的数据是info 结构变量,它是struct packet_info结构,这个结构包含了来源/目的地址两个成员。Netfilter Hook 不是本文描述的重点,略过。

send_to_user 用于将数据发送给用户空间进程,发送调用的是API 函数netlink_unicast 完成的: int netlink_unicast(struct sock *sk, struct sk_buff *skb, u32 pid, int nonblock);

参数sk 为函数netlink_kernel_create()返回的套接字,参数skb 存放待发送的消息,它的data字段指向要发送的netlink 消息结构,而skb 的控制块保存了消息的地址信息, 参数pid 为接收消息进程的pid,参数nonblock 表示该函数是否为非阻塞,如果为1,该函数将在没有接收缓存可利用时立即返回,而如果为0,该函数在没有接收缓存可利用时睡眠。

向用户空间进程发送的消息包含三个部份:netlink 消息头部、数据部份和控制字段,控制字段包含了内核发送netlink 消息时,需要设置的目标地址与源地址,内核中消息是通过sk_buff 来管理的, linux/netlink.h 中定义了NETLINK_CB 宏来方便消息的地址设置:

#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))

例如:

NETLINK_CB(skb).pid = 0;

NETLINK_CB(skb).dst_pid = 0;

NETLINK_CB(skb).dst_group = 1;

字段pid 表示消息发送者进程ID,也即源地址,对于内核,它为 0, dst_pid 表示消息接收者进程 ID,也即目标地址,如果目标为组或内核,它设置为 0,否则 dst_group 表示目标组地址,如果它目标为某一进程或内核,dst_group 应当设置为 0。

static int send_to_user(struct packet_info *info)

{

int ret;

int size;

unsigned char *old_tail;

struct sk_buff *skb;

struct nlmsghdr *nlh;

struct packet_info *packet;

size = NLMSG_SPACE(sizeof(*info)); /*计算消息总长:消息首部加上数据加度*/

netlink的使用方法(5).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
×
二维码
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)