/**
 * 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
    }
  }
}
/**
 * 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;
}
Beispiel #3
0
struct in_addr
S_find_linklocal_address(ServiceRef service_p)
{
    int				count;
    int				i;
    interface_t *		if_p;
    struct in_addr		ll_addr;

    ll_addr = linklocal_get_address(service_p);
    if (ll_addr.s_addr != 0) {
        return (ll_addr);
    }
    if_p = service_interface(service_p);
    count = if_inet_count(if_p);
    for (i = 0; i < count; i++) {
        inet_addrinfo_t * 	info = if_inet_addr_at(if_p, i);

        if (ip_is_linklocal(info->addr)) {
            my_log(LOG_DEBUG, "LINKLOCAL %s: found address " IP_FORMAT,
                   if_name(if_p), IP_LIST(&info->addr));
            return (info->addr);
        }
    }
    return (G_ip_zeroes);
}
Beispiel #4
0
void p2p_get_peers_get_nodes(BEN * nodes, UCHAR * node_id, ITEM * ti,
			     BEN * token, IP * from)
{

	LOOKUP *l = tdb_ldb(ti);
	UCHAR *target = NULL;
	UCHAR *id = NULL;
	UCHAR *p = NULL;
	long int i = 0;
	IP sin;

	if (l == NULL) {
		return;
	} else {
		target = l->target;
	}

	ldb_update(l, node_id, token, from);

	p = ben_str_s(nodes);
	for (i = 0; i < ben_str_i(nodes); i += IP_SIZE_META_TRIPLE) {

		/* ID */
		id = p;
		p += SHA1_SIZE;

		/* IP + Port */
		p = ip_tuple_to_sin(&sin, p);

		/* Ignore myself */
		if (node_me(id)) {
			continue;
		}

		/* Ignore link-local address */
		if (ip_is_linklocal(&sin)) {
			continue;
		}

		nbhd_put(id, &sin);

		/* Node known. Do not send requests twice. Stop here. */
		if (ldb_find(l, id) != NULL) {
			continue;
		}

		/* Add this node to a sorted list. And only send a new lookup request
		 * to this node if it gets inserted on top of the sorted list. */
		if (ldb_put(l, id, (IP *) & sin) >= 8) {
			continue;
		}

		/* Send a new lookup request. */
		send_get_peers_request((IP *) & sin, target, tdb_tid(ti));
	}
}
Beispiel #5
0
void p2p_find_node_get_reply(BEN * arg, UCHAR * node_id, IP * from)
{
	BEN *nodes = NULL;
	UCHAR *id = NULL;
	UCHAR *p = NULL;
	long int i = 0;
	IP sin;

#ifdef IPV6
	nodes = ben_dict_search_str(arg, "nodes6");
#elif IPV4
	nodes = ben_dict_search_str(arg, "nodes");
#endif
	if (!ben_is_str(nodes)) {
		info(_log, NULL, "nodes key missing");
		return;
	}

	if (ben_str_i(nodes) % IP_SIZE_META_TRIPLE != 0) {
		info(_log, NULL, "nodes key broken");
		return;
	}

	p = ben_str_s(nodes);
	for (i = 0; i < ben_str_i(nodes); i += IP_SIZE_META_TRIPLE) {

		/* ID */
		id = p;
		p += SHA1_SIZE;

		/* IP + Port */
		p = ip_tuple_to_sin(&sin, p);

		/* Ignore myself */
		if (node_me(id)) {
			continue;
		}

		/* Ignore link-local address */
		if (ip_is_linklocal(&sin)) {
			continue;
		}

		/* Store node */
		nbhd_put(id, &sin);
	}
}
Beispiel #6
0
void p2p_parse(UCHAR * bencode, size_t bensize, IP * from)
{
	/* Tick Tock */
	mutex_block(_main->work->mutex);
	gettimeofday(&_main->p2p->time_now, NULL);
	mutex_unblock(_main->work->mutex);

	/* UDP packet too small */
	if (bensize < 1) {
		info(_log, from, "Zero size packet from");
		return;
	}

	/* Ignore link-local address */
	if (ip_is_linklocal(from)) {
		info(_log, from, "Drop LINK-LOCAL message from");
		return;
	}

	/* Validate bencode */
	if (!ben_validate(bencode, bensize)) {
		info(_log, from, "Received broken bencode from");
		return;
	}

	/* Encrypted message or plaintext message */
#ifdef POLARSSL
	if (_main->conf->bool_encryption && !ip_is_localhost(from)) {
		p2p_decrypt(bencode, bensize, from);
	} else {
		p2p_decode(bencode, bensize, from);
	}
#else
	p2p_decode(bencode, bensize, from);
#endif
}