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

📄 olsr.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met: * * * Redistributions of source code must retain the above copyright  *   notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright  *   notice, this list of conditions and the following disclaimer in  *   the documentation and/or other materials provided with the  *   distribution. * * Neither the name of olsr.org, olsrd nor the names of its  *   contributors may be used to endorse or promote products derived  *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: olsr.c,v 1.60 2007/10/16 10:01:29 bernd67 Exp $ *//** * All these functions are global */#include "defs.h"#include "olsr.h"#include "link_set.h"#include "two_hop_neighbor_table.h"#include "tc_set.h"#include "duplicate_set.h"#include "mpr_selector_set.h"#include "mid_set.h"#include "mpr.h"#include "lq_mpr.h"#include "lq_route.h"#include "scheduler.h"#include "apm.h"#include "misc.h"#include "neighbor_table.h"#include "log.h"#include "lq_packet.h"#include "lq_avl.h"#include <stdarg.h>#include <signal.h>olsr_bool changes_topology;olsr_bool changes_neighborhood;olsr_bool changes_hna;olsr_bool changes_force;/** * Process changes functions */struct pcf{  int (*function)(int, int, int);  struct pcf *next;};static struct pcf *pcf_list;static olsr_u16_t message_seqno;/** *Initialize the message sequence number as a random value */voidinit_msg_seqno(void){  message_seqno = random() & 0xFFFF;}/** * Get and increment the message sequence number * *@return the seqno */olsr_u16_tget_msg_seqno(void){  return message_seqno++;}voidregister_pcf(int (*f)(int, int, int)){  struct pcf *new_pcf;  OLSR_PRINTF(1, "Registering pcf function\n");  new_pcf = olsr_malloc(sizeof(struct pcf), "New PCF");  new_pcf->function = f;  new_pcf->next = pcf_list;  pcf_list = new_pcf;}/** *Process changes in neighborhood or/and topology. *Re-calculates the neighborhooh/topology if there *are any updates - then calls the right functions to *update the routing table. *@return 0 */voidolsr_process_changes(void){  struct pcf *tmp_pc_list;#ifdef DEBUG  if(changes_neighborhood)    OLSR_PRINTF(3, "CHANGES IN NEIGHBORHOOD\n");  if(changes_topology)    OLSR_PRINTF(3, "CHANGES IN TOPOLOGY\n");  if(changes_hna)    OLSR_PRINTF(3, "CHANGES IN HNA\n");#endif    if(!changes_force &&     2 <= olsr_cnf->lq_level &&     0 >= olsr_cnf->lq_dlimit)    return;      if(!changes_neighborhood &&     !changes_topology &&     !changes_hna)    return;  if (olsr_cnf->debug_level > 0 && olsr_cnf->clear_screen && isatty(1))  {      clear_console();      printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);  }  if (changes_neighborhood)    {      /* Calculate new mprs, HNA and routing table */      if (olsr_cnf->lq_level < 1)        {          olsr_calculate_mpr();        }      else        {          olsr_calculate_lq_mpr();        }      olsr_calculate_routing_table();      olsr_calculate_hna_routes();    }    else if (changes_topology || changes_hna)    {      /* calculate the routing table and HNA */        olsr_calculate_routing_table();        olsr_calculate_hna_routes();    }    if (olsr_cnf->debug_level > 0)    {            if (olsr_cnf->debug_level > 2)         {          olsr_print_mid_set();	            if (olsr_cnf->debug_level > 3)            {             if (olsr_cnf->debug_level > 8)               {                 olsr_print_duplicate_table();               }              olsr_print_hna_set();            }        }            olsr_print_link_set();      olsr_print_neighbor_table();      olsr_print_two_hop_neighbor_table();      olsr_print_tc_table();    }  for(tmp_pc_list = pcf_list;       tmp_pc_list != NULL;      tmp_pc_list = tmp_pc_list->next)    {      tmp_pc_list->function(changes_neighborhood,			    changes_topology,			    changes_hna);    }  changes_neighborhood = OLSR_FALSE;  changes_topology = OLSR_FALSE;  changes_hna = OLSR_FALSE;  changes_force = OLSR_FALSE;  return;}/** *Initialize all the tables used(neighbor, *topology, MID,  HNA, MPR, dup). *Also initalizes other variables */voidolsr_init_tables(void){    changes_topology = OLSR_FALSE;  changes_neighborhood = OLSR_FALSE;  changes_hna = OLSR_FALSE;  /* Set avl tree comparator */  if (olsr_cnf->ipsize == 4) {    avl_comp_default = NULL;    avl_comp_prefix_default = avl_comp_ipv4_prefix;  } else {    avl_comp_default = avl_comp_ipv6;    avl_comp_prefix_default = avl_comp_ipv6_prefix;  }  /* Initialize link set */  olsr_init_link_set();  /* Initialize duplicate table */  olsr_init_duplicate_table();  /* Initialize neighbor table */  olsr_init_neighbor_table();  /* Initialize routing table */  olsr_init_routing_table();  /* Initialize two hop table */  olsr_init_two_hop_table();  /* Initialize topology */  olsr_init_tc();  /* Initialize mpr selector table */  olsr_init_mprs_set();  /* Initialize MID set */  olsr_init_mid_set();  /* Initialize HNA set */  olsr_init_hna_set();  }/** *Check if a message is to be forwarded and forward *it if necessary. * *@param m the OLSR message recieved *@param originator the originator of this message *@param seqno the seqno of the message * *@returns positive if forwarded */intolsr_forward_message(union olsr_message *m, 		     union olsr_ip_addr *originator, 		     olsr_u16_t seqno,		     struct interface *in_if, 		     union olsr_ip_addr *from_addr){  union olsr_ip_addr *src;  struct neighbor_entry *neighbor;  int msgsize;  struct interface *ifn;  const int ttl = olsr_cnf->ip_version == AF_INET ? m->v4.ttl : m->v6.ttl;  if (ttl < 2) {    return 0;  }  if(!olsr_check_dup_table_fwd(originator, seqno, &in_if->ip_addr))    {#ifdef DEBUG      OLSR_PRINTF(3, "Message already forwarded!\n");#endif      return 0;    }  /* Lookup sender address */  src = mid_lookup_main_addr(from_addr);  if(!src)    src = from_addr;  neighbor=olsr_lookup_neighbor_table(src);  if(!neighbor)    return 0;  if(neighbor->status != SYM)    return 0;  /* Update duplicate table interface */  olsr_update_dup_entry(originator, seqno, &in_if->ip_addr);    /* Check MPR */  if(olsr_lookup_mprs_set(src) == NULL)    {#ifdef DEBUG      OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(src));#endif      return 0;    }  /* Treat TTL hopcnt */  if(olsr_cnf->ip_version == AF_INET)    {      /* IPv4 */      m->v4.hopcnt++;      m->v4.ttl--;     }  else    {      /* IPv6 */      m->v6.hopcnt++;      m->v6.ttl--;     }  /* Update dup forwarded */  olsr_set_dup_forward(originator, seqno);  /* Update packet data */  msgsize = ntohs(m->v4.olsr_msgsize);  /* looping trough interfaces */  for (ifn = ifnet; ifn ; ifn = ifn->int_next)     {       if(net_output_pending(ifn))	{	  /*	   * Check if message is to big to be piggybacked	   */	  if(net_outbuffer_push(ifn, m, msgsize) != msgsize)	    {	      /* Send */	      net_output(ifn);	      /* Buffer message */	      set_buffer_timer(ifn);	      	      if(net_outbuffer_push(ifn, m, msgsize) != msgsize)		{		  OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);		  olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);		}	    }	}      else	{	  /* No forwarding pending */	  set_buffer_timer(ifn);	  	  if(net_outbuffer_push(ifn, m, msgsize) != msgsize)	    {	      OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);	      olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);	    }	}    }  return 1;}voidset_buffer_timer(struct interface *ifn){        /* Set timer */  ifn->fwdtimer = GET_TIMESTAMP(random() * olsr_cnf->max_jitter * 1000 / RAND_MAX);}voidolsr_init_willingness(void){  if(olsr_cnf->willingness_auto)    olsr_register_scheduler_event(&olsr_update_willingness, 				  NULL, olsr_cnf->will_int, olsr_cnf->will_int, NULL);}voidolsr_update_willingness(void *foo __attribute__((unused))){  int tmp_will = olsr_cnf->willingness;  /* Re-calculate willingness */  olsr_cnf->willingness = olsr_calculate_willingness();  if(tmp_will != olsr_cnf->willingness)    {      OLSR_PRINTF(1, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);    }}/** *Calculate this nodes willingness to act as a MPR *based on either a fixed value or the power status *of the node using APM * *@return a 8bit value from 0-7 representing the willingness */olsr_u8_tolsr_calculate_willingness(void){  struct olsr_apm_info ainfo;  /* If fixed willingness */  if(!olsr_cnf->willingness_auto)    return olsr_cnf->willingness;  if(apm_read(&ainfo) < 1)    return WILL_DEFAULT;  apm_printinfo(&ainfo);  /* If AC powered */  if(ainfo.ac_line_status == OLSR_AC_POWERED)    return 6;  /* If battery powered    *   * juice > 78% will: 3   * 78% > juice > 26% will: 2   * 26% > juice will: 1   */  return (ainfo.battery_percentage / 26);}const char *olsr_msgtype_to_string(olsr_u8_t msgtype){  static char type[20];  switch(msgtype)    {    case(HELLO_MESSAGE):      return "HELLO";    case(TC_MESSAGE):      return "TC";    case(MID_MESSAGE):      return "MID";    case(HNA_MESSAGE):      return "HNA";    case(LQ_HELLO_MESSAGE):      return("LQ-HELLO");    case(LQ_TC_MESSAGE):      return("LQ-TC");    default:      break;    }  snprintf(type, sizeof(type), "UNKNOWN(%d)", msgtype);  return type;}const char *olsr_link_to_string(olsr_u8_t linktype){  static char type[20];  switch(linktype)    {    case(UNSPEC_LINK):      return "UNSPEC";    case(ASYM_LINK):      return "ASYM";    case(SYM_LINK):      return "SYM";    case(LOST_LINK):      return "LOST";    case(HIDE_LINK):      return "HIDE";    default:      break;    }  snprintf(type, sizeof(type), "UNKNOWN(%d)", linktype);  return type;}const char *olsr_status_to_string(olsr_u8_t status){  static char type[20];  switch(status)    {    case(NOT_NEIGH):      return "NOT NEIGH";    case(SYM_NEIGH):      return "NEIGHBOR";    case(MPR_NEIGH):      return "MPR";    default:      break;    }  snprintf(type, sizeof(type), "UNKNOWN(%d)", status);  return type;}/** *Termination function to be called whenever a error occures *that requires the daemon to terminate * *@param msg the message to write to the syslog and possibly stdout */voidolsr_exit(const char *msg, int val){  OLSR_PRINTF(1, "OLSR EXIT: %s\n", msg);  olsr_syslog(OLSR_LOG_ERR, "olsrd exit: %s\n", msg);  fflush(stdout);  olsr_cnf->exit_value = val;  raise(SIGTERM);}/** *Wrapper for malloc(3) that does error-checking * *@param size the number of bytes to allocalte *@param caller a string identifying the caller for *use in error messaging * *@return a void pointer to the memory allocated */void *olsr_malloc(size_t size, const char *id){  void *ptr = malloc(size);  if(ptr == 0)     {      const char * const err_msg = strerror(errno);      OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);      olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);      olsr_exit(id, EXIT_FAILURE);    }  return ptr;}/** *Wrapper for printf that prints to a specific *debuglevel upper limit * */intolsr_printf(int loglevel, char *format, ...){  if((loglevel <= olsr_cnf->debug_level) && debug_handle)    {      va_list arglist;      va_start(arglist, format);      vfprintf(debug_handle, format, arglist);      va_end(arglist);    }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -