- 論壇徽章:
- 1
|
主要的目的是用戶態(tài)發(fā)送消息給內(nèi)核,內(nèi)核回復消息給用戶態(tài)。
我內(nèi)核嘗試了用2種方式回復。
一種是正常的處理,另一種是用kernel_thread一個線程,然后這個線程處理。
前一種用戶態(tài)能正常收到,后一種用戶態(tài)收不到數(shù)據(jù),不知道問題在哪里。
- 用戶態(tài)程序:
- int main()
- {
-
- struct sockaddr_nl src_addr;
- s32 ret;
- //我用自己的結構以體
- struct struReq_s
- {
- int pid; //存放當前進程的pid,內(nèi)核回復消息的時候需要
- int data_len;
- char data[0];
- };
- u8 buf[1024] = {0};//存放內(nèi)核傳回的數(shù)據(jù)
- 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;
-
- // 發(fā)送消息給內(nèi)核
- 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;
復制代碼 在內(nèi)核中我用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;
-
- /*打印出用戶態(tài)傳來的數(shù)據(jù)*/
- printk("kernel recv data:%s\n",msg->data);
- printk("kernel recv pid :%d\n",msg->pid);
- /*構造回復的數(shù)據(jù)*/
- 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"));
-
- /*發(fā)出去*/
- netlink_unicast(netlinkfd, skb, msg->pid, MSG_DONTWAIT);
-
- printk("kernel send over\n");
- kfree(needtosend);
- return 0;
- }
- 這個方法用戶態(tài)recv的時候能收到數(shù)據(jù),并且打印出來。
復制代碼 但是這種方法不行:- void kernel_receive(struct sk_buff *skb)
- {
- printk("#########recv###########\n");
- kernel_thread(process_message_thread, skb, CLONE_KERNEL);
- printk("#########leave###########\n");
- }
復制代碼 這個方法不行,用戶態(tài)一直阻塞的在recv。
不知道哪位能幫兄弟解決一下疑惑 |
|