コード例 #1
0
ファイル: kaodv-netlink.c プロジェクト: azhgul/AODV-1
static int kaodv_netlink_receive_peer(unsigned char type, void *msg,
				      unsigned int len)
{
	int ret = 0;
	struct kaodv_rt_msg *m;
	struct kaodv_conf_msg *cm;
	struct expl_entry e;

	KAODV_DEBUG("Received msg: %s", kaodv_msg_type_to_str(type));

	switch (type) {
	case KAODVM_ADDROUTE:
		if (len < sizeof(struct kaodv_rt_msg))
			return -EINVAL;

		m = (struct kaodv_rt_msg *)msg;

		ret = kaodv_expl_get(m->dst, &e);

		if (ret > 0) {
			ret = kaodv_expl_update(m->dst, m->nhop, m->time,
						m->flags, m->ifindex);
		} else {
			ret = kaodv_expl_add(m->dst, m->nhop, m->time,
					     m->flags, m->ifindex);
		}
		printk(KERN_DEBUG "kaodv: KAODVM_ADDROUTE!\n");
		kaodv_queue_set_verdict(KAODV_QUEUE_SEND, m->dst);
		break;
	case KAODVM_DELROUTE:
		if (len < sizeof(struct kaodv_rt_msg))
			return -EINVAL;

		m = (struct kaodv_rt_msg *)msg;
		kaodv_expl_del(m->dst);
		kaodv_queue_set_verdict(KAODV_QUEUE_DROP, m->dst);
		break;
	case KAODVM_NOROUTE_FOUND:
		if (len < sizeof(struct kaodv_rt_msg))
			return -EINVAL;

		m = (struct kaodv_rt_msg *)msg;
		KAODV_DEBUG("No route found for %s", print_ip(m->dst));
		kaodv_queue_set_verdict(KAODV_QUEUE_DROP, m->dst);
		break;
	case KAODVM_CONFIG:
		if (len < sizeof(struct kaodv_conf_msg))
			return -EINVAL;

		cm = (struct kaodv_conf_msg *)msg;
		active_route_timeout = cm->active_route_timeout;
		qual_th = cm->qual_th;
		is_gateway = cm->is_gateway;
		break;
	default:
		printk("kaodv-netlink: Unknown message type\n");
		ret = -EINVAL;
	}
	return ret;
}
コード例 #2
0
ファイル: kaodv-mod.c プロジェクト: wujingbang/aodv-uu
void kaodv_update_route_timeouts(int hooknum, const struct net_device *dev,
				 struct iphdr *iph)
{
	struct expl_entry e;
	struct in_addr bcaddr;
	int res;

	bcaddr.s_addr = 0; /* Stop compiler from complaining about
			    * uninitialized bcaddr */

	res = if_info_from_ifindex(NULL, &bcaddr, dev->ifindex);

	if (res < 0)
		return;

	if (hooknum == NF_INET_PRE_ROUTING)
		kaodv_netlink_send_rt_update_msg(PKT_INBOUND, iph->saddr,
						 iph->daddr, dev->ifindex);
	else if (iph->daddr != INADDR_BROADCAST && iph->daddr != bcaddr.s_addr)
		kaodv_netlink_send_rt_update_msg(PKT_OUTBOUND, iph->saddr,
						 iph->daddr, dev->ifindex);

	/* First update forward route and next hop */
	if (kaodv_expl_get(iph->daddr, &e)) {

		kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
				  e.flags, dev->ifindex);

		if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e))
			kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
					  e.flags, dev->ifindex);
	}
	/* Update reverse route */
	if (kaodv_expl_get(iph->saddr, &e)) {

		kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
				  e.flags, dev->ifindex);

		if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e))
			kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
					  e.flags, dev->ifindex);
	}
}
コード例 #3
0
static void
kaodv_update_route_timeouts(int hooknum, const struct net_device *dev,
			    struct iphdr *iph)
{
	struct expl_entry e;
	struct netdev_info *netdi;

	netdi = netdev_info_from_ifindex(dev->ifindex);

