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