在內核態將本地網絡接口加入多播組

    咱們能夠在用戶態經過socket接口,將一個本地網絡接口加入某個多播組,一般是調用setsockopt,並使用IP_ADD_MEMBERSHIP參數,如:

..........
imr.imr_multiaddr.s_addr = netAddr.s_addr;
  imr.imr_interface.s_addr = interfaceAddr.s_addr;
  setsockopt(netPath->eventSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq);
.......... (此代碼能夠工做,經測試能夠接收發往多播組的數據)

但是若是在本身的一個內核模塊裏,如何讓本地網絡接口加入某個多播組呢,我本身寫了一個內核模塊,但願在模塊加載的時候,使本地網絡接口加入一個組播地址(IEEE1588的多播地址 - 224.0.1.129),但是失敗了(已經成功,實際上是由於我對報文解析有誤,誤認爲沒有收到),代碼片斷以下: 網絡

 

  
  
  
  
  1. /* initialize a kernel socket which used to control eth */ 
  2. sock_create_kern(PF_INET, SOCK_DGRAM, 0, &privdata->sock);  
  3.  
  4. strcpy(privdata->ifr.ifr_ifrn.ifrn_name, IF_NAME);  
  5.  
  6. kernel_sock_ioctl(privdata->sock, SIOCSIFNAME, (unsigned long) &privdata->ifr);  
  7. kernel_sock_ioctl(privdata->sock, SIOCGIFADDR, (unsigned long) &privdata->ifr);  
  8.  
  9. ieee1588_ntoa(&privdata->ifr.ifr_ifru.ifru_addr, local_ipaddr);  
  10. printk("Local IP Addr: %s\n", local_ipaddr);  
  11. printk("Multicast IP Addr: %s\n", DEFAULT_PTP_DOMAIN_ADDRESS);  
  12.  
  13. imr.imr_multiaddr.s_addr = in_aton(DEFAULT_PTP_DOMAIN_ADDRESS);  
  14. imr.imr_interface.s_addr = in_aton(local_ipaddr);  
  15.  
  16. ret = kernel_setsockopt(privdata->sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &imr.imr_interface.s_addr, sizeof(struct in_addr));  
  17. if (ret) {  
  18.         printk("set Multicast option failed.\n";  
  19. }  
  20.  
  21. ret = kernel_setsockopt(privdata->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq));  
  22. if (ret) {  
  23.         printk("set Multicast option failed.\n";  
  24. }  

 

    雖然kernel_setsockopt沒有返回錯誤(返回0),可是本地網絡接口eth0仍然沒法收到發送給這個多播地址的網絡數據(只能收單播)其實能夠,我判斷失誤

   曾經考慮過將網卡初始化爲混雜模式,去收多播數據,可那不是正確的作法,太佔CPU資源,正確的作法應該是加入多播組

   請你們一塊兒思考一下,怎樣才能實如今內核模塊裏,將本地網絡接口(如eth0)加入某個多播組呢,有沒有其它更好的方法去接收多播數據呢(除了混雜模式,由於我並不但願作一個嗅探器)
 socket

相關文章
相關標籤/搜索