/* 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 "module.h" /*#ifdef ARM #define EXPORT_SYMBOL_ALIAS ( __do_softirq, do_softirq); #endif */ /**************************************************** module ---------------------------------------------------- These are the two functions which are used to start things up and shut things down. ****************************************************/ struct nf_hook_ops input_filter; struct nf_hook_ops output_filter; struct nf_hook_ops forward_filter; struct nf_hook_ops post_routing_filter; struct route_table_entry *g_my_entry; // a pointer to my route entry in the table u_int32_t g_my_ip; // my IP number, set on the command line u_int32_t g_broadcast_ip; // the broadcast address to use. u_int8_t use_lo; //variable for command line options struct flood_id_queue_entry *rreq_id_queue; //entries for our different PROC files static struct proc_dir_entry *aodv_dir, *route_table_proc, *rreq_id_proc, *timer_queue_proc, *monitor_proc, *stats_proc; #ifdef AODV_MULTICAST static struct proc_dir_entry *multicast_id_proc; #endif #ifdef AODV_SIGNAL static struct proc_dir_entry *signal_proc; #endif #ifdef AODV_GATEWAY char *block_dev; char *aodv_dev; char *aodv_subnet; MODULE_PARM(aodv_dev,"s"); MODULE_PARM(aodv_subnet,"s"); MODULE_PARM(block_dev, "s"); #endif MODULE_PARM(use_lo,"i"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luke Klein-Berndt"); MODULE_DESCRIPTION("A AODV ad-hoc routing kernel module"); u_int8_t USE_LO; struct metric monitor; char g_block_dev[8]; char g_aodv_dev[8]; u_int32_t g_aodv_subnet; /**************************************************** init_module ---------------------------------------------------- This is called by insmod when things get started up! ****************************************************/ int init_module(void) { int result; if (use_lo==0) USE_LO=0; else USE_LO=1; #ifdef AODV_GATEWAY if (block_dev==NULL) strcpy(g_block_dev,""); else strcpy(g_block_dev,block_dev); if (aodv_dev==NULL) strcpy(g_aodv_dev,""); else strcpy(g_aodv_dev,aodv_dev); if (aodv_subnet==NULL) g_aodv_subnet=0; else { inet_aton(aodv_subnet, &g_aodv_subnet); } #endif inet_aton("255.255.255.255",&g_broadcast_ip); printk("\n-=: Kernel AODV v2.1 :=-\nLuke Klein-Berndt\nWireless Communications Technologies Group\nNational Institue of Standards and Technology\n"); printk("---------------------------------------------\n"); //netfilter stuff /* input hook */ input_filter.list.next = NULL; input_filter.list.prev = NULL; input_filter.hook = input_handler; input_filter.pf = PF_INET; // IPv4 input_filter.hooknum = NF_IP_PRE_ROUTING; /* output hook */ output_filter.list.next = NULL; output_filter.list.prev = NULL; output_filter.hook = output_handler; output_filter.pf = PF_INET; // IPv4 output_filter.hooknum = NF_IP_LOCAL_OUT; /* output hook */ forward_filter.list.next = NULL; forward_filter.list.prev = NULL; forward_filter.hook = output_handler; forward_filter.pf = PF_INET; // IPv4 forward_filter.hooknum = NF_IP_FORWARD; /* output hook */ /* post_routing_filter.list.next = NULL; post_routing_filter.list.prev = NULL; post_routing_filter.hook = output_handler; post_routing_filter.pf = PF_INET; // IPv4 post_routing_filter.hooknum = NF_IP_POST_ROUTING; */ monitor.bytes=0; monitor.packets=0; monitor.routing_packets=0; monitor.rreq=0; monitor.rrep=0; monitor.rrer=0; monitor.last_read=getcurrtime(); init_check(); init_route_table(); init_event_queue(); init_timer_queue(); init_flood_id_queue(); init_neighbor_list(); #ifdef AODV_MULTICAST init_rebroadcast_queue(); init_multicast_sock(); #endif init_interface_list(); #ifdef AODV_SIGNAL init_iw_sock(); #endif init_packet_queue(); startup_aodv(); /* hooks registration */ result = nf_register_hook(&output_filter); if (result) goto hook_failed; #ifdef TRACE printk("Kernel_AODV: Output filter registered!\n"); #endif result = nf_register_hook(&input_filter); if (result) goto hook_failed; #ifdef TRACE printk("Kernel_AODV: Input filter registered!\n"); #endif result = nf_register_hook(&forward_filter); if (result) goto hook_failed; #ifdef TRACE printk("Kernel_AODV: Output filter registered!\n"); #endif /* result = nf_register_hook(&post_routing_filter); if (result) goto hook_failed; #ifdef TRACE printk("Kernel_AODV: Output filter registered!\n"); #endif */ #ifdef MESSAGES printk("Kernel_AODV: Principal IP address - %s\n",inet_ntoa(g_my_ip)); #endif insert_timer_queue_entry(getcurrtime() + ACTIVE_ROUTE_TIMEOUT, NULL,0,g_my_ip,0,0, EVENT_CLEANUP); update_timer_queue(); //setup the proc file system aodv_dir=proc_mkdir("aodv",NULL); aodv_dir->owner=THIS_MODULE; stats_proc=create_proc_read_entry("aodv/stats", 0, NULL, read_stats_proc, NULL); stats_proc->owner=THIS_MODULE; route_table_proc=create_proc_read_entry("aodv/route_table", 0, NULL, read_route_table_proc, NULL); route_table_proc->owner=THIS_MODULE; rreq_id_proc=create_proc_read_entry("aodv/rreq_id_queue", 0, NULL, read_rreq_id_proc, NULL); rreq_id_proc->owner=THIS_MODULE; timer_queue_proc=create_proc_read_entry("aodv/timer_queue", 0, NULL, read_timer_queue_proc, NULL); timer_queue_proc->owner=THIS_MODULE; monitor_proc=create_proc_read_entry("aodv/monitor", 0, NULL, read_monitor_proc, NULL); monitor_proc->owner=THIS_MODULE; #ifdef AODV_SIGNAL signal_proc=create_proc_read_entry("aodv/signal", 0, NULL, read_signal_proc, NULL); signal_proc->owner=THIS_MODULE; #endif //starts aodv thread return 0; hook_failed: #ifndef NO_ERROR printk(KERN_INFO "Kernel_AODV: error registering hook (%d)", result); #endif return 1; } /**************************************************** cleanup_module ---------------------------------------------------- cleans up the module. called by rmmod ****************************************************/ void cleanup_module(void) { //get rid of all our proc files #ifdef AODV_SIGNAL remove_proc_entry("aodv/signal",NULL); #endif remove_proc_entry("aodv/stats",NULL); remove_proc_entry("aodv/monitor",NULL); remove_proc_entry("aodv/route_table",NULL); remove_proc_entry("aodv/rreq_id_queue", NULL); remove_proc_entry("aodv/timer_queue", NULL); remove_proc_entry("aodv", NULL); /* unregister hooks */ #ifdef MESSAGES printk("Kernel_AODV: Shutting down...\n"); #endif kill_rebroadcast_thread(); nf_unregister_hook(&input_filter); nf_unregister_hook(&output_filter); nf_unregister_hook(&forward_filter); // nf_unregister_hook(&post_routing_filter); #ifdef MESSAGES printk("Kernel_AODV: Unregistered NetFilter hooks...\n"); #endif cleanup_packet_queue(); cleanup_event_queue(); cleanup_flood_id_queue(rreq_id_queue); #ifdef MESSAGES printk("Kernel_AODV: Cleaned up AODV Queues...\n"); #endif kill_aodv(); #ifdef MESSAGES printk("Kernel_AODV: Killed router thread...\n"); #endif del_timer(&aodv_timer); #ifdef MESSAGES printk("Kernel_AODV: Removed timer...\n"); #endif cleanup_route_table(); #ifdef MESSAGES printk("Kernel_AODV: Cleaned up Route Table...\n"); #endif close_sock(); #ifdef AODV_SIGNAL close_iw_sock(); #endif #ifdef MESSAGES printk("Kernel_AODV: Closed sockets...\n"); #endif #ifdef MESSAGES printk("Kernel_AODV: Shutdown complete!\n"); #endif }