/* Kernel AODV v2.1 National Institute of Standards and Technology Luke Klein-Berndt ----------------------------------------------------- Version 2.1 new features: * Much more stable! * Added locks around important areas * Multihop Internet gatewaying now works * Multicast hack added * Many bug fixes! ----------------------------------------------------- Originally based upon MadHoc code. I am not sure how much of it is left anymore, but MadHoc proved to be a great starting point. MadHoc was written by - Fredrik Lilieblad, Oskar Mattsson, Petra Nylund, Dan Ouchterlony and Anders Roxenhag Mail: mad-hoc@flyinglinux.net This software is Open Source under the GNU General Public Licence. */ #include "packet_out.h" /**************************************************** packet_out ---------------------------------------------------- All packets going out of the computer get intercepted by netfilter and passed to this function. ****************************************************/ extern struct route_table_entry *g_my_entry; extern u_int32_t g_my_ip; extern u_int32_t g_broadcast_ip; extern struct nf_hook_ops output_filter; #ifdef AODV_MULTICAST static u_int16_t temp_id=0; #endif /**************************************************** output_handler ---------------------------------------------------- Looks at all the packets leaving the computer ****************************************************/ unsigned int output_handler( unsigned int hooknum,struct sk_buff **skb,const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct iphdr *ip; struct route_table_entry *tmp_route; struct net_device *dev; // get some useful pointers ip = (*skb)->nh.iph; dev = (*skb)->dev; #ifdef AODV_MULTICAST if(hooknum==NF_IP_LOCAL_OUT) { if ( (multicast_test(ip->daddr)) && (ip->id==0) && (ip->ttl!=0)) { temp_id++; ip->id=htons(temp_id); ip->check = 0; ip->check = ip_fast_csum((unsigned char *) ip, ip->ihl); } } #endif #ifdef AODV_MULTICAST if (multicast_test(ip->daddr) || (ip->daddr==g_broadcast_ip) ) #else if (ip->daddr==g_broadcast_ip) #endif { monitor.bytes=(*skb)->len + monitor.bytes; monitor.packets++; return NF_ACCEPT; } //Try to get a route to the destination tmp_route=find_route_table_entry(ip->daddr); #ifdef AODV_GATEWAY if (adhoc_subnet_test(ip->daddr) &&( (tmp_route==NULL) || !(tmp_route->route_valid))) #else if ( (tmp_route==NULL) || !(tmp_route->route_valid)) #endif { printk("Generating a RREQ for: %s\n",inet_ntoa(ip->daddr)); gen_rreq(g_my_ip,ip->daddr); return NF_QUEUE; } if ((tmp_route!=NULL) && (tmp_route->route_valid)) //Found after an LONG search by Jon Anderson tmp_route->lifetime = MAX(tmp_route->lifetime,getcurrtime() + ACTIVE_ROUTE_TIMEOUT); monitor.bytes=(*skb)->len + monitor.bytes; monitor.packets++; return NF_ACCEPT; }