ed9a41d646a6d7159bcd39a911159504b63b2c3d
[olsrd.git] / src / rebuild_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: rebuild_packet.c,v 1.21 2007/04/25 22:08:13 bernd67 Exp $
40  */
41
42
43 #include "rebuild_packet.h"
44 #include "defs.h"
45 #include "olsr.h"
46 #include "mid_set.h"
47 #include "mantissa.h"
48
49 /**
50  *Process/rebuild HNA message. Converts the OLSR
51  *packet to the internal hna_message format.
52  *@param hmsg the hna_message struct in wich infomation
53  *is to be put.
54  *@param m the entire OLSR message revieved.
55  *@return negative on error
56  */
57
58 void
59 hna_chgestruct(struct hna_message *hmsg, union olsr_message *m)
60 {
61   struct hna_net_addr *hna_pairs, *tmp_pairs;
62   int no_pairs, i;
63
64   /*Check if everyting is ok*/
65   if ((!m) || (m->v4.olsr_msgtype != HNA_MESSAGE))
66     return;
67   
68
69   if(olsr_cnf->ip_version == AF_INET)
70     {
71       /* IPv4 */
72       struct hnapair *haddr;
73
74       haddr = m->v4.message.hna.hna_net;
75
76       /*
77        * How many HNA pairs?
78        * nextmsg contains size of
79        * the addresses + 12 bytes(nextmessage, from address and the header)
80        */
81       no_pairs = (ntohs(m->v4.olsr_msgsize) - 12) / 8;
82       
83       COPY_IP(&hmsg->originator, &m->v4.originator);
84       hmsg->packet_seq_number = ntohs(m->v4.seqno);
85       hmsg->hop_count =  m->v4.hopcnt;
86
87       //printf("HNA from %s\n\n", olsr_ip_to_string((union olsr_ip_addr *)&hmsg->originator));
88
89       /* Get vtime */
90       hmsg->vtime = ME_TO_DOUBLE(m->v4.olsr_vtime);
91
92       tmp_pairs = NULL;
93       hna_pairs = NULL;
94
95       for(i = 0; i < no_pairs; i++)
96         {
97           
98           hna_pairs = olsr_malloc(sizeof(struct hna_net_addr), "HNA chgestruct");
99           
100           
101           COPY_IP(&hna_pairs->net, &haddr->addr);
102           COPY_IP(&hna_pairs->netmask, &haddr->netmask);
103           hna_pairs->next = tmp_pairs;
104           
105           tmp_pairs = hna_pairs;
106           haddr++;
107       
108         }
109
110     }
111   else
112     {
113       /* IPv6 */
114       struct hnapair6 *haddr6;
115
116       haddr6 = m->v6.message.hna.hna_net;
117
118       /*
119        * How many HNA pairs?
120        * nextmsg contains size of
121        * the addresses + 12 bytes(nextmessage, from address and the header)
122        */
123       no_pairs = (ntohs(m->v6.olsr_msgsize) - 24) / 32; /* NB 32 not 8 */
124       
125       COPY_IP(&hmsg->originator, &m->v6.originator);
126       hmsg->packet_seq_number = ntohs(m->v6.seqno);
127       hmsg->hop_count =  m->v6.hopcnt;
128       
129       /* Get vtime */
130       hmsg->vtime = ME_TO_DOUBLE(m->v6.olsr_vtime);
131       
132       tmp_pairs = NULL;
133       hna_pairs = NULL;
134       
135       for(i = 0; i < no_pairs; i++)
136         {
137           
138           hna_pairs = olsr_malloc(sizeof(struct hna_net_addr), "HNA chgestruct 2");       
139           
140           COPY_IP(&hna_pairs->net, &haddr6->addr);
141           hna_pairs->netmask.v6 = olsr_netmask_to_prefix((union olsr_ip_addr *)&haddr6->netmask);
142
143           hna_pairs->next = tmp_pairs;
144           
145           tmp_pairs = hna_pairs;
146           haddr6++;
147           
148         }
149
150       
151     }      
152
153   /* 
154      tmp_pairs = hna_pairs;
155          
156      while(tmp_pairs)
157      {
158      printf("\t net: %s ", ip_to_string(&tmp_pairs->net));
159      printf("\t mask: %s\n", ip_to_string(&tmp_pairs->netmask));
160      tmp_pairs = tmp_pairs->next;
161      }
162      printf("\n");
163   */
164
165
166
167   hmsg->hna_net = hna_pairs;
168  
169 }
170
171
172 /**
173  *Process/rebuild MID message. Converts the OLSR
174  *packet to the internal mid_message format.
175  *@param mmsg the mid_message struct in wich infomation
176  *is to be put.
177  *@param m the entire OLSR message revieved.
178  *@return negative on error
179  */
180
181 void
182 mid_chgestruct(struct mid_message *mmsg, union olsr_message *m)
183 {
184   int i;
185   struct mid_alias *alias, *alias_tmp;
186   int no_aliases;
187
188   /* Checking if everything is ok */
189   if ((!m) || (m->v4.olsr_msgtype != MID_MESSAGE))
190     return;
191
192   alias = NULL;
193
194   if(olsr_cnf->ip_version == AF_INET)
195     {
196       /* IPv4 */
197       struct midaddr *maddr;
198
199       maddr = m->v4.message.mid.mid_addr;
200       /*
201        * How many aliases?
202        * nextmsg contains size of
203        * the addresses + 12 bytes(nextmessage, from address and the header)
204        */
205       no_aliases =  ((ntohs(m->v4.olsr_msgsize) - 12) / 4);
206
207       //printf("Aliases: %d\n", no_aliases);
208       COPY_IP(&mmsg->mid_origaddr, &m->v4.originator);
209       COPY_IP(&mmsg->addr, &m->v4.originator);
210       /*seq number*/
211       mmsg->mid_seqno = ntohs(m->v4.seqno);
212       mmsg->mid_addr = NULL;
213
214       /* Get vtime */
215       mmsg->vtime = ME_TO_DOUBLE(m->v4.olsr_vtime);
216
217       //printf("Sequencenuber of MID from %s is %d\n", ip_to_string(&mmsg->addr), mmsg->mid_seqno);
218
219
220       for(i = 0; i < no_aliases; i++)
221         {
222           alias = olsr_malloc(sizeof(struct mid_alias), "MID chgestruct");
223           
224           COPY_IP(&alias->alias_addr, &maddr->addr);
225           alias->next = mmsg->mid_addr;
226           mmsg->mid_addr = alias;
227           maddr++;
228         }
229       
230       
231       if(olsr_cnf->debug_level > 1)
232         {
233           OLSR_PRINTF(3, "Alias list for %s: ", ip_to_string(&mmsg->mid_origaddr.v4));
234           OLSR_PRINTF(3, "%s", ip_to_string(&mmsg->addr.v4));
235           alias_tmp = mmsg->mid_addr;
236           while(alias_tmp)
237             {
238               OLSR_PRINTF(3, " - %s", ip_to_string(&alias_tmp->alias_addr.v4));
239               alias_tmp = alias_tmp->next;
240             }
241           OLSR_PRINTF(3, "\n");
242         }
243     }
244   else
245     {
246       /* IPv6 */
247       struct midaddr6 *maddr6;
248
249       maddr6 = m->v6.message.mid.mid_addr;
250       /*
251        * How many aliases?
252        * nextmsg contains size of
253        * the addresses + 12 bytes(nextmessage, from address and the header)
254        */
255       no_aliases =  ((ntohs(m->v6.olsr_msgsize) - 12) / 16); /* NB 16 */
256
257       //printf("Aliases: %d\n", no_aliases);
258       COPY_IP(&mmsg->mid_origaddr, &m->v6.originator);
259       COPY_IP(&mmsg->addr, &m->v6.originator);
260       /*seq number*/
261       mmsg->mid_seqno = ntohs(m->v6.seqno);
262       mmsg->mid_addr = NULL;
263
264       /* Get vtime */
265       mmsg->vtime = ME_TO_DOUBLE(m->v6.olsr_vtime);
266
267       //printf("Sequencenuber of MID from %s is %d\n", ip_to_string(&mmsg->addr), mmsg->mid_seqno);
268
269
270       for(i = 0; i < no_aliases; i++)
271         {
272           alias = olsr_malloc(sizeof(struct mid_alias), "MID chgestruct 2");
273           
274           //printf("Adding alias: %s\n", olsr_ip_to_string((union olsr_ip_addr *)&maddr6->addr));
275           COPY_IP(&alias->alias_addr, &maddr6->addr);
276           alias->next = mmsg->mid_addr;
277           mmsg->mid_addr = alias;
278            
279           maddr6++;
280         }
281
282
283       if(olsr_cnf->debug_level > 1)
284         {
285           OLSR_PRINTF(3, "Alias list for %s", ip6_to_string(&mmsg->mid_origaddr.v6));
286           OLSR_PRINTF(3, "%s", ip6_to_string(&mmsg->addr.v6));
287
288           alias_tmp = mmsg->mid_addr;
289           while(alias_tmp)
290             {
291               OLSR_PRINTF(3, " - %s", ip6_to_string(&alias_tmp->alias_addr.v6));
292               alias_tmp = alias_tmp->next;
293             }
294           OLSR_PRINTF(3, "\n");
295         }
296     }
297
298 }
299
300
301
302
303 /**
304  *Process/rebuild a message of unknown type. Converts the OLSR
305  *packet to the internal unknown_message format.
306  *@param umsg the unknown_message struct in wich infomation
307  *is to be put.
308  *@param m the entire OLSR message revieved.
309  *@return negative on error
310  */
311
312 void
313 unk_chgestruct(struct unknown_message *umsg, union olsr_message *m)
314 {
315
316   /* Checking if everything is ok */
317   if (!m)
318     return;
319
320
321   if(olsr_cnf->ip_version == AF_INET)
322     {
323       /* IPv4 */
324       /* address */
325       COPY_IP(&umsg->originator, &m->v4.originator);
326       /*seq number*/
327       umsg->seqno = ntohs(m->v4.seqno);
328       /* type */
329       umsg->type = m->v4.olsr_msgtype;
330     }
331   else
332     {
333       /* IPv6 */
334       /* address */
335       COPY_IP(&umsg->originator, &m->v6.originator);
336       /*seq number*/
337       umsg->seqno = ntohs(m->v6.seqno);
338       /* type */
339       umsg->type = m->v4.olsr_msgtype;
340     }
341   
342 }
343
344
345
346 /**
347  *Process/rebuild HELLO message. Converts the OLSR
348  *packet to the internal hello_message format.
349  *@param hmsg the hello_message struct in wich infomation
350  *is to be put.
351  *@param m the entire OLSR message revieved.
352  *@return negative on error
353  */
354
355 void
356 hello_chgestruct(struct hello_message *hmsg, union olsr_message *m)
357 {
358   union olsr_ip_addr *hadr;
359   struct hello_neighbor *nb;
360   
361   hmsg->neighbors = NULL;
362
363   if ((!m) || (m->v4.olsr_msgtype != HELLO_MESSAGE))
364     return;
365
366   if(olsr_cnf->ip_version == AF_INET)
367     {
368       struct hellinfo *hinf;
369
370       /* IPv4 */
371       COPY_IP(&hmsg->source_addr, &m->v4.originator);
372       hmsg->packet_seq_number = ntohs(m->v4.seqno);
373
374
375       /* Get vtime */
376       hmsg->vtime = ME_TO_DOUBLE(m->v4.olsr_vtime);
377
378       /* Get htime */
379       hmsg->htime = ME_TO_DOUBLE(m->v4.message.hello.htime);
380
381       /* Willingness */
382       hmsg->willingness = m->v4.message.hello.willingness;
383
384       OLSR_PRINTF(3, "Got HELLO vtime: %f htime: %f\n", hmsg->vtime, hmsg->htime);
385
386       for (hinf = m->v4.message.hello.hell_info; 
387            (char *)hinf < ((char *)m + (ntohs(m->v4.olsr_msgsize))); 
388            hinf = (struct hellinfo *)((char *)hinf + ntohs(hinf->size)))
389         {
390           
391           for (hadr = (union olsr_ip_addr  *)&hinf->neigh_addr; 
392                (char *)hadr < (char *)hinf + ntohs(hinf->size); 
393                hadr = (union olsr_ip_addr *)&hadr->v6.s6_addr[4])
394             {
395               nb = olsr_malloc(sizeof (struct hello_neighbor), "HELLO chgestruct");
396
397               COPY_IP(&nb->address, hadr);
398
399               /* Fetch link and status */
400               nb->link = EXTRACT_LINK(hinf->link_code);
401               nb->status = EXTRACT_STATUS(hinf->link_code);
402
403               nb->next = hmsg->neighbors;
404               hmsg->neighbors = nb;
405             }
406         }
407
408       
409     }
410   else
411     {
412       struct hellinfo6 *hinf6;
413
414       /* IPv6 */
415       COPY_IP(&hmsg->source_addr, &m->v6.originator);
416       //printf("parsing HELLO from %s\n", olsr_ip_to_string(&hmsg->source_addr));
417       hmsg->packet_seq_number = ntohs(m->v6.seqno);
418
419       /* Get vtime */
420       hmsg->vtime = ME_TO_DOUBLE(m->v6.olsr_vtime);
421
422       /* Get htime */
423       hmsg->htime = ME_TO_DOUBLE(m->v6.message.hello.htime);
424
425       /* Willingness */
426       hmsg->willingness = m->v6.message.hello.willingness;
427
428       OLSR_PRINTF(3, "Got HELLO vtime: %f htime: %f\n", hmsg->vtime, hmsg->htime);
429
430
431       for (hinf6 = m->v6.message.hello.hell_info; 
432            (char *)hinf6 < ((char *)m + (ntohs(m->v6.olsr_msgsize))); 
433            hinf6 = (struct hellinfo6 *)((char *)hinf6 + ntohs(hinf6->size)))
434         {
435
436           for (hadr = (union olsr_ip_addr *)hinf6->neigh_addr; 
437                (char *)hadr < (char *)hinf6 + ntohs(hinf6->size); 
438                hadr++)
439             {
440               nb = olsr_malloc(sizeof (struct hello_neighbor), "OLSR chgestruct 2");
441
442               COPY_IP(&nb->address, hadr);
443
444               /* Fetch link and status */
445               nb->link = EXTRACT_LINK(hinf6->link_code);
446               nb->status = EXTRACT_STATUS(hinf6->link_code);
447
448               nb->next = hmsg->neighbors;
449               hmsg->neighbors = nb;
450             }
451         }
452
453     }
454
455 }
456
457
458 /**
459  *Process/rebuild TC message. Converts the OLSR
460  *packet to the internal tc_message format.
461  *@param tmsg the tc_message struct in wich infomation
462  *is to be put.
463  *@param m the entire OLSR message revieved.
464  *@param from a sockaddr struct describing the 1 hop sender
465  *@return negative on error
466  */
467
468 void
469 tc_chgestruct(struct tc_message *tmsg, union olsr_message *m, union olsr_ip_addr *from_addr)
470 {
471   struct tc_mpr_addr *mprs;
472   union olsr_ip_addr *tmp_addr;
473
474   tmsg->multipoint_relay_selector_address = NULL;
475
476   if ((!m) || (m->v4.olsr_msgtype != TC_MESSAGE))
477     return;
478
479   if(olsr_cnf->ip_version == AF_INET)
480     {
481       /* IPv4 */
482       struct olsr_tcmsg *tc;
483       struct neigh_info *mprsaddr, *maddr;
484
485       tc = &m->v4.message.tc;
486       mprsaddr = tc->neigh;
487
488       if((tmp_addr = mid_lookup_main_addr(from_addr)) == 0)
489         {
490           COPY_IP(&tmsg->source_addr, from_addr);
491         }
492       else
493         {
494           COPY_IP(&tmsg->source_addr, tmp_addr);
495         }
496
497
498       /* Get vtime */
499       tmsg->vtime = ME_TO_DOUBLE(m->v4.olsr_vtime);
500
501       OLSR_PRINTF(3, "Got TC vtime: %f\n", tmsg->vtime);
502
503       COPY_IP(&tmsg->originator, &m->v4.originator);
504       tmsg->packet_seq_number = ntohs(m->v4.seqno);
505       tmsg->hop_count =  m->v4.hopcnt;
506       tmsg->ansn =  ntohs(tc->ansn);
507
508       //printf("TC from %s seqno %d\n", olsr_ip_to_string(&tmsg->originator), tmsg->packet_seq_number);
509
510       for (maddr = mprsaddr; (char *)maddr < ((char *)m + (ntohs(m->v4.olsr_msgsize))); maddr++)
511         {
512           
513           mprs = olsr_malloc(sizeof(struct tc_mpr_addr), "TC chgestruct");
514
515           COPY_IP(&mprs->address, &maddr->addr);
516           mprs->next = tmsg->multipoint_relay_selector_address;
517           tmsg->multipoint_relay_selector_address = mprs;
518         }
519     }
520   else
521     {
522       /* IPv6 */
523       struct olsr_tcmsg6 *tc6;
524       struct neigh_info6 *mprsaddr6, *maddr6;
525
526       tc6 = &m->v6.message.tc;
527       mprsaddr6 = tc6->neigh;
528
529       if((tmp_addr = mid_lookup_main_addr(from_addr)) == 0)
530         {
531           COPY_IP(&tmsg->source_addr, from_addr);
532         }
533       else
534         {
535           COPY_IP(&tmsg->source_addr, tmp_addr);
536         }
537
538       /* Check if sender is symmetric neighbor here !! */
539       
540       /* Get vtime */
541       tmsg->vtime = ME_TO_DOUBLE(m->v6.olsr_vtime);
542
543       OLSR_PRINTF(3, "Got TC vtime: %f\n", tmsg->vtime);
544
545       COPY_IP(&tmsg->originator, &m->v6.originator);
546       tmsg->packet_seq_number = ntohs(m->v6.seqno);
547       tmsg->hop_count =  m->v6.hopcnt;
548       tmsg->ansn =  ntohs(tc6->ansn);
549
550       for (maddr6 = mprsaddr6; (char *)maddr6 < ((char *)m + (ntohs(m->v6.olsr_msgsize))); maddr6++)
551         {
552           
553           mprs = olsr_malloc(sizeof(struct tc_mpr_addr), "TC chgestruct 2");
554
555           COPY_IP(&mprs->address, &maddr6->addr);
556           mprs->next = tmsg->multipoint_relay_selector_address;
557           tmsg->multipoint_relay_selector_address = mprs;
558         }
559
560     }
561
562 }