2 * Copyright (c) 2006, Jens Nachtigall <nachtigall@web.de>
3 * Copyright (c) 2005, Bruno Randolf <bruno.randolf@4g-systems.biz>
4 * Copyright (c) 2004, Andreas Tønnesen(andreto-at-olsr.org)
5 * Copyright (c) 2007, Sven-Ola <sven-ola@gmx.de>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * * Neither the name of the UniK olsr daemon nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Dynamic linked library for UniK OLSRd
44 #include <sys/types.h>
54 #include "routing_table.h"
56 #include "scheduler.h"
58 #include "duplicate_set.h"
64 #include "plugin_util.h"
65 #include "nameservice.h"
68 #include "common/string.h"
71 /* config parameters */
72 static char my_hosts_file[MAX_FILE + 1];
73 static char my_sighup_pid_file[MAX_FILE + 1];
75 static char my_add_hosts[MAX_FILE + 1];
76 static char my_suffix[MAX_SUFFIX];
77 static int my_interval = EMISSION_INTERVAL;
78 static double my_timeout = NAME_VALID_TIME;
79 static char my_resolv_file[MAX_FILE +1];
80 static char my_services_file[MAX_FILE + 1];
81 static char my_name_change_script[MAX_FILE + 1];
82 static char my_services_change_script[MAX_FILE + 1];
83 static char latlon_in_file[MAX_FILE + 1];
84 static char my_latlon_file[MAX_FILE + 1];
85 float my_lat = 0.0, my_lon = 0.0;
86 static struct olsr_cookie_info *msg_gen_timer_cookie;
87 static struct olsr_cookie_info *write_file_timer_cookie;
88 struct olsr_cookie_info *map_poll_timer_cookie;
90 /* the databases (using hashing)
91 * for hostnames, service_lines and dns-servers
93 * my own hostnames, service_lines and dns-servers
94 * are store in a linked list (without hashing)
96 static struct list_node name_list[HASHSIZE];
97 struct name_entry *my_names = NULL;
98 static olsr_bool name_table_changed = OLSR_TRUE;
100 static struct list_node service_list[HASHSIZE];
101 static struct name_entry *my_services = NULL;
102 static olsr_bool service_table_changed = OLSR_TRUE;
104 static struct list_node forwarder_list[HASHSIZE];
105 static struct name_entry *my_forwarders = NULL;
106 static olsr_bool forwarder_table_changed = OLSR_TRUE;
108 struct list_node latlon_list[HASHSIZE];
109 static olsr_bool latlon_table_changed = OLSR_TRUE;
111 /* backoff timer for writing changes into a file */
112 struct timer_entry *write_file_timer = NULL;
114 /* periodic message generation */
115 struct timer_entry *msg_gen_timer = NULL;
117 /* regular expression to be matched by valid hostnames, compiled in name_init() */
118 static regex_t regex_t_name;
119 static regmatch_t regmatch_t_name;
121 /* regular expression to be matched by valid service_lines, compiled in name_init() */
122 static regex_t regex_t_service;
123 static int pmatch_service = 10;
124 static regmatch_t regmatch_t_service[10];
130 name_constructor(void)
137 GetWindowsDirectory(my_hosts_file, MAX_FILE - 12);
138 GetWindowsDirectory(my_services_file, MAX_FILE - 12);
139 GetWindowsDirectory(my_resolv_file, MAX_FILE - 12);
141 len = strlen(my_hosts_file);
142 if (my_hosts_file[len - 1] != '\\')
143 strscat(my_hosts_file, "\\", sizeof(my_host_file));
144 strscat(my_hosts_file, "hosts_olsr", sizeof(my_host_file));
146 len = strlen(my_services_file);
147 if (my_services_file[len - 1] != '\\')
148 strscat(my_services_file, "\\", sizeof(my_services_file));
149 strscat(my_services_file, "services_olsr", sizeof(my_services_file));
151 len = strlen(my_resolv_file);
152 if (my_resolv_file[len - 1] != '\\')
153 strscat(my_resolv_file, "\\", sizeof(my_resolv_file));
154 strscat(my_resolv_file, "resolvconf_olsr", sizeof(my_resolv_file));
156 strscpy(my_hosts_file, "/var/run/hosts_olsr", sizeof(my_hosts_file));
157 strscpy(my_services_file, "/var/run/services_olsr", sizeof(my_services_file));
158 strscpy(my_resolv_file, "/var/run/resolvconf_olsr", sizeof(my_resolv_file));
159 *my_sighup_pid_file = 0;
163 my_add_hosts[0] = '\0';
164 my_latlon_file[0] = '\0';
165 latlon_in_file[0] = '\0';
166 my_name_change_script[0] = '\0';
167 my_services_change_script[0] = '\0';
169 /* init the lists heads */
170 for(i = 0; i < HASHSIZE; i++) {
171 list_head_init(&name_list[i]);
172 list_head_init(&forwarder_list[i]);
173 list_head_init(&service_list[i]);
174 list_head_init(&latlon_list[i]);
177 msg_gen_timer_cookie = olsr_alloc_cookie("Nameservice: message gen", OLSR_COOKIE_TYPE_TIMER);
178 write_file_timer_cookie = olsr_alloc_cookie("Nameservice: write file", OLSR_COOKIE_TYPE_TIMER);
179 map_poll_timer_cookie = olsr_alloc_cookie("Nameservice: map poll", OLSR_COOKIE_TYPE_TIMER);
183 static int set_nameservice_server(const char *value, void *data, set_plugin_parameter_addon addon)
185 union olsr_ip_addr ip;
186 struct name_entry **v = data;
187 if (0 == strlen(value))
189 *v = add_name_to_list(*v, "", addon.ui, NULL);
190 OLSR_PRINTF(1, "%s got %s (main address)\n", "Got", value);
193 else if (0 < inet_pton(olsr_cnf->ip_version, value, &ip))
195 *v = add_name_to_list(*v, "", addon.ui, &ip);
196 OLSR_PRINTF(1, "%s got %s\n", "Got", value);
201 OLSR_PRINTF(0, "Illegal IP address \"%s\"", value);
206 static int set_nameservice_name(const char *value, void *data, set_plugin_parameter_addon addon)
208 struct name_entry **v = data;
209 if (0 < strlen(value))
211 *v = add_name_to_list(*v, value, addon.ui, NULL);
212 OLSR_PRINTF(1, "%s got %s (main address)\n", "Got", value);
217 OLSR_PRINTF(0, "Illegal name \"%s\"", value);
222 static int set_nameservice_host(const char *value, void *data, set_plugin_parameter_addon addon)
224 union olsr_ip_addr ip;
225 struct name_entry **v = data;
226 if (0 < inet_pton(olsr_cnf->ip_version, addon.pc, &ip))
228 // the IP is validated later
229 *v = add_name_to_list(*v, value, NAME_HOST, &ip);
230 OLSR_PRINTF(1, "%s: %s got %s\n", "Got", addon.pc, value);
235 OLSR_PRINTF(0, "%s: Illegal IP address \"%s\"", addon.pc, value);
240 static int set_nameservice_float(const char *value, void *data, set_plugin_parameter_addon addon __attribute__((unused)))
244 sscanf(value, "%f", (float*)data);
245 OLSR_PRINTF(1, "%s float %f\n", "Got", *(float*)data);
249 OLSR_PRINTF(0, "%s float %s\n", "Ignored", value);
254 static const struct olsrd_plugin_parameters plugin_parameters[] = {
255 { .name = "interval", .set_plugin_parameter = &set_plugin_int, .data = &my_interval },
256 { .name = "timeout", .set_plugin_parameter = &set_nameservice_float, .data = &my_timeout },
257 { .name = "sighup-pid-file",.set_plugin_parameter = &set_plugin_string, .data = &my_sighup_pid_file, .addon = {sizeof(my_sighup_pid_file)} },
258 { .name = "hosts-file", .set_plugin_parameter = &set_plugin_string, .data = &my_hosts_file, .addon = {sizeof(my_hosts_file)} },
259 { .name = "name-change-script", .set_plugin_parameter = &set_plugin_string, .data = &my_name_change_script, .addon = {sizeof(my_name_change_script)} },
260 { .name = "services-change-script", .set_plugin_parameter = &set_plugin_string, .data = &my_services_change_script, .addon = {sizeof(my_services_change_script)} },
261 { .name = "resolv-file", .set_plugin_parameter = &set_plugin_string, .data = &my_resolv_file, .addon = {sizeof(my_resolv_file)} },
262 { .name = "suffix", .set_plugin_parameter = &set_plugin_string, .data = &my_suffix, .addon = {sizeof(my_suffix)} },
263 { .name = "add-hosts", .set_plugin_parameter = &set_plugin_string, .data = &my_add_hosts, .addon = {sizeof(my_add_hosts)} },
264 { .name = "services-file", .set_plugin_parameter = &set_plugin_string, .data = &my_services_file, .addon = {sizeof(my_services_file)} },
265 { .name = "lat", .set_plugin_parameter = &set_nameservice_float, .data = &my_lat },
266 { .name = "lon", .set_plugin_parameter = &set_nameservice_float, .data = &my_lon },
267 { .name = "latlon-file", .set_plugin_parameter = &set_plugin_string, .data = &my_latlon_file, .addon = {sizeof(my_latlon_file)} },
268 { .name = "latlon-infile", .set_plugin_parameter = &set_plugin_string, .data = &latlon_in_file, .addon = {sizeof(latlon_in_file)} },
269 { .name = "dns-server", .set_plugin_parameter = &set_nameservice_server, .data = &my_forwarders, .addon = {NAME_FORWARDER} },
270 { .name = "name", .set_plugin_parameter = &set_nameservice_name, .data = &my_names, .addon = {NAME_HOST} },
271 { .name = "service", .set_plugin_parameter = &set_nameservice_name, .data = &my_services, .addon = {NAME_SERVICE} },
272 { .name = "", .set_plugin_parameter = &set_nameservice_host, .data = &my_names },
275 void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
277 *params = plugin_parameters;
278 *size = sizeof(plugin_parameters)/sizeof(*plugin_parameters);
283 * queue the name/forwarder/service given in value
284 * to the front of my_list
287 add_name_to_list(struct name_entry *my_list, const char *value, int type, const union olsr_ip_addr *ip)
289 struct name_entry *tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry add_name_to_list");
290 tmp->name = strndup( value, MAX_NAME );
291 tmp->len = strlen( tmp->name );
293 // all IPs with value 0 will be set to main_addr later
295 memset(&tmp->ip, 0, sizeof(tmp->ip));
304 * last initialization
306 * we have to do this here because some things like main_addr
307 * or the dns suffix (for validation) are not known before
309 * this is beause of the order in which the plugin is initialized
310 * by the plugin loader:
311 * - first the parameters are sent
312 * - then register_olsr_data() from olsrd_plugin.c is called
313 * which sets up main_addr and some other variables
314 * - register_olsr_data() then then finally calls this function
319 struct name_entry *name;
320 union olsr_ip_addr ipz;
323 //regex string for validating the hostnames
324 const char *regex_name = "^[[:alnum:]_.-]+$";
325 //regex string for the service line
326 size_t regex_size = 256 * sizeof(char) + strlen(my_suffix);
327 char *regex_service = olsr_malloc(regex_size, "new *char from name_init for regex_service");
328 memset(&ipz, 0, sizeof(ipz));
330 //compile the regex from the string
331 if ((ret = regcomp(®ex_t_name, regex_name , REG_EXTENDED)) != 0)
333 /* #2: call regerror() if regcomp failed
334 * commented out, because only for debuggin needed
336 int errmsgsz = regerror(ret, ®ex_t_name, NULL, 0);
337 char *errmsg = malloc(errmsgsz);
338 regerror(ret, ®ex_t_name, errmsg, errmsgsz);
339 fprintf(stderr, "regcomp: %s", errmsg);
341 regfree(®ex_t_name);
343 OLSR_PRINTF(0, "compilation of regex \"%s\" for hostname failed", regex_name);
346 // a service line is something like prot://hostname.suffix:port|tcp|my little description about this service
347 // for example http://router.olsr:80|tcp|my homepage
348 // prot :// (hostname.suffix OR ip)
349 //regex_service = "^[[:alnum:]]+://(([[:alnum:]_.-]+.olsr)|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}))
350 // : port /path |(tcp OR udp) |short description
351 // :[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$";
352 strscpy(regex_service, "^[[:alnum:]]+://(([[:alnum:]_.-]+", regex_size);
353 strscat(regex_service, my_suffix, regex_size);
354 strscat(regex_service, ")|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3})):[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$", regex_size);
356 /* #1: call regcomp() to compile the regex */
357 if ((ret = regcomp(®ex_t_service, regex_service , REG_EXTENDED )) != 0)
359 /* #2: call regerror() if regcomp failed
360 * commented out, because only for debuggin needed
362 int errmsgsz = regerror(ret, ®ex_t_service, NULL, 0);
363 char *errmsg = malloc(errmsgsz);
364 regerror(ret, ®ex_t_service, errmsg, errmsgsz);
365 fprintf(stderr, "regcomp: %s", errmsg);
367 regfree(®ex_t_service);
369 OLSR_PRINTF(0, "compilation of regex \"%s\" for hostname failed", regex_name);
372 regex_service = NULL;
374 //fill in main addr for all entries with ip==0
375 //this does not matter for service, because the ip does not matter
378 for (name = my_names; name != NULL; name = name->next) {
379 if (ipequal(&name->ip, &ipz)) {
380 OLSR_PRINTF(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
381 name->ip = olsr_cnf->main_addr;
384 for (name = my_forwarders; name != NULL; name = name->next) {
385 if (name->ip.v4.s_addr == 0) {
386 OLSR_PRINTF(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
387 name->ip = olsr_cnf->main_addr;
391 //check if entries I want to announce myself are valid and allowed
392 my_names = remove_nonvalid_names_from_list(my_names, NAME_HOST);
393 my_forwarders = remove_nonvalid_names_from_list(my_forwarders, NAME_FORWARDER);
394 my_services = remove_nonvalid_names_from_list(my_services, NAME_SERVICE);
397 /* register functions with olsrd */
398 olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1);
400 /* periodic message generation */
401 msg_gen_timer = olsr_start_timer(my_interval * MSEC_PER_SEC, EMISSION_JITTER,
402 OLSR_TIMER_PERIODIC, &olsr_namesvc_gen,
403 NULL, msg_gen_timer_cookie->ci_id);
405 mapwrite_init(my_latlon_file);
412 remove_nonvalid_names_from_list(struct name_entry *my_list, int type)
414 struct name_entry *next = my_list;
415 olsr_bool valid = OLSR_FALSE;
416 if (my_list == NULL) {
422 valid = is_name_wellformed(my_list->name) && allowed_ip(&my_list->ip);
425 valid = allowed_ip(&my_list->ip);
428 valid = allowed_service(my_list->name);
431 valid = is_latlon_wellformed(my_list->name);
436 struct ipaddr_str strbuf;
437 OLSR_PRINTF(1, "NAME PLUGIN: invalid or malformed parameter %s (%s), fix your config!\n", my_list->name, olsr_ip_to_string(&strbuf, &my_list->ip));
438 next = my_list->next;
440 my_list->name = NULL;
443 return remove_nonvalid_names_from_list(next, type);
445 struct ipaddr_str strbuf;
446 OLSR_PRINTF(2, "NAME PLUGIN: validate parameter %s (%s) -> OK\n", my_list->name, olsr_ip_to_string(&strbuf, &my_list->ip));
447 my_list->next = remove_nonvalid_names_from_list(my_list->next, type);
455 * called at unload: free everything
457 * XXX: should I delete the hosts/services/resolv.conf files on exit?
460 name_destructor(void)
462 OLSR_PRINTF(2, "NAME PLUGIN: exit. cleaning up...\n");
464 free_name_entry_list(&my_names);
465 free_name_entry_list(&my_services);
466 free_name_entry_list(&my_forwarders);
468 free_all_list_entries(name_list);
469 free_all_list_entries(service_list);
470 free_all_list_entries(forwarder_list);
471 free_all_list_entries(latlon_list);
473 olsr_stop_timer(write_file_timer);
474 olsr_stop_timer(msg_gen_timer);
476 regfree(®ex_t_name);
477 regfree(®ex_t_service);
481 /* free all list entries */
483 free_all_list_entries(struct list_node *this_db_list)
486 struct list_node *list_head, *list_node, *list_node_next;
490 for (i = 0; i < HASHSIZE; i++) {
492 list_head = &this_db_list[i];
494 for (list_node = list_head->next;
495 list_node != list_head;
496 list_node = list_node_next) {
498 /* prefetch next node before loosing context */
499 list_node_next = list_node->next;
501 db = list2db(list_node);
502 olsr_namesvc_delete_db_entry(db);
509 * The write file timer has fired.
512 olsr_expire_write_file_timer(void *context __attribute__((unused)))
514 write_file_timer = NULL;
516 write_resolv_file(); /* if forwarder_table_changed */
517 write_hosts_file(); /* if name_table_changed */
518 write_services_file(); /* if service_table_changed */
520 write_latlon_file(); /* if latlon_table_changed */
526 * Kick a timer to write everything into a file.
527 * This also paces things a bit.
530 olsr_start_write_file_timer(void)
532 if (write_file_timer) {
536 write_file_timer = olsr_start_timer(5 * MSEC_PER_SEC, 5, OLSR_TIMER_ONESHOT,
537 olsr_expire_write_file_timer, NULL, write_file_timer_cookie->ci_id);
541 * Delete and unlink db_entry.
544 olsr_namesvc_delete_db_entry(struct db_entry *db)
546 struct ipaddr_str strbuf;
547 OLSR_PRINTF(2, "NAME PLUGIN: %s timed out... deleting\n",
548 olsr_ip_to_string(&strbuf, &db->originator));
550 olsr_start_write_file_timer();
551 olsr_stop_timer(db->db_timer); /* stop timer if running */
554 free_name_entry_list(&db->names);
555 list_remove(&db->db_list);
560 * Callback for the db validity timer.
563 olsr_nameservice_expire_db_timer(void *context)
567 db = (struct db_entry *)context;
568 db->db_timer = NULL; /* be pedandic */
570 olsr_namesvc_delete_db_entry(db);
574 * Scheduled event: generate and send NAME packet
577 olsr_namesvc_gen(void *foo __attribute__((unused)))
579 /* send buffer: huge */
581 union olsr_message *message = (union olsr_message *)buffer;
582 struct interface *ifn;
586 if(olsr_cnf->ip_version == AF_INET)
589 message->v4.olsr_msgtype = MESSAGE_TYPE;
590 message->v4.olsr_vtime = reltime_to_me(my_timeout * MSEC_PER_SEC);
591 memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
592 message->v4.ttl = MAX_TTL;
593 message->v4.hopcnt = 0;
594 message->v4.seqno = htons(get_msg_seqno());
596 namesize = encap_namemsg((struct namemsg*)&message->v4.message);
597 namesize = namesize + sizeof(struct olsrmsg);
599 message->v4.olsr_msgsize = htons(namesize);
604 message->v6.olsr_msgtype = MESSAGE_TYPE;
605 message->v6.olsr_vtime = reltime_to_me(my_timeout * MSEC_PER_SEC);
606 memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
607 message->v6.ttl = MAX_TTL;
608 message->v6.hopcnt = 0;
609 message->v6.seqno = htons(get_msg_seqno());
611 namesize = encap_namemsg((struct namemsg*)&message->v6.message);
612 namesize = namesize + sizeof(struct olsrmsg6);
614 message->v6.olsr_msgsize = htons(namesize);
617 /* looping trough interfaces */
618 for (ifn = ifnet; ifn ; ifn = ifn->int_next)
620 OLSR_PRINTF(3, "NAME PLUGIN: Generating packet - [%s]\n", ifn->int_name);
622 if(net_outbuffer_push(ifn, message, namesize) != namesize ) {
623 /* send data and try again */
625 if(net_outbuffer_push(ifn, message, namesize) != namesize ) {
626 OLSR_PRINTF(1, "NAME PLUGIN: could not send on interface: %s\n", ifn->int_name);
634 * Parse name olsr message of NAME type
637 olsr_parser(union olsr_message *m,
638 struct interface *in_if __attribute__((unused)),
639 union olsr_ip_addr *ipaddr)
641 struct namemsg *namemessage;
642 union olsr_ip_addr originator;
647 /* Fetch the originator of the messsage */
648 if(olsr_cnf->ip_version == AF_INET) {
649 memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
650 seqno = ntohs(m->v4.seqno);
652 memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
653 seqno = ntohs(m->v6.seqno);
656 /* Fetch the message based on IP version */
657 if(olsr_cnf->ip_version == AF_INET) {
658 vtime = me_to_reltime(m->v4.olsr_vtime);
659 size = ntohs(m->v4.olsr_msgsize);
660 namemessage = (struct namemsg*)&m->v4.message;
663 vtime = me_to_reltime(m->v6.olsr_vtime);
664 size = ntohs(m->v6.olsr_msgsize);
665 namemessage = (struct namemsg*)&m->v6.message;
668 /* Check if message originated from this node.
670 if(ipequal(&originator, &olsr_cnf->main_addr))
673 /* Check that the neighbor this message was received from is symmetric.
675 if(check_neighbor_link(ipaddr) != SYM_LINK) {
676 struct ipaddr_str strbuf;
677 OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
681 update_name_entry(&originator, namemessage, size, vtime);
683 /* Forward the message if nessecary
684 * default_fwd does all the work for us! */
685 olsr_forward_message(m, ipaddr);
689 * Encapsulate a name message into a packet.
691 * It assumed that there is enough space in the buffer to do this!
693 * Returns: the length of the message that was appended
696 encap_namemsg(struct namemsg* msg)
698 struct name_entry *my_name;
699 struct name_entry *my_service;
701 // add the hostname, service and forwarder entries after the namemsg header
702 char* pos = (char*)msg + sizeof(struct namemsg);
706 for (my_name = my_names; my_name!=NULL; my_name = my_name->next)
708 pos = create_packet( (struct name*) pos, my_name);
712 for (my_name = my_forwarders; my_name!=NULL; my_name = my_name->next)
714 pos = create_packet( (struct name*) pos, my_name);
718 for (my_service = my_services; my_service!=NULL; my_service = my_service->next)
720 pos = create_packet( (struct name*) pos, my_service);
724 if ('\0' != latlon_in_file[0])
726 FILE* in = fopen( latlon_in_file, "r" );
728 fscanf(in, "%f,%f", &my_lat, &my_lon);
733 OLSR_PRINTF(0, "NAME PLUGIN: cant read latlon in file %s\n", latlon_in_file);
736 if (0.0 != my_lat && 0.0 != my_lon)
740 memset(&e, 0, sizeof(e));
741 sprintf(s, "%f,%f,%d", my_lat, my_lon, get_isdefhna_latlon());
743 e.type = NAME_LATLON;
745 lookup_defhna_latlon(&e.ip);
746 pos = create_packet( (struct name*) pos, &e);
750 // write the namemsg header with the number of announced entries and the protocol version
751 msg->nr_names = htons(i);
752 msg->version = htons(NAME_PROTOCOL_VERSION);
754 return pos - (char*)msg; //length
759 * convert each of my to be announced name_entries into network
762 * return the length of the name packet
765 create_packet(struct name* to, struct name_entry *from)
767 char *pos = (char*) to;
769 struct ipaddr_str strbuf;
770 OLSR_PRINTF(3, "NAME PLUGIN: Announcing name %s (%s) %d\n",
771 from->name, olsr_ip_to_string(&strbuf, &from->ip), from->len);
772 to->type = htons(from->type);
773 to->len = htons(from->len);
775 pos += sizeof(struct name);
776 memcpy(pos, from->name, from->len);
778 for (k = from->len; (k & 3) != 0; k++)
784 * decapsulate a received name, service or forwarder and update the corresponding hash table if necessary
787 decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed )
789 struct ipaddr_str strbuf;
790 struct name_entry *tmp;
791 struct name_entry *already_saved_name_entries;
792 char *name = (char*)from_packet + sizeof(struct name);
793 int type_of_from_packet = ntohs(from_packet->type);
794 unsigned int len_of_name = ntohs(from_packet->len);
795 OLSR_PRINTF(4, "NAME PLUGIN: decap type=%d, len=%d, name=%s\n",
796 type_of_from_packet, len_of_name, name);
798 //XXX: should I check the from_packet->ip here? If so, why not also check the ip from HOST and SERVICE?
799 if( (type_of_from_packet==NAME_HOST && !is_name_wellformed(name)) ||
800 (type_of_from_packet==NAME_SERVICE && !is_service_wellformed(name)) ||
801 (type_of_from_packet==NAME_LATLON && !is_latlon_wellformed(name)))
803 OLSR_PRINTF(4, "NAME PLUGIN: invalid name [%s] received, skipping.\n", name );
807 //ignore all packets with a too long name
808 //or a spoofed len of its included name string
809 if (len_of_name > MAX_NAME || strlen(name) != len_of_name || NULL != strchr(name, '\\') || NULL != strchr(name, '\'')) {
810 OLSR_PRINTF(4, "NAME PLUGIN: from_packet->len %d > MAX_NAME %d or from_packet->len %d !0 strlen(name [%s] in packet)\n",
811 len_of_name, MAX_NAME, len_of_name, name );
815 // don't insert the received entry again, if it has already been inserted in the hash table.
816 // Instead only the validity time is set in insert_new_name_in_list function, which calls this one
817 for (already_saved_name_entries = (*to); already_saved_name_entries != NULL ; already_saved_name_entries = already_saved_name_entries->next)
819 if ( (type_of_from_packet==NAME_HOST || type_of_from_packet==NAME_SERVICE) && strncmp(already_saved_name_entries->name, name, len_of_name) == 0 ) {
820 OLSR_PRINTF(4, "NAME PLUGIN: received name or service entry %s (%s) already in hash table\n",
821 name, olsr_ip_to_string(&strbuf, &already_saved_name_entries->ip));
823 } else if (type_of_from_packet==NAME_FORWARDER && ipequal(&already_saved_name_entries->ip, &from_packet->ip) ) {
824 OLSR_PRINTF(4, "NAME PLUGIN: received forwarder entry %s (%s) already in hash table\n",
825 name, olsr_ip_to_string(&strbuf, &already_saved_name_entries->ip));
827 } else if (type_of_from_packet==NAME_LATLON ) {
828 if (0 != strncmp(already_saved_name_entries->name, name, len_of_name))
830 OLSR_PRINTF(4, "NAME PLUGIN: updating name %s -> %s (%s)\n",
831 already_saved_name_entries->name, name,
832 olsr_ip_to_string(&strbuf, &already_saved_name_entries->ip));
833 free(already_saved_name_entries->name);
834 already_saved_name_entries->name = olsr_malloc(len_of_name + 1, "upd name_entry name");
835 strscpy(already_saved_name_entries->name, name, len_of_name + 1);
837 *this_table_changed = OLSR_TRUE;
838 olsr_start_write_file_timer();
840 if (!ipequal(&already_saved_name_entries->ip, &from_packet->ip))
842 struct ipaddr_str strbuf2, strbuf3;
843 OLSR_PRINTF(4, "NAME PLUGIN: updating ip %s -> %s (%s)\n",
844 olsr_ip_to_string(&strbuf, &already_saved_name_entries->ip),
845 olsr_ip_to_string(&strbuf2, &from_packet->ip),
846 olsr_ip_to_string(&strbuf3, &already_saved_name_entries->ip));
847 already_saved_name_entries->ip = from_packet->ip;
849 *this_table_changed = OLSR_TRUE;
850 olsr_start_write_file_timer();
852 if (!*this_table_changed)
854 OLSR_PRINTF(4, "NAME PLUGIN: received latlon entry %s (%s) already in hash table\n",
855 name, olsr_ip_to_string(&strbuf, &already_saved_name_entries->ip));
861 //if not yet known entry
862 tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry");
863 tmp->type = ntohs(from_packet->type);
864 tmp->len = len_of_name > MAX_NAME ? MAX_NAME : ntohs(from_packet->len);
865 tmp->name = olsr_malloc(tmp->len + 1, "new name_entry name");
866 tmp->ip = from_packet->ip;
867 strscpy(tmp->name, name, tmp->len + 1);
869 OLSR_PRINTF(3, "\nNAME PLUGIN: create new name/service/forwarder entry %s (%s) [len=%d] [type=%d] in linked list\n",
870 tmp->name, olsr_ip_to_string(&strbuf, &tmp->ip), tmp->len, tmp->type);
872 *this_table_changed = OLSR_TRUE;
873 olsr_start_write_file_timer();
882 * unpack the received message and delegate to the decapsulation function for each
883 * name/service/forwarder entry in the message
886 update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, olsr_reltime vtime)
888 struct ipaddr_str strbuf;
890 struct name *from_packet;
893 OLSR_PRINTF(3, "NAME PLUGIN: Received Message from %s\n",
894 olsr_ip_to_string(&strbuf, originator));
896 if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) {
897 OLSR_PRINTF(3, "NAME PLUGIN: ignoring wrong version %d\n", msg->version);
901 /* now add the names from the message */
902 pos = (char*)msg + sizeof(struct namemsg);
903 end_pos = pos + msg_size - sizeof(struct name*); // at least one struct name has to be left
905 for (i=ntohs(msg->nr_names); i > 0 && pos<end_pos; i--)
907 from_packet = (struct name*)pos;
909 switch (ntohs(from_packet->type)) {
911 insert_new_name_in_list(originator, name_list, from_packet,
912 &name_table_changed, vtime);
915 insert_new_name_in_list(originator, forwarder_list, from_packet,
916 &forwarder_table_changed, vtime);
919 insert_new_name_in_list(originator, service_list, from_packet,
920 &service_table_changed, vtime);
923 insert_new_name_in_list(originator, latlon_list, from_packet,
924 &latlon_table_changed, vtime);
927 OLSR_PRINTF(3, "NAME PLUGIN: Received Message of unknown type [%d] from (%s)\n",
928 from_packet->type, olsr_ip_to_string(&strbuf, originator));
932 pos += sizeof(struct name);
933 pos += 1 + (( ntohs(from_packet->len) - 1) | 3);
936 OLSR_PRINTF(4, "NAME PLUGIN: Lost %d entries in received packet due to length inconsistency (%s)\n", i, olsr_ip_to_string(&strbuf, originator));
941 * insert all the new names,services and forwarders from a received packet into the
942 * corresponding entry for this ip in the corresponding hash table
945 insert_new_name_in_list(union olsr_ip_addr *originator,
946 struct list_node *this_list,
947 struct name *from_packet, olsr_bool *this_table_changed,
951 struct db_entry *entry;
952 struct list_node *list_head, *list_node;
954 olsr_bool entry_found = OLSR_FALSE;
956 hash = olsr_ip_hashing(originator);
958 /* find the entry for originator, if there is already one */
959 list_head = &this_list[hash];
960 for (list_node = list_head->next; list_node != list_head;
961 list_node = list_node->next) {
963 entry = list2db(list_node);
965 if (ipequal(originator, &entry->originator)) {
966 struct ipaddr_str strbuf;
968 OLSR_PRINTF(4, "NAME PLUGIN: found entry for (%s) in its hash table\n",
969 olsr_ip_to_string(&strbuf, originator));
971 //delegate to function for parsing the packet and linking it to entry->names
972 decap_namemsg(from_packet, &entry->names, this_table_changed);
974 olsr_set_timer(&entry->db_timer, vtime,
975 OLSR_NAMESVC_DB_JITTER, OLSR_TIMER_ONESHOT,
976 &olsr_nameservice_expire_db_timer, entry, 0);
978 entry_found = OLSR_TRUE;
984 struct ipaddr_str strbuf;
985 OLSR_PRINTF(3, "NAME PLUGIN: create new db entry for ip (%s) in hash table\n",
986 olsr_ip_to_string(&strbuf, originator));
988 /* insert a new entry */
989 entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
990 memset(entry, 0, sizeof(struct db_entry));
992 entry->originator = *originator;
994 olsr_set_timer(&entry->db_timer, vtime,
995 OLSR_LINK_LOSS_JITTER, OLSR_TIMER_ONESHOT,
996 &olsr_nameservice_expire_db_timer, entry, 0);
1000 /* insert to the list */
1001 list_add_before(&this_list[hash], &entry->db_list);
1003 //delegate to function for parsing the packet and linking it to entry->names
1004 decap_namemsg(from_packet, &entry->names, this_table_changed);
1010 send_sighup_to_pidfile(char * pid_file){
1018 fd = open(pid_file, O_RDONLY);
1020 OLSR_PRINTF(2, "NAME PLUGIN: can't open file %s\n", pid_file);
1025 result = read(fd, line+i, 19-i);
1026 if (!result) { /* EOF */
1028 } else if (result>0) {
1030 } else if(errno!=EINTR && errno!=EAGAIN) {
1031 OLSR_PRINTF(2, "NAME PLUGIN: can't read file %s\n", pid_file);
1037 ipid = strtol(line, &endptr, 0);
1039 OLSR_PRINTF(2, "NAME PLUGIN: invalid pid at file %s\n", pid_file);
1043 result=kill(ipid, SIGHUP);
1045 OLSR_PRINTF(2, "NAME PLUGIN: SIGHUP sent to pid %i\n", ipid);
1047 OLSR_PRINTF(2, "NAME PLUGIN: failed to send SIGHUP to pid %i\n", ipid);
1054 * write names to a file in /etc/hosts compatible format
1057 write_hosts_file(void)
1060 struct name_entry *name;
1061 struct db_entry *entry;
1062 struct list_node *list_head, *list_node;
1069 struct mid_entry *alias;
1070 struct tc_entry *tc;
1073 if (!name_table_changed)
1076 OLSR_PRINTF(2, "NAME PLUGIN: writing hosts file\n");
1078 hosts = fopen( my_hosts_file, "w" );
1079 if (hosts == NULL) {
1080 OLSR_PRINTF(2, "NAME PLUGIN: cant write hosts file\n");
1084 fprintf(hosts, "### this /etc/hosts file is overwritten regularly by olsrd\n");
1085 fprintf(hosts, "### do not edit\n\n");
1087 fprintf(hosts, "127.0.0.1\tlocalhost\n");
1088 fprintf(hosts, "::1\t\tlocalhost\n\n");
1090 // copy content from additional hosts filename
1091 if (my_add_hosts[0] != '\0') {
1092 add_hosts = fopen( my_add_hosts, "r" );
1093 if (add_hosts == NULL) {
1094 OLSR_PRINTF(2, "NAME PLUGIN: cant open additional hosts file\n");
1097 fprintf(hosts, "### contents from '%s' ###\n\n", my_add_hosts);
1098 while ((c = getc(add_hosts)) != EOF)
1102 fprintf(hosts, "\n### olsr names ###\n\n");
1106 for (name = my_names; name != NULL; name = name->next) {
1107 struct ipaddr_str strbuf;
1108 fprintf(hosts, "%s\t%s%s\t# myself\n", olsr_ip_to_string(&strbuf, &name->ip), name->name, my_suffix );
1111 // write received names
1112 for (hash = 0; hash < HASHSIZE; hash++) {
1113 list_head = &name_list[hash];
1114 for (list_node = list_head->next; list_node != list_head;
1115 list_node = list_node->next) {
1117 entry = list2db(list_node);
1119 for (name = entry->names; name != NULL; name = name->next) {
1120 struct ipaddr_str strbuf;
1122 6, "%s\t%s%s\t#%s\n",
1123 olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
1124 olsr_ip_to_string( &strbuf, &entry->originator )
1128 hosts, "%s\t%s%s\t# %s\n",
1129 olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
1130 olsr_ip_to_string( &strbuf, &entry->originator )
1134 // write mid entries
1135 if (( tc = olsr_lookup_tc_entry( &name->ip ) ) != NULL ) {
1136 unsigned short mid_num = 1;
1137 char mid_prefix[MID_MAXLEN];
1139 OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
1140 struct ipaddr_str midbuf;
1142 // generate mid prefix
1143 sprintf( mid_prefix, MID_PREFIX, mid_num );
1146 6, "%s\t%s%s%s\t# %s (mid #%i)\n",
1147 olsr_ip_to_string( &midbuf, &alias->mid_alias_addr ),
1148 mid_prefix, name->name, my_suffix,
1149 olsr_ip_to_string( &strbuf, &entry->originator ),
1154 hosts, "%s\t%s%s%s\t# %s (mid #%i)\n",
1155 olsr_ip_to_string( &midbuf, &alias->mid_alias_addr ),
1156 mid_prefix, name->name, my_suffix,
1157 olsr_ip_to_string( &strbuf, &entry->originator ),
1162 } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
1169 if (time(&currtime)) {
1170 fprintf(hosts, "\n### written by olsrd at %s", ctime(&currtime));
1176 if (*my_sighup_pid_file)
1177 send_sighup_to_pidfile(my_sighup_pid_file);
1179 name_table_changed = OLSR_FALSE;
1181 // Executes my_name_change_script after writing the hosts file
1182 if (my_name_change_script[0] != '\0') {
1183 if(system(my_name_change_script) != -1) {
1184 OLSR_PRINTF(2, "NAME PLUGIN: Name changed, %s executed\n", my_name_change_script);
1187 OLSR_PRINTF(2, "NAME PLUGIN: WARNING! Failed to execute %s on hosts change\n", my_name_change_script);
1194 * write services to a file in the format:
1195 * service #originator ip
1197 * since service has a special format
1198 * each line will look similar to e.g.
1199 * http://me.olsr:80|tcp|my little homepage
1202 write_services_file(void)
1205 struct name_entry *name;
1206 struct db_entry *entry;
1207 struct list_node *list_head, *list_node;
1208 FILE* services_file;
1212 if (!service_table_changed)
1215 OLSR_PRINTF(2, "NAME PLUGIN: writing services file\n");
1217 services_file = fopen( my_services_file, "w" );
1218 if (services_file == NULL) {
1219 OLSR_PRINTF(2, "NAME PLUGIN: cant write services_file file\n");
1223 fprintf(services_file, "### this file is overwritten regularly by olsrd\n");
1224 fprintf(services_file, "### do not edit\n\n");
1227 // write own services
1228 for (name = my_services; name != NULL; name = name->next) {
1229 fprintf(services_file, "%s\t# my own service\n", name->name);
1232 // write received services
1233 for (hash = 0; hash < HASHSIZE; hash++) {
1234 list_head = &service_list[hash];
1235 for (list_node = list_head->next; list_node != list_head;
1236 list_node = list_node->next) {
1238 entry = list2db(list_node);
1240 for (name = entry->names; name != NULL; name = name->next) {
1241 struct ipaddr_str strbuf;
1242 OLSR_PRINTF(6, "%s\t", name->name);
1243 OLSR_PRINTF(6, "\t#%s\n",
1244 olsr_ip_to_string(&strbuf, &entry->originator));
1246 fprintf(services_file, "%s\t", name->name );
1247 fprintf(services_file, "\t#%s\n",
1248 olsr_ip_to_string(&strbuf, &entry->originator));
1253 if (time(&currtime)) {
1254 fprintf(services_file, "\n### written by olsrd at %s", ctime(&currtime));
1257 fclose(services_file);
1258 service_table_changed = OLSR_FALSE;
1260 // Executes my_services_change_script after writing the services file
1261 if (my_services_change_script[0] != '\0') {
1262 if(system(my_services_change_script) != -1) {
1263 OLSR_PRINTF(2, "NAME PLUGIN: Service changed, %s executed\n", my_services_change_script);
1266 OLSR_PRINTF(2, "NAME PLUGIN: WARNING! Failed to execute %s on service change\n", my_services_change_script);
1272 * Sort the nameserver pointer array.
1274 * fresh entries are at the beginning of the array and
1275 * the best entry is at the end of the array.
1278 select_best_nameserver(struct rt_entry **rt)
1281 struct rt_entry *rt1, *rt2;
1283 for (nameserver_idx = 0;
1284 nameserver_idx < NAMESERVER_COUNT;
1287 rt1 = rt[nameserver_idx];
1288 rt2 = rt[nameserver_idx+1];
1291 * compare the next two pointers in the array.
1292 * if the second pointer is NULL then percolate it up.
1294 if (!rt2 || olsr_cmp_rt(rt1, rt2)) {
1296 struct ipaddr_str strbuf;
1297 struct lqtextbuffer lqbuffer;
1300 * first is better, swap the pointers.
1302 OLSR_PRINTF(6, "NAME PLUGIN: nameserver %s, cost %s\n",
1303 olsr_ip_to_string(&strbuf, &rt1->rt_dst.prefix),
1304 get_linkcost_text(rt1->rt_best->rtp_metric.cost, OLSR_TRUE, &lqbuffer));
1306 rt[nameserver_idx] = rt2;
1307 rt[nameserver_idx+1] = rt1;
1313 * write the 3 best upstream DNS servers to resolv.conf file
1314 * best means the 3 with the best etx value in routing table
1317 write_resolv_file(void)
1320 struct name_entry *name;
1321 struct db_entry *entry;
1322 struct list_node *list_head, *list_node;
1323 struct rt_entry *route;
1324 static struct rt_entry *nameserver_routes[NAMESERVER_COUNT+1];
1329 if (!forwarder_table_changed || my_forwarders != NULL || my_resolv_file[0] == '\0')
1332 /* clear the array of 3+1 nameserver routes */
1333 memset(nameserver_routes, 0, sizeof(nameserver_routes));
1335 for (hash = 0; hash < HASHSIZE; hash++) {
1336 list_head = &forwarder_list[hash];
1337 for (list_node = list_head->next; list_node != list_head;
1338 list_node = list_node->next) {
1340 entry = list2db(list_node);
1342 for (name = entry->names; name != NULL; name = name->next) {
1344 struct ipaddr_str strbuf;
1345 struct lqtextbuffer lqbuffer;
1347 route = olsr_lookup_routing_table(&name->ip);
1349 OLSR_PRINTF(6, "NAME PLUGIN: check route for nameserver %s %s",
1350 olsr_ip_to_string(&strbuf, &name->ip),
1351 route ? "suceeded" : "failed");
1353 if (route==NULL) // it's possible that route is not present yet
1356 /* enqueue it on the head of list */
1357 *nameserver_routes = route;
1358 OLSR_PRINTF(6, "NAME PLUGIN: found nameserver %s, cost %s",
1359 olsr_ip_to_string(&strbuf, &name->ip),
1360 get_linkcost_text(route->rt_best->rtp_metric.cost, OLSR_TRUE, &lqbuffer));
1362 /* find the closet one */
1363 select_best_nameserver(nameserver_routes);
1368 /* if there is no best route we are done */
1369 if (nameserver_routes[NAMESERVER_COUNT]==NULL)
1373 OLSR_PRINTF(2, "NAME PLUGIN: try to write to resolv file\n");
1374 resolv = fopen( my_resolv_file, "w" );
1375 if (resolv == NULL) {
1376 OLSR_PRINTF(2, "NAME PLUGIN: can't write resolv file\n");
1379 fprintf(resolv, "### this file is overwritten regularly by olsrd\n");
1380 fprintf(resolv, "### do not edit\n\n");
1382 for (i = NAMESERVER_COUNT; i >= 0; i--) {
1383 struct ipaddr_str strbuf;
1385 route = nameserver_routes[i];
1387 OLSR_PRINTF(2, "NAME PLUGIN: nameserver_routes #%d %p\n", i, route);
1393 OLSR_PRINTF(2, "NAME PLUGIN: nameserver %s\n",
1394 olsr_ip_to_string(&strbuf, &route->rt_dst.prefix));
1395 fprintf(resolv, "nameserver %s\n",
1396 olsr_ip_to_string(&strbuf, &route->rt_dst.prefix));
1398 if (time(&currtime)) {
1399 fprintf(resolv, "\n### written by olsrd at %s", ctime(&currtime));
1402 forwarder_table_changed = OLSR_FALSE;
1407 * completely free a list of name_entries
1410 free_name_entry_list(struct name_entry **list)
1412 struct name_entry **tmp = list;
1413 struct name_entry *to_delete;
1414 while (*tmp != NULL) {
1416 *tmp = (*tmp)->next;
1419 switch (to_delete->type) {
1421 name_table_changed = OLSR_TRUE;
1423 case NAME_FORWARDER:
1424 forwarder_table_changed = OLSR_TRUE;
1427 service_table_changed = OLSR_TRUE;
1430 latlon_table_changed = OLSR_TRUE;
1436 free( to_delete->name );
1437 to_delete->name = NULL;
1445 * we only allow names for IP addresses which we are
1447 * so the IP must either be from one of the interfaces
1448 * or inside a HNA which we have configured
1451 allowed_ip(const union olsr_ip_addr *addr)
1453 struct ip_prefix_list *hna;
1454 struct interface *iface;
1455 union olsr_ip_addr tmp_ip, tmp_msk;
1456 struct ipaddr_str strbuf;
1457 struct ipprefix_str prefixstr;
1459 OLSR_PRINTF(6, "checking %s\n", olsr_ip_to_string(&strbuf, addr));
1461 for(iface = ifnet; iface; iface = iface->int_next)
1463 OLSR_PRINTF(6, "interface %s\n", olsr_ip_to_string(&strbuf, &iface->ip_addr));
1464 if (ipequal(&iface->ip_addr, addr)) {
1465 OLSR_PRINTF(6, "MATCHED\n");
1470 if (olsr_cnf->ip_version == AF_INET) {
1471 for (hna = olsr_cnf->hna_entries; hna != NULL; hna = hna->next) {
1472 union olsr_ip_addr netmask;
1473 OLSR_PRINTF(6, "HNA %s\n",
1474 olsr_ip_prefix_to_string(&prefixstr, &hna->net));
1475 if (hna->net.prefix_len == 0) {
1478 olsr_prefix_to_netmask(&netmask, hna->net.prefix_len);
1479 if ((addr->v4.s_addr & netmask.v4.s_addr) == hna->net.prefix.v4.s_addr) {
1480 OLSR_PRINTF(6, "MATCHED\n");
1485 for (hna = olsr_cnf->hna_entries; hna != NULL; hna = hna->next)
1488 OLSR_PRINTF(6, "HNA %s\n",
1489 olsr_ip_prefix_to_string(&prefixstr, &hna->net));
1490 if ( hna->net.prefix_len == 0 )
1492 olsr_prefix_to_netmask(&tmp_msk, hna->net.prefix_len);
1493 for (i = 0; i < sizeof(tmp_ip.v6.s6_addr); i++) {
1494 tmp_ip.v6.s6_addr[i] = addr->v6.s6_addr[i] & tmp_msk.v6.s6_addr[i];
1496 if (ipequal(&tmp_ip, &hna->net.prefix)) {
1497 OLSR_PRINTF(6, "MATCHED\n");
1505 /** check if name has the right syntax, i.e. it must adhere to a special regex
1506 * stored in regex_t_name
1507 * necessary to avaid names like "0.0.0.0 google.de\n etc"
1510 is_name_wellformed(const char *name) {
1511 return regexec(®ex_t_name, name, 1, ®match_t_name, 0) == 0 ;
1516 * check if the service is in the right syntax and also that the hostname
1517 * or ip whithin the service is allowed
1520 allowed_service(const char *service_line)
1522 /* the call of is_service_wellformed generates the submatches stored in regmatch_t_service
1523 * these are then used by allowed_hostname_or_ip_in_service
1524 * see regexec(3) for more infos */
1525 if (!is_service_wellformed(service_line)) {
1527 } else if (!allowed_hostname_or_ip_in_service(service_line, &(regmatch_t_service[1]))) {
1535 allowed_hostname_or_ip_in_service(const char *service_line, const regmatch_t *hostname_or_ip_match)
1537 char *hostname_or_ip;
1538 union olsr_ip_addr olsr_ip;
1539 struct name_entry *name;
1540 if (hostname_or_ip_match->rm_so < 0 || hostname_or_ip_match->rm_eo < 0) {
1544 hostname_or_ip = strndup(&service_line[hostname_or_ip_match->rm_so], hostname_or_ip_match->rm_eo - hostname_or_ip_match->rm_so);
1545 //hostname is one of the names, that I announce (i.e. one that i am allowed to announce)
1546 for (name = my_names; name != NULL; name = name->next) {
1547 if (strncmp(name->name, hostname_or_ip, name->len - strlen(my_suffix)) == 0 ) {
1548 OLSR_PRINTF(4, "NAME PLUGIN: hostname %s in service %s is OK\n", hostname_or_ip, service_line);
1549 free(hostname_or_ip);
1550 hostname_or_ip = NULL;
1555 //ip in service-line is allowed
1556 if (inet_pton(olsr_cnf->ip_version, hostname_or_ip, &olsr_ip) > 0) {
1557 if (allowed_ip(&olsr_ip)) {
1558 struct ipaddr_str strbuf;
1559 OLSR_PRINTF(2, "NAME PLUGIN: ip %s in service %s is OK\n", olsr_ip_to_string(&strbuf, &olsr_ip), service_line);
1560 free(hostname_or_ip);
1561 hostname_or_ip = NULL;
1566 OLSR_PRINTF(1, "NAME PLUGIN: ip or hostname %s in service %s is NOT allowed (does not belong to you)\n", hostname_or_ip, service_line);
1567 free(hostname_or_ip);
1568 hostname_or_ip = NULL;
1574 * check if the service matches the syntax
1575 * of "protocol://host:port/path|tcp_or_udp|a short description",
1576 * which is given in the regex regex_t_service
1579 is_service_wellformed(const char *service_line)
1581 return regexec(®ex_t_service, service_line, pmatch_service, regmatch_t_service, 0) == 0;
1585 * check if the latlot matches the syntax
1588 is_latlon_wellformed(const char *latlon_line)
1591 float a = 0.0, b = 0.0;
1592 sscanf(latlon_line, "%f,%f,%d", &a, &b, &hna);
1593 return (a != 0.0 && b != 0.0 && -1 != hna);
1597 * Returns 1 if this olsrd announces inet
1599 olsr_bool get_isdefhna_latlon(void)
1601 struct ip_prefix_list *hna;
1602 for (hna = olsr_cnf->hna_entries; hna != NULL; hna = hna->next){
1603 if (hna->net.prefix_len == 0) {
1611 * Grabs the current HNA selected default route
1613 void lookup_defhna_latlon(union olsr_ip_addr *ip)
1615 struct rt_entry *rt;
1616 struct avl_node *rt_tree_node;
1617 struct olsr_ip_prefix prefix;
1619 memset(ip, 0, sizeof(ip));
1620 memset(&prefix, 0, sizeof(prefix));
1622 if (NULL != (rt_tree_node = avl_find(&routingtree, &prefix))) {
1623 rt = rt_tree2rt(rt_tree_node);
1624 *ip = rt->rt_best->rtp_nexthop.gateway;
1629 * lookup a nodes name
1632 lookup_name_latlon(union olsr_ip_addr *ip)
1635 struct db_entry *entry;
1636 struct list_node *list_head, *list_node;
1637 struct name_entry *name;
1639 for (hash = 0; hash < HASHSIZE; hash++) {
1640 list_head = &name_list[hash];
1641 for (list_node = list_head->next; list_node != list_head;
1642 list_node = list_node->next) {
1644 entry = list2db(list_node);
1646 for (name = entry->names; name != NULL; name = name->next) {
1647 if (ipequal(&name->ip, ip)) return name->name;
1656 * write latlon positions to a javascript file
1659 write_latlon_file(void)
1663 if (!my_names || !latlon_table_changed) return;
1665 OLSR_PRINTF(2, "NAME PLUGIN: writing latlon file\n");
1667 if (NULL == (fmap = fopen(my_latlon_file, "w"))) {
1668 OLSR_PRINTF(0, "NAME PLUGIN: cant write latlon file\n");
1671 fprintf(fmap, "/* This file is overwritten regularly by olsrd */\n");
1672 mapwrite_work(fmap);
1674 latlon_table_changed = OLSR_FALSE;
1681 * c-indent-tabs-mode: t
1682 * indent-tabs-mode: t