	if (!netdi)
		return;

	if (hooknum == NF_IP_PRE_ROUTING)
		kaodv_netlink_send_rt_update_msg(PKT_INBOUND, iph->saddr,
						 iph->daddr, dev->ifindex);
	else if (iph->daddr != INADDR_BROADCAST && iph->daddr != netdi->bc_addr)
		kaodv_netlink_send_rt_update_msg(PKT_OUTBOUND, iph->saddr,
						 iph->daddr, dev->ifindex);

	/* First update forward route and next hop */
	if (kaodv_expl_get(iph->daddr, &e)) {

		kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
				  e.flags);

		if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e))
			kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
					  e.flags);
	}
	/* Update reverse route */
	if (kaodv_expl_get(iph->saddr, &e)) {

		kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
				  e.flags);

		if (e.nhop != e.daddr && kaodv_expl_get(e.nhop, &e))
			kaodv_expl_update(e.daddr, e.nhop, ACTIVE_ROUTE_TIMEOUT,
					  e.flags);

	}
}
コード例 #4
0
ファイル: kaodv-mod.c プロジェクト: wujingbang/aodv-uu
static unsigned int kaodv_hook(unsigned int hooknum,
			       struct sk_buff *skb,
			       const struct net_device *in,
			       const struct net_device *out,
			       int (*okfn) (struct sk_buff *))
{
	struct iphdr *iph = SKB_NETWORK_HDR_IPH(skb);
	struct expl_entry e;
	struct in_addr ifaddr, bcaddr;
	int res = 0;

	memset(&ifaddr, 0, sizeof(struct in_addr));
	memset(&bcaddr, 0, sizeof(struct in_addr));

	/* We are only interested in IP packets */
	if (iph == NULL)
		return NF_ACCEPT;
	
	/* We want AODV control messages to go through directly to the
	 * AODV socket.... */
	if (iph && iph->protocol == IPPROTO_UDP) {
		struct udphdr *udph;

		udph = (struct udphdr *)((char *)iph + (iph->ihl << 2));

		if (ntohs(udph->dest) == AODV_PORT ||
		    ntohs(udph->source) == AODV_PORT) {

#ifdef CONFIG_QUAL_THRESHOLD
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
			qual = (int)(skb)->__unused;
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
			qual = (skb)->iwq.qual;
#endif
			if (qual_th && hooknum == NF_INET_PRE_ROUTING) {

				if (qual && qual < qual_th) {
					pkts_dropped++;
					return NF_DROP;
				}
			}
#endif /* CONFIG_QUAL_THRESHOLD */
			if (hooknum == NF_INET_PRE_ROUTING && in)
				kaodv_update_route_timeouts(hooknum, in, iph);

			return NF_ACCEPT;
		}
	}
	
	if (hooknum == NF_INET_PRE_ROUTING)
		res = if_info_from_ifindex(&ifaddr, &bcaddr, in->ifindex);
	else 
		res = if_info_from_ifindex(&ifaddr, &bcaddr, out->ifindex);
	
	if (res < 0)
		return NF_ACCEPT;
	

	/* Ignore broadcast and multicast packets */
	if (iph->daddr == INADDR_BROADCAST ||
	    IN_MULTICAST(ntohl(iph->daddr)) || 
	    iph->daddr == bcaddr.s_addr)
		return NF_ACCEPT;

       
	/* Check which hook the packet is on... */
	switch (hooknum) {
	case NF_INET_PRE_ROUTING:
		kaodv_update_route_timeouts(hooknum, in, iph);
		
		/* If we are a gateway maybe we need to decapsulate? */
		if (is_gateway && iph->protocol == IPPROTO_MIPE &&
		    iph->daddr == ifaddr.s_addr) {
			ip_pkt_decapsulate(skb);
			iph = SKB_NETWORK_HDR_IPH(skb);
			return NF_ACCEPT;
		}
		/* Ignore packets generated locally or that are for this
		 * node. */
		if (iph->saddr == ifaddr.s_addr ||
		    iph->daddr == ifaddr.s_addr) {
			return NF_ACCEPT;
		}
		/* Check for unsolicited data packets */
		else if (!kaodv_expl_get(iph->daddr, &e)) {
			kaodv_netlink_send_rerr_msg(PKT_INBOUND, iph->saddr,
						    iph->daddr, in->ifindex);
			return NF_DROP;

		}
		/* Check if we should repair the route */
		else if (e.flags & KAODV_RT_REPAIR) {

			kaodv_netlink_send_rt_msg(KAODVM_REPAIR, iph->saddr,
						  iph->daddr);

			kaodv_queue_enqueue_packet(skb, okfn);

			return NF_STOLEN;
		}
		break;
	case NF_INET_LOCAL_OUT:

		if (!kaodv_expl_get(iph->daddr, &e) ||
		    (e.flags & KAODV_RT_REPAIR)) {

			if (!kaodv_queue_find(iph->daddr))
				kaodv_netlink_send_rt_msg(KAODVM_ROUTE_REQ,
							  0,
							  iph->daddr);
			
			kaodv_queue_enqueue_packet(skb, okfn);
			
			return NF_STOLEN;

		} else if (e.flags & KAODV_RT_GW_ENCAP) {
			/* Make sure that also the virtual Internet
			 * dest entry is refreshed */
			kaodv_update_route_timeouts(hooknum, out, iph);
			
			skb = ip_pkt_encapsulate(skb, e.nhop);
			
			if (!skb)
				return NF_STOLEN;

			ip_route_me_harder(skb, RTN_LOCAL);
		}
		break;
	case NF_INET_POST_ROUTING:
		kaodv_update_route_timeouts(hooknum, out, iph);
	}
	return NF_ACCEPT;
}
コード例 #5
0
ファイル: kaodv-mod.c プロジェクト: azhgul/AODV-1
static unsigned int kaodv_hook(unsigned int hooknum,
			       struct sk_buff *skb,
			       const struct net_device *in,
			       const struct net_device *out,
			       int (*okfn) (struct sk_buff *))
{
	struct iphdr *iph = SKB_NETWORK_HDR_IPH(skb);
	struct expl_entry e;
	struct in_addr ifaddr, bcaddr;
	int res = 0;

	memset(&ifaddr, 0, sizeof(struct in_addr));
	memset(&bcaddr, 0, sizeof(struct in_addr));

	/* We are only interested in IP packets */
	if (iph == NULL)
		return NF_ACCEPT;
		
	/* Hook FORWARD only takecare of gateway packets */
	if(hooknum == NF_INET_FORWARD)
	{
		//we are only handle forwarded packets in gateway mode
		if(!is_gateway)
			return NF_ACCEPT;
		//we don't process packets from binded interface
		if(!in || if_info_from_ifindex(NULL, NULL, in->ifindex) == 0)
			return NF_ACCEPT;
	}
	
	/* We want AODV control messages to go through directly to the
	 * AODV socket.... */
	if (iph && iph->protocol == IPPROTO_UDP) {
		struct udphdr *udph;

		udph = (struct udphdr *)((char *)iph + (iph->ihl << 2));

		if (ntohs(udph->dest) == AODV_PORT ||
		    ntohs(udph->source) == AODV_PORT) {

#ifdef CONFIG_QUAL_THRESHOLD
			qual = (skb)->iwq.qual;
			if (qual_th && hooknum == NF_INET_PRE_ROUTING) {

				if (qual && qual < qual_th) {
					pkts_dropped++;
					return NF_DROP;
				}
			}
#endif /* CONFIG_QUAL_THRESHOLD */
			if (hooknum == NF_INET_PRE_ROUTING && in)
				kaodv_update_route_timeouts(hooknum, in, iph);
			
			return NF_ACCEPT;
		}
	}
	
	if (hooknum == NF_INET_PRE_ROUTING)
	{
		res = if_info_from_ifindex(&ifaddr, &bcaddr, in->ifindex);
		printk(KERN_DEBUG "kaodv: in->ifindex %d, res %d.\n", in->ifindex, res);
	}
	else 
	{
		res = if_info_from_ifindex(&ifaddr, &bcaddr, out->ifindex);
		printk(KERN_DEBUG "kaodv: out->ifindex %d, res %d.\n", out->ifindex, res);
	}
	
	if (res < 0)
	{
		printk(KERN_DEBUG "kaodv: No information!\n");
		return NF_ACCEPT;
	}

	/* Ignore broadcast and multicast packets */
	if (iph->daddr == INADDR_BROADCAST ||
	    IN_MULTICAST(ntohl(iph->daddr)) || 
	    iph->daddr == bcaddr.s_addr)
	{
		printk(KERN_DEBUG "kaodv: Broadcast packet!\n");
		return NF_ACCEPT;
	}
       
	/* Check which hook the packet is on... */
	
	printk(KERN_DEBUG "kaodv: Check which hook the packet is on...\n");
	
	switch (hooknum) {
	case NF_INET_PRE_ROUTING:
	
		printk(KERN_DEBUG "kaodv: NF_INET_PRE_ROUTING\n");
		
		kaodv_update_route_timeouts(hooknum, in, iph);
		
		/* If we are a gateway maybe we need to decapsulate? */
		if (is_gateway && iph->protocol == IPPROTO_MIPE &&
		    iph->daddr == ifaddr.s_addr) {
			ip_pkt_decapsulate(skb);
			printk(KERN_DEBUG "kaodv: successfully returned from ip_pkt_decapsulate!\n");
			iph = SKB_NETWORK_HDR_IPH(skb);
			return NF_ACCEPT;
		}
		/* Ignore packets generated locally or that are for this
		 * node. */
		if (iph->saddr == ifaddr.s_addr ||
		    iph->daddr == ifaddr.s_addr) {
			return NF_ACCEPT;
		}
		/* Check for unsolicited data packets */
		else if (!kaodv_expl_get(iph->daddr, &e)) {
			kaodv_netlink_send_rerr_msg(PKT_INBOUND, iph->saddr,
						    iph->daddr, in->ifindex);
			return NF_DROP;

		}
		/* Check if we should repair the route */
		else if (e.flags & KAODV_RT_REPAIR) {

			kaodv_netlink_send_rt_msg(KAODVM_REPAIR, iph->saddr,
						  iph->daddr);

			kaodv_queue_enqueue_packet(skb, okfn);

			return NF_STOLEN;
		}
		break;
	case NF_INET_FORWARD:
	case NF_INET_LOCAL_OUT:
		printk(KERN_DEBUG "kaodv: NF_INET_LOCAL_OUT\n");
		
		if (!kaodv_expl_get(iph->daddr, &e) ||
		    (e.flags & KAODV_RT_REPAIR)) {

			if (!kaodv_queue_find(iph->daddr))
				kaodv_netlink_send_rt_msg(KAODVM_ROUTE_REQ,
							  0,
							  iph->daddr);
			
			kaodv_queue_enqueue_packet(skb, okfn);
			
			return NF_STOLEN;

		} else if (e.flags & KAODV_RT_GW_ENCAP) {
			/* Make sure that also the virtual Internet
			 * dest entry is refreshed */
			kaodv_update_route_timeouts(hooknum, out, iph);
			
			skb = ip_pkt_encapsulate(skb, e.nhop);
			
			if (!skb)
				return NF_STOLEN;
				
			printk(KERN_DEBUG "kaodv: successfully returned from ip_pkt_encapsulate!\n");
			
			ip_route_me_harder(skb, RTN_LOCAL);
		}
		break;
	case NF_INET_POST_ROUTING:
		printk(KERN_DEBUG "kaodv: NF_INET_POST_ROUTING\n");
		kaodv_update_route_timeouts(hooknum, out, iph);
		break;
	}
	printk(KERN_DEBUG "kaodv: Succesfully returned from NF_HOOK!\n");
	return NF_ACCEPT;
}