Пример #1
0
/**
 * Load plugins and call the init callback
 * @param fail_fast if true OLSRd will exit if a plugin throws an error
 *   during initialization
 */
void
olsr_plugins_init(bool fail_fast) {
  struct plugin_entry *entry;
  struct olsr_plugin *plugin;

  OLSR_INFO(LOG_PLUGINS, "Loading configured plugins...\n");
  /* first load anything requested but not already loaded */
  for (entry = olsr_cnf->plugins; entry != NULL; entry = entry->next) {
    if (olsr_init_plugin(entry->name) == NULL) {
      if (fail_fast) {
        OLSR_ERROR(LOG_PLUGINS, "Cannot load plugin %s.\n", entry->name);
        olsr_exit(1);
      }
      OLSR_WARN(LOG_PLUGINS, "Cannot load plugin %s.\n", entry->name);
    }
  }

  /* now hookup parameters to plugins */
  for (entry = olsr_cnf->plugins; entry != NULL; entry = entry->next) {
    plugin = olsr_get_plugin(entry->name);
    if (plugin == NULL) {
      if (fail_fast) {
        OLSR_ERROR(LOG_PLUGINS, "Internal error in plugin storage tree, cannot find plugin %s\n", entry->name);
        olsr_exit(1);
      }
      OLSR_WARN(LOG_PLUGINS, "Internal error in plugin storage tree, cannot find plugin %s\n", entry->name);
    }

    plugin->internal_params = entry->params;
  }
}
Пример #2
0
/*
 * Creates a zero-length locking file and use fcntl to
 * place an exclusive lock over it. The lock will be
 * automatically erased when the olsrd process ends,
 * so it will even work well with a SIGKILL.
 *
 * Additionally the lock can be killed by removing the
 * locking file.
 */
static int olsr_create_lock_file(bool noExitOnFail) {
#ifdef WIN32
  HANDLE lck = CreateEvent(NULL, TRUE, FALSE, lock_file_name);
  if (NULL == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
    if (noenoExitOnFail) {
      return -1;
    }
    if (NULL == lck) {
      fprintf(stderr,
          "Error, cannot create OLSR lock '%s'.\n",
          lock_file_name);
    } else {
      CloseHandle(lck);
      fprintf(stderr,
          "Error, cannot aquire OLSR lock '%s'.\n"
          "Another OLSR instance might be running.\n",
          lock_file_name);
    }
    olsr_exit("", EXIT_FAILURE);
  }
#else
  struct flock lck;

  /* create file for lock */
  lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
  if (lock_fd == 0) {
    if (noExitOnFail) {
      return -1;
    }
    fprintf(stderr,
        "Error, cannot create OLSR lock '%s'.\n",
        lock_file_name);
    olsr_exit("", EXIT_FAILURE);
  }

  /* create exclusive lock for the whole file */
  lck.l_type = F_WRLCK;
  lck.l_whence = SEEK_SET;
  lck.l_start = 0;
  lck.l_len = 0;
  lck.l_pid = 0;

  if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
    close(lock_fd);
    if (noExitOnFail) {
      return -1;
    }
    fprintf(stderr,
        "Error, cannot aquire OLSR lock '%s'.\n"
        "Another OLSR instance might be running.\n",
        lock_file_name);
    olsr_exit("", EXIT_FAILURE);
  }
#endif
  return 0;
}
Пример #3
0
/**
 *Create the socket to use for IPC to the
 *GUI front-end
 *
 *@return the socket FD
 */
int
ipc_init(void)
{
  //int flags;
  struct   sockaddr_in sin;
  int yes = 1;

  /* Add parser function */
  olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS, 0);

  /* get an internet domain socket */
  if ((ipc_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
    {
      perror("IPC socket");
      olsr_exit("IPC socket", EXIT_FAILURE);
    }

  if(setsockopt(ipc_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) 
    {
      perror("SO_REUSEADDR failed");
      return 0;
    }

  /* complete the socket structure */
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = INADDR_ANY;
  sin.sin_port = htons(IPC_PORT);

  /* bind the socket to the port number */
  if(bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) 
    {
      perror("IPC bind");
      OLSR_PRINTF(1, "Will retry in 10 seconds...\n");
      sleep(10);
      if(bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) 
	{
	  perror("IPC bind");
	  olsr_exit("IPC bind", EXIT_FAILURE);
	}
      OLSR_PRINTF(1, "OK\n");
    }

  /* show that we are willing to listen */
  if(listen(ipc_sock, olsr_cnf->ipc_connections) == -1) 
    {
      perror("IPC listen");
      olsr_exit("IPC listen", EXIT_FAILURE);
    }

  /* Register the socket with the socket parser */
  add_olsr_socket(ipc_sock, &ipc_accept);

  return ipc_sock;
}
Пример #4
0
void
olsr_pktbuf_grow_capa(olsr_pktbuf_t *self)
{
  int new_capa = (int)self->capa + BUF_GROW_SIZE;
  if (self->capa == 0)
    {
      olsr_exit("try to modify read only pktbuf.", 1);
    }
  self->data = (olsr_u8_t *)realloc(self->data, new_capa);
  if (self->data == NULL)
    {
      olsr_exit("cannot allocate memory.", 1);
    }
  self->capa = new_capa;
}
Пример #5
0
void
ipc_accept(int fd)
{
  socklen_t addrlen;
  struct sockaddr_in pin;
  char *addr;  


  addrlen = sizeof (struct sockaddr_in);
  
  if ((ipc_conn = accept(fd, (struct sockaddr *)  &pin, &addrlen)) == -1)
    {
      perror("IPC accept");
      olsr_exit("IPC accept", EXIT_FAILURE);
    }
  else
    {
      OLSR_PRINTF(1, "Front end connected\n");
      addr = inet_ntoa(pin.sin_addr);
      if(ipc_check_allowed_ip((union olsr_ip_addr *)&pin.sin_addr.s_addr))
	{
	  ipc_active = OLSR_TRUE;
	  ipc_send_net_info(ipc_conn);
	  ipc_send_all_routes(ipc_conn);
	  OLSR_PRINTF(1, "Connection from %s\n",addr);
	}
      else
	{
	  OLSR_PRINTF(1, "Front end-connection from foregin host(%s) not allowed!\n", addr);
	  olsr_syslog(OLSR_LOG_ERR, "OLSR: Front end-connection from foregin host(%s) not allowed!\n", addr);
	  CLOSE(ipc_conn);
	}
    }

}
Пример #6
0
/**
 * Init datastructures for maintaining timers.
 */
void
olsr_init_timers(void)
{
  int idx;

  OLSR_PRINTF(3, "Initializing scheduler.\n");

  /* Grab initial timestamp */
  if (gettimeofday(&first_tv, NULL)) {
    olsr_exit("OS clock is not working, have to shut down OLSR", 1);
  }
  last_tv = first_tv;
  now_times = olsr_times();

  for (idx = 0; idx < TIMER_WHEEL_SLOTS; idx++) {
    list_head_init(&timer_wheel[idx]);
  }

  /*
   * Reset the last timer run.
   */
  timer_last_run = now_times;

  /* Allocate a cookie for the block based memeory manager. */
  timer_mem_cookie = olsr_alloc_cookie("timer_entry", OLSR_COOKIE_TYPE_MEMORY);
  olsr_cookie_set_memory_size(timer_mem_cookie, sizeof(struct timer_entry));
}
Пример #7
0
unsigned char
*zpacket_redistribute (uint16_t cmd, unsigned char type)
{
  unsigned char *data, *pnt;
  uint16_t size;

  data = olsr_malloc(ZEBRA_MAX_PACKET_SIZ , "QUAGGA: New redistribute packet");

  pnt = &data[2];
  switch (zebra.version) {
  case 0:
    *pnt++ = (unsigned char) cmd;
    break;
  case 1:
  case 2:
    *pnt++ = ZEBRA_HEADER_MARKER;
    *pnt++ = zebra.version;
    cmd = htons(cmd);
    memcpy(pnt, &cmd, sizeof cmd);
    pnt += sizeof cmd;
    break;
  default:
    olsr_exit("(QUAGGA) Unsupported zebra packet version!\n", EXIT_FAILURE);
    break;
  }
  *pnt++ = type;
  size = htons(pnt - data);
  memcpy(data, &size, sizeof size);

  return data;
}
Пример #8
0
/*
 * A wrapper around times(2). Note, that this function has some
 * portability problems, so do not rely on absolute values returned.
 * Under Linux, uclibc and libc directly call the sys_times() located
 * in kernel/sys.c and will only return an error if the tms_buf is
 * not writeable.
 */
static uint32_t
olsr_times(void)
{
  struct timeval tv;
  uint32_t t;

  if (gettimeofday(&tv, NULL) != 0) {
    olsr_exit("OS clock is not working, have to shut down OLSR", 1);
  }

  /* test if time jumped backward or more than 60 seconds forward */
  if (tv.tv_sec < last_tv.tv_sec || (tv.tv_sec == last_tv.tv_sec && tv.tv_usec < last_tv.tv_usec)
      || tv.tv_sec - last_tv.tv_sec > 60) {
    OLSR_PRINTF(1, "Time jump (%d.%06d to %d.%06d)\n",
              (int32_t) (last_tv.tv_sec), (int32_t) (last_tv.tv_usec), (int32_t) (tv.tv_sec), (int32_t) (tv.tv_usec));

    t = (last_tv.tv_sec - first_tv.tv_sec) * 1000 + (last_tv.tv_usec - first_tv.tv_usec) / 1000;
    t++;                        /* advance time by one millisecond */

    first_tv = tv;
    first_tv.tv_sec -= (t / 1000);
    first_tv.tv_usec -= ((t % 1000) * 1000);

    if (first_tv.tv_usec < 0) {
      first_tv.tv_sec--;
      first_tv.tv_usec += 1000000;
    }
    last_tv = tv;
    return t;
  }
  last_tv = tv;
  return (tv.tv_sec - first_tv.tv_sec) * 1000 + (tv.tv_usec - first_tv.tv_usec) / 1000;
}
Пример #9
0
Файл: net.c Проект: Dany3R9/Proj
/**
 * Setup global interface options (icmp redirect, ip forwarding, rp_filter)
 * @return 1 on success 0 on failure
 */
void
net_os_set_global_ifoptions(void) {

  if (writeToProc(olsr_cnf->ip_version == AF_INET ? PROC_IPFORWARD_V4 : PROC_IPFORWARD_V6, &orig_fwd_state,
          olsr_cnf->set_ip_forward ? OLSRD_FORWARD_VALUE : 0 )) {
    OLSR_PRINTF(1, "Warning, could not enable IP forwarding!\n"
        "you should manually ensure that IP forwarding is enabled!\n\n");
    olsr_startup_sleep(3);
  }
  else if ((!olsr_cnf->set_ip_forward) && (orig_fwd_state != OLSRD_FORWARD_VALUE)) {
    olsr_exit("IP forwarding not activated, shutting down.\n", 1);
  }

  if (olsr_cnf->smart_gw_active) {
    char procfile[FILENAME_MAX];

    /* Generate the procfile name */
    if (olsr_cnf->ip_version == AF_INET || olsr_cnf->use_niit) {
      snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, TUNNEL_ENDPOINT_IF);
      if (writeToProc(procfile, &orig_tunnel_rp_filter, OLSRD_SPOOF_VALUE)) {
        OLSR_PRINTF(0, "WARNING! Could not disable the IP spoof filter for tunnel!\n"
            "you should manually ensure that IP spoof filtering is disabled!\n\n");

        olsr_startup_sleep(3);
      }
    }

#if 0 // should not be necessary for IPv6
    if (olsr_cnf->ip_version == AF_INET6) {
      snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, TUNNEL_ENDPOINT_IF6);
      if (writeToProc(procfile, &orig_tunnel6_rp_filter, OLSRD_SPOOF_VALUE)) {
        OLSR_PRINTF(0, "WARNING! Could not disable the IP spoof filter for tunnel6!\n"
            "you should manually ensure that IP spoof filtering is disabled!\n\n");

        olsr_startup_sleep(3);
      }
    }
#endif
  }

  if (olsr_cnf->ip_version == AF_INET) {
    if (writeToProc(PROC_ALL_REDIRECT, &orig_global_redirect_state, OLSRD_REDIRECT_VALUE)) {
      OLSR_PRINTF(1, "WARNING! Could not disable ICMP redirects!\n"
          "you should manually ensure that ICMP redirects are disabled!\n\n");

      olsr_startup_sleep(3);
    }

    /* check kernel version and disable global rp_filter */
    if (is_at_least_linuxkernel_2_6_31()) {
      if (writeToProc(PROC_ALL_SPOOF, &orig_global_rp_filter, OLSRD_SPOOF_VALUE)) {
        OLSR_PRINTF(1, "WARNING! Could not disable global rp_filter (necessary for kernel 2.6.31 and higher!\n"
            "you should manually ensure that rp_filter is disabled!\n\n");

        olsr_startup_sleep(3);
      }
    }
  }
  return;
}
Пример #10
0
static void
check_buffspace(int msgsize, int buffsize, const char *type)
{
  if (msgsize > buffsize) {
    char buf[1024];
    snprintf(buf, sizeof(buf), "%s: %s build, output buffer too small (%d/%u)", __func__, type, msgsize, buffsize);
    olsr_exit(buf, EXIT_FAILURE);
  }
}
Пример #11
0
static void
check_buffspace(int msgsize, int buffsize, const char *type)
{
  if (msgsize > buffsize) {
    OLSR_PRINTF(1, "%s build, outputbuffer to small(%d/%u)!\n", type, msgsize, buffsize);
    olsr_syslog(OLSR_LOG_ERR, "%s build, outputbuffer to small(%d/%u)!\n", type, msgsize, buffsize);
    olsr_exit(__func__, EXIT_FAILURE);
  }
}
Пример #12
0
/**
 * Activate a LQ handler
 * @param name
 */
static void
activate_lq_handler(const char *name)
{
  struct lq_handler_node *node;

  node = (struct lq_handler_node *)avl_find(&lq_handler_tree, name);
  if (node == NULL) {
    OLSR_PRINTF(1, "Error, unknown lq_handler '%s'\n", name);
    olsr_exit("", 1);
  }

  OLSR_PRINTF(1, "Using '%s' algorithm for lq calculation.\n", name);
  active_lq_handler = node->handler;
  active_lq_handler->initialize();
}
Пример #13
0
void *
olsr_malloc(size_t size, const char *id)
{
  void *ptr = NULL;

  if (size > 0 )                     //Zero byte memory allocation fix
  {
      if ((ptr = malloc(size)) == 0)
        {
          olsr_exit((char *)id, EXIT_FAILURE);
        }
//Added for Solaris mismatch
  memset(ptr, 0, size);
//Added for Solaris mismatch
  }
  return ptr;
}
Пример #14
0
/**
 * Enables all plugins of a certain type
 * @param type PLUGIN_TYPE_ALL, PLUGIN_TYPE_LQ or PLUGIN_TYPE_DEFAULT
 * @param fail_fast if true OLSRd will exit if a plugin throws an error
 *   by the enable callback
 */
void
olsr_plugins_enable(enum plugin_type type, bool fail_fast) {
  struct olsr_plugin *plugin, *iterator;

  /* activate all plugins (configured and static linked ones) */
  OLSR_FOR_ALL_PLUGIN_ENTRIES(plugin, iterator) {
    if ((type != PLUGIN_TYPE_ALL && type != plugin->type) || plugin->internal_active) {
      continue;
    }

    if (olsr_enable_plugin(plugin)) {
      if (fail_fast) {
        OLSR_ERROR(LOG_PLUGINS, "Error, cannot activate plugin %s.\n", plugin->name);
        olsr_exit(1);
      }
      OLSR_WARN(LOG_PLUGINS, "Error, cannot activate plugin %s.\n", plugin->name);
    }
  }
  OLSR_INFO(LOG_PLUGINS, "All plugins loaded.\n");
}
Пример #15
0
/**
 *Creates a nonblocking IPv6 socket
 *@param sin sockaddr_in6 struct. Used for bind(2).
 *@return the FD of the socket or -1 on error.
 */
int
os_getsocket6(const char *if_name, uint16_t port, int bufspace, union olsr_sockaddr *bindto)
{
  struct sockaddr_in6 sin6;
  int on;
  int sock = socket(AF_INET6, SOCK_DGRAM, 0);
  if (sock < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno));
    olsr_exit(EXIT_FAILURE);
  }
#ifdef IPV6_V6ONLY
  on = 1;
  if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
    OLSR_WARN(LOG_NETWORKING, "Cannot set socket for OLSR PDUs to ipv6 only (%s)\n", strerror(errno));
  }
#endif


  //#ifdef SO_BROADCAST
  /*
     if (setsockopt(sock, SOL_SOCKET, SO_MULTICAST, &on, sizeof(on)) < 0)
     {
     perror("setsockopt");
     syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
     close(sock);
     return (-1);
     }
   */
  //#endif

#ifdef SO_RCVBUF
  if(bufspace > 0) {
    for (on = bufspace;; on -= 1024) {
      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) {
        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
        break;
      }
      if (on <= 8 * 1024) {
        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
        break;
      }
    }
  }
#endif

  on = 1;
  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for socket for OLSR PDUs (%s)\n", strerror(errno));
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }

  /*
   * we are abusing "on" here. The value is 1 which is our intended
   * hop limit value.
   */
  if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &on, sizeof(on)) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot set multicast hops to 1 for socket for OLSR PDUs (%s)\n", strerror(errno));
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }


  /*
   * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
   */

  /* Bind to device */
  if (bind_socket_to_device(sock, if_name) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s: %s (%d)\n", if_name, strerror(errno), errno);
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }

  if (bindto == NULL) {
    memset(&sin6, 0, sizeof(sin6));
    sin6.sin6_family = AF_INET6;
    sin6.sin6_port = htons(port);
    bindto = (union olsr_sockaddr *)&sin6;
  }
  if (bind(sock, &bindto->std, sizeof(*bindto)) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs (%s)\n", strerror(errno));
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }

  os_socket_set_nonblocking(sock);
  return sock;
}
Пример #16
0
/**
 *Creates a nonblocking broadcast socket.
 *@param sa sockaddr struct. Used for bind(2).
 *@return the FD of the socket or -1 on error.
 */
int
os_getsocket4(const char *if_name, uint16_t port, int bufspace, union olsr_sockaddr *bindto)
{
  struct sockaddr_in sin4;
  int on;
  int sock = socket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno));
    olsr_exit(EXIT_FAILURE);
  }

  on = 1;
#ifdef SO_BROADCAST
  if (bindto) {
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
      OLSR_ERROR(LOG_NETWORKING, "Cannot set socket for OLSR PDUs to broadcast mode (%s)\n", strerror(errno));
      close(sock);
      olsr_exit(EXIT_FAILURE);
    }
  }
#endif

  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for OLSR PDUs (%s)\n", strerror(errno));
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }
#ifdef SO_RCVBUF
  if(bufspace > 0) {
    for (on = bufspace;; on -= 1024) {
      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) {
        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
        break;
      }
      if (on <= 8 * 1024) {
        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
        break;
      }
    }
  }
#endif

  /*
   * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
   */

  /* Bind to device */
  if (bind_socket_to_device(sock, if_name) < 0) {
    OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s: %s (%d)\n", if_name, strerror(errno), errno);
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }

  if (bindto == NULL) {
    memset(&sin4, 0, sizeof(sin4));
    sin4.sin_family = AF_INET;
    sin4.sin_port = htons(port);
    sin4.sin_addr.s_addr = 0;
    bindto = (union olsr_sockaddr *)&sin4;
  }
  if (bind(sock, &bindto->std, sizeof(*bindto)) < 0) {
#if !defined(REMOVE_LOG_ERROR)
    struct ipaddr_str buf;
#endif
    OLSR_ERROR(LOG_NETWORKING, "Could not bind socket for OLSR PDUs to %s/%d: %s (%d)\n",
        inet_ntop(AF_INET, &sin4.sin_addr, buf.buf, sizeof(buf)), port, strerror(errno), errno);
    close(sock);
    olsr_exit(EXIT_FAILURE);
  }

  os_socket_set_nonblocking(sock);
  return sock;
}
Пример #17
0
/*
 * Allocate a fixed amount of memory based on a passed in cookie type.
 */
void *
olsr_cookie_malloc(struct olsr_cookie_info *ci)
{
  void *ptr;
  struct olsr_cookie_mem_brand *branding;
  struct list_node *free_list_node;

#ifdef OLSR_COOKIE_DEBUG
  bool reuse = false;
#endif

  /*
   * Check first if we have reusable memory.
   */
  if (!ci->ci_free_list_usage) {

    /*
     * No reusable memory block on the free_list.
     */
    ptr = calloc(1, ci->ci_size + sizeof(struct olsr_cookie_mem_brand));

    if (!ptr) {
      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(ci->ci_name, EXIT_FAILURE);
    }
  } else {

    /*
     * There is a memory block on the free list.
     * Carve it out of the list, and clean.
     */
    free_list_node = ci->ci_free_list.next;
    list_remove(free_list_node);
    ptr = (void *)free_list_node;
    memset(ptr, 0, ci->ci_size);
    ci->ci_free_list_usage--;
#ifdef OLSR_COOKIE_DEBUG
    reuse = true;
#endif
  }

  /*
   * Now brand mark the end of the memory block with a short signature
   * indicating presence of a cookie. This will be checked against
   * When the block is freed to detect corruption.
   */
  branding = (struct olsr_cookie_mem_brand *)ARM_NOWARN_ALIGN(((unsigned char *)ptr + ci->ci_size));
  memcpy(&branding->cmb_sig, "cookie", 6);
  branding->cmb_id = ci->ci_id;

  /* Stats keeping */
  olsr_cookie_usage_incr(ci->ci_id);

#ifdef OLSR_COOKIE_DEBUG
  OLSR_PRINTF(1, "MEMORY: alloc %s, %p, %u bytes%s\n", ci->ci_name, ptr, ci->ci_size, reuse ? ", reuse" : "");
#endif

  return ptr;
}
Пример #18
0
void
olsr_remove_interface(struct olsr_if * iface)
{
  struct interface *ifp, *tmp_ifp;
  ifp = iface->interf;

  OLSR_PRINTF(1, "Removing interface %s (%d)\n", iface->name, ifp->if_index);
  olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);

  olsr_delete_link_entry_by_ip(&ifp->ip_addr);

  /*
   *Call possible ifchange functions registered by plugins
   */
  olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_REMOVE);

  /* cleanup routes over this interface */
  olsr_delete_interface_routes(ifp->if_index);

  /* Dequeue */
  if (ifp == ifnet) {
    ifnet = ifp->int_next;
  } else {
    tmp_ifp = ifnet;
    while (tmp_ifp->int_next != ifp) {
      tmp_ifp = tmp_ifp->int_next;
    }
    tmp_ifp->int_next = ifp->int_next;
  }

  /* Remove output buffer */
  net_remove_buffer(ifp);

  /* Check main addr */
  /* deactivated to prevent change of originator IP */
#if 0
  if (ipequal(&olsr_cnf->main_addr, &ifp->ip_addr)) {
    if (ifnet == NULL) {
      /* No more interfaces */
      memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
      OLSR_PRINTF(1, "No more interfaces...\n");
    } else {
      struct ipaddr_str buf;
      olsr_cnf->main_addr = ifnet->ip_addr;
      OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
      olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
    }
  }
#endif /* 0 */
  /*
   * Deregister functions for periodic message generation
   */
  olsr_stop_timer(ifp->hello_gen_timer);
  olsr_stop_timer(ifp->tc_gen_timer);
  olsr_stop_timer(ifp->mid_gen_timer);
  olsr_stop_timer(ifp->hna_gen_timer);

  iface->configured = 0;
  iface->interf = NULL;

  /* Close olsr socket */
  remove_olsr_socket(ifp->olsr_socket, &olsr_input, NULL);
  close(ifp->olsr_socket);

  remove_olsr_socket(ifp->send_socket, &olsr_input, NULL);
  close(ifp->send_socket);

  /* Free memory */
  free(ifp->int_name);
  free(ifp);

  if ((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces)) {
    olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
    olsr_exit("No more active interfaces - exiting.\n", EXIT_FAILURE);
  }
}
Пример #19
0
unsigned char
*zpacket_route(uint16_t cmd, struct zroute *r)
{
  int count;
  uint8_t len;
  uint16_t size, safi;
  uint32_t ind, metric;
  unsigned char *cmdopt, *t;

  cmdopt = olsr_malloc(ZEBRA_MAX_PACKET_SIZ, "QUAGGA: New route packet");

  t = &cmdopt[2];
  switch (zebra.version) {
  case 0:
    *t++ = (unsigned char) cmd;
    break;
  case 1:
  case 2:
    *t++ = ZEBRA_HEADER_MARKER;
    *t++ = zebra.version;
    cmd = htons(cmd);
    memcpy(t, &cmd, sizeof cmd);
    t += sizeof cmd;
    break;
  default:
    olsr_exit("(QUAGGA) Unsupported zebra packet version!\n", EXIT_FAILURE);
    break;
  }
  *t++ = r->type;
  *t++ = r->flags;
  *t++ = r->message;
  switch (zebra.version) {
  case 0:
  case 1:
    break;
  case 2:
    safi = htons(r->safi);
    memcpy(t, &safi, sizeof safi);
    t += sizeof safi;
    break;
  default:
    olsr_exit("(QUAGGA) Unsupported zebra packet version!\n", EXIT_FAILURE);
    break;
  }
  *t++ = r->prefixlen;
  len = (r->prefixlen + 7) / 8;
  if (olsr_cnf->ip_version == AF_INET)
    memcpy(t, &r->prefix.v4.s_addr, len);
  else
    memcpy(t, r->prefix.v6.s6_addr, len);
  t = t + len;

  if (r->message & ZAPI_MESSAGE_NEXTHOP) {
    *t++ = r->nexthop_num + r->ifindex_num;

    for (count = 0; count < r->nexthop_num; count++) {
      if (olsr_cnf->ip_version == AF_INET) {
        *t++ = ZEBRA_NEXTHOP_IPV4;
        memcpy(t, &r->nexthop[count].v4.s_addr, sizeof r->nexthop[count].v4.s_addr);
        t += sizeof r->nexthop[count].v4.s_addr;
      } else {
        *t++ = ZEBRA_NEXTHOP_IPV6;
        memcpy(t, r->nexthop[count].v6.s6_addr, sizeof r->nexthop[count].v6.s6_addr);
        t += sizeof r->nexthop[count].v6.s6_addr;
      }
    }
    for (count = 0; count < r->ifindex_num; count++) {
      *t++ = ZEBRA_NEXTHOP_IFINDEX;
      ind = htonl(r->ifindex[count]);
      memcpy(t, &ind, sizeof ind);
      t += sizeof ind;
    }
  }
  if ((r->message & ZAPI_MESSAGE_DISTANCE) > 0)
    *t++ = r->distance;
  if ((r->message & ZAPI_MESSAGE_METRIC) > 0) {
    metric = htonl(r->metric);
    memcpy(t, &metric, sizeof metric);
    t += sizeof metric;
  }
  size = htons(t - cmdopt);
  memcpy(cmdopt, &size, sizeof size);

  return cmdopt;
}
Пример #20
0
/*
 * Creates a zero-length locking file and use fcntl to
 * place an exclusive lock over it. The lock will be
 * automatically erased when the olsrd process ends,
 * so it will even work well with a SIGKILL.
 *
 * Additionally the lock can be killed by removing the
 * locking file.
 */
static int olsr_create_lock_file(bool noExitOnFail) {
#ifdef WIN32
    bool success;
    HANDLE lck;

    lck = CreateFile(lock_file_name,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_ALWAYS,
            FILE_ATTRIBUTE_NORMAL |
            FILE_FLAG_DELETE_ON_CLOSE,
            NULL);
  CreateEvent(NULL, TRUE, FALSE, lock_file_name);
  if (INVALID_HANDLE_VALUE == lck || ERROR_ALREADY_EXISTS == GetLastError()) {
    if (noExitOnFail) {
      return -1;
    }
    if (NULL == lck) {
      fprintf(stderr,
          "Error, cannot create OLSR lock '%s'.\n",
          lock_file_name);
    } else {
      CloseHandle(lck);
      fprintf(stderr,
          "Error, cannot aquire OLSR lock '%s'.\n"
          "Another OLSR instance might be running.\n",
          lock_file_name);
    }
    olsr_exit("", EXIT_FAILURE);
  }

  success = LockFile( lck, 0, 0, 0, 0);

  if (!success) {
      CloseHandle(lck);
      if (noExitOnFail) {
          return -1;
      }
      fprintf(stderr,
          "Error, cannot aquire OLSR lock '%s'.\n"
          "Another OLSR instance might be running.\n",
          lock_file_name);
    olsr_exit("", EXIT_FAILURE);
  }
      
#else
  struct flock lck;

  /* create file for lock */
  lock_fd = open(lock_file_name, O_WRONLY | O_CREAT, S_IRWXU);
  if (lock_fd == 0) {
    if (noExitOnFail) {
      return -1;
    }
    fprintf(stderr,
        "Error, cannot create OLSR lock '%s'.\n",
        lock_file_name);
    olsr_exit("", EXIT_FAILURE);
  }

  /* create exclusive lock for the whole file */
  lck.l_type = F_WRLCK;
  lck.l_whence = SEEK_SET;
  lck.l_start = 0;
  lck.l_len = 0;
  lck.l_pid = 0;

  if (fcntl(lock_fd, F_SETLK, &lck) == -1) {
    close(lock_fd);
    if (noExitOnFail) {
      return -1;
    }
    fprintf(stderr,
        "Error, cannot aquire OLSR lock '%s'.\n"
        "Another OLSR instance might be running.\n",
        lock_file_name);
    olsr_exit("", EXIT_FAILURE);
  }
#endif
  return 0;
}
Пример #21
0
/**
 * Process command line arguments passed to olsrd
 *
 */
static int olsr_process_arguments(int argc, char *argv[],
    struct olsrd_config *cnf, struct if_config_options *ifcnf) {
  while (argc > 1) {
    NEXT_ARG;
#ifdef WIN32
    /*
     *Interface list
     */
    if (strcmp(*argv, "-int") == 0) {
      ListInterfaces();
      exit(0);
    }
#endif

    /*
     *Configfilename
     */
    if (strcmp(*argv, "-f") == 0) {
      fprintf(stderr, "Configfilename must ALWAYS be first argument!\n\n");
      olsr_exit(__func__, EXIT_FAILURE);
    }

    /*
     *Use IP version 6
     */
    if (strcmp(*argv, "-ipv6") == 0) {
      cnf->ip_version = AF_INET6;
      continue;
    }

    /*
     *Broadcast address
     */
    if (strcmp(*argv, "-bcast") == 0) {
      struct in_addr in;
      NEXT_ARG;
      CHECK_ARGC;

      if (inet_aton(*argv, &in) == 0) {
        printf("Invalid broadcast address! %s\nSkipping it!\n", *argv);
        continue;
      }
      memcpy(&ifcnf->ipv4_multicast.v4, &in.s_addr, sizeof(ifcnf->ipv4_multicast.v4));
      continue;
    }

    /*
     * Set LQ level
     */
    if (strcmp(*argv, "-lql") == 0) {
      int tmp_lq_level;
      NEXT_ARG;
      CHECK_ARGC;

      /* Sanity checking is done later */
      sscanf(*argv, "%d", &tmp_lq_level);
      olsr_cnf->lq_level = tmp_lq_level;
      continue;
    }

    /*
     * Set LQ winsize
     */
    if (strcmp(*argv, "-lqa") == 0) {
      float tmp_lq_aging;
      NEXT_ARG;
      CHECK_ARGC;

      sscanf(*argv, "%f", &tmp_lq_aging);

      if (tmp_lq_aging < MIN_LQ_AGING || tmp_lq_aging > MAX_LQ_AGING) {
        printf("LQ aging factor %f not allowed. Range [%f-%f]\n", tmp_lq_aging,
            MIN_LQ_AGING, MAX_LQ_AGING);
        olsr_exit(__func__, EXIT_FAILURE);
      }
      olsr_cnf->lq_aging = tmp_lq_aging;
      continue;
    }

    /*
     * Set NAT threshold
     */
    if (strcmp(*argv, "-lqnt") == 0) {
      float tmp_lq_nat_thresh;
      NEXT_ARG;
      CHECK_ARGC;

      sscanf(*argv, "%f", &tmp_lq_nat_thresh);

      if (tmp_lq_nat_thresh < 0.1 || tmp_lq_nat_thresh > 1.0) {
        printf("NAT threshold %f not allowed. Range [%f-%f]\n",
            tmp_lq_nat_thresh, 0.1, 1.0);
        olsr_exit(__func__, EXIT_FAILURE);
      }
      olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
      continue;
    }

    /*
     * Enable additional debugging information to be logged.
     */
    if (strcmp(*argv, "-d") == 0) {
      NEXT_ARG;
      CHECK_ARGC;

      sscanf(*argv, "%d", &cnf->debug_level);
      continue;
    }

    /*
     * Interfaces to be used by olsrd.
     */
    if (strcmp(*argv, "-i") == 0) {
      NEXT_ARG;
      CHECK_ARGC;

      if (*argv[0] == '-') {
        fprintf(stderr, "You must provide an interface label!\n");
        olsr_exit(__func__, EXIT_FAILURE);
      }
      printf("Queuing if %s\n", *argv);
      olsr_create_olsrif(*argv, false);

      while ((argc - 1) && (argv[1][0] != '-')) {
        NEXT_ARG;
        printf("Queuing if %s\n", *argv);
        olsr_create_olsrif(*argv, false);
      }

      continue;
    }
    /*
     * Set the hello interval to be used by olsrd.
     *
     */
    if (strcmp(*argv, "-hint") == 0) {
      NEXT_ARG;
      CHECK_ARGC;
      sscanf(*argv, "%f", &ifcnf->hello_params.emission_interval);
      ifcnf->hello_params.validity_time = ifcnf->hello_params.emission_interval
          * 3;
      continue;
    }

    /*
     * Set the HNA interval to be used by olsrd.
     *
     */
    if (strcmp(*argv, "-hnaint") == 0) {
      NEXT_ARG;
      CHECK_ARGC;
      sscanf(*argv, "%f", &ifcnf->hna_params.emission_interval);
      ifcnf->hna_params.validity_time = ifcnf->hna_params.emission_interval * 3;
      continue;
    }

    /*
     * Set the MID interval to be used by olsrd.
     *
     */
    if (strcmp(*argv, "-midint") == 0) {
      NEXT_ARG;
      CHECK_ARGC;
      sscanf(*argv, "%f", &ifcnf->mid_params.emission_interval);
      ifcnf->mid_params.validity_time = ifcnf->mid_params.emission_interval * 3;
      continue;
    }

    /*
     * Set the tc interval to be used by olsrd.
     *
     */
    if (strcmp(*argv, "-tcint") == 0) {
      NEXT_ARG;
      CHECK_ARGC;
      sscanf(*argv, "%f", &ifcnf->tc_params.emission_interval);
      ifcnf->tc_params.validity_time = ifcnf->tc_params.emission_interval * 3;
      continue;
    }

    /*
     * Set the polling interval to be used by olsrd.
     */
    if (strcmp(*argv, "-T") == 0) {
      NEXT_ARG;
      CHECK_ARGC;
      sscanf(*argv, "%f", &cnf->pollrate);
      continue;
    }

    /*
     * Should we display the contents of packages beeing sent?
     */
    if (strcmp(*argv, "-dispin") == 0) {
      parser_set_disp_pack_in(true);
      continue;
    }

    /*
     * Should we display the contents of incoming packages?
     */
    if (strcmp(*argv, "-dispout") == 0) {
      net_set_disp_pack_out(true);
      continue;
    }

    /*
     * Should we set up and send on a IPC socket for the front-end?
     */
    if (strcmp(*argv, "-ipc") == 0) {
      cnf->ipc_connections = 1;
      continue;
    }

    /*
     * IPv6 multicast addr
     */
    if (strcmp(*argv, "-multi") == 0) {
      struct in6_addr in6;
      NEXT_ARG;
      CHECK_ARGC;
      if (inet_pton(AF_INET6, *argv, &in6) <= 0) {
        fprintf(stderr, "Failed converting IP address %s\n", *argv);
        exit(EXIT_FAILURE);
      }

      memcpy(&ifcnf->ipv6_multicast, &in6, sizeof(struct in6_addr));

      continue;
    }

    /*
     * Host emulation
     */
    if (strcmp(*argv, "-hemu") == 0) {
      struct in_addr in;
      struct olsr_if *ifa;

      NEXT_ARG;
      CHECK_ARGC;
      if (inet_pton(AF_INET, *argv, &in) <= 0) {
        fprintf(stderr, "Failed converting IP address %s\n", *argv);
        exit(EXIT_FAILURE);
      }
      /* Add hemu interface */

      ifa = olsr_create_olsrif("hcif01", true);

      if (!ifa)
        continue;

      ifa->cnf = get_default_if_config();
      ifa->host_emul = true;
      memcpy(&ifa->hemu_ip, &in, sizeof(union olsr_ip_addr));
      cnf->host_emul = true;

      continue;
    }

    /*
     * Delete possible default GWs
     */
    if (strcmp(*argv, "-delgw") == 0) {
      olsr_cnf->del_gws = true;
      continue;
    }

    if (strcmp(*argv, "-nofork") == 0) {
      cnf->no_fork = true;
      continue;
    }

    return -1;
  }
  return 0;
}
Пример #22
0
int main(int argc, char *argv[]) {
  struct if_config_options *default_ifcnf;
  char conf_file_name[FILENAME_MAX];
  struct ipaddr_str buf;
  bool loadedConfig = false;
  int i;

#ifdef LINUX_NETLINK_ROUTING
  struct interface *ifn;
#endif

#ifdef WIN32
  WSADATA WsaData;
  size_t len;
#endif

  /* paranoia checks */
  assert(sizeof(uint8_t) == 1);
  assert(sizeof(uint16_t) == 2);
  assert(sizeof(uint32_t) == 4);
  assert(sizeof(int8_t) == 1);
  assert(sizeof(int16_t) == 2);
  assert(sizeof(int32_t) == 4);

  printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
      olsrd_version, build_date, build_host);

  if (argc == 2) {
    if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "/?") == 0) {
      print_usage(false);
      exit(0);
    }
    if (strcmp(argv[1], "-v") == 0) {
      exit(0);
    }
  }

  debug_handle = stdout;
#ifndef WIN32
  olsr_argv = argv;
#endif
  setbuf(stdout, NULL);
  setbuf(stderr, NULL);

#ifndef WIN32
  /* Check if user is root */
  if (geteuid()) {
    fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
    exit(EXIT_FAILURE);
  }
#else
  DisableIcmpRedirects();

  if (WSAStartup(0x0202, &WsaData)) {
    fprintf(stderr, "Could not initialize WinSock.\n");
    olsr_exit(__func__, EXIT_FAILURE);
  }
#endif

  /* Open syslog */
  olsr_openlog("olsrd");

  /* Using PID as random seed */
  srandom(getpid());

  /* Init widely used statics */
  memset(&all_zero, 0, sizeof(union olsr_ip_addr));

  /*
   * Set configfile name and
   * check if a configfile name was given as parameter
   */
#ifdef WIN32
#ifndef WINCE
  GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11);
#else
  conf_file_name[0] = 0;
#endif

  len = strlen(conf_file_name);

  if (len == 0 || conf_file_name[len - 1] != '\\')
  conf_file_name[len++] = '\\';

  strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len);
#else
  strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name));
#endif

  olsr_cnf = olsrd_get_default_cnf();
  for (i=1; i < argc-1;) {
    if (strcmp(argv[i], "-f") == 0) {
      loadedConfig = true;

      if (olsrmain_load_config(argv[i+1]) < 0) {
        exit(EXIT_FAILURE);
      }

      if (i+2 < argc) {
        memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1));
      }
      argc -= 2;
    }
    else {
      i++;
    }
  }

  /*
   * set up configuration prior to processing commandline options
   */
  if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) {
    loadedConfig = true;
  }

  if (!loadedConfig) {
    olsrd_free_cnf(olsr_cnf);
    olsr_cnf = olsrd_get_default_cnf();
  }

  default_ifcnf = get_default_if_config();
  if (default_ifcnf == NULL) {
    fprintf(stderr, "No default ifconfig found!\n");
    exit(EXIT_FAILURE);
  }

  /* Initialize timers */
  olsr_init_timers();

  /*
   * Process olsrd options.
   */
  if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) {
    print_usage(true);
    olsr_exit(__func__, EXIT_FAILURE);
  }

  /*
   * Set configuration for command-line specified interfaces
   */
  set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);

  /* free the default ifcnf */
  free(default_ifcnf);

  /* Sanity check configuration */
  if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
    fprintf(stderr, "Bad configuration!\n");
    olsr_exit(__func__, EXIT_FAILURE);
  }

  /*
   * Establish file lock to prevent multiple instances
   */
  if (olsr_cnf->lock_file) {
    strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name));
  } else {
    size_t l;
#ifdef DEFAULT_LOCKFILE_PREFIX
    strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name));
#else
    strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name));
#endif
    l = strlen(lock_file_name);
    snprintf(&lock_file_name[l], sizeof(lock_file_name) - l, "-ipv%d.lock",
        olsr_cnf->ip_version == AF_INET ? 4 : 6);
  }

  /*
   * Print configuration
   */
  if (olsr_cnf->debug_level > 1) {
    olsrd_print_cnf(olsr_cnf);
  }

  def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);

  /*
   * socket for ioctl calls
   */
  olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
  if (olsr_cnf->ioctl_s < 0) {
#ifndef WIN32
    olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m");
#endif
    olsr_exit(__func__, 0);
  }
#ifdef LINUX_NETLINK_ROUTING
  olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
  if (olsr_cnf->rtnl_s < 0) {
    olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
    olsr_exit(__func__, 0);
  }
  fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);

  if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
    olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m");
    olsr_exit(__func__, 0);
  }
#endif

  /*
   * create routing socket
   */
#if defined __FreeBSD__ || __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
  olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
  if (olsr_cnf->rts < 0) {
    olsr_syslog(OLSR_LOG_ERR, "routing socket: %m");
    olsr_exit(__func__, 0);
  }
#endif

#ifdef LINUX_NETLINK_ROUTING
  /* initialize gateway system */
  if (olsr_cnf->smart_gw_active) {
    if (olsr_init_gateways()) {
      olsr_exit("Cannot initialize gateway tunnels", 1);
    }
  }

  /* initialize niit if index */
  if (olsr_cnf->use_niit) {
    olsr_init_niit();
  }
#endif

  /* Init empty TC timer */
  set_empty_tc_timer(GET_TIMESTAMP(0));

  /* enable ip forwarding on host */
  /* Disable redirects globally */
#ifndef WIN32
  net_os_set_global_ifoptions();
#endif

  /* Initialize parser */
  olsr_init_parser();

  /* Initialize route-exporter */
  olsr_init_export_route();

  /* Initialize message sequencnumber */
  init_msg_seqno();

  /* Initialize dynamic willingness calculation */
  olsr_init_willingness();

  /*
   *Set up willingness/APM
   */
  if (olsr_cnf->willingness_auto) {
    if (apm_init() < 0) {
      OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);

      olsr_syslog(OLSR_LOG_ERR,
          "Could not read APM info - setting default willingness(%d)\n",
          WILL_DEFAULT);

      olsr_cnf->willingness_auto = 0;
      olsr_cnf->willingness = WILL_DEFAULT;
    } else {
      olsr_cnf->willingness = olsr_calculate_willingness();

      OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, olsr_cnf->will_int);
    }
  }

  /* Initialize net */
  init_net();

  /* Initializing networkinterfaces */
  if (!olsr_init_interfacedb()) {
    if (olsr_cnf->allow_no_interfaces) {
      fprintf(
          stderr,
          "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n");
      olsr_startup_sleep(5);
    } else {
      fprintf(stderr, "No interfaces detected!\nBailing out!\n");
      olsr_exit(__func__, EXIT_FAILURE);
    }
  }

  olsr_do_startup_sleep();

  /* Print heartbeat to stdout */

#if !defined WINCE
  if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
    olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
        &generate_stdout_pulse, NULL, 0);
  }
#endif

  /* Initialize the IPC socket */

  if (olsr_cnf->ipc_connections > 0) {
    ipc_init();
  }
  /* Initialisation of different tables to be used. */
  olsr_init_tables();

  /* daemon mode */
#ifndef WIN32
  if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
    printf("%s detaching from the current process...\n", olsrd_version);
    if (daemon(0, 0) < 0) {
      printf("daemon(3) failed: %s\n", strerror(errno));
      exit(EXIT_FAILURE);
    }
  }
#endif

  /*
   * Create locking file for olsrd, will be cleared after olsrd exits
   */
  for (i=5; i>=0; i--) {
    OLSR_PRINTF(3, "Trying to get olsrd lock...\n");
    if (olsr_create_lock_file(i > 0) == 0) {
      /* lock sucessfully created */
      break;
    }
    sleep (1);
  }

  /* Load plugins */
  olsr_load_plugins();

  OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));

#ifdef LINUX_NETLINK_ROUTING
  /* create policy routing priorities if necessary */
  if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
    olsr_os_policy_rule(olsr_cnf->ip_version,
        olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
  }
  if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
    olsr_os_policy_rule(olsr_cnf->ip_version,
        olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
  }
  if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
    olsr_os_policy_rule(olsr_cnf->ip_version,
        olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
  }

  /* OLSR sockets */
  if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
    for (ifn = ifnet; ifn; ifn = ifn->int_next) {
      olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
          olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
    }
  }

  /* trigger gateway selection */
  if (olsr_cnf->smart_gw_active) {
    olsr_trigger_inetgw_startup();
  }

  /* trigger niit static route setup */
  if (olsr_cnf->use_niit) {
    olsr_setup_niit_routes();
  }

  /* create lo:olsr interface */
  if (olsr_cnf->use_src_ip_routes) {
    olsr_os_localhost_if(&olsr_cnf->main_addr, true);
  }
#endif

  /* Start syslog entry */
  olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);

  /*
   *signal-handlers
   */

  /* ctrl-C and friends */
#ifdef WIN32
#ifndef WINCE
  SetConsoleCtrlHandler(SignalHandler, true);
#endif
#else
  signal(SIGHUP, olsr_reconfigure);
  signal(SIGINT, olsr_shutdown);
  signal(SIGQUIT, olsr_shutdown);
  signal(SIGILL, olsr_shutdown);
  signal(SIGABRT, olsr_shutdown);
  //  signal(SIGSEGV, olsr_shutdown);
  signal(SIGTERM, olsr_shutdown);
  signal(SIGPIPE, SIG_IGN);
  // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
  signal(SIGUSR1, SIG_IGN);
  signal(SIGUSR2, SIG_IGN);
#endif

  link_changes = false;

  /* Starting scheduler */
  olsr_scheduler();

  /* Like we're ever going to reach this ;-) */
  return 1;
} /* main */
Пример #23
0
static struct zroute
*zparse_route(unsigned char *opt)
{
  struct zroute *r;
  int c;
  size_t size;
  uint16_t length;
  unsigned char *pnt;

  memcpy(&length, opt, sizeof length);
  length = ntohs (length);

  r = olsr_malloc(sizeof *r, "QUAGGA: New zebra route");
  pnt = (zebra.version ? &opt[6] : &opt[3]);
  r->type = *pnt++;
  r->flags = *pnt++;
  r->message = *pnt++;
  r->prefixlen = *pnt++;
  size = (r->prefixlen + 7) / 8;
  memset(&r->prefix, 0, sizeof r->prefix);
  if (olsr_cnf->ip_version == AF_INET)
    memcpy(&r->prefix.v4.s_addr, pnt, size);
  else
    memcpy(r->prefix.v6.s6_addr, pnt, size);
  pnt += size;

  switch (zebra.version) {
    case 0:
    case 1:
      if (r->message & ZAPI_MESSAGE_NEXTHOP) {
        r->nexthop_num = *pnt++;
        r->nexthop = olsr_malloc((sizeof *r->nexthop) * r->nexthop_num, "QUAGGA: New zebra route nexthop");
        for (c = 0; c < r->nexthop_num; c++) {
          if (olsr_cnf->ip_version == AF_INET) {
            memcpy(&r->nexthop[c].v4.s_addr, pnt, sizeof r->nexthop[c].v4.s_addr);
            pnt += sizeof r->nexthop[c].v4.s_addr;
          } else {
            memcpy(r->nexthop[c].v6.s6_addr, pnt, sizeof r->nexthop[c].v6.s6_addr);
            pnt += sizeof r->nexthop[c].v6.s6_addr;
          }
        }
      }

      if (r->message & ZAPI_MESSAGE_IFINDEX) {
        r->ifindex_num = *pnt++;
        r->ifindex = olsr_malloc(sizeof(uint32_t) * r->ifindex_num, "QUAGGA: New zebra route ifindex");
        for (c = 0; c < r->ifindex_num; c++) {
          memcpy(&r->ifindex[c], pnt, sizeof r->ifindex[c]);
          r->ifindex[c] = ntohl (r->ifindex[c]);
          pnt += sizeof r->ifindex[c];
        }
      }
      break;
    default:
      OLSR_PRINTF(1, "(QUAGGA) Unsupported zebra packet version!\n");
      break;
  }

  if (r->message & ZAPI_MESSAGE_DISTANCE) {
    r->distance = *pnt++;
  }

// Quagga v0.98.6 BUG workaround: metric is always sent by zebra
// even without ZAPI_MESSAGE_METRIC message.
//  if (r.message & ZAPI_MESSAGE_METRIC) {
    memcpy(&r->metric, pnt, sizeof r->metric);
    r->metric = ntohl(r->metric);
    pnt += sizeof r->metric;
//  }

  if (pnt - opt != length) {
    olsr_exit("(QUAGGA) Length does not match!", EXIT_FAILURE);
  }

  return r;
}