- 论坛徽章:
- 0
|
本帖最后由 dolphin1987 于 2012-08-01 16:41 编辑
想做的有两个方面
1. 自己在内核中申请一个skb,然后手工构造多播数据包成功之后,从指定的eth0发送出去,
2. 在pre_routing钩子点注册一个钩子函数,然后截获上面发送的多播数据包。
问解决在三楼。
头都整晕了,请高手指点指点- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/netdevice.h>
- #include <linux/skbuff.h>
- #include <net/sock.h>
- #include <net/route.h>
- #include <net/ip.h>
- #include <net/udp.h>
- #include <linux/ip.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/list.h>
- #include <linux/netdevice.h>
- #include <linux/skbuff.h>
- #include <sync_multicast.h>
- /*
- * date 20120730
- *
- */
- #define SYNC_PORT 0x0727 /*mulitcast port 1831*/
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("c");
- __be32 master_ip = 0xe0000040;/*multicaste addr 224.0.0.64*/
- unsigned char mac_addr[ETH_ALEN]={0x01,0x00,0x5e,0x00,0x00,0x40};
- char eth_name[] = "eth0";
- struct net_device *egress;
- char test[] = "hello,multicast!\n";
- /* need a locker ?*/
- struct slave_ip *slave_ip; /*multicast addr-- backup ip*/
- int is_slave_ip( __be32 dst)
- {
- int ret = 0;
- struct slave_ip *pos;
- if (slave_ip){
- return 0;
- }
- list_for_each_entry(pos,&slave_ip->list,list){
- if(pos->ipaddr == dst){
- ret = 1;
- break;
- }
- }
- return ret;
- }
- int sync_multicast(struct sk_buff *skb)
- {
- struct iphdr *iph;
- struct udphdr *udph;
- struct ethhdr *ethh;
- int total_len,eth_len,ip_len,udp_len,header_len;
- udp_len = sizeof(test) + sizeof(struct udphdr);
- ip_len = eth_len = udp_len + sizeof(struct iphdr);
- total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;
- header_len = total_len - sizeof(test);
- /* reserve all the headers */
- skb_reserve(skb,LL_MAX_HEADER + header_len);
- /* copy the payload to buff */
- skb_copy_to_linear_data(skb,test,sizeof(test));
- skb->len += sizeof(test);
- /* move to udp header*/
- skb_push(skb,sizeof(struct udphdr));
- skb_reset_transport_header(skb);
- udph = udp_hdr(skb);
- udph->source = htons(SYNC_PORT);
- udph->dest = htons(SYNC_PORT);
- udph->len = udp_len;
- udph->check = csum_tcpudp_magic(htonl(master_ip),
- htonl(master_ip),
- udp_len,IPPROTO_UDP,
- csum_partial(udph,udp_len,0));
- if(udph->check == 0)
- udph->check = CSUM_MANGLED_0;
- /* move to ip header*/
- skb_push(skb,sizeof(struct iphdr));
- skb_reset_network_header(skb);
- iph = ip_hdr(skb);
- iph->version = 4;
- iph->ihl = sizeof(struct iphdr)/4;
- iph->tos= 0;
- iph->id = 0;
- iph->frag_off = htons(IP_DF);
- iph->protocol = IPPROTO_UDP;
- iph->ttl = 64;
- iph->check = 0;
- /* XXXXXXXXXXXXXXXXXX*/
- iph->saddr = htonl(master_ip);
- iph->daddr = htonl(master_ip);
- iph->check = ip_fast_csum((unsigned char *)iph,iph->ihl);
- /* move to eth header*/
- ethh = (struct ethhdr *)skb_push(skb,ETH_HLEN);
- skb_reset_mac_header(skb);
- skb->protocol = ethh->h_proto = htons(ETH_P_IP);
- memcpy(ethh->h_source,mac_addr,ETH_ALEN);
- memcpy(ethh->h_dest,mac_addr,ETH_ALEN);
- int i;
- for (i = 0 ; i < 6; i++){
-
- printk(KERN_ALERT "%x \n",ethh->h_dest[i]);
-
- }
- for (i = 0 ; i < 6; i++){
-
- printk(KERN_ALERT "%x \n",ethh->h_source[i]);
-
- }
-
- //printk(KERN_ALERT "%x \n",iph->saddr);
- /* specify outing net device*/
- skb->dev = egress;
- /* directly send the skb from egress*/
- int ret;
- ret = dev_queue_xmit(skb);
- printk(KERN_ALERT "%i \n",ret);
- return 0;
- }
- int sync_send_msg(char *conn)
- {
- struct sk_buff *nskb;
- int total_len,eth_len,ip_len,udp_len,header_len;
- udp_len = sizeof(test) + sizeof(struct udphdr);
- ip_len = eth_len = udp_len + sizeof(struct iphdr);
- total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;
- header_len = total_len - sizeof(test);
- nskb = alloc_skb(LL_MAX_HEADER
- + total_len,GFP_ATOMIC);
- if(!nskb){
- printk(KERN_ALERT "EROR not enough memory!\n");
- return 0;
- }
- sync_multicast(nskb);
- return 0;
- }
- EXPORT_SYMBOL(sync_send_msg);
- int sync_rcv_msg(struct sk_buff *skb)
- {
- printk(KERN_ALERT "recieve a special multicast packet!\n");
- return 0;
- }
- /*
- * the capture hook function
- */
- static unsigned int
- sync_rcv_skb(unsigned int hook,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
- struct iphdr *iph;
- struct udphdr *udph;
-
- iph = ip_hdr(skb);
- udph = (struct udphdr *)((void *)skb->data + ip_hdrlen(skb));
-
- if(hook != NF_INET_PRE_ROUTING)
- return NF_ACCEPT;
- /*the packet must be a multicast packet*/
- if (iph->protocol != IPPROTO_UDP)
- return NF_ACCEPT;
- printk(KERN_ALERT "recieve a UDP packet!\n");
- /*
- * if (!is_slave_ip(ntohl(iph->daddr)))
- return NF_ACCEPT;
- */
-
- if (ntohs(udph->source) != cpu_to_be16(SYNC_PORT) ||
- ntohs(udph->dest) != cpu_to_be16(SYNC_PORT))
- return NF_ACCEPT;
-
- sync_rcv_msg(skb);
- //return NF_DROP;
- return NF_ACCEPT;
- }
- /*
- * this hook capture the multicast packets
- */
- static struct nf_hook_ops pre_capture __read_mostly=
- {
- .hook =sync_rcv_skb,
- .owner =THIS_MODULE,
- .pf =PF_INET,
- .hooknum =NF_INET_PRE_ROUTING,
- .priority =NF_IP_PRI_RAW,
- };
- static int __init sync_multicast_init(void)
- {
- int ret;
- ret = nf_register_hook(&pre_capture);
- if(ret < 0)
- printk(KERN_ALERT "ERROR,registering hook failed\n");
- else
- printk(KERN_ALERT "register success!\n");
- egress = dev_get_by_name(&init_net,eth_name);
- if(egress)
- printk(KERN_ALERT "find specical device\n");
- sync_send_msg( (char* )0);
- return 0;
- }
- static void __exit sync_multicast_exit(void)
- {
- nf_unregister_hook(&pre_capture);
- dev_put(egress);
- printk(KERN_ALERT "Sync_multicate:Goodbye!\n");
- }
- module_init(sync_multicast_init);
- module_exit(sync_multicast_exit);
复制代码 头文件 sync_multicast.h
- #ifndef __SYNC_MULTICAST_H
- #define __SYNC_MULTICAST_H
- struct slave_ip{
- struct list_head list;
- __be32 ipaddr;
- };
- #endif
复制代码 Makefile文件
- EXTRA_CFLAGS += -I$(src)/
- ifneq ($(KERNELRELEASE),)
- obj-m := sync_multicast.o
- else
- KERNELDIR ?= /lib/modules/$(shell uname -r)/build
- PWD := $(shell pwd)
- default:
- $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
- endif
复制代码 |
|