New configfile parser and configuration scheme integrated
[olsrd.git] / src / packet.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: packet.c,v 1.6 2004/10/18 13:13:37 kattemat Exp $
23  *
24  */
25
26
27 #include "defs.h"
28 #include "link_set.h"
29 #include "mpr_selector_set.h"
30 #include "mpr.h"
31 #include "olsr.h"
32
33
34 /**
35  *Build an internal HELLO package for this
36  *node. This MUST be done for each interface.
37  *
38  *@param message the hello_message struct to fill with info
39  *@param outif the interface to send the message on - messages
40  *are created individually for each interface!
41  *@return 0
42  */
43 int
44 olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
45 {
46   struct hello_neighbor   *message_neighbor, *tmp_neigh;
47   struct link_entry       *links;
48   struct neighbor_entry   *neighbor;
49   olsr_u16_t              index;
50   int                     found, link;
51
52   olsr_printf(3, "\tBuilding HELLO on interface %d\n", outif->if_nr);
53
54   message->neighbors=NULL;
55   message->packet_seq_number=0;
56   
57   //message->mpr_seq_number=neighbortable.neighbor_mpr_seq;
58
59   /* Set willingness */
60
61   message->willingness = olsr_cnf->willingness;
62   //printf("Willingness: %d\n", olsr_cnf->willingness);
63
64
65   /* Set TTL */
66
67   message->ttl = 1;
68   
69   //olsr_printf(3, "mpr is %d\n",message->mpr_seq_number);
70
71   COPY_IP(&message->source_addr, &main_addr);
72
73
74   /* Get the links of this interface */
75   links = link_set;
76
77   while(links != NULL)
78     {      
79       
80       link = lookup_link_status(links);
81       /* Update the status */
82       
83       /* Update neighbor */
84       /* UPDATED ! */
85       //update_neighbor_status(links->neighbor, link);
86       //update_neighbor_status(links->neighbor);
87
88       //printf("\nLINK: %d\nSTATUS: %d\n\n", link, neighbor->status);
89       //printf("\nProcessing %s\n", olsr_ip_to_string(&links->neighbor_iface_addr));
90
91
92       /* Check if this link tuple is registered on the outgoing interface */
93       if(!COMP_IP(&links->local_iface_addr, &outif->ip_addr))
94         {
95           olsr_printf(3, "ADDR: %s - ", olsr_ip_to_string(&outif->ip_addr));
96           olsr_printf(3, "Wrong interface for %s ", olsr_ip_to_string(&links->local_iface_addr));
97
98           links = links->next;
99           continue;
100         }
101       
102       //printf("\tAdding link to %s\n", olsr_ip_to_string(&links->neighbor_main_address));
103
104
105       //printf("\tStatus: %d\n", neighbor->status);
106       //printf("\tLink: %d\n", message_neighbor->link);
107
108       message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO");
109       
110
111       /* Find the link status */
112       message_neighbor->link = link;
113
114    
115       /*
116        * Calculate neighbor status
117        */
118       /* 
119        * 2.1  If the main address, corresponding to
120        *      L_neighbor_iface_addr, is included in the MPR set:
121        *
122        *            Neighbor Type = MPR_NEIGH
123        */
124       if(links->neighbor->is_mpr)
125         {
126           message_neighbor->status = MPR_NEIGH;
127         }
128       /*
129        *  2.2  Otherwise, if the main address, corresponding to
130        *       L_neighbor_iface_addr, is included in the neighbor set:
131        */
132       
133       /* NOTE:
134        * It is garanteed to be included when come this far
135        * due to the extentions made in the link sensing
136        * regarding main addresses.
137        */
138       else
139         {
140           /*
141            *   2.2.1
142            *        if N_status == SYM
143            *
144            *             Neighbor Type = SYM_NEIGH
145            */
146           if(links->neighbor->status == SYM)
147             {
148               message_neighbor->status = SYM_NEIGH;
149             }
150           /*
151            *   2.2.2
152            *        Otherwise, if N_status == NOT_SYM
153            *             Neighbor Type = NOT_NEIGH
154            */
155           else
156             if(links->neighbor->status == NOT_SYM)
157               {
158                 message_neighbor->status = NOT_NEIGH;
159               }
160         }
161   
162       /* Set the remote interface address */
163       COPY_IP(&message_neighbor->address, &links->neighbor_iface_addr);
164       
165       /* Set the main address */
166       COPY_IP(&message_neighbor->main_address, &links->neighbor->neighbor_main_addr);
167       
168       olsr_printf(5, "%s - ", olsr_ip_to_string(&message_neighbor->address));
169       olsr_printf(5, " status %d\n", message_neighbor->status);
170       
171       message_neighbor->next=message->neighbors;
172       message->neighbors=message_neighbor;          
173       
174       links = links->next;
175     }
176   
177   /* Add the links */
178
179
180
181
182   /* Add the rest of the neighbors */
183   
184   if(nbinterf > 1)
185     for(index=0;index<HASHSIZE;index++)
186       {       
187         for(neighbor = neighbortable[index].next;
188             neighbor != &neighbortable[index];
189             neighbor=neighbor->next)
190           {         
191             found = 0;
192             /* Check that the neighbor is not added yet */
193             tmp_neigh = message->neighbors;
194             //printf("Checking that the neighbor is not yet added\n");
195             while(tmp_neigh)
196               {
197                 if(COMP_IP(&tmp_neigh->main_address, &neighbor->neighbor_main_addr))
198                   {
199                     //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
200                     found = 1;
201                     break;
202                   }
203                 tmp_neigh = tmp_neigh->next;
204               }
205
206             if(found)
207               continue;
208             
209             message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO 2");
210             
211             message_neighbor->link = UNSPEC_LINK;
212             
213             /*
214              * Calculate neighbor status
215              */
216             /* 
217              * 2.1  If the main address, corresponding to
218              *      L_neighbor_iface_addr, is included in the MPR set:
219              *
220              *            Neighbor Type = MPR_NEIGH
221              */
222             if(neighbor->is_mpr)
223               {
224                 message_neighbor->status = MPR_NEIGH;
225               }
226             /*
227              *  2.2  Otherwise, if the main address, corresponding to
228              *       L_neighbor_iface_addr, is included in the neighbor set:
229              */
230             
231             /* NOTE:
232              * It is garanteed to be included when come this far
233              * due to the extentions made in the link sensing
234              * regarding main addresses.
235              */
236             else
237               {
238                 /*
239                  *   2.2.1
240                  *        if N_status == SYM
241                  *
242                  *             Neighbor Type = SYM_NEIGH
243                  */
244                 if(neighbor->status == SYM)
245                   {
246                     message_neighbor->status = SYM_NEIGH;
247                   }
248                 /*
249                  *   2.2.2
250                  *        Otherwise, if N_status == NOT_SYM
251                  *             Neighbor Type = NOT_NEIGH
252                  */
253                 else
254                   if(neighbor->status == NOT_SYM)
255                     {
256                       message_neighbor->status = NOT_NEIGH;                   
257                     }
258               }
259             
260
261             COPY_IP(&message_neighbor->address, &neighbor->neighbor_main_addr);
262
263             COPY_IP(&message_neighbor->main_address, &neighbor->neighbor_main_addr);
264             
265             olsr_printf(5, "%s           \n ", olsr_ip_to_string(&message_neighbor->address));
266             olsr_printf(5, " status  %d\n", message_neighbor->status);
267             
268             message_neighbor->next=message->neighbors;
269             message->neighbors=message_neighbor;            
270           }
271       }
272   
273
274   return 0;
275 }
276
277
278 /**
279  *Build an internal TC package for this
280  *node.
281  *
282  *@param message the tc_message struct to fill with info
283  *@return 0
284  */
285 int
286 olsr_build_tc_packet(struct tc_message *message)
287 {
288   struct tc_mpr_addr        *message_mpr;
289   //struct mpr_selector       *mprs;
290   olsr_u8_t              index;
291   struct neighbor_entry  *entry;
292   //struct mpr_selector_hash  *mprs_hash;
293   //olsr_u16_t          index;
294   int entry_added;
295   struct timeval tmp_timer;
296
297
298   entry_added = 0;
299
300   message->multipoint_relay_selector_address=NULL;
301   message->packet_seq_number=0;
302  
303   message->hop_count = 0;
304   message->ttl = MAX_TTL;
305   message->ansn = ansn;
306
307   COPY_IP(&message->originator, &main_addr);
308   COPY_IP(&message->source_addr, &main_addr);
309   
310
311   /* Loop trough all neighbors */  
312   for(index=0;index<HASHSIZE;index++)
313     {
314       for(entry = neighbortable[index].next;
315           entry != &neighbortable[index];
316           entry = entry->next)
317         {
318           if(entry->status != SYM)
319             continue;
320
321           switch(olsr_cnf->tc_redundancy)
322             {
323             case(2):
324               {
325                 /* 2 = Add all neighbors */
326                 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
327                 message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC");
328                 
329                 COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
330                 message_mpr->next = message->multipoint_relay_selector_address;
331                 message->multipoint_relay_selector_address = message_mpr;
332                 entry_added = 1;
333                 
334                 break;
335               }
336             case(1):
337               {
338                 /* 1 = Add all MPR selectors and selected MPRs */
339                 if((entry->is_mpr == 1) ||
340                    (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL))
341                   {
342                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
343                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 2");
344                     
345                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
346                     message_mpr->next = message->multipoint_relay_selector_address;
347                     message->multipoint_relay_selector_address = message_mpr;
348                     entry_added = 1;
349                   }
350                 break;
351               }
352             default:
353               {
354                 /* 0 = Add only MPR selectors(default) */
355                 if(olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)
356                   {
357                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
358                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 3");
359                     
360                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
361                     message_mpr->next = message->multipoint_relay_selector_address;
362                     message->multipoint_relay_selector_address = message_mpr;
363                     entry_added = 1;
364                   }
365                 break;
366               }         
367           
368             } /* Switch */
369         } /* For */
370     } /* For index */
371
372   if(entry_added)
373     {
374       sending_tc = 1;
375     }
376   else
377     {
378       if(sending_tc)
379         {
380           /* Send empty TC */
381           olsr_init_timer((olsr_u32_t) (max_tc_vtime*3)*1000, &tmp_timer);
382           olsr_printf(3, "No more MPR selectors - will send empty TCs\n");
383           timeradd(&now, &tmp_timer, &send_empty_tc);
384
385           sending_tc = 0;
386         }
387     }
388
389
390   return 0;
391 }
392
393
394
395
396 /**
397  *Free the memory allocated for a HELLO packet.
398  *
399  *@param message the pointer to the packet to erase
400  *
401  *@return nada
402  */
403 void
404 olsr_destroy_hello_message(struct hello_message *message)
405 {
406   struct hello_neighbor  *neighbors;
407   struct hello_neighbor  *neighbors_tmp;
408
409
410   neighbors=message->neighbors;
411   
412   while(neighbors!=NULL)
413     {
414       neighbors_tmp=neighbors;
415       neighbors=neighbors->next;
416       free(neighbors_tmp);
417     }
418 }
419
420
421 /**
422  *Free the memory allocated for a TC packet.
423  *
424  *@param message the pointer to the packet to erase
425  *
426  *@return nada
427  */
428
429 void
430 olsr_destroy_tc_message(struct tc_message *message)
431 {
432   struct tc_mpr_addr  *mpr_set;
433   struct tc_mpr_addr  *mpr_set_tmp;
434
435   mpr_set=message->multipoint_relay_selector_address;
436
437   while( mpr_set!=NULL)
438     {
439       mpr_set_tmp=mpr_set;
440       mpr_set=mpr_set->next;
441       free(mpr_set_tmp);
442     }
443 }
444
445
446
447 /**
448  *Free the memory allocated for a HNA packet.
449  *
450  *@param message the pointer to the packet to erase
451  *
452  *@return nada
453  */
454
455 void
456 olsr_destroy_hna_message(struct hna_message *message)
457 {
458   struct hna_net_addr  *hna_tmp, *hna_tmp2;
459
460   hna_tmp = message->hna_net;
461
462   while(hna_tmp)
463     {
464       hna_tmp2 = hna_tmp;
465       hna_tmp = hna_tmp->next;
466       free(hna_tmp2);
467     }
468 }
469
470
471
472 /**
473  *Free the memory allocated for a MID packet.
474  *
475  *@param message the pointer to the packet to erase
476  *
477  *@return nada
478  */
479
480 void
481 olsr_destroy_mid_message(struct mid_message *message)
482 {
483   struct mid_alias *tmp_adr, *tmp_adr2;
484
485   tmp_adr = message->mid_addr;
486
487   while(tmp_adr)
488     {
489       tmp_adr2 = tmp_adr;
490       tmp_adr = tmp_adr->next;
491       free(tmp_adr2);
492     }
493 }
494
495