netlink_kernel_create函数调用时的问题【已解决】
本帖最后由 jiufei19 于 2010-06-02 10:58 编辑大家好,我按照CU中介绍的关于netlink原理的例子(netlink socket 编程之 why & how )在我本地机器上进行编译,我的内核版本2.6.23.1-42.fc8,在调用到netlink_kernel_create函数时,总是有如下警告,望各位赐教如何消除此警告:
-----------------------------------------------------
netlink_k.c:19: 警告:函数声明不是一个原型
netlink_k.c: In function ‘netlink_test’:
netlink_k.c:25: 警告:传递参数 4 (属于 ‘netlink_kernel_create’)时在不兼容的指针类型间转换
-----------------------------------------------------
下面我将netlink_k.c的源码例在下面:
1 #include <linux/socket.h>
2 #include <linux/netlink.h>
3 #include <net/sock.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/init.h>
7
8 #define NETLINK_TEST 17
9 #define MAX_PAYLOAD 1024
10
11 struct sock *nl_sk = NULL;
12
13 void nl_data_ready (struct sock *sk, int len)
14 {
15 wake_up_interruptible(sk->sk_sleep);
16 }
17
18 void netlink_test()
19 {
20 struct sk_buff *skb = NULL;
21 struct nlmsghdr *nlh = NULL;
22 int err;
23 unsigned long pid;
24
25 nl_sk = netlink_kernel_create(NETLINK_TEST, 0, NULL, nl_data_ready, THIS_MODULE);
26 /* wait for message coming down from user-space */
27 skb = skb_recv_datagram(nl_sk, 0, 0, &err);
28
29 nlh = (struct nlmsghdr *)skb->data;
30 printk("%s: received netlink message payload:%s\n",
31 __FUNCTION__, (char *)NLMSG_DATA(nlh));
32
33 pid = nlh->nlmsg_pid; /*pid of sending process */
34 /*NETLINK_CB(skb).groups = 0; [> not in mcast group <]*/
35 /*NETLINK_CB(skb).pid = 0; [>from kernel <]*/
36 NETLINK_CB(skb).pid = pid;
37 NETLINK_CB(skb).dst_group = 0;/* unicast */
38 netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
39 sock_release(nl_sk->sk_socket);
40 }
41
42 static int __init hello_start(void)
43 {
44 printk("Loading netlink demo module...\n");
45
46 netlink_test();
47 return 0;
48 }
49
50 static void __exit hello_end(void)
51 {
52 printk("Exiting netlink demo module...\n");
53 }
54
55 module_init(hello_start);
56 module_exit(hello_end);
另外,我还存在如下两个疑问:
1、因为我的内核版本中netlink_kernel_create函数原型如下,其中增加了struct mutex *cb_mutex这个参数,我这里用NULL来进行调用,是否正确?
netlink_kernel_create(int unit, unsigned int groups,void (*input)(struct sock *sk, int len),struct mutex *cb_mutex, struct module *module)
2、对于这个参数NETLINK_CB(skb).pid,到底填什么?因为2.6.23内核中已经没有dst_pid了,所以这里的pid到底是什么呢? LZ先明确一下内核版本是否一致。netlink的接口在2.4和2.6中是有所变化的。 回复 2# Godbach
我的内核版本的确和CU上给出的这篇文章的版本不一致,于是我进行了对应的修改,本帖就是对修改后的一些错误现象的求助 其实LZ可以直接参考内核代码的实现。比如ip_queue.c中在模块入口ip_queue_init中也调用了netlink_kernel_create,看看人家是怎么传递参数的。 本帖最后由 jiufei19 于 2010-06-01 14:33 编辑
回复 4# Godbach
谢谢!果然根据斑竹的提示,在ip_queue_init中使用了NULL作为了调用时的实参:
ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk,NULL, THIS_MODULE);
晕,我自己粗心大意了,谢谢!
现在还剩最后1个问题:netlink_k.c|19| 警告:函数声明不是一个原型
请问此问题是什么原因造成? 25 nl_sk = netlink_kernel_create(NETLINK_TEST, 0, NULL, nl_data_ready, THIS_MODULE);
仔细看看这行代码有什么问题。 回复 6# Godbach
谢谢指正,我刚才的发帖已经纠正了这个粗心的错误,请问刚才那个警告是什么原因? netlink_kernel_create(int unit, unsigned int groups,void (*input)(struct sock *sk, int len),struct mutex *cb_mutex, struct module *module)
你看看你实际调用的时候,各个参数类型是否正确。
倒数第二个参数是什么类型,你传递进去的是什么类型? 回复 8# Godbach
我的实际调用语句如下,倒数第2个参数是NULL
nl_sk = netlink_kernel_create(NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE);
另外,在仍然有此警告的情况下,内核模块和用户态程序之间的通信过程成功了,在此我将代码完整贴出来,供大家参考,并请斑竹帮我解决刚才那个警告问题
1 #include <linux/socket.h>
2 #include <linux/netlink.h>
3 #include <net/sock.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/init.h>
7
8 #define NETLINK_TEST 17
9 #define MAX_PAYLOAD 1024
10
11 struct sock *nl_sk = NULL;
12
13 void nl_data_ready (struct sock *sk, int len)
14 {
15 wake_up_interruptible(sk->sk_sleep);
16 }
17
18 void netlink_test()
19 {
20 struct sk_buff *skb = NULL;
21 struct nlmsghdr *nlh = NULL;
22 int err;
23 unsigned long pid;
24
25 nl_sk = netlink_kernel_create(NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE);
26 /* wait for message coming down from user-space */
27 skb = skb_recv_datagram(nl_sk, 0, 0, &err);
28
29 nlh = (struct nlmsghdr *)skb->data;
30 printk("%s: received netlink message payload:%s\n",
31 __FUNCTION__, (char *)NLMSG_DATA(nlh));
32
33 pid = nlh->nlmsg_pid; /*pid of sending process */
34 NETLINK_CB(skb).pid = pid;
35 NETLINK_CB(skb).dst_group = 0;/* unicast */
36 netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
37 sock_release(nl_sk->sk_socket);
38 }
39
40 static int __init hello_start(void)
41 {
42 printk("Loading netlink demo module...\n");
43
44 netlink_test();
45 return 0;
46 }
47
48 static void __exit hello_end(void)
49 {
50 printk("Exiting netlink demo module...\n");
51 }
52
53 module_init(hello_start);
54 module_exit(hello_end);
用户态程序:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <linux/netlink.h>
7
8 #define NETLINK_TEST 17
9 #define MAX_PAYLOAD 1024/* maximum payload size*/
10
11 struct sockaddr_nl src_addr, dest_addr;
12 struct nlmsghdr *nlh = NULL;
13 struct iovec iov;
14 struct msghdr msg;
15 int sock_fd;
16
17 int main() {
18 sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
19
20 memset(&src_addr, 0, sizeof(src_addr));
21 src_addr.nl_family = AF_NETLINK;
22 src_addr.nl_pid = getpid();/* self pid */
23 src_addr.nl_groups = 0;/* not in mcast groups */
24 bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
25
26 memset(&dest_addr, 0, sizeof(dest_addr));
27 dest_addr.nl_family = AF_NETLINK;
28 dest_addr.nl_pid = 0; /* For Linux Kernel */
29 dest_addr.nl_groups = 0; /* unicast */
30
31 nlh=(struct nlmsghdr *)malloc(
32 NLMSG_SPACE(MAX_PAYLOAD));
33 /* Fill the netlink message header */
34 nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
35 nlh->nlmsg_pid = getpid();/* self pid */
36 nlh->nlmsg_flags = 0;
37 /* Fill in the netlink message payload */
38 strcpy(NLMSG_DATA(nlh), "Hello you!");
39
40 iov.iov_base = (void *)nlh;
41 iov.iov_len = nlh->nlmsg_len;
42 msg.msg_name = (void *)&dest_addr;
43 msg.msg_namelen = sizeof(dest_addr);
44 msg.msg_iov = &iov;
45 msg.msg_iovlen = 1;
46
47 sendmsg(sock_fd, &msg, 0);
48
49 /* Read message from kernel */
50 memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
51 recvmsg(sock_fd, &msg, 0);
52 printf(" Received message payload: %s\n", NLMSG_DATA(nlh));
53
54 /* Close Netlink Socket */
55 close(sock_fd);
56
57 return 0;
58 }
Makefile:
1 obj-m = netlink_k.o
2 KVERSION = $(shell uname -r)
3 all:
4 make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
5 gcc netlink_u.c -o netlink_u
6 clean:
7 make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean 回复Godbach
我的实际调用语句如下,倒数第2个参数是NULL
nl_sk = netlink_kernel_creat ...
jiufei19 发表于 2010-06-01 14:45 http://linux.chinaunix.net/bbs/images/common/back.gif
还有警告吗,警告信息是什么,贴出来。
页:
[1]
2