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