- 论坛徽章:
- 1
|
主要的目的是用户态发送消息给内核,内核回复消息给用户态。
我内核尝试了用2种方式回复。
一种是正常的处理,另一种是用kernel_thread一个线程,然后这个线程处理。
前一种用户态能正常收到,后一种用户态收不到数据,不知道问题在哪里。
- 用户态程序:
- int main()
- {
-
- struct sockaddr_nl src_addr;
- s32 ret;
- //我用自己的结构以体
- struct struReq_s
- {
- int pid; //存放当前进程的pid,内核回复消息的时候需要
- int data_len;
- char data[0];
- };
- u8 buf[1024] = {0};//存放内核传回的数据
- struct struReq_s *struReq = NULL;
- netlink_socket = socket(AF_NETLINK, SOCK_RAW, NL_ADX);
- if(netlink_socket < 0)
- {
- return -1;
- }
- memset(&src_addr, 0, sizeof(src_addr));
- src_addr.nl_family = AF_NETLINK;
- src_addr.nl_pid = getpid();
- src_addr.nl_groups = 1;
-
- ret = bind(netlink_socket, (struct sockaddr *)&src_addr, sizeof(src_addr));
- if(ret < 0)
- {
- return -1;
- }
- struReq = malloc(sizeof( struct struReq_s) + 10);
- if(struReq == NULL)
- {
- printf("malloc fail\n");
- return 0;
- }
- memset(struReq, 0, sizeof(struct struReq_s) + 10);
- struReq->pid = getpid();
- struReq->data_len = 10;
- memcpy(struReq->data,"nihao",strlen("nihao"));
-
- memset(&src_addr, 0, sizeof(src_addr));
- src_addr.nl_family = AF_NETLINK;
- src_addr.nl_pid = 0;
- src_addr.nl_groups = 0;
-
- // 发送消息给内核
- if(sendto(netlink_socket, struReq, struReq->data_len + sizeof(struct struReq_s), 0,
- (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0)
- {
- return -1;
- }
-
- printf("user recv\n");
- /*阻塞的读*/
- recv(netlink_socket,buf,1024,0);
- printf("recv from kernel len : %d\n",((struct struReq_s *)buf)->data_len);
- printf("recv from kernel data: %s\n",((struct struReq_s *)buf)->data);
-
- free(struReq);
- return 0;
复制代码 在内核中我用2种方法回复,但是其中一个不行。
netlinkfd = netlink_kernel_create(&init_vrf, NL_ADX, 0, kernel_receive, NULL, THIS_MODULE);
可行的方法如下:
- void kernel_receive(struct sk_buff *skb)
- {
- printk("#########recv###########\n");
- process_message_thread(skb);
- printk("#########leave###########\n");
- }
- int process_message_thread(void *arg)
- {
- struct sk_buff *skb = (struct sk_buff *)(arg);
-
- struct struReq_s *msg = (struct struReq_s *) skb->data;
-
- /*打印出用户态传来的数据*/
- printk("kernel recv data:%s\n",msg->data);
- printk("kernel recv pid :%d\n",msg->pid);
- /*构造回复的数据*/
- struct struReq_s *needtosend = kmalloc(sizeof(struct struReq_s) + strlen("niyehao"),GFP_KERNEL);
- needtosend->data_len = strlen("niyehao");
- memcpy(needtosend->data,"niyehao", needtosend->data_len);
- /*构造回复用的skb*/
- skb = alloc_skb(sizeof(struct struReq_s) + strlen("niyehao"), GFP_ATOMIC);
- skb_put(skb,sizeof(struct struReq_s) + strlen("niyehao"));
- memcpy(skb->data,needtosend,sizeof(struct struReq_s) + strlen("niyehao"));
-
- /*发出去*/
- netlink_unicast(netlinkfd, skb, msg->pid, MSG_DONTWAIT);
-
- printk("kernel send over\n");
- kfree(needtosend);
- return 0;
- }
- 这个方法用户态recv的时候能收到数据,并且打印出来。
复制代码 但是这种方法不行:- void kernel_receive(struct sk_buff *skb)
- {
- printk("#########recv###########\n");
- kernel_thread(process_message_thread, skb, CLONE_KERNEL);
- printk("#########leave###########\n");
- }
复制代码 这个方法不行,用户态一直阻塞的在recv。
不知道哪位能帮兄弟解决一下疑惑 |
|