--- lib/nameservice/src/nameservice.c.orig Sun May 29 14:47:42 2005 +++ lib/nameservice/src/nameservice.c Mon Dec 11 13:52:46 2006 @@ -71,6 +71,8 @@ struct name_entry *my_names = NULL; olsr_bool name_table_changed = OLSR_TRUE; +static void free_routing_table_list(struct rt_entry **list) ; +static struct rt_entry *host_lookup_routing_table(union olsr_ip_addr *); /** * do initialization @@ -139,14 +141,14 @@ printf("\nNAME PLUGIN: parameter additional host: %s\n", my_add_hosts); } else if(!strcmp(key, "dns-server")) { - struct in_addr ip; + union olsr_ip_addr ip; if (strlen(value) == 0) { // set dns server ip to main address // which is not known yet have_dns_server = OLSR_TRUE; } - else if (inet_aton(value, &ip)) { - my_dns_server.v4 = ip.s_addr; + else if (inet_pton(olsr_cnf->ip_version, value, &ip) == 1) { + memcpy(&my_dns_server, &ip, ipsize); have_dns_server = OLSR_TRUE; } else { @@ -169,16 +171,16 @@ } else { // assume this is an IP address and hostname - struct in_addr ip; + union olsr_ip_addr ip; - if (inet_aton(key, &ip)) { + if (inet_pton(olsr_cnf->ip_version, key, &ip) == 1) { // the IP is validated later struct name_entry *tmp; tmp = malloc(sizeof(struct name_entry)); tmp->name = strndup( value, MAX_NAME ); tmp->len = strlen( tmp->name ); tmp->type = NAME_HOST; - tmp->ip.v4 = ip.s_addr; + memcpy(&tmp->ip, &ip, ipsize); tmp->next = my_names; my_names = tmp; printf("\nNAME PLUGIN: parameter %s (%s)\n", tmp->name, @@ -211,10 +213,13 @@ { struct name_entry *name; struct name_entry *prev=NULL; + union olsr_ip_addr ipz; + + memset(&ipz, 0, sizeof(ipz)); /* fixup names and IP addresses */ for (name = my_names; name != NULL; name = name->next) { - if (name->ip.v4 == 0) { + if (memcmp(&name->ip, &ipz, ipsize) == 0) { // insert main_addr memcpy(&name->ip, &main_addr, ipsize); prev = name; @@ -238,7 +243,7 @@ } if (have_dns_server) { - if (my_dns_server.v4 == 0) { + if (memcmp(&my_dns_server, &ipz, ipsize) == 0) { memcpy(&my_dns_server, &main_addr, ipsize); printf("\nNAME PLUGIN: announcing upstream DNS server: %s\n", olsr_ip_to_string(&my_dns_server)); @@ -401,9 +406,16 @@ union olsr_ip_addr originator; double vtime; int size; + olsr_u16_t seqno; /* Fetch the originator of the messsage */ - memcpy(&originator, &m->v4.originator, ipsize); + if(olsr_cnf->ip_version == AF_INET) { + memcpy(&originator, &m->v4.originator, ipsize); + seqno = ntohs(m->v4.seqno); + } else { + memcpy(&originator, &m->v6.originator, ipsize); + seqno = ntohs(m->v6.seqno); + } /* Fetch the message based on IP version */ if(olsr_cnf->ip_version == AF_INET) { @@ -414,7 +426,7 @@ else { vtime = ME_TO_DOUBLE(m->v6.olsr_vtime); size = ntohs(m->v6.olsr_msgsize); - namemessage = (struct namemsg*)&m->v4.message; + namemessage = (struct namemsg*)&m->v6.message; } /* Check if message originated from this node. @@ -433,7 +445,7 @@ * Remeber that this also registeres the message as * processed if nessecary */ - if(!olsr_check_dup_table_proc(&originator, ntohs(m->v4.seqno))) { + if(!olsr_check_dup_table_proc(&originator, seqno)) { /* If so - do not process */ goto forward; } @@ -443,7 +455,7 @@ forward: /* Forward the message if nessecary * default_fwd does all the work for us! */ - olsr_forward_message(m, &originator, ntohs(m->v4.seqno), in_if, in_addr); + olsr_forward_message(m, &originator, seqno, in_if, in_addr); } @@ -631,7 +643,8 @@ fprintf(hosts, "### this /etc/hosts file is overwritten regularly by olsrd\n"); fprintf(hosts, "### do not edit\n\n"); - fprintf(hosts, "127.0.0.1\tlocalhost\n\n"); + fprintf(hosts, "127.0.0.1\tlocalhost\n"); + fprintf(hosts, "::1\t\tlocalhost\n\n"); // copy content from additional hosts filename if (my_add_hosts[0] != '\0') { @@ -688,7 +701,7 @@ write_resolv_file() { int hash; - struct name_entry *name; + struct name_entry *name, *tmp_dns, *last_dns, *dnslist = NULL; struct db_entry *entry; struct rt_entry *best_routes = NULL; struct rt_entry *route, *tmp, *last; @@ -713,13 +726,13 @@ continue; /* find the nearest one */ - route = olsr_lookup_routing_table(&name->ip); + route = host_lookup_routing_table(&name->ip); if (route==NULL) // it's possible that route is not present yet continue; if (best_routes == NULL || route->rt_etx < best_routes->rt_etx) { olsr_printf(6, "NAME PLUGIN: best nameserver %s\n", - olsr_ip_to_string(&route->rt_dst)); + olsr_ip_to_string(&name->ip)); if (best_routes!=NULL) olsr_printf(6, "NAME PLUGIN: better than %f (%s)\n", best_routes->rt_etx, @@ -730,27 +743,44 @@ tmp->rt_etx = route->rt_etx; tmp->next = best_routes; best_routes = tmp; + tmp_dns = olsr_malloc(sizeof(struct name_entry), "write_resolv name_entry"); + COPY_IP(&tmp_dns->ip, &name->ip); + tmp_dns->type = name->type; + tmp_dns->len = 0; + tmp_dns->name = NULL; + tmp_dns->next = dnslist; + dnslist = tmp_dns; } else { // queue in etx order last = best_routes; + last_dns = dnslist; while ( last->next!=NULL && i<3 ) { if (last->next->rt_etx > route->rt_etx) break; last = last->next; + last_dns = last_dns->next; i++; } if (i<3) { olsr_printf(6, "NAME PLUGIN: queue %f (%s)", route->rt_etx, - olsr_ip_to_string(&route->rt_dst)); + olsr_ip_to_string(&name->ip)); olsr_printf(6, " after %f (%s)\n", - last->rt_etx, olsr_ip_to_string(&last->rt_dst)); + last->rt_etx, olsr_ip_to_string(&last_dns->ip)); tmp = olsr_malloc(sizeof(struct rt_entry), "new rt_entry"); memcpy(&tmp->rt_dst, &route->rt_dst, ipsize); tmp->rt_etx = route->rt_etx; tmp->next = last->next; last->next = tmp; + + tmp_dns = olsr_malloc(sizeof(struct name_entry), "write_resolv name_entry"); + COPY_IP(&tmp_dns->ip, &name->ip); + tmp_dns->type = name->type; + tmp_dns->len = 0; + tmp_dns->name = NULL; + tmp_dns->next = last_dns->next; + last_dns->next = tmp_dns; } else { olsr_printf(6, "NAME PLUGIN: don't need more than 3 nameservers\n"); } @@ -768,11 +798,13 @@ return; } i=0; - for (tmp=best_routes; tmp!=NULL && i<3; tmp=tmp->next) { - olsr_printf(6, "NAME PLUGIN: nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst)); - fprintf(resolv, "nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst)); + for (tmp_dns=dnslist; tmp_dns!=NULL && i<3; tmp_dns=tmp_dns->next) { + olsr_printf(6, "NAME PLUGIN: nameserver %s\n", olsr_ip_to_string(&tmp_dns->ip)); + fprintf(resolv, "nameserver %s\n", olsr_ip_to_string(&tmp_dns->ip)); i++; } + free_name_entry_list(&dnslist); + free_routing_table_list(&tmp); fclose(resolv); } @@ -796,6 +828,23 @@ /** + * completely free a list of rt_entries + */ +static void +free_routing_table_list(struct rt_entry **list) +{ + struct rt_entry **tmp = list; + struct rt_entry *to_delete; + while (*tmp != NULL) { + to_delete = *tmp; + *tmp = (*tmp)->next; + free( to_delete ); + to_delete = NULL; + } +} + + +/** * we only allow names for IP addresses which we are * responsible for: * so the IP must either be from one of the interfaces @@ -805,7 +854,9 @@ allowed_ip(union olsr_ip_addr *addr) { struct hna4_entry *hna4; + struct hna6_entry *hna6; struct interface *iface; + union olsr_ip_addr tmp_ip, tmp_msk; olsr_printf(6, "checking %s\n", olsr_ip_to_string(addr)); @@ -818,16 +869,83 @@ } } - for (hna4 = olsr_cnf->hna4_entries; hna4; hna4 = hna4->next) - { - olsr_printf(6, "HNA %s/%s\n", - olsr_ip_to_string(&hna4->net), - olsr_ip_to_string(&hna4->netmask)); - - if ( hna4->netmask.v4 != 0 && (addr->v4 & hna4->netmask.v4) == hna4->net.v4 ) { - olsr_printf(6, "MATCHED\n"); - return OLSR_TRUE; + if (olsr_cnf->ip_version == AF_INET) { + for (hna4 = olsr_cnf->hna4_entries; hna4; hna4 = hna4->next) + { + olsr_printf(6, "HNA %s/%s\n", + olsr_ip_to_string(&hna4->net), + olsr_ip_to_string(&hna4->netmask)); + + if ( hna4->netmask.v4 != 0 && + (addr->v4 & hna4->netmask.v4) == hna4->net.v4 ) { + olsr_printf(6, "MATCHED\n"); + return OLSR_TRUE; + } + } + } else { + int i; + + for (hna6 = olsr_cnf->hna6_entries; hna6; hna6 = hna6->next) + { + olsr_printf(6, "HNA %s/%d\n", + olsr_ip_to_string(&hna6->net), + hna6->prefix_len); + if ( hna6->prefix_len == 0 ) + continue; + olsr_prefix_to_netmask(&tmp_msk, hna6->prefix_len); + for (i = 0; i < 16; i++) { + tmp_ip.v6.s6_addr[i] = addr->v6.s6_addr[i] & + tmp_msk.v6.s6_addr[i]; + } + if (COMP_IP(&tmp_ip, &hna6->net)) { + olsr_printf(6, "MATCHED\n"); + return OLSR_TRUE; + } } } return OLSR_FALSE; +} + +static struct rt_entry * +host_lookup_routing_table(union olsr_ip_addr *dst) +{ + olsr_u32_t index; + union olsr_ip_addr tmp_ip, tmp_msk; + struct rt_entry *walker; + + walker = olsr_lookup_routing_table(dst); + if (walker != NULL) + return walker; + + for (index = 0; index < HASHSIZE; index++) { + for (walker = hna_routes[index].next; + walker != &hna_routes[index]; walker = walker->next) { + if (COMP_IP(&walker->rt_dst, dst)) + return walker; + if (olsr_cnf->ip_version == AF_INET) { + if ( walker->rt_mask.v4 != 0 && + (dst->v4 & walker->rt_mask.v4) == + walker->rt_dst.v4 ) { + olsr_printf(6, "MATCHED\n"); + return walker; + } + } else { + int i; + + if ( walker->rt_mask.v6 == 0 ) + continue; + olsr_prefix_to_netmask(&tmp_msk, + walker->rt_mask.v6); + for (i = 0; i < 16; i++) { + tmp_ip.v6.s6_addr[i] = + dst->v6.s6_addr[i] & + tmp_msk.v6.s6_addr[i]; + } + if (COMP_IP(&tmp_ip, &walker->rt_dst)) { + olsr_printf(6, "MATCHED\n"); + return walker; + } + } + } + } }