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