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