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