Added CVS Id fields to all ca nd h files
[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 $
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 = my_willingness;
62   //printf("Willingness: %d\n", my_willingness);
63
64
65   /* Set TTL */
66
67   message->ttl = 1;
68   
69   //if(debug_level > 3)
70   //printf("mpr is %d\n",message->mpr_seq_number);
71
72   COPY_IP(&message->source_addr, &main_addr);
73
74
75   /* Get the links of this interface */
76   links = link_set;
77
78   while(links != NULL)
79     {      
80       
81       link = lookup_link_status(links);
82       /* Update the status */
83       
84       /* Update neighbor */
85       /* UPDATED ! */
86       //update_neighbor_status(links->neighbor, link);
87       //update_neighbor_status(links->neighbor);
88
89       //printf("\nLINK: %d\nSTATUS: %d\n\n", link, neighbor->status);
90       //printf("\nProcessing %s\n", olsr_ip_to_string(&links->neighbor_iface_addr));
91
92
93       /* Check if this link tuple is registered on the outgoing interface */
94       if(!COMP_IP(&links->local_iface_addr, &outif->ip_addr))
95         {
96           olsr_printf(3, "ADDR: %s - ", olsr_ip_to_string(&outif->ip_addr));
97           olsr_printf(3, "Wrong interface for %s ", olsr_ip_to_string(&links->local_iface_addr));
98
99           links = links->next;
100           continue;
101         }
102       
103       //printf("\tAdding link to %s\n", olsr_ip_to_string(&links->neighbor_main_address));
104
105
106       //printf("\tStatus: %d\n", neighbor->status);
107       //printf("\tLink: %d\n", message_neighbor->link);
108
109       message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO");
110       
111
112       /* Find the link status */
113       message_neighbor->link = link;
114
115    
116       /*
117        * Calculate neighbor status
118        */
119       /* 
120        * 2.1  If the main address, corresponding to
121        *      L_neighbor_iface_addr, is included in the MPR set:
122        *
123        *            Neighbor Type = MPR_NEIGH
124        */
125       if(links->neighbor->is_mpr)
126         {
127           message_neighbor->status = MPR_NEIGH;
128         }
129       /*
130        *  2.2  Otherwise, if the main address, corresponding to
131        *       L_neighbor_iface_addr, is included in the neighbor set:
132        */
133       
134       /* NOTE:
135        * It is garanteed to be included when come this far
136        * due to the extentions made in the link sensing
137        * regarding main addresses.
138        */
139       else
140         {
141           /*
142            *   2.2.1
143            *        if N_status == SYM
144            *
145            *             Neighbor Type = SYM_NEIGH
146            */
147           if(links->neighbor->status == SYM)
148             {
149               message_neighbor->status = SYM_NEIGH;
150             }
151           /*
152            *   2.2.2
153            *        Otherwise, if N_status == NOT_SYM
154            *             Neighbor Type = NOT_NEIGH
155            */
156           else
157             if(links->neighbor->status == NOT_SYM)
158               {
159                 message_neighbor->status = NOT_NEIGH;
160               }
161         }
162   
163       /* Set the remote interface address */
164       COPY_IP(&message_neighbor->address, &links->neighbor_iface_addr);
165       
166       /* Set the main address */
167       COPY_IP(&message_neighbor->main_address, &links->neighbor->neighbor_main_addr);
168       
169       olsr_printf(5, "%s - ", olsr_ip_to_string(&message_neighbor->address));
170       olsr_printf(5, " status %d\n", message_neighbor->status);
171       
172       message_neighbor->next=message->neighbors;
173       message->neighbors=message_neighbor;          
174       
175       links = links->next;
176     }
177   
178   /* Add the links */
179
180
181
182
183   /* Add the rest of the neighbors */
184   
185   if(nbinterf > 1)
186     for(index=0;index<HASHSIZE;index++)
187       {       
188         for(neighbor = neighbortable[index].next;
189             neighbor != &neighbortable[index];
190             neighbor=neighbor->next)
191           {         
192             found = 0;
193             /* Check that the neighbor is not added yet */
194             tmp_neigh = message->neighbors;
195             //printf("Checking that the neighbor is not yet added\n");
196             while(tmp_neigh)
197               {
198                 if(COMP_IP(&tmp_neigh->main_address, &neighbor->neighbor_main_addr))
199                   {
200                     //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
201                     found = 1;
202                     break;
203                   }
204                 tmp_neigh = tmp_neigh->next;
205               }
206
207             if(found)
208               continue;
209             
210             message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO 2");
211             
212             message_neighbor->link = UNSPEC_LINK;
213             
214             /*
215              * Calculate neighbor status
216              */
217             /* 
218              * 2.1  If the main address, corresponding to
219              *      L_neighbor_iface_addr, is included in the MPR set:
220              *
221              *            Neighbor Type = MPR_NEIGH
222              */
223             if(neighbor->is_mpr)
224               {
225                 message_neighbor->status = MPR_NEIGH;
226               }
227             /*
228              *  2.2  Otherwise, if the main address, corresponding to
229              *       L_neighbor_iface_addr, is included in the neighbor set:
230              */
231             
232             /* NOTE:
233              * It is garanteed to be included when come this far
234              * due to the extentions made in the link sensing
235              * regarding main addresses.
236              */
237             else
238               {
239                 /*
240                  *   2.2.1
241                  *        if N_status == SYM
242                  *
243                  *             Neighbor Type = SYM_NEIGH
244                  */
245                 if(neighbor->status == SYM)
246                   {
247                     message_neighbor->status = SYM_NEIGH;
248                   }
249                 /*
250                  *   2.2.2
251                  *        Otherwise, if N_status == NOT_SYM
252                  *             Neighbor Type = NOT_NEIGH
253                  */
254                 else
255                   if(neighbor->status == NOT_SYM)
256                     {
257                       message_neighbor->status = NOT_NEIGH;                   
258                     }
259               }
260             
261
262             COPY_IP(&message_neighbor->address, &neighbor->neighbor_main_addr);
263
264             COPY_IP(&message_neighbor->main_address, &neighbor->neighbor_main_addr);
265             
266             olsr_printf(5, "%s           \n ", olsr_ip_to_string(&message_neighbor->address));
267             olsr_printf(5, " status  %d\n", message_neighbor->status);
268             
269             message_neighbor->next=message->neighbors;
270             message->neighbors=message_neighbor;            
271           }
272       }
273   
274
275   return 0;
276 }
277
278
279 /**
280  *Build an internal TC package for this
281  *node.
282  *
283  *@param message the tc_message struct to fill with info
284  *@return 0
285  */
286 int
287 olsr_build_tc_packet(struct tc_message *message)
288 {
289   struct tc_mpr_addr        *message_mpr;
290   //struct mpr_selector       *mprs;
291   olsr_u8_t              index;
292   struct neighbor_entry  *entry;
293   //struct mpr_selector_hash  *mprs_hash;
294   //olsr_u16_t          index;
295   int entry_added;
296   struct timeval tmp_timer;
297
298
299   entry_added = 0;
300
301   message->multipoint_relay_selector_address=NULL;
302   message->packet_seq_number=0;
303  
304   message->hop_count = 0;
305   message->ttl = MAX_TTL;
306   message->ansn = ansn;
307
308   COPY_IP(&message->originator, &main_addr);
309   COPY_IP(&message->source_addr, &main_addr);
310   
311
312   /* Loop trough all neighbors */  
313   for(index=0;index<HASHSIZE;index++)
314     {
315       for(entry = neighbortable[index].next;
316           entry != &neighbortable[index];
317           entry = entry->next)
318         {
319           if(entry->status != SYM)
320             continue;
321
322           switch(tc_redundancy)
323             {
324             case(2):
325               {
326                 /* 2 = Add all neighbors */
327                 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
328                 message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC");
329                 
330                 COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
331                 message_mpr->next = message->multipoint_relay_selector_address;
332                 message->multipoint_relay_selector_address = message_mpr;
333                 entry_added = 1;
334                 
335                 break;
336               }
337             case(1):
338               {
339                 /* 1 = Add all MPR selectors and selected MPRs */
340                 if((entry->is_mpr == 1) ||
341                    (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL))
342                   {
343                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
344                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 2");
345                     
346                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
347                     message_mpr->next = message->multipoint_relay_selector_address;
348                     message->multipoint_relay_selector_address = message_mpr;
349                     entry_added = 1;
350                   }
351                 break;
352               }
353             default:
354               {
355                 /* 0 = Add only MPR selectors(default) */
356                 if(olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)
357                   {
358                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
359                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 3");
360                     
361                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
362                     message_mpr->next = message->multipoint_relay_selector_address;
363                     message->multipoint_relay_selector_address = message_mpr;
364                     entry_added = 1;
365                   }
366                 break;
367               }         
368           
369             } /* Switch */
370         } /* For */
371     } /* For index */
372
373   if(entry_added)
374     {
375       sending_tc = 1;
376     }
377   else
378     {
379       if(sending_tc)
380         {
381           /* Send empty TC */
382           olsr_init_timer((olsr_u32_t) topology_hold_time*1000, &tmp_timer);
383           olsr_printf(3, "No more MPR selectors - will send empty TCs\n");
384           timeradd(&now, &tmp_timer, &send_empty_tc);
385
386           sending_tc = 0;
387         }
388     }
389
390
391   return 0;
392 }
393
394
395
396
397 /**
398  *Free the memory allocated for a HELLO packet.
399  *
400  *@param message the pointer to the packet to erase
401  *
402  *@return nada
403  */
404 void
405 olsr_destroy_hello_message(struct hello_message *message)
406 {
407   struct hello_neighbor  *neighbors;
408   struct hello_neighbor  *neighbors_tmp;
409
410
411   neighbors=message->neighbors;
412   
413   while(neighbors!=NULL)
414     {
415       neighbors_tmp=neighbors;
416       neighbors=neighbors->next;
417       free(neighbors_tmp);
418     }
419 }
420
421
422 /**
423  *Free the memory allocated for a TC packet.
424  *
425  *@param message the pointer to the packet to erase
426  *
427  *@return nada
428  */
429
430 void
431 olsr_destroy_tc_message(struct tc_message *message)
432 {
433   struct tc_mpr_addr  *mpr_set;
434   struct tc_mpr_addr  *mpr_set_tmp;
435
436   mpr_set=message->multipoint_relay_selector_address;
437
438   while( mpr_set!=NULL)
439     {
440       mpr_set_tmp=mpr_set;
441       mpr_set=mpr_set->next;
442       free(mpr_set_tmp);
443     }
444 }
445
446
447
448 /**
449  *Free the memory allocated for a HNA packet.
450  *
451  *@param message the pointer to the packet to erase
452  *
453  *@return nada
454  */
455
456 void
457 olsr_destroy_hna_message(struct hna_message *message)
458 {
459   struct hna_net_addr  *hna_tmp, *hna_tmp2;
460
461   hna_tmp = message->hna_net;
462
463   while(hna_tmp)
464     {
465       hna_tmp2 = hna_tmp;
466       hna_tmp = hna_tmp->next;
467       free(hna_tmp2);
468     }
469 }
470
471
472
473 /**
474  *Free the memory allocated for a MID packet.
475  *
476  *@param message the pointer to the packet to erase
477  *
478  *@return nada
479  */
480
481 void
482 olsr_destroy_mid_message(struct mid_message *message)
483 {
484   struct mid_alias *tmp_adr, *tmp_adr2;
485
486   tmp_adr = message->mid_addr;
487
488   while(tmp_adr)
489     {
490       tmp_adr2 = tmp_adr;
491       tmp_adr = tmp_adr->next;
492       free(tmp_adr2);
493     }
494 }
495
496