📄 main.c
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University and Ericsson AB. * Copyright (C) 2003 Simon Fraser University and NewMIC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: Erik Nordstr鰉, <erik.nordstrom@it.uu.se> * : Peter Lee <peter.lee@shaw.ca> * *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <linux/sockios.h>#include <linux/wireless.h>#include <getopt.h>#include <ctype.h>#include "defs.h"#include "debug.h"#include "timer_queue.h"#include "params.h"#include "aodv_socket.h"#include "aodv_timeout.h"#include "k_route.h"#include "routing_table.h"#include "aodv_hello.h"#include "packet_input.h"#include "packet_queue.h"#include "address_conf.h"//PL:#ifdef _IPV6#include "ipv6_utils.h"#endif /* _IPV6 *//* Global variables: */int log_to_file = 0;int rt_log_interval = 0; /* msecs between routing table logging 0=off */int unidir_hack = 0;int rreq_gratuitous = 0;int expanding_ring_search = 1;int internet_gw_mode = 0;int is_gateway = 0;int local_repair = 0;int receive_n_hellos = 0;int hello_jittering = 1;char *progname;char versionstring[100];int wait_on_reboot = 1;int hello_qual_threshold = 12;char *spy_addrs = NULL;struct timer worb_timer; /* Wait on reboot timer */int old_default_gw_exist=0;//PL:#ifdef _IPV6struct in6_addr ipv6_multicast_addr = IPV6_ALL_MANET_NODES;struct in6_addr ipv6_default_addr = IPV6_DEFAULT_ADDR;struct in6_addr gateway_mcast_addr = ALL_MANET_GW_MULTICAST;struct in6_addr ipv6_dest_default = IPV6_DEST_DEFAULT;struct in6_addr old_default_gw;//struct in6_addr gw_global_addr = NULL;#endif /* _IPV6 */static void cleanup();struct option longopts[] = { {"interface", required_argument, NULL, 'i'}, {"hello-jitter", no_argument, NULL, 'j'}, {"log", no_argument, NULL, 'l'}, {"n-hellos", required_argument, NULL, 'n'}, {"daemon", no_argument, NULL, 'd'}, {"force-gratuitous", no_argument, NULL, 'g'}, {"global-prefix",required_argument,NULL,'p'}, {"quality-threshold", required_argument, NULL, 'q'}, {"log-rt-table", required_argument, NULL, 'r'}, {"add-spy", required_argument, NULL, 's'}, {"unidir_hack", no_argument, NULL, 'u'}, {"gateway-mode", no_argument, NULL, 'w'}, {"help", no_argument, NULL, 'h'}, {"no-expanding-ring", no_argument, NULL, 'x'}, {"no-worb", no_argument, NULL, 'D'}, {"version", no_argument, NULL, 'V'}, {0}};void usage(int status){ if (status != 0) { fprintf(stderr, "Try `%s --help' for more information.\n", progname); exit(status); } printf ("\nUsage: %s [-dghjluwxDV] [-i if0,if1,..] [-r N] [-n N]\n\n" "-d, --daemon Daemon mode, i.e. detach from the console.\n" "-g, --force-gratuitous Force the gratuitous flag to be set on all RREQ's.\n" "-h, --help This information.\n" "-i, --interface Network interfaces to attach to. Defaults to first\n" " wireless interface.\n" "-j, --hello-jitter Toggle hello jittering (default on).\n" "-l, --log Log debug output to %s.\n" "-r, --log-rt-table Log routing table to %s every N secs.\n" "-n, --n-hellos Receive N hellos from host before treating as neighbor.\n" "-p, --global-prefix Internet gateway's global prefix.\n" "-u, --unidir-hack Detect and avoid unidirectional links (experimental).\n" "-w, --gateway-mode Enable experimental Internet gateway support.\n" "-x, --no-expanding-ring Disable expanding ring search for RREQs.\n" "-D, --no-worb Disable 15 seconds wait on reboot delay.\n" "-V, --version Show version.\n\n" "Author: Erik Nordstr鰉 erik.nordstrom@it.uu.se\n" "Author(IPv6): Peter Lee mclee@sfu.ca\n\n", //PL:#ifdef _IPV6 progname, AODV6_LOG_PATH, AODV6_RT_LOG_PATH);#else progname, AODV_LOG_PATH, AODV_RT_LOG_PATH);#endif /* _IPV6 */ exit(status);}int set_kernel_options(){ int i, fd = -1; char off = '0'; char on = '1'; char command[64]; //PL: IPv6 doesn't has these files: ip_forward, max/min_delay#ifdef _IPV6 if ((fd = open("/proc/sys/net/ipv6/conf/all/forwarding", O_WRONLY)) < 0) return -1; if (write(fd, &on, sizeof(char)) < 0) return -1; close(fd);#else if ((fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY)) < 0) return -1; if (write(fd, &on, sizeof(char)) < 0) return -1; close(fd); if ((fd = open("/proc/sys/net/ipv4/route/max_delay", O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); if ((fd = open("/proc/sys/net/ipv4/route/min_delay", O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd);#endif /* _IPV6 */ /* Disable ICMP redirects on all interfaces: */ for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; memset(command, '\0', 64); //PL:#ifdef _IPV6 //PL: IPv6 doesn't has send_redirects#else sprintf(command, "/proc/sys/net/ipv4/conf/%s/send_redirects", DEV_NR(i).ifname); if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd);#endif /* _IPV6 */ memset(command, '\0', 64); //PL:#ifdef _IPV6 sprintf(command, "/proc/sys/net/ipv6/conf/%s/accept_redirects", DEV_NR(i).ifname);#else sprintf(command, "/proc/sys/net/ipv4/conf/%s/accept_redirects", DEV_NR(i).ifname);#endif /* _IPV6 */ if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); } //PL: IPv6#ifdef _IPV6#else memset(command, '\0', 64); sprintf(command, "/proc/sys/net/ipv4/conf/all/send_redirects"); if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd);#endif /* _IPV6 */ memset(command, '\0', 64); //PL:#ifdef _IPV6 sprintf(command, "/proc/sys/net/ipv6/conf/all/accept_redirects");#else sprintf(command, "/proc/sys/net/ipv4/conf/all/accept_redirects");#endif /* _IPV6 */ if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); return 0;}//PL:#ifdef _IPV6int find_default_gw6(void){//PL: from net-tools-1.60: lib/net-support.h#define RTF_GATEWAY 0x0002 /* destination is a gateway */ FILE *route; //char buf[200], *l; char buff[4096], iface[16], addr6[40]; char addr6p[8][5], saddr6p[8][5], naddr6p[8][5]; struct in6_addr ip_addr; int num, iflags, metric, refcnt, use, prefix_len, slen; route = fopen("/proc/net/ipv6_route", "r"); if (route == NULL) { perror("open /proc/net/ipv6_route"); exit(-1); } //PL: Got this from net-tools-1.60: lib/inet6_gr.c while (fgets(buff, 1023, route)) { num = sscanf(buff, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %4s%4s%4s%4s%4s%4s%4s%4s %02x %4s%4s%4s%4s%4s%4s%4s%4s %08x %08x %08x %08x %s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], &prefix_len, saddr6p[0], saddr6p[1], saddr6p[2], saddr6p[3], saddr6p[4], saddr6p[5], saddr6p[6], saddr6p[7], &slen, naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3], naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7], &metric, &use, &refcnt, &iflags, iface); if ( (iflags & RTF_GATEWAY) && (prefix_len == /*0*/3) ) { sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); inet_pton(AF_INET6, addr6, &ip_addr); /*if(memcmp(&ip_addr, &ipv6_default_addr, sizeof(struct in6_addr)) == 0) { fclose(route); return 1; }*/ if(memcmp(&ip_addr,&ipv6_dest_default,sizeof(struct in6_addr))==0){ sprintf(addr6,"%s:%s:%s:%s:%s:%s:%s:%s", naddr6p[0],naddr6p[1],naddr6p[2],naddr6p[3], naddr6p[4],naddr6p[5],naddr6p[6],naddr6p[7]); inet_pton(AF_INET6,addr6,&old_default_gw); fclose(route); memset(buff,'\0',sizeof(buff)); sprintf(buff,"route -A inet6 del %s/%d",ip6_to_str(ipv6_dest_default),prefix_len); printf("buff:%s\n",buff); system(buff); return 1; } } } /* while (fgets(buf, sizeof(buf), route)) { l = strtok(buf, " \t"); if (l != NULL) { if (strcmp("00000000000000000000000000000000", l) == 0) { l = strtok(NULL, " \t"); if (strcmp("00", l) == 0) { l = strtok(NULL, " \t"); l = strtok(NULL, " \t"); l = strtok(NULL, " \t"); l = strtok(NULL, " \t"); //PL: Need to verify this if (strcmp("ffffffff", l) == 0) { fclose(route); return 1; } } } } } */ // end of while fclose(route); return 0;}#elseint find_default_gw(void){ FILE *route; char buf[100], *l; route = fopen("/proc/net/route", "r"); if (route == NULL) { perror("open /proc/net/route"); exit(-1); } while (fgets(buf, sizeof(buf), route)) { l = strtok(buf, " \t"); l = strtok(NULL, " \t"); if (l != NULL) { if (strcmp("00000000", l) == 0) { l = strtok(NULL, " \t"); l = strtok(NULL, " \t"); if (strcmp("0003", l) == 0) { fclose(route); return 1; } } } } fclose(route); return 0;}#endif /* _IPV6 *//* * Returns information on a network interface given its name... */struct sockaddr_in *get_if_info(char *ifname, int type){ int skfd; struct sockaddr_in *ina; struct ifreq ifr; /* Get address of interface... */ skfd = socket(AF_INET, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, type, &ifr) < 0) { log(LOG_ERR, errno, "Could not get address of %s ", ifname); close(skfd); return NULL; } else { ina = (struct sockaddr_in *) &ifr.ifr_addr; close(skfd); return ina; }}/* This will limit the number of handler functions we can have for sockets and file descriptors and so on... */#define CALLBACK_FUNCS 4static struct callback { int fd; callback_func_t func;} callbacks[CALLBACK_FUNCS];static int nr_callbacks = 0;int attach_callback_func(int fd, callback_func_t func){ if (nr_callbacks >= CALLBACK_FUNCS) { fprintf(stderr, "callback attach limit reached!!\n"); exit(-1); } callbacks[nr_callbacks].fd = fd; callbacks[nr_callbacks].func = func; nr_callbacks++; return 0;}/* Here we find out how to load the kernel modules... If the modules are located in the current directory. use those. Otherwise fall back to modprobe. *///PL:#ifdef _IPV6void load_ipv6_modules(char *ifname){ struct stat st; char buf[1024], *l = NULL; int found = 0; FILE *m; system("/sbin/modprobe ip6table_filter &>/dev/null"); memset(buf, '\0', 64); if (stat("./ip6_queue.o", &st) < 0) sprintf(buf, "/sbin/modprobe ip6_queue &>/dev/null"); else sprintf(buf, "/sbin/insmod ip6_queue.o &>/dev/null"); system(buf); memset(buf, '\0', 64); if (stat("./kaodv6.o", &st) < 0) sprintf(buf, "/sbin/modprobe kaodv6 ifname=%s &>/dev/null", ifname); else sprintf(buf, "/sbin/insmod kaodv6.o ifname=%s &>/dev/null", ifname); system(buf); /* Check result */ m = fopen("/proc/modules", "r"); while (fgets(buf, sizeof(buf), m)) { l = strtok(buf, " \t"); if (!strcmp(l, "kaodv6")) found++; if (!strcmp(l, "ip6_queue")) found++; if (!strcmp(l, "ip6chains")) { fprintf(stderr, "ERROR: The ipchains kernel module is loaded and prevents AODV-UU from functioning properly.\n"); exit(-1); } } fclose(m); if (found != 2) { printf("found value:%d\n",found); fprintf(stderr, "A kernel module could not be loaded, check your installation...\n"); exit(-1); } printf("ZJH:modules loaded successfully!!!\n");}#elsevoid load_modules(char *ifname){ struct stat st; char buf[1024], *l = NULL; int found = 0; FILE *m; system("/sbin/modprobe iptable_filter &>/dev/null"); memset(buf, '\0', 64); if (stat("./ip_queue.o", &st) < 0) sprintf(buf, "/sbin/modprobe ip_queue &>/dev/null"); else sprintf(buf, "/sbin/insmod ip_queue.o &>/dev/null"); system(buf); memset(buf, '\0', 64); if (stat("./kaodv.o", &st) < 0) sprintf(buf, "/sbin/modprobe kaodv ifname=%s &>/dev/null", ifname); else sprintf(buf, "/sbin/insmod kaodv.o ifname=%s &>/dev/null", ifname); system(buf); /* Check result */ m = fopen("/proc/modules", "r"); while (fgets(buf, sizeof(buf), m)) { l = strtok(buf, " \t"); if (!strcmp(l, "kaodv")) found++; if (!strcmp(l, "ip_queue")) found++; if (!strcmp(l, "ipchains")) { fprintf(stderr, "ERROR: The ipchains kernel module is loaded and prevents AODV-UU from functioning properly.\n"); exit(-1); } } fclose(m); if (found != 2) { fprintf(stderr, "A kernel module could not be loaded, check your installation...\n"); exit(-1); } }#endif /* _IPV6 */void remove_modules(void){ //PL:#ifdef _IPV6 system("/sbin/modprobe -r kaodv6 &>/dev/null"); system("/sbin/modprobe -r ip6_queue &>/dev/null");#else system("/sbin/modprobe -r kaodv &>/dev/null"); system("/sbin/modprobe -r ip_queue &>/dev/null");#endif /* _IPV6 */ system("/sbin/modprobe -r iptable_filter &>/dev/null"); printf("ZJH:modules unloaded successfully!!!\n"); ip6addr_clear();}void host_init(char *ifname){ char ifnames[(IFNAMSIZ + 1) * MAX_NR_INTERFACES], *iface/*, buf[1024]*/; //PL:#ifdef _IPV6 //PL: I don't need ina at all.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -