2 * Copyright (c) 2005, Bruno Randolf <bruno.randolf@4g-systems.biz>
3 * Copyright (c) 2004, Andreas Tønnesen(andreto-at-olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 * * Neither the name of the UniK olsr daemon nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
32 /* $Id: nameservice.c,v 1.1 2005/01/16 13:06:00 kattemat Exp $ */
35 * Dynamic linked library for UniK OLSRd
42 #include "nameservice.h"
43 #include "olsrd_copy.h"
46 /* The database - (using hashing) */
47 struct name_entry list[HASHSIZE];
49 /* send buffer: size of IPv6 message + the maximum size of the name */
50 static char buffer[sizeof(struct olsrmsg6) + MAX_NAME];
52 olsr_u8_t name_table_changed=0;
55 olsr_u8_t my_name_len = 0;
56 char* my_filename = "/var/run/hosts_olsr";
67 for(i = 0; i < HASHSIZE; i++)
69 list[i].next = &list[i];
70 list[i].prev = &list[i];
73 /* Register functions with olsrd */
74 olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1);
75 olsr_register_timeout_function(&olsr_timeout);
76 olsr_register_scheduler_event(&olsr_event, NULL, EMISSION_INTERVAL, 0, NULL);
89 struct name_entry *tmp_list;
90 struct name_entry *entry_to_delete;
92 /* free list entries */
93 for(i = 0; i < HASHSIZE; i++)
95 tmp_list = list[i].next;
96 while(tmp_list != &list[i])
98 entry_to_delete = tmp_list;
99 tmp_list = tmp_list->next;
100 entry_to_delete->prev->next = entry_to_delete->next;
101 entry_to_delete->next->prev = entry_to_delete->prev;
102 free(entry_to_delete->name);
103 free(entry_to_delete);
110 * A timeout function called every time
111 * the scheduler is polled: time out old list entries
116 struct name_entry *tmp_list;
117 struct name_entry *entry_to_delete;
120 for(index=0;index<HASHSIZE;index++)
122 tmp_list = list[index].next;
123 while(tmp_list != &list[index])
125 /*Check if the entry is timed out*/
126 if(olsr_timed_out(&tmp_list->timer))
128 entry_to_delete = tmp_list;
129 tmp_list = tmp_list->next;
130 olsr_printf(2, "NAME PLUGIN: %s timed out.. deleting\n",
131 olsr_ip_to_string(&entry_to_delete->originator));
133 entry_to_delete->prev->next = entry_to_delete->next;
134 entry_to_delete->next->prev = entry_to_delete->prev;
137 free(entry_to_delete->name);
138 free(entry_to_delete);
140 name_table_changed = 1;
143 tmp_list = tmp_list->next;
151 * Scheduled event: generate and send NAME packet
154 olsr_event(void *foo)
156 union olsr_message *message = (union olsr_message*)buffer;
157 struct interface *ifn;
160 olsr_printf(3, "NAME PLUGIN: Generating packet - ");
162 /* looping trough interfaces */
163 for (ifn = ifs; ifn ; ifn = ifn->int_next)
165 olsr_printf(3, "[%s] ", ifn->int_name);
167 if(ipversion == AF_INET)
170 message->v4.olsr_msgtype = MESSAGE_TYPE;
171 message->v4.olsr_vtime = double_to_me(NAME_VALID_TIME);
172 memcpy(&message->v4.originator, main_addr, ipsize);
173 message->v4.ttl = MAX_TTL;
174 message->v4.hopcnt = 0;
175 message->v4.seqno = htons(get_msg_seqno());
177 namesize = get_namemsg(&message->v4.msg);
178 namesize = namesize + sizeof(struct olsrmsg);
180 message->v4.olsr_msgsize = htons(namesize);
185 message->v6.olsr_msgtype = MESSAGE_TYPE;
186 message->v6.olsr_vtime = double_to_me(NAME_VALID_TIME);
187 memcpy(&message->v6.originator, main_addr, ipsize);
188 message->v6.ttl = MAX_TTL;
189 message->v6.hopcnt = 0;
190 message->v6.seqno = htons(get_msg_seqno());
192 namesize = get_namemsg(&message->v6.msg);
193 namesize = namesize + sizeof(struct olsrmsg6);
195 message->v6.olsr_msgsize = htons(namesize);
198 if(net_outbuffer_push(ifn, (olsr_u8_t *)message, namesize) != namesize ) {
199 /* Send data and try again */
201 if(net_outbuffer_push(ifn, (olsr_u8_t *)message, namesize) != namesize ) {
202 olsr_printf(1, "NAME PLUGIN: could not send on interface: %s\n", ifn->int_name);
206 olsr_printf(3, "\n");
213 * Parse name olsr message of NAME type
216 olsr_parser(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *in_addr)
218 struct namemsg *message;
219 union olsr_ip_addr originator;
222 /* Fetch the originator of the messsage */
223 memcpy(&originator, &m->v4.originator, ipsize);
225 /* Fetch the message based on IP version */
226 if(ipversion == AF_INET) {
227 message = &m->v4.msg;
228 vtime = me_to_double(m->v4.olsr_vtime);
231 message = &m->v6.msg;
232 vtime = me_to_double(m->v6.olsr_vtime);
235 /* Check if message originated from this node.
237 if(memcmp(&originator, main_addr, ipsize) == 0)
240 /* Check that the neighbor this message was received from is symmetric.
242 if(check_neighbor_link(in_addr) != SYM_LINK) {
243 olsr_printf(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(in_addr));
247 /* Check if this message has been processed before
248 * Remeber that this also registeres the message as
249 * processed if nessecary
251 if(!check_dup_proc(&originator, ntohs(m->v4.seqno))) {
252 /* If so - do not process */
257 olsr_printf(3, "NAME PLUGIN: Processing NAME info from %s seqno: %d\n",
258 olsr_ip_to_string(&originator),
261 update_name_entry(&originator, message, vtime);
265 /* Forward the message if nessecary
266 * default_fwd does all the work for us! */
267 default_fwd(m, &originator, ntohs(m->v4.seqno), in_if, in_addr);
272 * Get a name message. This fills the namemsg struct
273 * AND appends the name after that!
275 * It assumed that there is enough space in the buffer to do this!
277 * Returns: the length of the name that was appended
280 get_namemsg(struct namemsg *msg)
282 msg->name_len = my_name_len;
283 char* txt = (char*)(msg + sizeof(struct namemsg));
284 strncpy(txt, my_name, MAX_NAME);
290 * Read a name message and update name_entry if necessary
292 * Return: 1 if entry was changed
295 read_namemsg(struct namemsg *msg, struct name_entry *to)
297 char* txt = (char*)(msg + sizeof(struct namemsg));
298 if (to->name == NULL || strncmp(to->name, txt, MAX_NAME) != 0) {
299 if (to->name != NULL) {
302 to->name = olsr_malloc(msg->name_len, "new name_entry name");
303 strncpy(to->name, txt, msg->name_len);
311 * Update or register a new name entry
314 update_name_entry(union olsr_ip_addr *originator, struct namemsg *message, double vtime)
317 struct name_entry *entry;
319 hash = olsr_hashing(originator);
321 /* Check for the entry */
322 for(entry = list[hash].next; entry != &list[hash]; entry = entry->next)
324 if(memcmp(originator, &entry->originator, ipsize) == 0) {
325 if (read_namemsg( message, entry )) {
326 name_table_changed = 1;
328 olsr_get_timestamp(vtime * 1000, &entry->timer);
333 entry = olsr_malloc(sizeof(struct name_entry), "new name_entry");
335 memcpy(&entry->originator, originator, ipsize);
336 olsr_get_timestamp(vtime * 1000, &entry->timer);
338 read_namemsg( message, entry );
340 olsr_printf(2, "NAME PLUGIN: New entry %s: %s\n", olsr_ip_to_string(originator), entry->name);
343 entry->next = list[hash].next->prev;
344 entry->prev = &list[hash];
345 list[hash].next->prev = entry;
346 list[hash].next = entry;
348 name_table_changed = 1;
354 * write names to a file in /etc/hosts compatible format
360 struct name_entry *entry;
361 char buf[MAX_NAME+17];
364 olsr_printf(2, "NAME PLUGIN: writing hosts file\n");
366 if(!name_table_changed)
369 hosts = fopen( my_filename, "w" );
371 fprintf(hosts, "# this /etc/hosts file is overwritten regularly by olsrd\n");
372 fprintf(hosts, "# do not edit\n");
373 // add own IP and name
374 fprintf(hosts, "%s\t%s\n", olsr_ip_to_string(main_addr), my_name );
376 for(hash = 0; hash < HASHSIZE; hash++)
378 for(entry = list[hash].next; entry != &list[hash]; entry = entry->next)
380 sprintf(buf, "%s\t%s\n", olsr_ip_to_string(&entry->originator), entry->name);
381 fprintf(hosts, "%s", buf);
386 name_table_changed = 0;