亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1584 | 回復: 1
打印 上一主題 下一主題

[網(wǎng)絡子系統(tǒng)] 剛學netlink,第一次寫netlink程序,有些疑問 [復制鏈接]

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2014-09-26 16:41 |只看該作者 |倒序瀏覽
主要的目的是用戶態(tài)發(fā)送消息給內(nèi)核,內(nèi)核回復消息給用戶態(tài)。
我內(nèi)核嘗試了用2種方式回復。
一種是正常的處理,另一種是用kernel_thread一個線程,然后這個線程處理。
前一種用戶態(tài)能正常收到,后一種用戶態(tài)收不到數(shù)據(jù),不知道問題在哪里。

  1. 用戶態(tài)程序:
  2. int main()
  3. {
  4.        
  5.     struct sockaddr_nl src_addr;
  6.     s32 ret;

  7.    //我用自己的結構以體
  8.     struct struReq_s
  9.         {
  10.                 int pid;         //存放當前進程的pid,內(nèi)核回復消息的時候需要
  11.                 int data_len;
  12.                 char data[0];
  13.         };

  14.    u8 buf[1024] = {0};//存放內(nèi)核傳回的數(shù)據(jù)

  15.     struct struReq_s *struReq = NULL;
  16.     netlink_socket = socket(AF_NETLINK, SOCK_RAW, NL_ADX);
  17.     if(netlink_socket < 0)
  18.     {
  19.         return -1;
  20.     }

  21.     memset(&src_addr, 0, sizeof(src_addr));
  22.     src_addr.nl_family = AF_NETLINK;
  23.     src_addr.nl_pid = getpid();
  24.     src_addr.nl_groups = 1;
  25.                
  26.     ret = bind(netlink_socket, (struct sockaddr *)&src_addr, sizeof(src_addr));
  27.     if(ret < 0)
  28.     {
  29.         return -1;
  30.     }


  31.         struReq = malloc(sizeof( struct struReq_s) + 10);
  32.         if(struReq == NULL)
  33.         {
  34.                 printf("malloc fail\n");
  35.                 return 0;
  36.         }
  37.         memset(struReq, 0, sizeof(struct struReq_s) +  10);

  38.         struReq->pid = getpid();
  39.         struReq->data_len  = 10;
  40.         memcpy(struReq->data,"nihao",strlen("nihao"));
  41.        
  42.         memset(&src_addr, 0, sizeof(src_addr));       
  43.         src_addr.nl_family = AF_NETLINK;       
  44.         src_addr.nl_pid = 0;       
  45.         src_addr.nl_groups = 0;
  46.    
  47.             // 發(fā)送消息給內(nèi)核
  48.         if(sendto(netlink_socket, struReq, struReq->data_len + sizeof(struct struReq_s), 0,               
  49.                 (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0)       
  50.         {
  51.                 return -1;         
  52.         }
  53.        
  54.         printf("user recv\n");
  55.         /*阻塞的讀*/
  56.         recv(netlink_socket,buf,1024,0);
  57.         printf("recv from kernel len : %d\n",((struct struReq_s *)buf)->data_len);
  58.         printf("recv from kernel data: %s\n",((struct struReq_s *)buf)->data);
  59.        
  60.         free(struReq);
  61.         return 0;
復制代碼
在內(nèi)核中我用2種方法回復,但是其中一個不行。
netlinkfd = netlink_kernel_create(&init_vrf, NL_ADX, 0, kernel_receive, NULL, THIS_MODULE);

可行的方法如下:

  1. void kernel_receive(struct sk_buff *skb)
  2. {
  3.         printk("#########recv###########\n");
  4.         process_message_thread(skb);
  5.         printk("#########leave###########\n");
  6. }
  7. int process_message_thread(void *arg)
  8. {
  9.         struct sk_buff *skb = (struct sk_buff *)(arg);
  10.        
  11.         struct struReq_s  *msg = (struct struReq_s *) skb->data;
  12.             
  13.             /*打印出用戶態(tài)傳來的數(shù)據(jù)*/
  14.         printk("kernel recv data:%s\n",msg->data);
  15.         printk("kernel recv pid :%d\n",msg->pid);

  16.              /*構造回復的數(shù)據(jù)*/
  17.         struct struReq_s *needtosend = kmalloc(sizeof(struct struReq_s) + strlen("niyehao"),GFP_KERNEL);
  18.         needtosend->data_len = strlen("niyehao");
  19.         memcpy(needtosend->data,"niyehao", needtosend->data_len);

  20.              /*構造回復用的skb*/
  21.         skb = alloc_skb(sizeof(struct struReq_s) + strlen("niyehao"), GFP_ATOMIC);
  22.         skb_put(skb,sizeof(struct struReq_s) + strlen("niyehao"));
  23.         memcpy(skb->data,needtosend,sizeof(struct struReq_s) + strlen("niyehao"));
  24.             
  25.              /*發(fā)出去*/
  26.         netlink_unicast(netlinkfd, skb, msg->pid, MSG_DONTWAIT);
  27.        
  28.         printk("kernel send over\n");
  29.              kfree(needtosend);
  30.         return 0;
  31. }
  32. 這個方法用戶態(tài)recv的時候能收到數(shù)據(jù),并且打印出來。
復制代碼
但是這種方法不行:
  1. void kernel_receive(struct sk_buff *skb)
  2. {
  3.         printk("#########recv###########\n");
  4.         kernel_thread(process_message_thread, skb, CLONE_KERNEL);
  5.         printk("#########leave###########\n");
  6. }
復制代碼
這個方法不行,用戶態(tài)一直阻塞的在recv。
不知道哪位能幫兄弟解決一下疑惑

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
2 [報告]
發(fā)表于 2014-09-28 14:08 |只看該作者
打了調(diào)試信息嚇我一跳:
在用kernel_thread的情況下,我新alloc_skb的data指針指向的地址,和入?yún)⑴f的skbdata指向的地址是一樣的。。

所以可否理解:
A線程創(chuàng)建B線程,A線程的skb當做B線程的入?yún),A線程skb的data指向的緩沖區(qū)被釋放,所以B線程alloc_skb的skb指向的data就用之前的緩沖區(qū)了。

您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP