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