/** * format a route path into a buffer */ char * olsr_rtp_to_string(const struct rt_path *rtp) { static char buff[128]; struct ipaddr_str prefixstr, origstr, gwstr; struct rt_entry *rt = rtp->rtp_rt; struct lqtextbuffer lqbuffer; snprintf(buff, sizeof(buff), "%s/%u from %s via %s, " "cost %s, metric %u, v %u", olsr_ip_to_string(&prefixstr, &rt->rt_dst.prefix), rt->rt_dst.prefix_len, olsr_ip_to_string(&origstr, &rtp->rtp_originator), olsr_ip_to_string(&gwstr, &rtp->rtp_nexthop.gateway), get_linkcost_text(rtp->rtp_metric.cost, OLSR_TRUE, &lqbuffer), rtp->rtp_metric.hops, rtp->rtp_version); return buff; }
int iterTcTabNext(char *buff, int len) { int res; int i; struct tc_edge_entry *tc_edge; struct lqtextbuffer lqbuffer; if (iterTcTab == NULL) return -1; res = snprintf(buff, len, "main~%s~[~destinations~", rawIpAddrToString(&iterTcTab->addr, ipAddrLen)); len -= res; buff += res; len -= 2; i = 0; OLSR_FOR_ALL_TC_EDGE_ENTRIES(iterTcTab, tc_edge) { res = snprintf(buff, len, "[~%d~address~%s~cost~%s~]~", i, rawIpAddrToString(&tc_edge->T_dest_addr, ipAddrLen), get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer)); if (res < len) buff += res; len -= res; if (len <= 0) break; i++; } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(iterTcTab, tc_edge);
/** * write latlon positions to a file */ void mapwrite_work(FILE* fmap) { int hash; struct olsr_if *ifs; union olsr_ip_addr ip; struct ipaddr_str strbuf1, strbuf2; struct tc_entry *tc; struct tc_edge_entry *tc_edge; if (!my_names || !fmap) return; for (ifs = olsr_cnf->interfaces; ifs; ifs = ifs->next) { if (0 != ifs->interf) { if (olsr_cnf->ip_version == AF_INET) { if (!(ip4equal((struct in_addr *)&olsr_cnf->main_addr, &ifs->interf->int_addr.sin_addr))) { if (0 > fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr), olsr_ip_to_string(&strbuf2, (union olsr_ip_addr *)&ifs->interf->int_addr.sin_addr))) { return; } } } else if (!(ip6equal((struct in6_addr *)&olsr_cnf->main_addr, &ifs->interf->int6_addr.sin6_addr))) { if (0 > fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr), olsr_ip_to_string(&strbuf2, (union olsr_ip_addr *)&ifs->interf->int6_addr.sin6_addr))) { return; } } } } for (hash = 0; hash < HASHSIZE; hash++) { struct mid_entry *entry = mid_set[hash].next; while(entry != &mid_set[hash]) { struct mid_address *alias = entry->aliases; while(alias) { if (0 > fprintf(fmap, "Mid('%s','%s');\n", olsr_ip_to_string(&strbuf1, &entry->main_addr), olsr_ip_to_string(&strbuf2, &alias->alias))) { return; } alias = alias->next_alias; } entry = entry->next; } } lookup_defhna_latlon(&ip); sprintf(my_latlon_str, "%f,%f,%d", my_lat, my_lon, get_isdefhna_latlon()); if (0 > fprintf(fmap, "Self('%s',%s,'%s','%s');\n", olsr_ip_to_string(&strbuf1, &olsr_cnf->main_addr), my_latlon_str, olsr_ip_to_string(&strbuf2, &ip), my_names->name)) { return; } for (hash = 0; hash < HASHSIZE; hash++) { struct db_entry *entry; struct list_node *list_head, *list_node; list_head = &latlon_list[hash]; for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) { entry = list2db(list_node); if (NULL != entry->names) { if (0 > fprintf(fmap, "Node('%s',%s,'%s','%s');\n", olsr_ip_to_string(&strbuf1, &entry->originator), entry->names->name, olsr_ip_to_string(&strbuf2, &entry->names->ip), lookup_name_latlon(&entry->originator))) { return; } } } } OLSR_FOR_ALL_TC_ENTRIES(tc) { OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) { char* lla = lookup_position_latlon(&tc->addr); char* llb = lookup_position_latlon(&tc_edge->T_dest_addr); if (NULL != lla && NULL != llb) { struct lqtextbuffer lqbuffer, lqbuffer2; /* * To speed up processing, Links with both positions are named PLink() */ if (0 > fprintf(fmap, "PLink('%s','%s',%s,%s,%s,%s);\n", olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr), olsr_ip_to_string(&strbuf2, &tc->addr), get_tc_edge_entry_text(tc_edge, ',', &lqbuffer2), get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer), lla, llb)) { return; } } else { struct lqtextbuffer lqbuffer, lqbuffer2; /* * If one link end pos is unkown, only send Link() */ if (0 > fprintf(fmap, "Link('%s','%s',%s,%s);\n", olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr), olsr_ip_to_string(&strbuf2, &tc->addr), get_tc_edge_entry_text(tc_edge, ',', &lqbuffer2), get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer))) { return; } } } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge); } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
/* * olsr_spf_relax * * Explore all edges of a node and add the node * to the candidate tree if the if the aggregate * path cost is better. */ static void olsr_spf_relax(struct avl_tree *cand_tree, struct tc_entry *tc) { struct avl_node *edge_node; olsr_linkcost new_cost; #ifdef DEBUG #ifndef NODEBUG struct ipaddr_str buf, nbuf; struct lqtextbuffer lqbuffer; #endif /* NODEBUG */ OLSR_PRINTF(2, "SPF: exploring node %s, cost %s\n", olsr_ip_to_string(&buf, &tc->addr), get_linkcost_text(tc->path_cost, false, &lqbuffer)); #endif /* DEBUG */ /* * loop through all edges of this vertex. */ for (edge_node = avl_walk_first(&tc->edge_tree); edge_node; edge_node = avl_walk_next(edge_node)) { struct tc_entry *new_tc; struct tc_edge_entry *tc_edge = edge_tree2tc_edge(edge_node); /* * We are not interested in dead-end edges. */ if (!tc_edge->edge_inv) { #ifdef DEBUG OLSR_PRINTF(2, "SPF: ignoring edge %s\n", olsr_ip_to_string(&buf, &tc_edge->T_dest_addr)); if (!tc_edge->edge_inv) { OLSR_PRINTF(2, "SPF: no inverse edge\n"); } #endif /* DEBUG */ continue; } if (tc_edge->cost == LINK_COST_BROKEN) { #ifdef DEBUG OLSR_PRINTF(2, "SPF: ignore edge %s (broken)\n", olsr_ip_to_string(&buf, &tc_edge->T_dest_addr)); #endif /* DEBUG */ continue; } /* * total quality of the path through this vertex * to the destination of this edge */ new_cost = tc->path_cost + tc_edge->cost; #ifdef DEBUG OLSR_PRINTF(2, "SPF: exploring edge %s, cost %s\n", olsr_ip_to_string(&buf, &tc_edge->T_dest_addr), get_linkcost_text(new_cost, true, &lqbuffer)); #endif /* DEBUG */ /* * if it's better than the current path quality of this edge's * destination node, then we've found a better path to this node. */ new_tc = tc_edge->edge_inv->tc; if (new_cost < new_tc->path_cost) { /* if this node has been on the candidate tree delete it */ if (new_tc->path_cost < ROUTE_COST_BROKEN) { olsr_spf_del_cand_tree(cand_tree, new_tc); } /* re-insert on candidate tree with the better metric */ new_tc->path_cost = new_cost; olsr_spf_add_cand_tree(cand_tree, new_tc); /* pull-up the next-hop and bump the hop count */ if (tc->next_hop) { new_tc->next_hop = tc->next_hop; } new_tc->hops = tc->hops + 1; #ifdef DEBUG OLSR_PRINTF(2, "SPF: better path to %s, cost %s, via %s, hops %u\n", olsr_ip_to_string(&buf, &new_tc->addr), get_linkcost_text(new_cost, true, &lqbuffer), tc->next_hop ? olsr_ip_to_string(&nbuf, &tc->next_hop->neighbor_iface_addr) : "<none>", new_tc->hops); #endif /* DEBUG */ } } }