- 论坛徽章:
- 0
|
本帖最后由 newand 于 2012-11-23 21:58 编辑
利用netfilter在NF_IP6_PRE_ROUTING挂载点对经过的指定组播报文报头做更改。
现在的问题是,更改报头之后发送的组播报文接收端却接收不到,除非卸载此模块。
所以我考虑是不是检验的问题,但IPV6报文不需要检验,MAC层的头部也没有校验,只剩UDP的校验。
代码如下:- /*
- * this programe is working as plugin of netfilter which will pin a timestamp to
- * the destination header of ipv6 packet every x seconds when the packet is
- * the object multicast packet.
- */
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv6.h>
- #include <linux/netfilter_ipv6/ip6_tables.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/kernel.h>
- #include <linux/inet.h>
- #include <linux/ip.h>
- #include <linux/udp.h>
- #include <net/checksum.h>
- #include <net/udp.h>
- #include <net/ipv6.h>
- #include <linux/time.h>
- #define PRINT(fmt,args...) printk("Marker: " fmt, ##args)
- /* IP6 Hooks */
- /* After promisc drops, checksum checks. */
- #define NF_IP6_PRE_ROUTING 0
- /* If the packet is destined for this box. */
- #define NF_IP6_LOCAL_IN 1
- /* If the packet is destined for another interface. */
- #define NF_IP6_FORWARD 2
- /* Packets coming from a local process. */
- #define NF_IP6_LOCAL_OUT 3
- /* Packets about to hit the wire. */
- #define NF_IP6_POST_ROUTING 4
- /*test begin*/
- /*原本打算使用skb_copy来拷贝一个sk_buff,然后再修改其中的某一项,最后kfree_skb原来的
- 但是不能free的总是出错,于是创新的,直接在原来的sk_buff的ip报头进行修改,结果却是接收端不能收到报文
- */
- struct sk_buff *
- ip6_encapsulate_pkt_t(struct sk_buff *skb)
- {
- struct sk_buff *new_skb, *temp_skb;
- struct ipv6hdr * ipv6h;
- struct udphdr *udph;
- //copy from the *skb to new_skb
- /*new_skb = skb_copy(skb, GFP_ATOMIC);
- if(new_skb == NULL)
- {
- PRINT("Allocate new sk_buffer error!\n");
- //kfree_skb(skb);
- return NULL;
- }*/
- udph = udp_hdr(skb);
- ipv6h->nexthdr = 0x60;//set next header as 60 which means next destination header.
- udph->check = csum_ipv6_magic(&ipv6h->saddr,&ipv6h->daddr, udplen,IPPROTO_UDP, csum_partial((char*)udph,udplen,0));
- printk(" skb sum %u,CheckSum = %u\n",skb->ip_summed,udph->check);
-
- //kfree_skb(skb);
- // skb = new_skb;//skb pointer to new_skb
-
- return skb;
- }
- /*test end*/
- /*Hook which will call the encapsulate func when condition satisfied
- *condition1: IPv6 Multicast packets
- *condition2: every 20ms
- */
- static unsigned int
- ip6_multi_modify(unsigned int hooknum,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff*))
- {
- struct sk_buff *sk = skb;
- struct ipv6hdr *ip6_hdr = ipv6_hdr(skb);//header
- if(ip6_hdr->version == 6)
- {
- struct in6_addr destip = ip6_hdr->daddr;//destination ip
-
- if(destip.s6_addr[0] == 0xff && destip.s6_addr[1] == 0x15)
- {
- if(skb_tailroom(sk) >= 40)
- {
- //expand
- PRINT("tailroom is enough\n");
- }
- else
- {
- //modify
- PRINT("not enough\n");
- }
- //print before change
- PRINT("before change %x", ip6_hdr->nexthdr);
- skb = ip6_encapsulate_pkt_t(skb);
- if(skb == NULL)
- {
- PRINT("Allocate new sk_buffer error!\n");
- return NF_STOLEN;
- }
- ip6_hdr= ipv6_hdr(skb);
- PRINT("after change %x \n", ip6_hdr->nexthdr);
- }
- }
- return NF_ACCEPT;
- }
- /*Initialize the hook*/
- static struct nf_hook_ops nf_out_modify =
- {
- .hook = ip6_multi_modify,
- .hooknum = NF_IP6_PRE_ROUTING,//Check all the forwarded packets
- .pf = PF_INET6,
- .priority = NF_IP6_PRI_FIRST,
- };
- /*Initialize the module*/
- static int __init ip6_multi_init(void)
- {
- int ret;
- ret = nf_register_hook(&nf_out_modify);
- PRINT("IPV6 multicast packet modify module init.\n");
- return 0; //success
- }
- /*Clear the module*/
- static void __exit ip6_multi_exit(void)
- {
- nf_unregister_hook(&nf_out_modify);
- PRINT("IPV6 multicast packet modify module exit.\n");
- }
- module_init(ip6_multi_init);
- module_exit(ip6_multi_exit);
复制代码 请各位帮忙看下。 |
|