⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ucsb大学开发的aodv路由协议代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -