Updated UniK olsrd to olsr.org in licence headers
[olsrd.git] / src / build_msg.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 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
23
24 #include "defs.h"
25 #include "build_msg.h"
26 #include "local_hna_set.h"
27 #include "olsr.h"
28
29
30 /* Begin:
31  * Prototypes for internal functions 
32  */
33
34 /* IPv4 */
35
36 static void
37 hello_build4(struct hello_message *, struct interface *);
38
39 static void
40 tc_build4(struct tc_message *, struct interface *);
41
42 static void
43 mid_build4(struct interface *);
44
45 static void
46 hna_build4(struct interface *);
47
48 /* IPv6 */
49
50 static void
51 hello_build6(struct hello_message *, struct interface *);
52
53 static void
54 tc_build6(struct tc_message *, struct interface *);
55
56 static void
57 mid_build6(struct interface *);
58
59 static void
60 hna_build6(struct interface *);
61
62 /* End:
63  * Prototypes for internal functions 
64  */
65
66
67
68 /*
69  * Generic calls
70  * These are the functions to call from outside
71  */
72
73
74 /**
75  * Generate HELLO packet with the contents of the parameter "message".
76  * If this won't fit in one packet, chop it up into several.
77  * Send the packet if the size of the data contained in the output buffer
78  * reach maxmessagesize. Can generate an empty HELLO packet if the 
79  * neighbor table is empty. The parameter messag is not used.
80  *
81  *
82  *@param message the hello_message struct containing the info
83  *to build the hello message from.
84  *@param ifp the interface to send the message on
85  *
86  *@return nada
87  */
88
89 void
90 hello_build(struct hello_message *message, struct interface *ifp)
91 {
92   switch(ipversion)
93     {
94     case(AF_INET):
95       hello_build4(message, ifp);
96       break;
97     case(AF_INET6):
98       hello_build6(message, ifp);
99       break;
100     default:
101       return;
102     }
103   return;
104 }
105
106
107 /*
108  * Generate TC packet with the contents of the parameter "message".
109  * If this won't fit in one packet, chop it up into several.
110  * Send the packet if the size of the data contained in the output buffer
111  * reach maxmessagesize. Don't generate an empty TC packet.
112  * The parameter messag is not used.
113  *
114  *If parameter ifp = NULL then this is a TC packet who is to be
115  *forwarded. In that case each chump of the packet(if bigger then
116  *maxmessagesize the packet has to be split) must be forwarded
117  *on each interface(exept the one it came on - if it was a wired interface)
118  *and seqnumbers must be taken from the recieved packet.
119  *
120  *@param message the tc_message struct containing the info
121  *to send
122  *@param ifp the interface to send the message on
123  *
124  *@return nada
125  */
126
127 void
128 tc_build(struct tc_message *message, struct interface *ifp)           
129 {
130   switch(ipversion)
131     {
132     case(AF_INET):
133       tc_build4(message, ifp);
134       break;
135     case(AF_INET6):
136       tc_build6(message, ifp);
137       break;
138     default:
139       return;
140     }
141   return;
142 }
143
144
145 /**
146  *Build a MID message to the outputbuffer
147  *
148  *<b>NO INTERNAL BUFFER</b>
149  *@param ifn use this interfaces address as main address
150  *@return 1 on success
151  */
152
153 void
154 mid_build(struct interface *ifn)
155 {
156   switch(ipversion)
157     {
158     case(AF_INET):
159       mid_build4(ifn);
160       break;
161     case(AF_INET6):
162       mid_build6(ifn);
163       break;
164     default:
165       return;
166     }
167   return;
168 }
169
170
171 /**
172  *Builds a HNA message in the outputbuffer
173  *<b>NB! Not internal packetformat!</b>
174  *
175  *@param ifp the interface to send on
176  *@return nada
177  */
178 void
179 hna_build(struct interface *ifp)
180 {
181   switch(ipversion)
182     {
183     case(AF_INET):
184       hna_build4(ifp);
185       break;
186     case(AF_INET6):
187       hna_build6(ifp);
188       break;
189     default:
190       return;
191     }
192   return;
193 }
194
195 /*
196  * Protocol specific versions
197  */
198
199
200
201
202 /**
203  * IP version 4
204  *
205  *@param message the hello_message struct containing the info
206  *to build the hello message from.
207  *@param ifp the interface to send the message on
208  *
209  *@return nada
210  */
211
212 static void
213 hello_build4(struct hello_message *message, struct interface *ifp)
214 {
215   int remainsize;
216   struct hello_neighbor *nb, *prev_nb;
217   union olsr_message *m;
218   struct hellomsg *h;
219   struct hellinfo *hinfo;
220   union olsr_ip_addr *haddr;
221   int i, j, sametype;
222   int lastpacket = 0; /* number of neighbors with the same
223                          greater link status in the last packet */
224   if((!message) || (!ifp) || (ipversion != AF_INET))
225     return;
226
227   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
228
229   //printf("HELLO build outputsize: %d\n", outputsize);
230
231   m = outputsize ? 
232     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
233     : (union olsr_message *) msg->v4.olsr_msg;
234
235   h = &m->v4.message.hello;
236   hinfo = h->hell_info;
237   haddr = (union olsr_ip_addr *)hinfo->neigh_addr;
238   
239   //printf("Neighbor addr: %s\n", olsr_ip_to_string(haddr));fflush(stdout);
240
241   /* Set hopcount and ttl */
242   m->v4.ttl = message->ttl;
243   m->v4.hopcnt = 0;
244
245   /* Send pending packet if not room in buffer */
246   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
247     net_output(ifp);
248
249   /* Set willingness */
250   h->willingness = message->willingness; 
251
252   if(ifp->is_wireless)
253     h->htime = htime;
254   else
255     h->htime = htime_nw;
256
257
258   memset(&h->reserved, 0, sizeof(olsr_u16_t));
259   
260   /* Set source(main) addr */
261   
262   COPY_IP(&m->v4.originator, &main_addr);
263
264   /*
265    *Loops trough all possible neighbor statuses
266    *The negbor list is grouped by status
267    *
268    */
269   /* Nighbor statuses */
270   for (i = 0; i <= MAX_NEIGH; i++) 
271     {
272       /* Link ststuses */
273       for(j = 0; j <= MAX_LINK; j++)
274         {
275
276           /*
277            *HYSTERESIS
278            *Not adding neighbors with link type HIDE
279            */
280           
281           if(j == HIDE_LINK)
282               continue;
283
284           lastpacket = sametype = 0;
285
286           outputsize = (char *)hinfo - packet;
287
288           //printf("Neighbortype %d outputsize %d\n", i, outputsize);
289
290           /*
291            *Only if we're gona chop the packet
292            */
293           if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
294             {
295               olsr_printf(1, "Chomping HELLO message\n");
296
297               m->v4.olsr_msgtype = HELLO_MESSAGE;
298               if(ifp->is_wireless)
299                 m->v4.olsr_vtime = hello_vtime;
300               else
301                 m->v4.olsr_vtime = hello_nw_vtime;
302
303               m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
304               m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
305               hinfo->size = (char *)haddr - (char *)hinfo;
306               hinfo->size = ntohs(hinfo->size);
307           
308               m->v4.seqno = htons(get_msg_seqno());             
309           
310               net_output(ifp);
311           
312               m = (union olsr_message *)msg->v4.olsr_msg;
313               h = &m->v4.message.hello;
314               hinfo = h->hell_info;
315               haddr = (union olsr_ip_addr *)&hinfo->neigh_addr; 
316             }
317
318           /*
319            *Looping trough neighbors
320            */
321           for (nb = message->neighbors; nb != NULL; nb = nb->next) 
322             {
323           
324               outputsize = (char *)haddr - packet;
325           
326               /*
327                *If we're gonna chop it...again
328                */
329               if (outputsize > maxmessagesize - (int)ipsize)
330                 {
331                   olsr_printf(1, "Chomping HELLO again\n");
332
333                   m->v4.olsr_msgtype = HELLO_MESSAGE;
334                   if(ifp->is_wireless)
335                     m->v4.olsr_vtime = hello_vtime;
336                   else
337                     m->v4.olsr_vtime = hello_nw_vtime;
338
339                   m->v4.olsr_msgsize = (char *)haddr - (char *)m;
340                   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
341                   hinfo->size = (char *)haddr - (char *)hinfo;
342                   hinfo->size = ntohs(hinfo->size);
343               
344                   m->v4.seqno = htons(get_msg_seqno());
345
346                   net_output(ifp);
347               
348                   m = (union olsr_message *)msg->v4.olsr_msg;
349                   h = &m->v4.message.hello;
350                   hinfo = h->hell_info;
351                   haddr = (union olsr_ip_addr *)&hinfo->neigh_addr;
352
353                   memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
354                   /* Set link and status */
355                   //hinfo->link_code = j | (i<<2);
356                   hinfo->link_code = CREATE_LINK_CODE(i, j);
357
358                   //printf("Setting neighbor link status: %x\n", hinfo->link_code);
359
360               
361                   lastpacket = sametype;
362                 }
363           
364           
365               if ((nb->status == i) && (nb->link == j))
366                 {
367                   sametype++;
368                   if (sametype == 1)
369                     {
370                       memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
371                       /* Set link and status for this group of neighbors (this is the first) */
372                       hinfo->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
373                       //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
374                     }
375
376 #ifdef DEBUG
377                   olsr_printf(5, "\tLink status of %s: ", olsr_ip_to_string(&nb->address));
378                   olsr_printf(5, "%d\n", nb->link);
379 #endif
380
381                   COPY_IP(haddr, &nb->address);
382
383                   //printf("\n\n1: %d\n", (char *)haddr - packet);
384                   /*
385                    *Point to next address
386                    */
387                   haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4];
388
389                   //printf("\n2: %d\n\n", (char *)haddr - packet); 
390                   //printf("Ipsize: %d\n", ipsize);
391
392                   //printf("Adding neighbor %s\n", olsr_ip_to_string(&nb->address));
393    
394                 }
395     
396             }/* looping trough neighbors */
397             
398
399           if (sametype && sametype > lastpacket)
400             {
401               hinfo->size = (char *)haddr - (char *)hinfo;
402               hinfo->size = ntohs(hinfo->size);
403               hinfo = (struct hellinfo *)((char *)haddr);
404               haddr = (union olsr_ip_addr *)&hinfo->neigh_addr;
405               
406             }
407         } /* for j */
408     } /* for i*/
409      
410   m->v4.seqno = htons(get_msg_seqno());
411   m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
412   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
413   m->v4.olsr_msgtype = HELLO_MESSAGE;
414   if(ifp->is_wireless)
415     m->v4.olsr_vtime = hello_vtime;
416   else
417     m->v4.olsr_vtime = hello_nw_vtime;
418
419   outputsize = (char *)hinfo - packet;
420   
421   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
422     net_output(ifp);
423
424
425   /*
426    * Delete the list of neighbor messages.
427    */
428      
429   nb = message->neighbors;
430      
431   while (nb)
432     {
433       prev_nb = nb;
434       nb = nb->next;
435       free(prev_nb);
436     }
437
438 }
439
440
441
442
443 /**
444  * IP version 6
445  *
446  *@param message the hello_message struct containing the info
447  *to build the hello message from.
448  *@param ifp the interface to send the message on
449  *
450  *@return nada
451  */
452
453
454 static void
455 hello_build6(struct hello_message *message, struct interface *ifp)
456 {
457   int remainsize;
458   struct hello_neighbor *nb, *prev_nb;
459   union olsr_message *m;
460   struct hellomsg6 *h6;
461   struct hellinfo6 *hinfo6;
462   union olsr_ip_addr *haddr;
463
464   int i, j, sametype;
465   int lastpacket = 0; /* number of neighbors with the same
466                          greater link status in the last packet */
467   if((!message) || (!ifp) || (ipversion != AF_INET6))
468     return;
469
470   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
471
472   //printf("HELLO build outputsize: %d\n", outputsize);
473
474   m = outputsize ? 
475     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
476     : (union olsr_message *) msg->v6.olsr_msg;
477   h6 = &m->v6.message.hello;
478   hinfo6 = h6->hell_info;
479   haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
480
481
482   /* Set hopcount and ttl */
483   m->v6.ttl = message->ttl;
484   m->v6.hopcnt = 0;
485
486   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
487     net_output(ifp);
488   
489   
490   /* Set willingness */
491   h6->willingness = message->willingness; 
492
493   if(ifp->is_wireless)
494     h6->htime = htime;
495   else
496     h6->htime = htime_nw;
497   
498   memset(&h6->reserved, 0, sizeof(olsr_u16_t));
499   
500   
501   /* Set source(main) addr */
502   
503   COPY_IP(&m->v6.originator, &main_addr);
504
505   /*
506    *Loops trough all possible neighbor statuses
507    *The negbor list is grouped by status
508    */
509
510   for (i = 0; i <= MAX_NEIGH; i++) 
511     {
512       for(j = 0; j <= MAX_LINK; j++)
513         {
514           
515           
516           lastpacket = sametype = 0;
517           
518           outputsize = (char *)hinfo6 - packet;
519           
520           //printf("Neighbortype %d outputsize %d\n", i, outputsize);
521           
522           /*
523            *Only if we're gona chop the packet
524            */
525           if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
526             {
527               olsr_printf(1, "Chomping HELLO message\n");
528               
529               m->v6.olsr_msgtype = HELLO_MESSAGE;
530               if(ifp->is_wireless)
531                 m->v6.olsr_vtime = hello_vtime;
532               else
533                 m->v6.olsr_vtime = hello_nw_vtime;
534               
535               m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
536               m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
537               hinfo6->size = (char *)haddr - (char *)hinfo6;
538               hinfo6->size = ntohs(hinfo6->size);
539               
540               m->v6.seqno = htons(get_msg_seqno());             
541               
542               net_output(ifp);
543               
544               m = (union olsr_message *)msg->v6.olsr_msg;
545               h6 = &m->v6.message.hello;
546               hinfo6 = h6->hell_info;
547               haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
548               
549             }
550           
551           /*
552            *Looping trough neighbors
553            */
554           for (nb = message->neighbors; nb != NULL; nb = nb->next) 
555             {
556               
557               outputsize = (char *)haddr - packet;
558               
559               /*
560                *If we're gonna chop it...again
561                */
562               if (outputsize > maxmessagesize - (int)ipsize)
563                 {
564                   olsr_printf(1, "Chomping HELLO again\n");
565                   
566                   m->v6.olsr_msgtype = HELLO_MESSAGE;
567                   if(ifp->is_wireless)
568                     m->v6.olsr_vtime = hello_vtime;
569                   else
570                     m->v6.olsr_vtime = hello_nw_vtime;
571                   
572                   m->v6.olsr_msgsize = (char *)haddr - (char *)m;
573                   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
574                   hinfo6->size = (char *)haddr - (char *)hinfo6;
575                   hinfo6->size = ntohs(hinfo6->size);
576                   
577                   m->v6.seqno = htons(get_msg_seqno());
578                   
579                   //m->v6.seqno = htons(message->mpr_seq_number);
580                   
581                   net_output(ifp);
582                   
583                   m = (union olsr_message *)msg->v6.olsr_msg;
584                   h6 = &m->v6.message.hello;
585                   hinfo6 = h6->hell_info;
586                   haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
587                   
588
589                   memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
590                   /* Set link and status */
591                   hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
592           
593                   //printf("Setting neighbor link status: %d\n", nb->link);
594                   
595                   
596                   lastpacket = sametype;
597                 }
598               
599               
600               if ((nb->status == i) && (nb->link == j))
601                 {             
602                   sametype++;
603                   if (sametype == 1)
604                     {
605                       memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
606                       /* Set link and status for this group of neighbors (this is the first) */
607                       hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
608                       //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
609                     }
610
611 #ifdef DEBUG
612                   olsr_printf(5, "\tLink status of %s: ", olsr_ip_to_string(&nb->address));
613                   olsr_printf(5, "%d\n", nb->link);
614 #endif
615
616                   COPY_IP(haddr, &nb->address);
617                   
618                   //printf("\n\n1: %d\n", (char *)haddr - packet);
619                   /*
620                    *Point to next address
621                    */
622                   haddr++;
623                   
624                   //printf("\n2: %d\n\n", (char *)haddr - packet); 
625                   //printf("Ipsize: %d\n", ipsize);
626                   
627                   //printf("Adding neighbor %s\n", olsr_ip_to_string(&nb->address));
628                   
629                 }
630               
631             }/* looping trough neighbors */
632             
633           
634           if (sametype && sametype > lastpacket)
635             {
636               hinfo6->size = (char *)haddr - (char *)hinfo6;
637               hinfo6->size = ntohs(hinfo6->size);
638               hinfo6 = (struct hellinfo6 *)((char *)haddr);
639               haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
640             }
641           
642         } /* for j */
643     } /* for i */
644
645   m->v6.seqno = htons(get_msg_seqno());
646   m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
647   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
648   m->v6.olsr_msgtype = HELLO_MESSAGE;
649   if(ifp->is_wireless)
650     m->v6.olsr_vtime = hello_vtime;
651   else
652     m->v6.olsr_vtime = hello_nw_vtime;
653
654   outputsize = (char *)hinfo6 - packet;
655
656   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg6)) 
657       net_output(ifp);
658
659
660   /*
661    * Delete the list of neighbor messages.
662    */
663      
664   nb = message->neighbors;
665      
666   while (nb)
667     {
668       prev_nb = nb;
669       nb = nb->next;
670       free(prev_nb);
671     }
672
673 }
674
675
676
677
678
679 /**
680  *IP version 4
681  *
682  *@param message the tc_message struct containing the info
683  *to send
684  *@param ifp the interface to send the message on
685  *
686  *@return nada
687  */
688
689 static void
690 tc_build4(struct tc_message *message, struct interface *ifp)           
691 {
692
693   int remainsize;
694   struct tc_mpr_addr *mprs, *prev_mprs;
695   union olsr_message *m;
696   struct tcmsg *tc;
697   struct neigh_info *mprsaddr; 
698   int found = 0;
699   int msgsize;
700
701
702   if((!message) || (!ifp) || (ipversion != AF_INET))
703     return;
704
705   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
706
707   m = outputsize ? 
708     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
709     : (union olsr_message *) msg->v4.olsr_msg;
710   tc = &m->v4.message.tc;
711   mprsaddr = tc->neigh;
712   msgsize = (int)sizeof(struct olsrmsg);
713   tc->reserved = 0;
714
715   if (outputsize > maxmessagesize - msgsize) 
716     net_output(ifp);
717             
718
719   /*Looping trough MPR selectors */
720   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
721     {
722             
723       outputsize = (char *)mprsaddr - packet;
724
725       /*If packet is to be chomped */
726       if (outputsize > maxmessagesize - (int)sizeof (mprsaddr))
727         {
728
729           olsr_printf(1, "Chomping TC!\n");
730
731           m->v4.olsr_vtime = tc_vtime;
732           m->v4.olsr_msgtype = TC_MESSAGE;
733           m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
734           m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
735           m->v4.seqno = htons(get_msg_seqno());
736           m->v4.hopcnt = message->hop_count;
737           m->v4.ttl = message->ttl;
738           COPY_IP(&m->v4.originator, &message->originator);
739
740           net_output(ifp);
741                 
742           m = (union olsr_message *)msg->v4.olsr_msg;
743           tc = &m->v4.message.tc;
744
745           mprsaddr = tc->neigh;
746           found = 0;
747         }
748       found = 1;
749             
750       COPY_IP(&mprsaddr->addr, &mprs->address);
751
752       mprsaddr++;
753     }
754
755   if (found)
756     {
757             
758       outputsize = (char *)mprsaddr - packet;
759
760       m->v4.olsr_msgtype = TC_MESSAGE;
761       m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
762       m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
763       m->v4.olsr_vtime = tc_vtime;
764       
765       m->v4.seqno = htons(get_msg_seqno());
766       tc->ansn = htons(message->ansn);
767       
768       m->v4.hopcnt = message->hop_count;
769       m->v4.ttl = message->ttl;
770
771       COPY_IP(&m->v4.originator, &message->originator);
772
773     }
774   else
775     {
776       if(!TIMED_OUT(&send_empty_tc))
777         {
778           olsr_printf(1, "TC: Sending empty package\n");
779
780             
781           outputsize = 20;
782
783           m->v4.olsr_msgtype = TC_MESSAGE;
784           m->v4.olsr_msgsize = 16;
785           m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
786           m->v4.olsr_vtime = tc_vtime;
787           
788           m->v4.seqno = htons(get_msg_seqno());
789           tc->ansn = htons(message->ansn);
790           
791           m->v4.hopcnt = message->hop_count;
792           m->v4.ttl = message->ttl;
793           
794           COPY_IP(&m->v4.originator, &message->originator);
795         }
796     }
797
798
799   /*
800    * Delete the list of mprs messages
801    */
802         
803   mprs = message->multipoint_relay_selector_address;
804         
805   while (mprs)
806     {
807       prev_mprs = mprs;
808       mprs = mprs->next;
809       free(prev_mprs);
810     }
811         
812         
813 }
814
815
816
817
818 /**
819  *IP version 6
820  *
821  *@param message the tc_message struct containing the info
822  *to send
823  *@param ifp the interface to send the message on
824  *
825  *@return nada
826  */
827
828 static void
829 tc_build6(struct tc_message *message, struct interface *ifp)           
830 {
831
832   int remainsize;
833   struct tc_mpr_addr *mprs, *prev_mprs;
834   union olsr_message *m;
835   struct tcmsg6 *tc6;
836   struct neigh_info6 *mprsaddr6; 
837   int found = 0;
838   int msgsize;
839
840
841   if ((!message) || (!ifp) || (ipversion != AF_INET6))
842     return;
843
844   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
845
846
847   m = outputsize ? 
848     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
849     : (union olsr_message *) msg->v6.olsr_msg;
850   tc6 = &m->v6.message.tc;
851   mprsaddr6 = tc6->neigh;
852   msgsize = (int)sizeof(struct olsrmsg6);
853   tc6->reserved = 0;
854
855   if (outputsize > maxmessagesize - msgsize) 
856     net_output(ifp);
857
858   
859
860   /*Looping trough MPR selectors */
861   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
862     {
863             
864       outputsize = (char *)mprsaddr6 - packet;
865
866
867       /*If packet is to be chomped */
868       if (outputsize > maxmessagesize - (int)sizeof (mprsaddr6))
869         {
870           m->v6.olsr_msgtype = TC_MESSAGE;
871           m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
872           m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
873           m->v6.olsr_vtime = tc_vtime;
874           
875           m->v6.seqno = htons(get_msg_seqno());
876           tc6->ansn = htons(message->ansn);
877           
878           m->v6.hopcnt = message->hop_count;
879           m->v6.ttl = message->ttl;
880
881           COPY_IP(&m->v6.originator, &message->originator);
882
883           net_output(ifp);
884                 
885           m = (union olsr_message *)msg->v6.olsr_msg;
886           tc6 = &m->v6.message.tc;
887
888           mprsaddr6 = tc6->neigh;
889
890           found = 0;
891         }
892       found = 1;
893
894       //printf("mprsaddr6 is %x\n", (char *)mprsaddr6 - packet);
895       //printf("Adding MPR-selector: %s\n", olsr_ip_to_string(&mprs->address));fflush(stdout);      
896       COPY_IP(&mprsaddr6->addr, &mprs->address);
897
898       mprsaddr6++;
899     }
900         
901   if (found)
902     {
903             
904       outputsize = (char *)mprsaddr6 - packet;
905
906       m->v6.olsr_msgtype = TC_MESSAGE;
907       m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
908       m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
909       m->v6.olsr_vtime = tc_vtime;
910
911       m->v6.seqno = htons(get_msg_seqno());
912       tc6->ansn = htons(message->ansn);
913       
914       m->v6.hopcnt = message->hop_count;
915       m->v6.ttl = message->ttl;
916
917       COPY_IP(&m->v6.originator, &message->originator);
918
919     }
920   else
921     {
922       if(!TIMED_OUT(&send_empty_tc))
923         {
924           olsr_printf(1, "TC: Sending empty package\n");
925             
926           outputsize = 32;
927
928           m->v6.olsr_msgtype = TC_MESSAGE;
929           m->v6.olsr_msgsize = 28;
930           m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
931           m->v6.olsr_vtime = tc_vtime;
932           
933           m->v6.seqno = htons(get_msg_seqno());
934           tc6->ansn = htons(message->ansn);
935           
936           m->v6.hopcnt = message->hop_count;
937           m->v6.ttl = message->ttl;
938           
939           COPY_IP(&m->v6.originator, &message->originator);
940         }
941     }
942
943   /*
944    * Delete the list of mprs messages
945    */
946         
947   mprs = message->multipoint_relay_selector_address;
948         
949   while (mprs)
950     {
951       prev_mprs = mprs;
952       mprs = mprs->next;
953       free(prev_mprs);
954     }
955         
956         
957 }
958
959
960
961
962 /**
963  *IP version 4
964  *
965  *<b>NO INTERNAL BUFFER</b>
966  *@param ifn use this interfaces address as main address
967  *@return 1 on success
968  */
969
970 static void
971 mid_build4(struct interface *ifn)
972 {
973   int remainsize;
974   /* preserve existing data in output buffer */
975   union olsr_message *m;
976   struct midaddr *addrs;
977   struct midmsg *mmsg;
978   struct interface *ifs;  
979
980   if((ipversion != AF_INET) || (!ifn) || (nbinterf <= 1))
981     return;
982
983   //printf("\t\tGenerating mid on %s\n", ifn->int_name);
984
985   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
986                              + sizeof(msg->v4.olsr_seqno));
987
988   m = outputsize ? 
989     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
990     :(union olsr_message *) msg->v4.olsr_msg;
991
992   mmsg = &m->v4.message.mid;
993
994   m->v4.hopcnt = 0;
995   m->v4.ttl = MAX_TTL;
996
997   m->v4.seqno = htons(get_msg_seqno());/* seqnumber */
998
999   /* pad - seems we don't need this....*/
1000   //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
1001   //mmsg->mid_res = 0;
1002       
1003   /* Set main(first) address */
1004   COPY_IP(&m->v4.originator, &main_addr);
1005       
1006   addrs = mmsg->mid_addr;
1007
1008   /* Don't add the main address... it's already there */
1009   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
1010     {
1011       if(!COMP_IP(&main_addr, &ifs->ip_addr))
1012         {
1013           COPY_IP(&addrs->addr, &ifs->ip_addr);
1014           addrs++;
1015         }
1016     }
1017
1018   m->v4.olsr_msgtype = MID_MESSAGE;
1019   m->v4.olsr_msgsize = (char*)addrs - (char*)m;
1020   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
1021
1022   m->v4.olsr_vtime = mid_vtime;
1023
1024   outputsize = (char*)addrs - packet; 
1025
1026   //printf("Sending MID (%d bytes)...\n", outputsize);
1027
1028
1029   return;
1030 }
1031
1032
1033
1034 /**
1035  *IP version 6
1036  *
1037  *<b>NO INTERNAL BUFFER</b>
1038  *@param ifn use this interfaces address as main address
1039  *@return 1 on success
1040  */
1041
1042 static void
1043 mid_build6(struct interface *ifn)
1044 {
1045   int remainsize;
1046   /* preserve existing data in output buffer */
1047   union olsr_message *m;
1048   struct midaddr6 *addrs6;
1049   struct midmsg6 *mmsg6;
1050   struct interface *ifs;
1051
1052   //printf("\t\tGenerating mid on %s\n", ifn->int_name);
1053
1054
1055   if((ipversion != AF_INET6) || (!ifn) || (nbinterf <= 1))
1056     return;
1057
1058   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
1059                              + sizeof(msg->v6.olsr_seqno));
1060
1061   m = outputsize ? 
1062     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
1063     :(union olsr_message *) msg->v6.olsr_msg;
1064       
1065   mmsg6 = &m->v6.message.mid;
1066
1067   m->v6.hopcnt = 0;
1068   m->v6.ttl = MAX_TTL;
1069
1070   m->v6.seqno = htons(get_msg_seqno());/* seqnumber */
1071   /* pad - seems we don't need this....*/
1072   //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
1073   //mmsg->mid_res = 0;
1074       
1075   /* Set main(first) address */
1076   COPY_IP(&m->v6.originator, &main_addr);
1077       
1078   addrs6 = mmsg6->mid_addr;
1079
1080   /* Don't add the main address... it's already there */
1081   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
1082     {
1083       if(!COMP_IP(&main_addr, &ifs->ip_addr))
1084         {
1085           COPY_IP(&addrs6->addr, &ifs->ip_addr);
1086           addrs6++;
1087         }
1088     }
1089
1090   m->v6.olsr_msgtype = MID_MESSAGE;
1091   m->v6.olsr_msgsize = (char*)addrs6 - (char*)m;
1092   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
1093   m->v6.olsr_vtime = mid_vtime;
1094
1095   outputsize = (char*)addrs6 - packet;
1096
1097   //printf("Sending MID (%d bytes)...\n", outputsize);
1098
1099
1100   return;
1101 }
1102
1103
1104
1105
1106 /**
1107  *IP version 4
1108  *
1109  *@param ifp the interface to send on
1110  *@return nada
1111  */
1112 static void
1113 hna_build4(struct interface *ifp)
1114 {
1115   int remainsize;
1116   /* preserve existing data in output buffer */
1117   union olsr_message *m;
1118   struct hnapair *pair;
1119   struct hnamsg *hmsg;
1120   struct local_hna_entry *h;
1121
1122   /* No hna nets */
1123   if((ipversion != AF_INET) || (!ifp) || (local_hna4_set.next == &local_hna4_set))
1124     return;
1125     
1126   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
1127                              + sizeof(msg->v4.olsr_seqno));
1128   m = outputsize ? 
1129     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
1130     :(union olsr_message *) msg->v4.olsr_msg;
1131
1132   hmsg = &m->v4.message.hna;
1133     
1134   COPY_IP(&m->v4.originator, &main_addr);
1135   m->v4.hopcnt = 0;
1136   m->v4.ttl = MAX_TTL;
1137
1138   m->v4.seqno = htons(get_msg_seqno());
1139
1140
1141   pair = hmsg->hna_net;
1142
1143   for(h = local_hna4_set.next;
1144       h != &local_hna4_set;
1145       h = h->next)
1146     {
1147       COPY_IP(&pair->addr, &h->A_network_addr);
1148       COPY_IP(&pair->netmask, &h->A_netmask);
1149       pair++;
1150     }
1151       
1152   m->v4.olsr_msgtype = HNA_MESSAGE;
1153   m->v4.olsr_msgsize = (char*)pair - (char*)m;
1154   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
1155   m->v4.olsr_vtime = hna_vtime;
1156
1157   outputsize = (char*)pair - packet;
1158   //printf("Sending HNA (%d bytes)...\n", outputsize);
1159   return;
1160 }
1161
1162
1163
1164
1165
1166 /**
1167  *IP version 6
1168  *
1169  *@param ifp the interface to send on
1170  *@return nada
1171  */
1172 static void
1173 hna_build6(struct interface *ifp)
1174 {
1175   int remainsize;
1176   /* preserve existing data in output buffer */
1177   union olsr_message *m;
1178   struct hnapair6 *pair6;
1179   struct hnamsg6 *hmsg6;
1180   union olsr_ip_addr tmp_netmask;
1181   struct local_hna_entry *h;
1182   
1183   /* No hna nets */
1184   if((ipversion != AF_INET6) || (!ifp) || (local_hna6_set.next == &local_hna6_set))
1185     return;
1186
1187   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
1188                              + sizeof(msg->v6.olsr_seqno));
1189
1190   m = outputsize ? 
1191     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
1192     :(union olsr_message *) msg->v6.olsr_msg;
1193
1194   hmsg6 = &m->v6.message.hna;
1195     
1196   COPY_IP(&m->v6.originator, &main_addr);
1197   m->v6.hopcnt = 0;
1198   m->v6.ttl = MAX_TTL;
1199
1200   m->v6.seqno = htons(get_msg_seqno());
1201
1202
1203   pair6 = hmsg6->hna_net;
1204
1205
1206   for(h = local_hna6_set.next;
1207       h != &local_hna6_set;
1208       h = h->next)
1209     {
1210       //printf("Adding %s\n", olsr_ip_to_string(&h->hna_net.addr));
1211       COPY_IP(&pair6->addr, &h->A_network_addr);
1212       olsr_prefix_to_netmask(&tmp_netmask, h->A_netmask.v6);
1213       COPY_IP(&pair6->netmask, &tmp_netmask);
1214       pair6++;
1215     }
1216   
1217   m->v6.olsr_msgtype = HNA_MESSAGE;
1218   m->v6.olsr_msgsize = (char*)pair6 - (char*)m;
1219   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
1220   m->v6.olsr_vtime = hna_vtime;
1221   
1222   outputsize = (char*)pair6 - packet;
1223   
1224   //printf("Sending HNA (%d bytes)...\n", outputsize);
1225   return;
1226
1227 }
1228