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