Ejemplo n.º 1
0
void olsr_reconfigure(int signo __attribute__ ((unused))) {
  /* if we are started with -nofork, we do not weant to go into the
   * background here. So we can simply stop on -HUP
   */
  olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
  if (!olsr_cnf->no_fork) {
    if (!fork()) {
      int i;
      sigset_t sigs;
      /* New process */
      sleep(3);
      sigemptyset(&sigs);
      sigaddset(&sigs, SIGHUP);
      sigprocmask(SIG_UNBLOCK, &sigs, NULL);
      for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
        close(i);
      }
      printf("Restarting %s\n", olsr_argv[0]);
      olsr_syslog(OLSR_LOG_INFO, "Restarting %s\n", olsr_argv[0]);
      execv(olsr_argv[0], olsr_argv);
      olsr_syslog(OLSR_LOG_ERR, "execv(%s) fails: %s!\n", olsr_argv[0],
          strerror(errno));
    } else {
      olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING!\n");
    }
  }
  olsr_shutdown(0);
}
static int
delete_all_inet_gws(void)
{
  int s;
  char buf[BUFSIZ], *cp, *cplim;
  struct ifconf ifc;
  struct ifreq *ifr;

  OLSR_PRINTF(1, "Internet gateway detected...\nTrying to delete default gateways\n");

  /* Get a socket */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    olsr_syslog(OLSR_LOG_ERR, "socket: %m");
    return -1;
  }

  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
    olsr_syslog(OLSR_LOG_ERR, "ioctl (get interface configuration)");
    close(s);
    return -1;
  }

  ifr = ifc.ifc_req;
  cplim = buf + ifc.ifc_len;    /*skip over if's with big ifr_addr's */
  for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
    struct rtentry kernel_route;
    ifr = (struct ifreq *)cp;

    if (strcmp(ifr->ifr_ifrn.ifrn_name, "lo") == 0) {
      OLSR_PRINTF(1, "Skipping loopback...\n");
      continue;
    }

    OLSR_PRINTF(1, "Trying 0.0.0.0/0 %s...", ifr->ifr_ifrn.ifrn_name);

    memset(&kernel_route, 0, sizeof(struct rtentry));

    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = 0;
    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_family = AF_INET;
    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = 0;
    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_family = AF_INET;

    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr.s_addr = INADDR_ANY;
    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_family = AF_INET;

    kernel_route.rt_flags = RTF_UP | RTF_GATEWAY;

    kernel_route.rt_dev = ifr->ifr_ifrn.ifrn_name;

    if ((ioctl(s, SIOCDELRT, &kernel_route)) < 0)
      OLSR_PRINTF(1, "NO\n");
    else
      OLSR_PRINTF(1, "YES\n");
  }
  close(s);
  return 0;
}
Ejemplo n.º 3
0
/**
 * creates an ipip tunnel (for ipv4 or ipv6)
 *
 * @param name interface name
 * @param target pointer to tunnel target IP, NULL if tunnel should be removed.
 * Must be of type 'in_addr_t *' for ipv4 and of type 'struct in6_addr *' for
 * ipv6
 * @return 0 if an error happened,
 *   if_index for successful created tunnel, 1 for successful deleted tunnel
 */
static int os_ip_tunnel(const char *name, void *target) {
	struct ifreq ifr;
	int err;
	void * p;
	char buffer[INET6_ADDRSTRLEN];
	struct ip_tunnel_parm p4;
#ifdef LINUX_IPV6_TUNNEL
	struct ip6_tnl_parm p6;
#endif

	assert (name != NULL);

	memset(&ifr, 0, sizeof(ifr));

	if (olsr_cnf->ip_version == AF_INET) {
		p = &p4;

		memset(&p4, 0, sizeof(p4));
		p4.iph.version = 4;
		p4.iph.ihl = 5;
		p4.iph.ttl = 64;
		p4.iph.protocol = IPPROTO_IPIP;
		if (target) {
			p4.iph.daddr = *((in_addr_t *) target);
		}
		strncpy(p4.name, name, IFNAMSIZ);
	} else {
#ifdef LINUX_IPV6_TUNNEL
		p = (void *) &p6;

		memset(&p6, 0, sizeof(p6));
		p6.proto = 0; /* any protocol */
		if (target) {
			p6.raddr = *((struct in6_addr *) target);
		}
		strncpy(p6.name, name, IFNAMSIZ);
#else
		return 0;
#endif
	}

	strncpy(ifr.ifr_name, name, IFNAMSIZ);
	ifr.ifr_ifru.ifru_data = p;

	if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
		olsr_syslog(OLSR_LOG_ERR, "Cannot %s tunnel %s to %s: %s (%d)\n", target != NULL ? "add" : "remove", name,
				target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-", strerror(errno),
				errno);
		return 0;
	}

	olsr_syslog(OLSR_LOG_INFO, "Tunnel %s %s, to %s", name, target != NULL ? "added" : "removed",
			target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-");

	return target != NULL ? if_nametoindex(name) : 1;
}
static int os_ip6_tunnel(const char *name, struct in6_addr *target)
{
  struct ifreq ifr;
  int err;
  struct ip6_tnl_parm p;

  /* only IP6 tunnel if OLSR runs with IPv6 */
  assert (olsr_cnf->ip_version == AF_INET6);
  memset(&p, 0, sizeof(p));
  p.proto = 0; /* any protocol */
  if (target) {
    p.raddr = *target;
  }
  strncpy(p.name, name, IFNAMSIZ);

  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, target != NULL ? DEV_IPV6_TUNNEL : name, IFNAMSIZ);
  ifr.ifr_ifru.ifru_data = (void *) &p;

  if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
    char buffer[INET6_ADDRSTRLEN];

    olsr_syslog(OLSR_LOG_ERR, "Cannot %s a tunnel %s to %s: %s (%d)\n",
        target != NULL ? "add" : "remove", name,
        target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-",
        strerror(errno), errno);
    return 0;
  }
  return target != NULL ? if_nametoindex(name) : 1;
}
Ejemplo n.º 5
0
/**
 * Process a route from the kernel deletion list.
 *
 *@return -1 on error, else 0
 */
static int
olsr_delete_kernel_route(struct rt_entry *rt)
{
  if (rt->rt_metric.hops > 1) {
    /* multihop route */
    if (ip_is_linklocal(&rt->rt_dst.prefix)) {
      /* do not delete a route with a LL IP as a destination */
      return 0;
    }
  }

  if (!olsr_cnf->host_emul) {
    int16_t error = olsr_cnf->ip_version == AF_INET ? olsr_delroute_function(rt) : olsr_delroute6_function(rt);

    if (error != 0) {
      const char *const err_msg = strerror(errno);
      const char *const routestr = olsr_rt_to_string(rt);
      OLSR_PRINTF(1, "KERN: ERROR deleting %s: %s\n", routestr, err_msg);

      olsr_syslog(OLSR_LOG_ERR, "Delete route %s: %s", routestr, err_msg);
      return -1;
    }
#ifdef linux
    /* call NIIT handler (always)*/
    if (olsr_cnf->use_niit) {
      olsr_niit_handle_route(rt, false);
    }
#endif
  }
  return 0;
}
Ejemplo n.º 6
0
/**
 * Process a route from the kernel addition list.
 *
 *@return nada
 */
static void
olsr_add_kernel_route(struct rt_entry *rt)
{
  if (rt->rt_best->rtp_metric.hops > 1) {
    /* multihop route */
    if (ip_is_linklocal(&rt->rt_best->rtp_dst.prefix)) {
      /* do not create a route with a LL IP as a destination */
      return;
    }
  }
  if (!olsr_cnf->host_emul) {
    int16_t error = (olsr_cnf->ip_version == AF_INET) ? olsr_addroute_function(rt) : olsr_addroute6_function(rt);

    if (error != 0) {
      const char *const err_msg = strerror(errno);
      const char *const routestr = olsr_rtp_to_string(rt->rt_best);
      OLSR_PRINTF(1, "KERN: ERROR adding %s: %s\n", routestr, err_msg);

      olsr_syslog(OLSR_LOG_ERR, "Add route %s: %s", routestr, err_msg);
    } else {
      /* route addition has suceeded */

      /* save the nexthop and metric in the route entry */
      rt->rt_nexthop = rt->rt_best->rtp_nexthop;
      rt->rt_metric = rt->rt_best->rtp_metric;

#ifdef linux
      /* call NIIT handler */
      if (olsr_cnf->use_niit) {
        olsr_niit_handle_route(rt, true);
      }
#endif
    }
  }
}
Ejemplo n.º 7
0
Archivo: pud.c Proyecto: cholin/olsrd
/**
 Report a plugin error.

 @param useErrno
 when true then errno is used in the error message; the error reason is also
 reported.
 @param format
 a pointer to the format string
 @param ...
 arguments to the format string
 */
void pudError(bool useErrno, const char *format, ...) {
	char strDesc[256];
	const char *colon;
	const char *stringErr;

	if ((format == NULL) || (*format == '\0')) {
		strDesc[0] = '\0';
		colon = "";
		if (!useErrno) {
			stringErr = "Unknown error";
		} else {
			stringErr = strerror(errno);
		}
	} else {
		va_list arglist;

		va_start(arglist, format);
		vsnprintf(strDesc, sizeof(strDesc), format, arglist);
		va_end(arglist);

		if (useErrno) {
			colon = ": ";
			stringErr = strerror(errno);
		} else {
			colon = "";
			stringErr = "";
		}
	}

	if (!pudErrorUseSysLog)
		olsr_printf(0, "%s: %s%s%s\n", PUD_PLUGIN_ABBR, strDesc, colon, stringErr);
	else
		olsr_syslog(OLSR_LOG_ERR, "%s: %s%s%s\n", PUD_PLUGIN_ABBR, strDesc, colon, stringErr);
}
Ejemplo n.º 8
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);
	}
    }

}
/**
 * demands an ipip tunnel to a certain target. If no tunnel exists it will be created
 * @param target ip address of the target
 * @param transportV4 true if IPv4 traffic is used, false for IPv6 traffic
 * @return NULL if an error happened, pointer to olsr_iptunnel_entry otherwise
 */
struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target, bool transportV4 __attribute__ ((unused))) {
  struct olsr_iptunnel_entry *t;

  assert(olsr_cnf->ip_version == AF_INET6 || transportV4);

  t = (struct olsr_iptunnel_entry *)avl_find(&tunnel_tree, target);
  if (t == NULL) {
    char name[IFNAMSIZ];
    int if_idx;
    struct ipaddr_str buf;

    memset(name, 0, sizeof(name));
    generate_iptunnel_name(target, name);

    if (olsr_cnf->ip_version == AF_INET) {
      if_idx = os_ip4_tunnel(name, &target->v4.s_addr);
    }
    else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
      if_idx = os_ip6_tunnel(name, &target->v6);
#else
      if_idx = 0;
#endif
    }

    if (if_idx == 0) {
      // cannot create tunnel
      olsr_syslog(OLSR_LOG_ERR, "Cannot create tunnel %s\n", name);
      return NULL;
    }

    if (olsr_if_set_state(name, true)) {
      if (olsr_cnf->ip_version == AF_INET) {
        os_ip4_tunnel(name, NULL);
      }
      else {
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
        os_ip6_tunnel(name, NULL);
  #endif
      }
      return NULL;
    }

    /* set originator IP for tunnel */
    olsr_os_ifip(if_idx, &olsr_cnf->main_addr, true);

    t = olsr_cookie_malloc(tunnel_cookie);
    memcpy(&t->target, target, sizeof(*target));
    t->node.key = &t->target;

    strncpy(t->if_name, name, IFNAMSIZ);
    t->if_index = if_idx;

    avl_insert(&tunnel_tree, &t->node, AVL_DUP_NO);
  }

  t->usage++;
  return t;
}
Ejemplo n.º 10
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);
  }
}
Ejemplo n.º 11
0
static void
default_lq_parser_ffeth(struct olsr *olsr, struct interface *in_if, union olsr_ip_addr *from_addr)
{
  const union olsr_ip_addr *main_addr;
  struct link_entry *lnk;
  struct default_lq_ffeth_hello *lq;
  uint32_t seq_diff;

  /* Find main address */
  main_addr = mid_lookup_main_addr(from_addr);

  /* Loopup link entry */
  lnk = lookup_link_entry(from_addr, main_addr, in_if);
  if (lnk == NULL) {
    return;
  }

  lq = (struct default_lq_ffeth_hello *)lnk->linkquality;

  /* ignore double package */
  if (lq->last_seq_nr == olsr->olsr_seqno) {
    struct ipaddr_str buf;
    olsr_syslog(OLSR_LOG_INFO, "detected duplicate packet with seqnr %d from %s on %s (%d Bytes)",
		olsr->olsr_seqno,olsr_ip_to_string(&buf, from_addr),in_if->int_name,ntohs(olsr->olsr_packlen));
    return;
  }

  if (lq->last_seq_nr > olsr->olsr_seqno) {
    seq_diff = (uint32_t) olsr->olsr_seqno + 65536 - lq->last_seq_nr;
  } else {
    seq_diff = olsr->olsr_seqno - lq->last_seq_nr;
  }

  /* Jump in sequence numbers ? */
  if (seq_diff > 256) {
    seq_diff = 1;
  }

  lq->received[lq->activePtr]++;
  lq->total[lq->activePtr] += seq_diff;

  lq->last_seq_nr = olsr->olsr_seqno;
  lq->missed_hellos = 0;
}
Ejemplo n.º 12
0
Archivo: net.c Proyecto: Dany3R9/Proj
static int writeToProc(const char *file, char *old, char value) {
  int fd;
  char rv;

  if ((fd = open(file, O_RDWR)) < 0) {
    OLSR_PRINTF(0, "Error, cannot open proc entry %s: %s (%d)\n", file, strerror(errno), errno);
    return -1;
  }

  if (read(fd, &rv, 1) != 1) {
    OLSR_PRINTF(0, "Error, cannot read proc entry %s: %s (%d)\n", file, strerror(errno), errno);
    return -1;
  }

  if (rv != value && value != 0) {
    if (lseek(fd, SEEK_SET, 0) == -1) {
      OLSR_PRINTF(0, "Error, cannot rewind proc entry %s: %s (%d)\n", file, strerror(errno), errno);
      return -1;
    }

    if (write(fd, &value, 1) != 1) {
      OLSR_PRINTF(0, "Error, cannot write proc entry %s: %s (%d)\n", file, strerror(errno), errno);
      return -1;
    }
  }

  if (close(fd) != 0) {
    OLSR_PRINTF(0, "Error while closing proc entry %s: %s (%d)\n", file, strerror(errno), errno);
    return -1;
  }

  if (old) {
    *old = rv;
  }

  if (value) {
    olsr_syslog(OLSR_LOG_INFO, "Writing '%c' (was %c) to %s", value, rv, file);
  }
  return 0;
}
Ejemplo n.º 13
0
/**
 *Sends a packet on a given interface.
 *
 *@param ifp the interface to send on.
 *
 *@return negative on error
 */
int
net_output(struct interface_olsr *ifp)
{
  struct sockaddr_in *sin = NULL;
  struct sockaddr_in6 *sin6 = NULL;
  struct sockaddr_in dst;
  struct sockaddr_in6 dst6;
  struct ptf *tmp_ptf_list;
  union olsr_packet *outmsg;
  int retval;

  if (!ifp->netbuf.pending)
    return 0;

  ifp->netbuf.pending += OLSR_HEADERSIZE;

  retval = ifp->netbuf.pending;

  outmsg = (union olsr_packet *)ifp->netbuf.buff;
  /* Add the Packet seqno */
  outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
  /* Set the packetlength */
  outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);

  if (olsr_cnf->ip_version == AF_INET) {
    /* IP version 4 */
    sin = (struct sockaddr_in *)&ifp->int_broadaddr;

    /* Copy sin */
    dst = *sin;
    sin = &dst;

    if (sin->sin_port == 0)
      sin->sin_port = htons(olsr_cnf->olsrport);
  } else {
    /* IP version 6 */
    sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
    /* Copy sin */
    dst6 = *sin6;
    sin6 = &dst6;
  }

  /*
   *Call possible packet transform functions registered by plugins
   */
  for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next) {
    tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
  }

  if (olsr_cnf->ip_version == AF_INET) {
    /* IP version 4 */
    if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
        0) {
      perror("sendto(v4)");
#ifndef _WIN32
      olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 '%s' on interface %s", strerror(errno), ifp->int_name);
#endif /* _WIN32 */
      retval = -1;
    }
  } else {
    /* IP version 6 */
    if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
        < 0) {
      struct ipaddr_str buf;
      perror("sendto(v6)");
#ifndef _WIN32
      olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 '%s' on interface %s", strerror(errno), ifp->int_name);
#endif /* _WIN32 */
      fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);
      fprintf(stderr, "To: %s (size: %u)\n", ip6_to_string(&buf, &sin6->sin6_addr), (unsigned int)sizeof(*sin6));
      fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
      retval = -1;
    }
  }

  ifp->netbuf.pending = 0;

  /*
   * if we've just transmitted a TC message, let Dijkstra use the current
   * link qualities for the links to our neighbours
   */

  lq_tc_pending = false;

  return retval;
}
Ejemplo n.º 14
0
void
olsr_hello_tap(struct hello_message *message, struct interface *in_if, const union olsr_ip_addr *from_addr)
{
  struct neighbor_entry *neighbor;

  /*
   * Update link status
   */
  struct link_entry *lnk = update_link_entry(&in_if->ip_addr, from_addr, message, in_if);

  /*check alias message->source_addr*/
  if (!ipequal(&message->source_addr,from_addr)){
    /*new alias of new neighbour are thrown in the mid table to speed up routing*/
    if (olsr_validate_address(from_addr)) {
      union olsr_ip_addr * main_addr = mid_lookup_main_addr(from_addr);
      if ((main_addr==NULL)||(ipequal(&message->source_addr, main_addr))){
        /*struct ipaddr_str srcbuf, origbuf;
        olsr_syslog(OLSR_LOG_INFO, "got hello from unknown alias ip of direct neighbour: ip: %s main-ip: %s",
                    olsr_ip_to_string(&origbuf,&message->source_addr),
                    olsr_ip_to_string(&srcbuf,from_addr));*/
        insert_mid_alias(&message->source_addr, from_addr, message->vtime);
      }
      else
      {
        struct ipaddr_str srcbuf, origbuf;
        olsr_syslog(OLSR_LOG_INFO, "got hello with invalid from and originator adress pair (%s, %s) Duplicate Ips?\n",
                    olsr_ip_to_string(&origbuf,&message->source_addr),
                    olsr_ip_to_string(&srcbuf,from_addr));
      }
    }
  }

  if (olsr_cnf->lq_level > 0) {
    struct hello_neighbor *walker;
    /* just in case our neighbor has changed its HELLO interval */
    olsr_update_packet_loss_hello_int(lnk, message->htime);

    /* find the input interface in the list of neighbor interfaces */
    for (walker = message->neighbors; walker != NULL; walker = walker->next) {
      if (walker->link != UNSPEC_LINK
          && ipequal(&walker->address, &in_if->ip_addr)) {
        break;
      }
    }

    /*
     * memorize our neighbour's idea of the link quality, so that we
     * know the link quality in both directions
     *
     * walker is NULL if there the current interface was not included in
     * the message (or was included as an UNSPEC_LINK)
     */
    olsr_memorize_foreign_hello_lq(lnk, walker);

    /* update packet loss for link quality calculation */
    olsr_received_hello_handler(lnk);
  }

  neighbor = lnk->neighbor;

  /*
   * Hysteresis
   */
  if (olsr_cnf->use_hysteresis) {
    /* Update HELLO timeout */
    /* printf("MESSAGE HTIME: %f\n", message->htime); */
    olsr_update_hysteresis_hello(lnk, message->htime);
  }

  /* Check if we are chosen as MPR */
  if (lookup_mpr_status(message, in_if))
    /* source_addr is always the main addr of a node! */
    olsr_update_mprs_set(&message->source_addr, message->vtime);

  /* Check willingness */
  if (neighbor->willingness != message->willingness) {
    struct ipaddr_str buf;
    OLSR_PRINTF(1, "Willingness for %s changed from %d to %d - UPDATING\n", olsr_ip_to_string(&buf, &neighbor->neighbor_main_addr),
                neighbor->willingness, message->willingness);
    /*
     *If willingness changed - recalculate
     */
    neighbor->willingness = message->willingness;
    changes_neighborhood = true;
    changes_topology = true;
  }

  /* Don't register neighbors of neighbors that announces WILL_NEVER */
  if (neighbor->willingness != WILL_NEVER)
    process_message_neighbors(neighbor, message);

  /* Process changes immedeatly in case of MPR updates */
  olsr_process_changes();

  olsr_free_hello_packet(message);

  return;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
static void olsr_shutdown(int signo __attribute__ ((unused)))
#endif
{
  struct interface *ifn;
  int exit_value;

  OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);

#ifdef WIN32
  OLSR_PRINTF(1, "Waiting for the scheduler to stop.\n");

  olsr_win32_end_request = TRUE;

  while (!olsr_win32_end_flag)
  Sleep(100);

  OLSR_PRINTF(1, "Scheduler stopped.\n");
#endif

  /* clear all links and send empty hellos/tcs */
  olsr_reset_all_links();

  /* deactivate fisheye and immediate TCs */
  olsr_cnf->lq_fish = 0;
  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
    ifn->immediate_send_tc = false;
  }
  increase_local_ansn();

  /* send first shutdown message burst */
  olsr_shutdown_messages();

  /* delete all routes */
  olsr_delete_all_kernel_routes();

  /* send second shutdown message burst */
  olsr_shutdown_messages();

  /* now try to cleanup the rest of the mess */
  olsr_delete_all_tc_entries();

  olsr_delete_all_mid_entries();

#ifdef LINUX_NETLINK_ROUTING
  /* trigger gateway selection */
  if (olsr_cnf->smart_gw_active) {
    olsr_cleanup_gateways();
  }

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

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

  olsr_destroy_parser();

  OLSR_PRINTF(1, "Closing sockets...\n");

  /* front-end IPC socket */
  if (olsr_cnf->ipc_connections > 0) {
    shutdown_ipc();
  }

  /* OLSR sockets */
  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
    close(ifn->olsr_socket);
    close(ifn->send_socket);

#ifdef LINUX_NETLINK_ROUTING
    if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
      olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
          olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, false);
    }
#endif
  }

  /* Closing plug-ins */
  olsr_close_plugins();

  /* Reset network settings */
  net_os_restore_ifoptions();

  /* ioctl socket */
  close(olsr_cnf->ioctl_s);

#ifdef LINUX_NETLINK_ROUTING
  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, false);
  }
  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, false);
  }
  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, false);
  }
  close(olsr_cnf->rtnl_s);
  close (olsr_cnf->rt_monitor_socket);
#endif

#if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
  /* routing socket */
  close(olsr_cnf->rts);
#endif

  /* Free cookies and memory pools attached. */
  OLSR_PRINTF(0, "Free all memory...\n");
  olsr_delete_all_cookies();

  olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);

  OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);

  exit_value = olsr_cnf->exit_value;
  olsrd_free_cnf(olsr_cnf);

  exit(exit_value);
}
Ejemplo n.º 17
0
/**
 *Check if a message is to be forwarded and forward
 *it if necessary.
 *
 *@param m the OLSR message to be forwarded
 *@param neighbour we received message from
 *
 *@returns positive if forwarded
 */
int
olsr_forward_message(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
{
  union olsr_ip_addr *src;
  struct neighbor_entry *neighbor;
  int msgsize;
  struct interface *ifn;
  bool is_ttl_1 = false;

  /*
   * Sven-Ola: We should not flood the mesh with overdue messages. Because
   * of a bug in parser.c:parse_packet, we have a lot of messages because
   * all older olsrd's have lq_fish enabled.
   */
  if (AF_INET == olsr_cnf->ip_version) {
    if (m->v4.ttl < 2 || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl)
      is_ttl_1 = true;
  } else {
    if (m->v6.ttl < 2 || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl)
      is_ttl_1 = true;
  }

  /* 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;

  /* Check MPR */
  if (olsr_lookup_mprs_set(src) == NULL) {
#ifdef DEBUG
    struct ipaddr_str buf;
    OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(&buf, src));
#endif
    return 0;
  }

  if (olsr_message_is_duplicate(m)) {
    return 0;
  }

  /* Treat TTL hopcnt except for ethernet link */
  if (!is_ttl_1) {
    if (olsr_cnf->ip_version == AF_INET) {
      /* IPv4 */
      m->v4.hopcnt++;
      m->v4.ttl--;
    } else {
      /* IPv6 */
      m->v6.hopcnt++;
      m->v6.ttl--;
    }
  }

  /* Update packet data */
  msgsize = ntohs(m->v4.olsr_msgsize);

  /* looping trough interfaces */
  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
    /* do not retransmit out through the same interface if it has mode == ether */
    if (ifn == in_if && ifn->mode == IF_MODE_ETHER) continue;

    /* do not forward TTL 1 messages to non-ether interfaces */
    if (is_ttl_1 && ifn->mode != IF_MODE_ETHER) continue;

    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;
}
Ejemplo n.º 18
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 */
Ejemplo n.º 19
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);
  }
}