📄 main.c
字号:
/* * Copyright (C) 2001, University of California, Santa Barbara * * 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. * * Other copyrights might apply to parts of this software and are so * noted when applicable. *//* * Parts of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * * The pimd program is COPYRIGHT 1998 by University of Southern California. * */#include <ctype.h>#include <signal.h>#include <stdio.h>#include <strings.h>#include <sys/ioctl.h>#include <sys/select.h>#include <sys/time.h>#include <sys/stat.h>#include "aodvConst.h"#include "aodvSocket.h"#include "const.h"#include "debug.h"#include "callout.h"#include "helloMsg.h"#include "inet.h"#include "kofn.h"#include "libnetlink.h"//from aodv-uu-0.1#include "packet_input.h"//TODO this should be in the kernel header compiling with#define RTM_LOOKUP_FAILED 99#define RTM_ROUTE_USED 100#define RTM_MAC_FAILURE 101#include "main.h"#include "rerr.h"#include "rreq.h"#include "rreqTable.h"#include "routingTable.h"#include "test.h"//static void read_netlinkSocket __P((int f, fd_set *rfd));int set_kernel_options(char *ifname);void load_modules(char *ifname);void handleCommandLineArguments(char* argc[], int argv);void initializeLogging();void initSignalActions();void createPidFile();void initDaemon();void mainLoop();int recv_msg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);static void timer __P(());static void handler __P((int));int rebootTime;struct rtnl_handle rth;struct tagname tagnames[] ={ { "all", TRACE_ALL }, { "init", TRACE_INIT }, { "timer", TRACE_TIMER }, { "rreq", TRACE_RREQ }, { "rrep", TRACE_RREP }, { "rerr", TRACE_RERR }, { "rt", TRACE_RT }, { "rreq_resend", TRACE_RREQ_RESEND }, { "rt_expire", TRACE_RT_EXPIRE }, { "memory", TRACE_MEMORY }, { "aodv_socket", TRACE_AODV_SOCKET }, { "hello", TRACE_HELLO }, { "local_repair", TRACE_LOCAL_REPAIR }, { "reboot", TRACE_REBOOT }, { "signal", TRACE_SIGNAL }, { "kernel_socket", TRACE_KERNEL_SOCKET }, { "recent_rreq", TRACE_RECENT_RREQ }, { "kernel_socket_bad", TRACE_KERNEL_SOCKET_BAD }, { "callout", TRACE_CALLOUT }, { "callout_periodic", TRACE_CALLOUT_PERIODIC }, { "rt_change", TRACE_RT_CHANGE }, { "packet_input", TRACE_PACKET_INPUT }, { "kofn", TRACE_KOFN }, { "metric", TRACE_METRIC }, { "current", TRACE_CUR }, { "demo", TRACE_DEMO }};void remove_modules();int main(int argc, char *argv[]){ char tmp1[150]; setlinebuf(stderr); if (geteuid() != 0) { fprintf(stderr, "aodvd: must be run as root\n"); exit(1); } handleCommandLineArguments(argv,argc); //set kernel options - from aodv-uu-0.1 /* Enable IP forwarding and set other kernel options... */ if(set_kernel_options(interface) < 0) { fprintf(stderr, "Could not set kernel options!\n"); fprintf(stderr, "Maybe you need to set the interface using -i.\n"); exit(-1); } sprintf(tmp1,"/sbin/route add -host 255.255.255.255 dev %s >/dev/null 2>&1" , interface); trace(TRACE_INIT,"executing:%s", tmp1); system(tmp1); //load_modules - from aodv-uu-0.1 load_modules(interface); initializeLogging(); initCallout(); packet_input_init(); //initalize first so aodv packets are processed first new_aodvSocket(); //IDC disable netlink messages //if (rtnl_open(&rth, groups) < 0){ // log(LOG_ERR,TRUE,"FAILED TO OPEN NETLINK SOCKET"); //} //if (register_input_handler(rth.fd, read_netlinkSocket) == ERROR){ // log(LOG_ERR,TRUE,"FAILED TO register_input for NETLINK SOCKET"); //} initSignalActions(); if(helloMsgSend == TRUE){ startHelloMsg(); } if(logToScreen == FALSE){ initDaemon(); } createPidFile(); mainLoop(); remove_modules(); log(LOG_NOTICE, FALSE, "aodvd exited normally"); return 0;}#define NHANDLERS 2static int nhandlers = 0;static struct ihandler { int fd; /* File descriptor */ ihfunc_t func; /* Function to call with &fd_set */} ihandlers[NHANDLERS];int register_input_handler(int fd, ihfunc_t func) { if (nhandlers >= NHANDLERS){ return ERROR; } else { ihandlers[nhandlers].fd = fd; ihandlers[nhandlers++].func = func; return SUCCESS; }}static void reboot(){ trace(TRACE_REBOOT,"reboot"); rebootTime=getTime()+DELETE_PERIOD;}static int sighandled = 0;#define GOT_SIGINT 0x01#define GOT_SIGHUP 0x02#define GOT_SIGUSR1 0x04#define GOT_SIGUSR2 0x08#define GOT_SIGALRM 0x10int handleSignal(){ int dummysigalrm; dummysigalrm=SIGALRM; if (sighandled) { if (sighandled & GOT_SIGINT) { sighandled &= ~GOT_SIGINT; trace(TRACE_SIGNAL,"returning TRUE from handleSignal"); return TRUE; } if (sighandled & GOT_SIGHUP) { sighandled &= ~GOT_SIGHUP; trace(TRACE_SIGNAL,"calling reboot"); reboot(); } if (sighandled & GOT_SIGUSR1) { sighandled &= ~GOT_SIGUSR1; printRoutingTable(); } if (sighandled & GOT_SIGUSR2) { sighandled &= ~GOT_SIGUSR2; test_link_break(); //cdump(SIGUSR2); } if (sighandled & GOT_SIGALRM) { sighandled &= ~GOT_SIGALRM; trace(TRACE_SIGNAL,"got SIGALRM"); timer(&dummysigalrm); } trace(TRACE_SIGNAL,"returning FALSE from handleSignal"); return FALSE; } return FALSE;}void handleTimeoutQueue(struct timeval *lasttime ,struct timeval *curtime ,struct timeval *difftime ,int *n ,long *msecs){ /* * Handle timeout queue. * * If select + packet processing took more than 1 second, * or if there is a timeout pending, age the timeout queue. * * If not, collect usec in difftime to make sure that the * time doesn't drift too badly. * * If the timeout handlers took more than 1 second, * age the timeout queue again. XXX This introduces the * potential for infinite loops! */ // do { /* * If the select timed out, then there's no other * activity to account for and we don't need to * call gettimeofday. */ gettimeofday(curtime, NULL); difftime->tv_sec = curtime->tv_sec - lasttime->tv_sec; difftime->tv_usec += curtime->tv_usec - lasttime->tv_usec; while (difftime->tv_usec > 1000000) { difftime->tv_sec++; difftime->tv_usec -= 1000000; } if (difftime->tv_usec < 0) { difftime->tv_sec--; difftime->tv_usec += 1000000; } //trace(TRACE_CALLOUT_PERIODIC,"lasttime->tv_sec=%i",lasttime->tv_sec); //trace(TRACE_CALLOUT_PERIODIC,"lasttime->tv_usec=%i",lasttime->tv_usec); //trace(TRACE_CALLOUT_PERIODIC,"curtime->tv_sec=%i",curtime->tv_sec); //trace(TRACE_CALLOUT_PERIODIC,"curtime->tv_usec=%i",curtime->tv_usec); *lasttime = *curtime; //trace(TRACE_CALLOUT_PERIODIC,"msecs=%i",*msecs); //trace(TRACE_CALLOUT_PERIODIC,"difftime->tv_sec=%i",difftime->tv_sec); //trace(TRACE_CALLOUT_PERIODIC,"difftime->tv_usec=%i",difftime->tv_usec); if (*msecs == 0 || difftime->tv_sec >= 1 || difftime->tv_usec > 100000){ //trace(TRACE_CALLOUT_PERIODIC // ,"age_callout_queue(%i)" // ,1000*difftime->tv_sec + difftime->tv_usec/1000); age_callout_queue(1000*difftime->tv_sec + difftime->tv_usec/1000); difftime->tv_sec = 0; difftime->tv_usec = 0; } //*msecs = -1; //}while (TRUE==FALSE); //while (difftime->tv_usec > 100000); //trace(TRACE_CALLOUT_PERIODIC,"leaving handleTimeoutQueue");}int reboot_flag = TRUE;int rreq_flag = TRUE;void mainLoop() { int i; long msecs; int n; int nfds; fd_set rfds, readers; struct timeval blanktv, *timeout; struct timeval lasttime, curtime, difftime; if(reboot_flag==TRUE){ reboot(); } //set first timer timer_setTimer(TIMER_INTERVAL, timer, NULL); difftime.tv_usec = 0; gettimeofday(&curtime, NULL); lasttime=curtime; FD_ZERO(&readers); for (i = 0; i < nhandlers; i++) { FD_SET(ihandlers[i].fd, &readers); if (ihandlers[i].fd >= nfds) nfds = ihandlers[i].fd + 1; } while(TRUE){ bcopy((char *)&readers, (char *)&rfds, sizeof(rfds)); if (handleSignal() == TRUE){ break; } //age timers msecs = timer_nextTimer(); //trace(TRACE_CALLOUT_PERIODIC,"msecs %i",msecs); //if (msecs == -1) // timeout = NULL; //else { timeout = &blanktv; timeout->tv_sec = 0; //timeout->tv_usec = msecs*1000; timeout->tv_usec = 50*1000; //} handleTimeoutQueue(&lasttime,&curtime,&difftime,&n,&msecs); //if(timeout == NULL){ //trace(TRACE_CALLOUT_PERIODIC,"timeout=NULL"); //}else{ //trace(TRACE_CALLOUT_PERIODIC,"timeout_tv_usec=%u",timeout->tv_usec); //} //check if any aodv or netlink pkts have come in if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0) { continue; } if ((n > 0)) { for (i = 0; i < nhandlers; i++) { if (FD_ISSET(ihandlers[i].fd, &rfds)) { (*ihandlers[i].func)(ihandlers[i].fd, &rfds); } } } if((rebootTime != 0) && (rebootTime < getTime())){ trace(TRACE_REBOOT|TRACE_INIT|TRACE_DEMO,"Reboot finished"); rebootTime = 0; } }}/* 'virtual_time' advances at a rate that is only a crude approximation of * real time, because it does not take into account any time spent processing, * and because the timer intervals are sometimes shrunk by a random amount to * avoid unwanted synchronization with other routers. */u_long virtual_time = 0;/* * Timer routine. Performs all perodic functions: * aging interfaces, neighbors, etc... * The granularity * is equal to TIMER_INTERVAL. */static void timer() { trace(TRACE_TIMER,"timer"); expireRoutes(); expireRREQBroadcasts(); virtual_time += TIMER_INTERVAL; timer_setTimer(TIMER_INTERVAL, timer, NULL);} /* * create a pid file */void createPidFile() { FILE *fp; fp = fopen(_PATH_AODVD_PID, "w"); if (fp != NULL) { fprintf(fp, "%d\n", (int)getpid()); (void) fclose(fp); }}/* * fork the process if you can */void initDaemon() { int t; //fork if (fork()){ exit(0); } else { (void)close(0); (void)close(1); (void)close(2); (void)open("/", 0); (void)dup2(0, 1); (void)dup2(0, 2); t = open("/dev/tty", 2); if (t >= 0) { (void)ioctl(t, TIOCNOTTY, (char *)0); (void)close(t); } }}void initSignalActions(){ struct sigaction sa; sa.sa_handler = handler; sa.sa_flags = 0; /* Interrupt system calls */ sigemptyset(&sa.sa_mask); sigaction(SIGALRM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); }void handleDebugCommandLineArguments(char *argv[], int argc);void handleTraceCommandLineArguments(char *argv[], int argc);void parseInterface(char *argv[], int argc);void parseSubnet(char *argv[], int argc);#define FLAG_NO_REBOOT "-nor"#define FLAG_NO_RREQ "-norreq"#define FLAG_KOFN "-kofn"#define FLAG_DEBUG "-d"#define FLAG_OUTPUT "-o"#define FLAG_INTERFACE "-i"#define FLAG_RING_SEARCH "-ers"#define FLAG_LOCAL_REPAIR "-lr"#define FLAG_HELLO_MSG "-hello"#define FLAG_HELLO_MSG_SEND "-hello_send"#define FLAG_HELLO_MSG_RECV "-hello_recv"#define FLAG_SUBNET "-subnet"#define FLAG_SYSLOG "-syslog"#define FLAG_TRACE "-t"#define FLAG_TRACE_TAGS "-tt"char subnet[8] = "192.168";#define FLAG_USAGE "-?"void usage();char interface[10] = DEFAULT_INTERFACE;void handleCommandLineArguments(char *argv[], int argc){ argv++; argc--; debug = LOG_DEBUG; while (argc > 0){ if (strcmp(*argv, FLAG_USAGE) == 0) { usage(); }else if (strcmp(*argv, FLAG_DEBUG) == 0) { argv++; argc--; handleDebugCommandLineArguments(argv,argc); //function used next argument argv++; argc--; }else if (strcmp(*argv, FLAG_TRACE) == 0) { argv++; argc--; handleTraceCommandLineArguments(argv,argc); //function used next argument argv++; argc--; }else if (strcmp(*argv, FLAG_TRACE_TAGS) == 0) { argv++; argc--; showtracetags=TRUE; handleTraceCommandLineArguments(argv,argc); //function used next argument argv++; argc--; }else if (strcmp(*argv, FLAG_INTERFACE) == 0) { argv++; argc--; parseInterface(argv,argc); //function used next argument argv++; argc--; }else if (strcmp(*argv, FLAG_SUBNET) == 0) { argv++; argc--; parseSubnet(argv,argc); //function used next argument argv++; argc--; } else if (strcmp(*argv, FLAG_OUTPUT) == 0) { argv++; argc--; logToScreen = TRUE; } else if (strcmp(*argv, FLAG_SYSLOG) == 0) { argv++; argc--; logToSysLog = TRUE; } else if (strcmp(*argv, FLAG_RING_SEARCH) == 0) { argv++; argc--; expandingRingSearch = TRUE; } else if (strcmp(*argv, FLAG_LOCAL_REPAIR) == 0) { argv++; argc--; localRepair = TRUE; } else if (strcmp(*argv, FLAG_HELLO_MSG) == 0) { argv++; argc--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -