General cleanups in header files
[olsrd.git] / src / packet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: packet.c,v 1.19 2005/02/20 18:52:18 kattemat Exp $
40  */
41
42
43 #include "defs.h"
44 #include "link_set.h"
45 #include "mpr_selector_set.h"
46 #include "mpr.h"
47 #include "olsr.h"
48 #include "neighbor_table.h"
49
50 static olsr_bool sending_tc = OLSR_FALSE;
51
52
53
54 /**
55  *Free the memory allocated for a HELLO packet.
56  *
57  *@param message the pointer to the packet to erase
58  *
59  *@return nada
60  */
61 void
62 olsr_free_hello_packet(struct hello_message *message)
63 {
64   struct hello_neighbor *nb, *prev_nb;
65
66   if(!message)
67     return;
68   
69   nb = message->neighbors;
70   
71   while (nb)
72     {
73       prev_nb = nb;
74       nb = nb->next;
75       free(prev_nb);
76     }
77 }
78
79 /**
80  *Build an internal HELLO package for this
81  *node. This MUST be done for each interface.
82  *
83  *@param message the hello_message struct to fill with info
84  *@param outif the interface to send the message on - messages
85  *are created individually for each interface!
86  *@return 0
87  */
88 int
89 olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
90 {
91   struct hello_neighbor   *message_neighbor, *tmp_neigh;
92   struct link_entry       *links;
93   struct neighbor_entry   *neighbor;
94   olsr_u16_t              index;
95   int                     link;
96
97 #ifdef DEBUG
98   olsr_printf(3, "\tBuilding HELLO on interface %d\n", outif->if_nr);
99 #endif
100
101   message->neighbors=NULL;
102   message->packet_seq_number=0;
103   
104   //message->mpr_seq_number=neighbortable.neighbor_mpr_seq;
105
106   /* Set willingness */
107
108   message->willingness = olsr_cnf->willingness;
109 #ifdef DEBUG
110   olsr_printf(3, "Willingness: %d\n", olsr_cnf->willingness);
111 #endif
112
113   /* Set TTL */
114
115   message->ttl = 1;  
116   COPY_IP(&message->source_addr, &main_addr);
117
118 #ifdef DEBUG      
119       olsr_printf(5, "On link:\n");
120 #endif
121
122   /* Get the links of this interface */
123   links = get_link_set();
124
125   while(links != NULL)
126     {      
127       
128       link = lookup_link_status(links);
129       /* Update the status */
130       
131       /* Check if this link tuple is registered on the outgoing interface */
132       if(!COMP_IP(&links->local_iface_addr, &outif->ip_addr))
133         {
134           links = links->next;
135           continue;
136         }
137
138       message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO");
139       
140
141       /* Find the link status */
142       message_neighbor->link = link;
143
144       /*
145        * Calculate neighbor status
146        */
147       /* 
148        * 2.1  If the main address, corresponding to
149        *      L_neighbor_iface_addr, is included in the MPR set:
150        *
151        *            Neighbor Type = MPR_NEIGH
152        */
153       if(links->neighbor->is_mpr)
154         {
155           message_neighbor->status = MPR_NEIGH;
156         }
157       /*
158        *  2.2  Otherwise, if the main address, corresponding to
159        *       L_neighbor_iface_addr, is included in the neighbor set:
160        */
161       
162       /* NOTE:
163        * It is garanteed to be included when come this far
164        * due to the extentions made in the link sensing
165        * regarding main addresses.
166        */
167       else
168         {
169           /*
170            *   2.2.1
171            *        if N_status == SYM
172            *
173            *             Neighbor Type = SYM_NEIGH
174            */
175           if(links->neighbor->status == SYM)
176             {
177               message_neighbor->status = SYM_NEIGH;
178             }
179           /*
180            *   2.2.2
181            *        Otherwise, if N_status == NOT_SYM
182            *             Neighbor Type = NOT_NEIGH
183            */
184           else
185             if(links->neighbor->status == NOT_SYM)
186               {
187                 message_neighbor->status = NOT_NEIGH;
188               }
189         }
190   
191       /* Set the remote interface address */
192       COPY_IP(&message_neighbor->address, &links->neighbor_iface_addr);
193       
194       /* Set the main address */
195       COPY_IP(&message_neighbor->main_address, &links->neighbor->neighbor_main_addr);
196 #ifdef DEBUG      
197       olsr_printf(5, "Added: %s - ", olsr_ip_to_string(&message_neighbor->address));
198       olsr_printf(5, " status %d\n", message_neighbor->status);
199 #endif
200       message_neighbor->next=message->neighbors;
201       message->neighbors=message_neighbor;          
202       
203       links = links->next;
204     }
205   
206   /* Add the links */
207
208
209
210 #ifdef DEBUG      
211       olsr_printf(5, "Not on link:\n");
212 #endif
213
214   /* Add the rest of the neighbors if running on multiple interfaces */
215   
216   if(ifnet != NULL && ifnet->int_next != NULL)
217     for(index=0;index<HASHSIZE;index++)
218       {       
219         for(neighbor = neighbortable[index].next;
220             neighbor != &neighbortable[index];
221             neighbor=neighbor->next)
222           {
223             /* Check that the neighbor is not added yet */
224             tmp_neigh = message->neighbors;
225             //printf("Checking that the neighbor is not yet added\n");
226             while(tmp_neigh)
227               {
228                 if(COMP_IP(&tmp_neigh->main_address, &neighbor->neighbor_main_addr))
229                   {
230                     //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
231                     break;
232                   }
233                 tmp_neigh = tmp_neigh->next;
234               }
235
236             if(tmp_neigh)
237               continue;
238             
239             message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO 2");
240             
241             message_neighbor->link = UNSPEC_LINK;
242             
243             /*
244              * Calculate neighbor status
245              */
246             /* 
247              * 2.1  If the main address, corresponding to
248              *      L_neighbor_iface_addr, is included in the MPR set:
249              *
250              *            Neighbor Type = MPR_NEIGH
251              */
252             if(neighbor->is_mpr)
253               {
254                 message_neighbor->status = MPR_NEIGH;
255               }
256             /*
257              *  2.2  Otherwise, if the main address, corresponding to
258              *       L_neighbor_iface_addr, is included in the neighbor set:
259              */
260             
261             /* NOTE:
262              * It is garanteed to be included when come this far
263              * due to the extentions made in the link sensing
264              * regarding main addresses.
265              */
266             else
267               {
268                 /*
269                  *   2.2.1
270                  *        if N_status == SYM
271                  *
272                  *             Neighbor Type = SYM_NEIGH
273                  */
274                 if(neighbor->status == SYM)
275                   {
276                     message_neighbor->status = SYM_NEIGH;
277                   }
278                 /*
279                  *   2.2.2
280                  *        Otherwise, if N_status == NOT_SYM
281                  *             Neighbor Type = NOT_NEIGH
282                  */
283                 else
284                   if(neighbor->status == NOT_SYM)
285                     {
286                       message_neighbor->status = NOT_NEIGH;                   
287                     }
288               }
289             
290
291             COPY_IP(&message_neighbor->address, &neighbor->neighbor_main_addr);
292
293             COPY_IP(&message_neighbor->main_address, &neighbor->neighbor_main_addr);
294 #ifdef DEBUG
295             olsr_printf(5, "Added: %s - ", olsr_ip_to_string(&message_neighbor->address));
296             olsr_printf(5, " status  %d\n", message_neighbor->status);
297 #endif
298             message_neighbor->next=message->neighbors;
299             message->neighbors=message_neighbor;            
300           }
301       }
302   
303
304   return 0;
305 }
306
307
308 /**
309  *Free the memory allocated for a TC packet.
310  *
311  *@param message the pointer to the packet to erase
312  *
313  *@return nada
314  */
315 void 
316 olsr_free_tc_packet(struct tc_message *message)
317 {
318   struct tc_mpr_addr *mprs, *prev_mprs;
319
320   if(!message)
321     return;
322
323   mprs = message->multipoint_relay_selector_address;
324   
325   while (mprs)
326     {
327       prev_mprs = mprs;
328       mprs = mprs->next;
329       free(prev_mprs);
330     }
331 }
332
333 /**
334  *Build an internal TC package for this
335  *node.
336  *
337  *@param message the tc_message struct to fill with info
338  *@return 0
339  */
340 int
341 olsr_build_tc_packet(struct tc_message *message)
342 {
343   struct tc_mpr_addr        *message_mpr;
344   //struct mpr_selector       *mprs;
345   olsr_u8_t              index;
346   struct neighbor_entry  *entry;
347   //struct mpr_selector_hash  *mprs_hash;
348   //olsr_u16_t          index;
349   olsr_bool entry_added = OLSR_FALSE;
350
351   message->multipoint_relay_selector_address=NULL;
352   message->packet_seq_number=0;
353  
354   message->hop_count = 0;
355   message->ttl = MAX_TTL;
356   message->ansn = get_local_ansn();
357
358   COPY_IP(&message->originator, &main_addr);
359   COPY_IP(&message->source_addr, &main_addr);
360   
361
362   /* Loop trough all neighbors */  
363   for(index=0;index<HASHSIZE;index++)
364     {
365       for(entry = neighbortable[index].next;
366           entry != &neighbortable[index];
367           entry = entry->next)
368         {
369           if(entry->status != SYM)
370             continue;
371
372           switch(olsr_cnf->tc_redundancy)
373             {
374             case(2):
375               {
376                 /* 2 = Add all neighbors */
377                 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
378                 message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC");
379                 
380                 COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
381                 message_mpr->next = message->multipoint_relay_selector_address;
382                 message->multipoint_relay_selector_address = message_mpr;
383                 entry_added = OLSR_TRUE;
384                 
385                 break;
386               }
387             case(1):
388               {
389                 /* 1 = Add all MPR selectors and selected MPRs */
390                 if((entry->is_mpr) ||
391                    (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL))
392                   {
393                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
394                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 2");
395                     
396                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
397                     message_mpr->next = message->multipoint_relay_selector_address;
398                     message->multipoint_relay_selector_address = message_mpr;
399                     entry_added = OLSR_TRUE;
400                   }
401                 break;
402               }
403             default:
404               {
405                 /* 0 = Add only MPR selectors(default) */
406                 if(olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)
407                   {
408                     //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
409                     message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 3");
410                     
411                     COPY_IP(&message_mpr->address, &entry->neighbor_main_addr);
412                     message_mpr->next = message->multipoint_relay_selector_address;
413                     message->multipoint_relay_selector_address = message_mpr;
414                     entry_added = OLSR_TRUE;
415                   }
416                 break;
417               }         
418           
419             } /* Switch */
420         } /* For */
421     } /* For index */
422
423   if(entry_added)
424     {
425       sending_tc = OLSR_TRUE;
426     }
427   else
428     {
429       if(sending_tc)
430         {
431           /* Send empty TC */
432           olsr_printf(3, "No more MPR selectors - will send empty TCs\n");
433           send_empty_tc = GET_TIMESTAMP((max_tc_vtime*3)*1000);
434
435           sending_tc = OLSR_FALSE;
436         }
437     }
438
439
440   return 0;
441 }
442
443
444 /**
445  *Free the memory allocated for a HNA packet.
446  *
447  *@param message the pointer to the packet to erase
448  *
449  *@return nada
450  */
451
452 void
453 olsr_free_hna_packet(struct hna_message *message)
454 {
455   struct hna_net_addr  *hna_tmp, *hna_tmp2;
456
457   hna_tmp = message->hna_net;
458
459   while(hna_tmp)
460     {
461       hna_tmp2 = hna_tmp;
462       hna_tmp = hna_tmp->next;
463       free(hna_tmp2);
464     }
465 }
466
467
468
469 /**
470  *Free the memory allocated for a MID packet.
471  *
472  *@param message the pointer to the packet to erase
473  *
474  *@return nada
475  */
476
477 void
478 olsr_free_mid_packet(struct mid_message *message)
479 {
480   struct mid_alias *tmp_adr, *tmp_adr2;
481
482   tmp_adr = message->mid_addr;
483
484   while(tmp_adr)
485     {
486       tmp_adr2 = tmp_adr;
487       tmp_adr = tmp_adr->next;
488       free(tmp_adr2);
489     }
490 }