* killed lots of #ifdef ... #endif which make the source quite unreadable
[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  */
40
41
42 #include "ipcalc.h"
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 #include "build_msg.h"
50 #include "net_olsr.h"
51 #include "lq_plugin.h"
52
53 static olsr_bool sending_tc = OLSR_FALSE;
54
55 /**
56  *Free the memory allocated for a HELLO packet.
57  *
58  *@param message the pointer to the packet to erase
59  *
60  *@return nada
61  */
62 void
63 olsr_free_hello_packet(struct hello_message *message)
64 {
65   struct hello_neighbor *nb;
66
67   if(!message)
68     return;
69   
70   nb = message->neighbors;
71   while (nb) {
72     struct hello_neighbor *prev_nb = nb;
73     nb = nb->next;
74     free(prev_nb);
75   }
76 }
77
78 /**
79  *Build an internal HELLO package for this
80  *node. This MUST be done for each interface.
81  *
82  *@param message the hello_message struct to fill with info
83  *@param outif the interface to send the message on - messages
84  *are created individually for each interface!
85  *@return 0
86  */
87 int
88 olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
89 {
90   struct hello_neighbor   *message_neighbor, *tmp_neigh;
91   struct link_entry       *links;
92   struct neighbor_entry   *neighbor;
93
94 #ifdef DEBUG
95   OLSR_PRINTF(3, "\tBuilding HELLO on interface \"%s\"\n", outif->int_name ? outif->int_name : "<null>");
96 #endif
97
98   message->neighbors=NULL;
99   message->packet_seq_number=0;
100   
101   //message->mpr_seq_number=neighbortable.neighbor_mpr_seq;
102
103   /* Set willingness */
104
105   message->willingness = olsr_cnf->willingness;
106 #ifdef DEBUG
107   OLSR_PRINTF(3, "Willingness: %d\n", olsr_cnf->willingness);
108 #endif
109
110   /* Set TTL */
111
112   message->ttl = 1;  
113   message->source_addr = olsr_cnf->main_addr;
114
115 #ifdef DEBUG
116   OLSR_PRINTF(5, "On link:\n");
117 #endif
118
119   /* Walk all links of this interface */
120   OLSR_FOR_ALL_LINK_ENTRIES(links) {
121 #ifdef DEBUG
122     struct ipaddr_str buf;
123 #endif
124     int lnk = lookup_link_status(links);
125     /* Update the status */
126       
127     /* Check if this link tuple is registered on the outgoing interface */
128     if (!ipequal(&links->local_iface_addr, &outif->ip_addr)) {
129       continue;
130     }
131
132     message_neighbor = olsr_malloc_hello_neighbor("Build HELLO");
133       
134     /* Find the link status */
135     message_neighbor->link = lnk;
136
137     /*
138      * Calculate neighbor status
139      */
140     /* 
141      * 2.1  If the main address, corresponding to
142      *      L_neighbor_iface_addr, is included in the MPR set:
143      *
144      *            Neighbor Type = MPR_NEIGH
145      */
146     if (links->neighbor->is_mpr) {
147       message_neighbor->status = MPR_NEIGH;
148     }
149     /*
150      *  2.2  Otherwise, if the main address, corresponding to
151      *       L_neighbor_iface_addr, is included in the neighbor set:
152      */
153       
154     /* NOTE:
155      * It is garanteed to be included when come this far
156      * due to the extentions made in the link sensing
157      * regarding main addresses.
158      */
159     else {
160
161       /*
162        *   2.2.1
163        *        if N_status == SYM
164        *
165        *             Neighbor Type = SYM_NEIGH
166        */
167       if (links->neighbor->status == SYM) {
168         message_neighbor->status = SYM_NEIGH;
169       }
170
171       /*
172        *   2.2.2
173        *        Otherwise, if N_status == NOT_SYM
174        *             Neighbor Type = NOT_NEIGH
175        */
176       else if (links->neighbor->status == NOT_SYM) {
177           message_neighbor->status = NOT_NEIGH;
178         }
179     }
180   
181     /* Set the remote interface address */
182     message_neighbor->address = links->neighbor_iface_addr;
183       
184     /* Set the main address */
185     message_neighbor->main_address = links->neighbor->neighbor_main_addr;
186 #ifdef DEBUG
187     OLSR_PRINTF(5, "Added: %s -  status %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
188 #endif
189     message_neighbor->next=message->neighbors;
190     message->neighbors=message_neighbor;            
191       
192   } OLSR_FOR_ALL_LINK_ENTRIES_END(links);
193   
194   /* Add the links */
195
196 #ifdef DEBUG
197     OLSR_PRINTF(5, "Not on link:\n");
198 #endif
199
200   /* Add the rest of the neighbors if running on multiple interfaces */
201   
202   if (ifnet != NULL && ifnet->int_next != NULL)
203     OLSR_FOR_ALL_NBR_ENTRIES(neighbor) {
204
205 #ifdef DEBUG
206     struct ipaddr_str buf;
207 #endif
208     /* Check that the neighbor is not added yet */
209     tmp_neigh = message->neighbors;
210     //printf("Checking that the neighbor is not yet added\n");
211     while (tmp_neigh) {
212       if (ipequal(&tmp_neigh->main_address, &neighbor->neighbor_main_addr)) {
213         //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
214         break;
215       }
216       tmp_neigh = tmp_neigh->next;
217     }
218
219     if (tmp_neigh) {
220       continue;
221     }
222             
223           message_neighbor = olsr_malloc_hello_neighbor("Build HELLO 2");
224             
225     message_neighbor->link = UNSPEC_LINK;
226             
227     /*
228      * Calculate neighbor status
229      */
230     /* 
231      * 2.1  If the main address, corresponding to
232      *      L_neighbor_iface_addr, is included in the MPR set:
233      *
234      *            Neighbor Type = MPR_NEIGH
235      */
236     if (neighbor->is_mpr) {
237       message_neighbor->status = MPR_NEIGH;
238     }
239     /*
240      *  2.2  Otherwise, if the main address, corresponding to
241      *       L_neighbor_iface_addr, is included in the neighbor set:
242      */
243             
244     /* NOTE:
245      * It is garanteed to be included when come this far
246      * due to the extentions made in the link sensing
247      * regarding main addresses.
248      */
249     else {
250
251       /*
252        *   2.2.1
253        *        if N_status == SYM
254        *
255        *             Neighbor Type = SYM_NEIGH
256        */
257       if (neighbor->status == SYM) {
258         message_neighbor->status = SYM_NEIGH;
259       }
260
261       /*
262        *   2.2.2
263        *        Otherwise, if N_status == NOT_SYM
264        *             Neighbor Type = NOT_NEIGH
265        */
266       else if (neighbor->status == NOT_SYM) {
267         message_neighbor->status = NOT_NEIGH;                 
268       }
269     }
270             
271
272     message_neighbor->address = neighbor->neighbor_main_addr;
273     message_neighbor->main_address = neighbor->neighbor_main_addr;
274 #ifdef DEBUG
275     OLSR_PRINTF(5, "Added: %s -  status  %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
276 #endif
277     message_neighbor->next=message->neighbors;
278     message->neighbors=message_neighbor;        
279     
280   } OLSR_FOR_ALL_NBR_ENTRIES_END(neighbor);
281
282   return 0;
283 }
284
285
286 /**
287  *Free the memory allocated for a TC packet.
288  *
289  *@param message the pointer to the packet to erase
290  *
291  *@return nada
292  */
293 void 
294 olsr_free_tc_packet(struct tc_message *message)
295 {
296   struct tc_mpr_addr *mprs;
297
298   if(!message)
299     return;
300
301   mprs = message->multipoint_relay_selector_address;
302   while (mprs != NULL) {
303     struct tc_mpr_addr *prev_mprs = mprs;
304     mprs = mprs->next;
305     free(prev_mprs);
306   }
307 }
308
309 /**
310  *Build an internal TC package for this
311  *node.
312  *
313  *@param message the tc_message struct to fill with info
314  *@return 0
315  */
316 int
317 olsr_build_tc_packet(struct tc_message *message)
318 {
319   struct tc_mpr_addr     *message_mpr;
320   struct neighbor_entry  *entry;
321   olsr_bool entry_added = OLSR_FALSE;
322
323   message->multipoint_relay_selector_address=NULL;
324   message->packet_seq_number=0;
325  
326   message->hop_count = 0;
327   message->ttl = MAX_TTL;
328   message->ansn = get_local_ansn();
329
330   message->originator = olsr_cnf->main_addr;
331   message->source_addr = olsr_cnf->main_addr;
332   
333
334   /* Loop trough all neighbors */  
335   OLSR_FOR_ALL_NBR_ENTRIES(entry) {
336     if (entry->status != SYM) {
337       continue;
338     }
339
340     switch (olsr_cnf->tc_redundancy) {
341     case(2):
342     {
343                 /* 2 = Add all neighbors */
344                 //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
345                   message_mpr = olsr_malloc_tc_mpr_addr("Build TC");
346                 
347       message_mpr->address = entry->neighbor_main_addr;
348       message_mpr->next = message->multipoint_relay_selector_address;
349       message->multipoint_relay_selector_address = message_mpr;
350       entry_added = OLSR_TRUE;          
351       break;
352     }
353     case(1):
354     {
355       /* 1 = Add all MPR selectors and selected MPRs */
356       if ((entry->is_mpr) ||
357           (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)) {
358         //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
359         message_mpr = olsr_malloc_tc_mpr_addr("Build TC 2");
360                     
361         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 = OLSR_TRUE;
365       }
366       break;
367     }
368     default:
369     {
370       /* 0 = Add only MPR selectors(default) */
371       if (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL) {
372         //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
373         message_mpr = olsr_malloc_tc_mpr_addr("Build TC 3");
374                     
375         message_mpr->address = entry->neighbor_main_addr;
376         message_mpr->next = message->multipoint_relay_selector_address;
377         message->multipoint_relay_selector_address = message_mpr;
378         entry_added = OLSR_TRUE;
379       }
380       break;
381     }           
382           
383     } /* Switch */
384   } OLSR_FOR_ALL_NBR_ENTRIES_END(entry);
385
386   if (entry_added) {
387     sending_tc = OLSR_TRUE;
388   } else {
389     if (sending_tc) {
390       /* Send empty TC */
391       OLSR_PRINTF(3, "No more MPR selectors - will send empty TCs\n");
392       set_empty_tc_timer(GET_TIMESTAMP((olsr_cnf->max_tc_vtime*3)*1000));
393       sending_tc = OLSR_FALSE;
394     }
395   }
396
397   return 0;
398 }
399
400 /**
401  *Free the memory allocated for a MID packet.
402  *
403  *@param message the pointer to the packet to erase
404  *
405  *@return nada
406  */
407
408 void
409 olsr_free_mid_packet(struct mid_message *message)
410 {
411   struct mid_alias *tmp_adr, *tmp_adr2;
412
413   tmp_adr = message->mid_addr;
414
415   while(tmp_adr)
416     {
417       tmp_adr2 = tmp_adr;
418       tmp_adr = tmp_adr->next;
419       free(tmp_adr2);
420     }
421 }
422
423 /*
424  * Local Variables:
425  * c-basic-offset: 2
426  * End:
427  */