📄 main.c
字号:
helloMsgSend = TRUE; helloMsgRecv = TRUE; } else if (strcmp(*argv, FLAG_HELLO_MSG_SEND) == 0) { argv++; argc--; helloMsgSend = TRUE; } else if (strcmp(*argv, FLAG_HELLO_MSG_RECV) == 0) { argv++; argc--; helloMsgRecv = TRUE; } else if (strcmp(*argv, FLAG_NO_REBOOT) == 0) { argv++; argc--; reboot_flag = FALSE; } else if (strcmp(*argv, FLAG_NO_RREQ) == 0) { argv++; argc--; rreq_flag = FALSE; } else if (strcmp(*argv, FLAG_KOFN) == 0) { argv++; argc--; kofn_flag = TRUE; } }} //handleCommandLineArgumentsstruct debugname { char *name; int val;} debugnames[] ={ { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, { "crit", LOG_CRIT }, { "err", LOG_ERR }, { "warning", LOG_WARNING }, { "notice", LOG_NOTICE }, { "info", LOG_INFO }, { "debug", LOG_DEBUG }};void handleDebugCommandLineArguments(char *argv[], int argc){ if (argc > 0 //have debug level && isdigit(*(argv)[0])){ debug = atoi(*argv); if(debug > LOG_DEBUG){ fprintf(stderr,"INVALID DEBUG LEVEL\n"); usage(); } }else{ fprintf(stderr,"INVALID DEBUG LEVEL\n"); usage(); }} //handleDebugCommandLineArgumentsvoid handleTraceCommandLineArguments(char *argv[], int argc){ char *csl; char tag[20]; char *cma_ptr; int i,lengthNames; struct tagname *tnames; if (argc > 0){ csl=argv[0]; //break string apart while (csl != NULL){ //parse each argument cma_ptr=strchr(csl,','); if(cma_ptr == NULL){ strncpy(tag,csl,20); }else{ strncpy(tag,csl,cma_ptr-csl); tag[cma_ptr-csl]='\0'; } //check in list lengthNames = sizeof(tagnames)/sizeof(tagnames[0]); for (i = 0,tnames = tagnames; i < lengthNames ; i++, tnames++){ if(strcmp(tag,tnames->name) == 0){ //or value with trace tracetag = tracetag | tnames->val; if (cma_ptr != 0){ csl=cma_ptr+1; } else { csl=NULL; } trace(TRACE_INIT,"adding tag %s",tag); goto nextCSV; } } //if not in list print usage fprintf(stderr,"INVALID TRACE TAG: %s\n",tag); usage(); nextCSV: } } else { fprintf(stderr,"TRACE TAGS REQUIRED\n"); usage(); }} //handleTraceCommandLineArguments/* * parse what interface to listen on */void parseInterface(char *argv[], int argc){ if (argc > 0){ strncpy(interface,*argv,sizeof(interface)); trace(TRACE_INIT,"parseInterface:%s",interface); }else{ fprintf(stderr,"INVALID INTERFACE\n"); usage(); }} //parseInterface/* * parse subnet */void parseSubnet(char *argv[], int argc){ if (argc > 0){ strncpy(subnet,*argv,sizeof(subnet)); //check subnet in form xxx.xxx where xxx is less than 255 trace(TRACE_INIT,"parseSubnet:%s",subnet); if( (isdigit(subnet[0]) == 0) || (isdigit(subnet[1]) == 0) || (isdigit(subnet[2]) == 0) || (subnet[3] != '.') || (isdigit(subnet[4]) == 0) || (isdigit(subnet[5]) == 0) || (isdigit(subnet[6]) == 0) || (subnet[4] > '2') || (subnet[0] > '2') || ((subnet[0] == '2') && (subnet[1] > '5')) || ((subnet[0] == '2') && (subnet[1] == '5') && (subnet[2] >= '5')) || ((subnet[4] == '2') && (subnet[5] > '5')) || ((subnet[4] == '2') && (subnet[5] == '5') && (subnet[6] >= '5')) ){ fprintf(stderr,"INVALID SUBNET\n"); usage(); } }else{ fprintf(stderr,"INVALID SUBNET\n"); usage(); }} //parseSubnet#define OPEN_PAR '('void usage(){ int i; int lengthNames; struct debugname *names; struct tagname *tnames; fprintf(stderr, "usage: \naodvd " \ "[-o] [-syslog] [-d debug_level] [-i if] [-hello|hello_send|hello_recv] " \ "[-ers] [-lr] [-subnet subnet] [-t tag1,tag2]\n"); fprintf(stderr, "\nMUST BE RUN AS ROOT\n"); fprintf(stderr, "-o: output messages to stdout. default off\n"); fprintf(stderr, "-syslog: output messages to syslog. default off\n"); fprintf(stderr, "-i if : specify interface. default eth1\n"); fprintf(stderr, "-norreq: don't send rreq. default send rreq\n"); fprintf(stderr, "-kofn: require 2 of 3 control messages from neighbor\n"); fprintf(stderr, "-hello: send and expect hello messages. default on \n"); fprintf(stderr, "-hello_send: send hello messages. default on \n"); fprintf(stderr, "-hello_recv: expect hello messages. default on \n"); fprintf(stderr, "-ers: use expanding ring search. default off \n"); fprintf(stderr, "-lr: use local repair. default off\n"); fprintf(stderr, "-nor: don't wait reboot time as specified in draft default on\n"); fprintf(stderr, "-subnet subnet: subnet specifies the first 7 char. default 192.168\n"); fprintf(stderr, "-d: debug levels: \n"); lengthNames = sizeof(debugnames)/sizeof(debugnames[0]); for (i = 0,names = debugnames; i < lengthNames ; i++, names++){ fprintf(stderr,"\t%s\t%i\n",names->name,names->val); } fprintf(stderr, "All levels lower than the value entered will be " \ "displayed\n"); fprintf(stderr, "-t: trace tags: \n"); fprintf(stderr, "-tt: trace tags include tag in output: \n"); lengthNames = sizeof(tagnames)/sizeof(tagnames[0]); for (i = 0,tnames = tagnames; i < lengthNames ; i++, tnames++){ fprintf(stderr,"\t%s\n",tnames->name); } exit(1);}/* * Signal handler. Take note of the fact that the signal arrived * so that the main loop can take care of it. */static void handler(int sig) { switch (sig) { case SIGALRM: sighandled |= GOT_SIGALRM; case SIGINT: case SIGTERM: sighandled |= GOT_SIGINT; break; case SIGHUP: sighandled |= GOT_SIGHUP; break; case SIGUSR1: sighandled |= GOT_SIGUSR1; break; case SIGUSR2: sighandled |= GOT_SIGUSR2; break; }}struct KernelMessage{ u_int32_t src; u_int32_t dst; u_int32_t oif;};int decodeKernelMessage(struct nlmsghdr *n,struct KernelMessage *msg){ struct rtmsg *r = NLMSG_DATA(n); int attrlen = 0; u_int32_t *temp; struct rtattr *rta = NULL; rta=RTM_RTA(r); if(RTA_OK(rta,rta->rta_len)){ temp = RTA_DATA(rta); msg->dst=*temp; rta=RTA_NEXT(rta,attrlen); if(RTA_OK(rta,rta->rta_len)){ temp = RTA_DATA(rta); msg->src=*temp; rta=RTA_NEXT(rta,attrlen); if(RTA_OK(rta,rta->rta_len)){ temp = RTA_DATA(rta); msg->oif=*temp; }else{ //problem with data disregard trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg: problem with oif"); return -1; } }else{ //problem with data disregard trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg: problem with src"); return -1; } }else{ //problem with data disregard trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg: problem with dst"); return -1; } //too many messages //trace(TRACE_KERNEL_SOCKET,"krl_msg:src=%s",inet_fmt(msg->src,s1)); //trace(TRACE_KERNEL_SOCKET,"krl_msg:dst=%s",inet_fmt(msg->dst,s1)); //trace(TRACE_KERNEL_SOCKET,"krl_msg:if=%u",msg->oif); return 0;}int recv_msg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { struct RoutingTableEntry *rt = NULL; char sbuf[25]; char dbuf[25]; struct KernelMessage msg; //IDC comment out all netlink message handling return 0; if((rreq_flag == TRUE) && (n->nlmsg_type == RTM_LOOKUP_FAILED)){ if(decodeKernelMessage(n,&msg) == 0){ if(msg.src==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:src broadcast"); return 0; } if(msg.dst==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:dst broadcast"); return 0; } if((msg.src!=0) && (msg.src!=getip())){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:src not this host"); return 0; } sprintf(dbuf,"%s",inet_fmt_n(msg.dst,s1)); if( ((subnet[0]!=0)&&(strncmp(subnet,dbuf,7)!=0)) ||(strstr(dbuf,"255")!=NULL)){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:OUT OF RANGE"); return 0; } //check if we have an active route //sometimes it hasn't registered in OS yet rt = getRoute(msg.dst); if((rt==NULL)||(rt->hopCount==DELETE_ROUTE)){ trace(TRACE_KERNEL_SOCKET,"RTM_ROUTE_LOOKUP"); trace(TRACE_KERNEL_SOCKET,"krl_msg:src=%s",inet_fmt_n(msg.src,s1)); trace(TRACE_KERNEL_SOCKET,"krl_msg:dst=%s",inet_fmt_n(msg.dst,s1)); trace(TRACE_KERNEL_SOCKET,"krl_msg:if=%u",msg.oif); trace(TRACE_KERNEL_SOCKET,"RTM_ROUTE_LOOKUP_FAILED"); generateRREQ(msg.dst,DEFAULT_G); }else{ trace(TRACE_KERNEL_SOCKET_BAD ,"DISREGARDING RTM MESSAGE ALREADY HAVE ROUTE"); } } }else if(n->nlmsg_type == RTM_ROUTE_USED){ if(decodeKernelMessage(n,&msg) == 0){ if(msg.src==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:src broadcast"); return 0; } if(msg.dst==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:dst broadcast"); return 0; } sprintf(sbuf,"%s",inet_fmt_n(msg.src,s1)); if( ((subnet[0]!=0)&&(strncmp(subnet,sbuf,7)!=0)) ||(strstr(sbuf,"255")!=NULL)){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:OUT OF RANGE"); return 0; } sprintf(dbuf,"%s",inet_fmt_n(msg.dst,s1)); if( ((subnet[0]!=0)&&(strncmp(subnet,dbuf,7)!=0)) ||(strstr(dbuf,"255")!=NULL)){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:OUT OF RANGE"); return 0; } if((rebootTime != 0) || (routeUsed(msg.dst)==FALSE)){ //if don't have an active route //and this is from us if(msg.src == 0){ trace(TRACE_RT|TRACE_RREQ,"trying to use bad route, generateRREQ"); //TODO fill in G in RREQ generateRREQ(msg.dst,DEFAULT_G); } else { //if it isn't from us //create RERR trace(TRACE_DEMO,"received message to (%s) NO ROUTE or DURING REBOOT" ,inet_fmt_n(msg.dst,s1)); generateRERR(msg.dst); } } } }else if(n->nlmsg_type == RTM_MAC_FAILURE){ trace(TRACE_CUR,"RTM_MAC_FAILURE"); if(decodeKernelMessage(n,&msg) == 0){ trace(TRACE_CUR,"krl_msg:src=%s",inet_fmt_n(msg.src,s1)); trace(TRACE_CUR,"krl_msg:dst=%s",inet_fmt_n(msg.dst,s1)); trace(TRACE_CUR,"krl_msg:src=%u",msg.src); trace(TRACE_CUR,"krl_msg:dst=%u",msg.dst); trace(TRACE_CUR,"krl_msg:if=%u",msg.oif); if(msg.src==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:src broadcast"); return 0; } if(msg.dst==BROADCAST){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:dst broadcast"); return 0; } sprintf(sbuf,"%s",inet_fmt_n(msg.src,s1)); if( ((subnet[0]!=0)&&(strncmp(subnet,sbuf,7)!=0)) ||(strstr(sbuf,"255")!=NULL)){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:OUT OF RANGE"); return 0; } sprintf(dbuf,"%s",inet_fmt_n(msg.dst,s1)); if( ((subnet[0]!=0)&&(strncmp(subnet,dbuf,7)!=0)) ||(strstr(dbuf,"255")!=NULL)){ trace(TRACE_KERNEL_SOCKET_BAD,"recv_msg:OUT OF RANGE"); return 0; } //failed to send //create RERR trace(TRACE_DEMO,"failed to send message to (%s) NO ROUTE" ,inet_fmt_n(msg.dst,s1)); //TODO fix RTM_MAC_FAILURE //generateRERR(msg.dst); } }else { trace(TRACE_KERNEL_SOCKET,"DISREGARDING RTM MESSAGE"); } return 0;}////static void read_netlinkSocket(int f, fd_set *rfd) { //too many messages //trace(TRACE_KERNEL_SOCKET,"read_netlinkSocket"); //check netlink socket//// rtnl_listen(&rth, recv_msg , (void*)stdout);////}/***************************************************************************** * * Copyright (C) 2001 Uppsala University. * * 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鰉, <erno3431@student.uu.se> * Henrik Lundgren, <henrikl@docs.uu.se> * *****************************************************************************///From aodv-uu-0.1 ---------------int set_kernel_options(char *ifname) { int fd = -1; char on = '1'; char off = '0'; char command[64]; 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); /* Disable ICMP redirects: */ memset(command, '\0', 64); sprintf(command, "/proc/sys/net/ipv4/conf/%s/send_redirects", ifname); if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); memset(command, '\0', 64); sprintf(command, "/proc/sys/net/ipv4/conf/%s/accept_redirects", ifname); if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); /* Disable ICMP redirects: */ 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); memset(command, '\0', 64); sprintf(command, "/proc/sys/net/ipv4/conf/all/accept_redirects"); if ((fd = open(command, O_WRONLY)) < 0) return -1; if (write(fd, &off, sizeof(char)) < 0) return -1; close(fd); 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. */void 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_aodv.o", &st) < 0) sprintf(buf, "/sbin/modprobe ip_queue_aodv &>/dev/null"); else sprintf(buf, "/sbin/insmod ip_queue_aodv.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_aodv")) found++; } fclose(m); if(found != 2) { fprintf(stderr, "A kernel module could not be loaded, check your installation...\n"); exit(-1); }}void remove_modules() { system("/sbin/modprobe -r kaodv &>/dev/null"); system("/sbin/modprobe -r ip_queue_aodv &>/dev/null"); system("/sbin/modprobe -r iptable_filter &>/dev/null");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -