免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3554 | 回复: 4
打印 上一主题 下一主题

[网络子系统] 发送和接收多播数据包问题!好像数据包没有出去!【问题解决】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-07-30 22:21 |只看该作者 |倒序浏览
本帖最后由 dolphin1987 于 2012-08-01 16:41 编辑

想做的有两个方面
1. 自己在内核中申请一个skb,然后手工构造多播数据包成功之后,从指定的eth0发送出去,
2. 在pre_routing钩子点注册一个钩子函数,然后截获上面发送的多播数据包。

问解决在三楼。

头都整晕了,请高手指点指点
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/netdevice.h>
  4. #include <linux/skbuff.h>
  5. #include <net/sock.h>
  6. #include <net/route.h>
  7. #include <net/ip.h>
  8. #include <net/udp.h>
  9. #include <linux/ip.h>
  10. #include <linux/netfilter_ipv4.h>
  11. #include <linux/list.h>
  12. #include <linux/netdevice.h>
  13. #include <linux/skbuff.h>

  14. #include <sync_multicast.h>

  15. /*
  16. * date 20120730
  17. *
  18. */
  19. #define SYNC_PORT 0x0727 /*mulitcast port 1831*/

  20. MODULE_LICENSE("GPL");
  21. MODULE_AUTHOR("c");



  22. __be32 master_ip = 0xe0000040;/*multicaste addr 224.0.0.64*/
  23. unsigned char        mac_addr[ETH_ALEN]={0x01,0x00,0x5e,0x00,0x00,0x40};
  24. char eth_name[] = "eth0";
  25. struct net_device *egress;
  26. char test[] = "hello,multicast!\n";

  27. /* need  a locker ?*/
  28. struct slave_ip *slave_ip; /*multicast addr-- backup ip*/

  29. int is_slave_ip( __be32 dst)
  30. {
  31.         int ret = 0;
  32.         struct slave_ip *pos;
  33.         if (slave_ip){
  34.                 return 0;
  35.         }
  36.         list_for_each_entry(pos,&slave_ip->list,list){
  37.                 if(pos->ipaddr == dst){
  38.                         ret = 1;
  39.                         break;
  40.                 }
  41.         }

  42.         return ret;

  43. }

  44. int sync_multicast(struct sk_buff *skb)
  45. {
  46.         struct iphdr *iph;
  47.         struct udphdr *udph;
  48.         struct ethhdr *ethh;

  49.         int total_len,eth_len,ip_len,udp_len,header_len;


  50.         udp_len = sizeof(test) + sizeof(struct udphdr);
  51.         ip_len = eth_len = udp_len + sizeof(struct iphdr);
  52.         total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;
  53.         header_len = total_len - sizeof(test);
  54. /* reserve all the headers */        
  55.         skb_reserve(skb,LL_MAX_HEADER + header_len);

  56.         /* copy the payload to buff */
  57.         skb_copy_to_linear_data(skb,test,sizeof(test));
  58.         skb->len += sizeof(test);

  59.         /* move to udp header*/
  60.         skb_push(skb,sizeof(struct udphdr));
  61.         skb_reset_transport_header(skb);
  62.         udph = udp_hdr(skb);
  63.         udph->source = htons(SYNC_PORT);
  64.         udph->dest = htons(SYNC_PORT);
  65.         udph->len = udp_len;
  66.         udph->check = csum_tcpudp_magic(htonl(master_ip),
  67.                         htonl(master_ip),
  68.                         udp_len,IPPROTO_UDP,
  69.                         csum_partial(udph,udp_len,0));
  70.         if(udph->check == 0)
  71.                 udph->check = CSUM_MANGLED_0;

  72.         /* move to ip header*/
  73.         skb_push(skb,sizeof(struct iphdr));
  74.         skb_reset_network_header(skb);
  75.         iph = ip_hdr(skb);
  76.         iph->version = 4;
  77.         iph->ihl = sizeof(struct iphdr)/4;
  78.         iph->tos= 0;
  79.         iph->id = 0;
  80.         iph->frag_off = htons(IP_DF);
  81.         iph->protocol =        IPPROTO_UDP;
  82.         iph->ttl = 64;
  83.         iph->check = 0;
  84.         /* XXXXXXXXXXXXXXXXXX*/
  85.         iph->saddr = htonl(master_ip);
  86.         iph->daddr = htonl(master_ip);
  87.         iph->check = ip_fast_csum((unsigned char *)iph,iph->ihl);

  88.         /* move to eth header*/
  89.         ethh = (struct ethhdr *)skb_push(skb,ETH_HLEN);
  90.         skb_reset_mac_header(skb);
  91.         skb->protocol = ethh->h_proto = htons(ETH_P_IP);
  92.         memcpy(ethh->h_source,mac_addr,ETH_ALEN);
  93.         memcpy(ethh->h_dest,mac_addr,ETH_ALEN);

  94.         int i;

  95.         for (i = 0 ; i < 6; i++){
  96.                
  97.                 printk(KERN_ALERT "%x \n",ethh->h_dest[i]);
  98.                
  99.         }
  100.         for (i = 0 ; i < 6; i++){
  101.                
  102.                 printk(KERN_ALERT "%x \n",ethh->h_source[i]);
  103.                
  104.         }
  105.        
  106.         //printk(KERN_ALERT "%x \n",iph->saddr);
  107.         /* specify outing net device*/
  108.         skb->dev = egress;

  109.         /* directly send the skb from egress*/
  110.         int ret;
  111.         ret = dev_queue_xmit(skb);
  112.         printk(KERN_ALERT "%i \n",ret);


  113.         return 0;
  114. }
  115. int sync_send_msg(char *conn)
  116. {
  117.         struct sk_buff *nskb;

  118.         int total_len,eth_len,ip_len,udp_len,header_len;


  119.         udp_len = sizeof(test) + sizeof(struct udphdr);
  120.         ip_len = eth_len = udp_len + sizeof(struct iphdr);
  121.         total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;
  122.         header_len = total_len - sizeof(test);

  123.         nskb = alloc_skb(LL_MAX_HEADER
  124.                         + total_len,GFP_ATOMIC);
  125.         if(!nskb){
  126.                 printk(KERN_ALERT "EROR not enough memory!\n");
  127.                 return 0;
  128.         }
  129.         sync_multicast(nskb);
  130.         return 0;
  131. }
  132. EXPORT_SYMBOL(sync_send_msg);

  133. int sync_rcv_msg(struct sk_buff *skb)
  134. {
  135.         printk(KERN_ALERT "recieve a special multicast packet!\n");
  136.         return 0;
  137. }
  138. /*
  139. * the capture hook function
  140. */
  141. static unsigned int
  142. sync_rcv_skb(unsigned int hook,
  143.                 struct sk_buff *skb,
  144.                 const struct net_device *in,
  145.                 const struct net_device *out,
  146.                 int (*okfn)(struct sk_buff *))
  147. {
  148.         struct iphdr *iph;
  149.         struct udphdr *udph;
  150.        


  151.         iph = ip_hdr(skb);
  152.         udph = (struct udphdr *)((void *)skb->data + ip_hdrlen(skb));

  153.        
  154.         if(hook != NF_INET_PRE_ROUTING)
  155.                 return NF_ACCEPT;
  156.         /*the packet must be a multicast packet*/

  157.         if (iph->protocol != IPPROTO_UDP)
  158.                 return NF_ACCEPT;
  159.         printk(KERN_ALERT "recieve a UDP packet!\n");
  160.         /*
  161.          * if (!is_slave_ip(ntohl(iph->daddr)))
  162.                 return NF_ACCEPT;
  163.                 */
  164.        
  165.         if (ntohs(udph->source) != cpu_to_be16(SYNC_PORT) ||
  166.                         ntohs(udph->dest) != cpu_to_be16(SYNC_PORT))
  167.                 return NF_ACCEPT;
  168.                
  169.         sync_rcv_msg(skb);


  170.         //return NF_DROP;
  171.         return NF_ACCEPT;

  172. }
  173. /*
  174. * this hook capture the multicast packets
  175. */
  176. static struct nf_hook_ops pre_capture __read_mostly=
  177. {
  178.         .hook                =sync_rcv_skb,
  179.         .owner                =THIS_MODULE,
  180.         .pf                        =PF_INET,
  181.         .hooknum        =NF_INET_PRE_ROUTING,
  182.         .priority        =NF_IP_PRI_RAW,
  183. };
  184. static int __init sync_multicast_init(void)
  185. {
  186.         int ret;
  187.         ret = nf_register_hook(&pre_capture);
  188.         if(ret < 0)
  189.                 printk(KERN_ALERT "ERROR,registering hook failed\n");
  190.         else
  191.                 printk(KERN_ALERT "register success!\n");
  192.         egress = dev_get_by_name(&init_net,eth_name);
  193.         if(egress)
  194.                 printk(KERN_ALERT "find specical device\n");

  195.         sync_send_msg( (char* )0);

  196.         return 0;
  197. }
  198. static void __exit sync_multicast_exit(void)
  199. {
  200.         nf_unregister_hook(&pre_capture);
  201.         dev_put(egress);
  202.         printk(KERN_ALERT "Sync_multicate:Goodbye!\n");
  203. }

  204. module_init(sync_multicast_init);
  205. module_exit(sync_multicast_exit);
复制代码
头文件 sync_multicast.h

  1. #ifndef __SYNC_MULTICAST_H
  2. #define __SYNC_MULTICAST_H


  3. struct slave_ip{
  4.         struct list_head list;
  5.         __be32 ipaddr;
  6. };
  7. #endif
复制代码
Makefile文件

  1. EXTRA_CFLAGS += -I$(src)/
  2. ifneq ($(KERNELRELEASE),)
  3.         obj-m := sync_multicast.o
  4. else
  5.         KERNELDIR ?= /lib/modules/$(shell uname -r)/build
  6.         PWD := $(shell pwd)
  7. default:
  8.         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  9. endif
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-07-30 23:54 |只看该作者
回复 1# dolphin1987


    自己来坐沙发哈。

利用tcpdump抓包分析,发送包是成功的,另外,对方也可以接收到数据包,但是数据包没有传到我注册的钩子点。

还在继续找原因,

大家帮忙分析一哈。

论坛徽章:
0
3 [报告]
发表于 2012-08-01 16:46 |只看该作者
回复 1# dolphin1987


    终于找到了问题,这个问题还是得怪自己太粗心了,也要怪wireshark不够智能(呵呵,搭上一个)

问题原因:没有给IP包的tot_len赋值,但是用wireshark抓包分析时,ip数据包长度和tot_len明显不一样,但是还不提示错误。
这样ip包还没有到达我注册的钩子点时,在ip包错误检查环节都已经被drop掉了。

评分

参与人数 1可用积分 +4 收起 理由
Godbach + 4 感谢分享

查看全部评分

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2012-08-03 17:39 |只看该作者
回复 1# dolphin1987
感谢 LZ 分享解决方法 :wink:


   

论坛徽章:
0
5 [报告]
发表于 2012-10-09 20:23 |只看该作者
回复 4# Godbach


    相互帮助,自己的很多问题,也是在cu找到了解决方法和思路。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP