Code cleanups - separating private and public functions
[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 olsrd-unik.
6  *
7  * UniK olsrd 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  * UniK olsrd 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 "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 int
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 int
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 int
154 mid_build(struct interface *ifn)
155 {
156   switch(ipversion)
157     {
158     case(AF_INET):
159       return mid_build4(ifn);
160       break;
161     case(AF_INET6):
162       return mid_build6(ifn);
163       break;
164     default:
165       return -1;
166     }
167   return -1;
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, npackets = 0;
222   int lastpacket = 0; /* number of neighbors with the same
223                          greater link status in the last packet */
224   if (!message)
225     return;
226
227   if(ipversion != AF_INET)
228     return;
229
230   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
231
232   //printf("HELLO build outputsize: %d\n", outputsize);
233
234   m = outputsize ? 
235     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
236     : (union olsr_message *) msg->v4.olsr_msg;
237
238   h = &m->v4.message.hello;
239   hinfo = h->hell_info;
240   haddr = (union olsr_ip_addr *)hinfo->neigh_addr;
241   
242   //printf("Neighbor addr: %s\n", olsr_ip_to_string(haddr));fflush(stdout);
243
244   /* Set hopcount and ttl */
245   m->v4.ttl = message->ttl;
246   m->v4.hopcnt = 0;
247
248   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
249     {
250       msg->v4.olsr_packlen = htons(outputsize);
251       net_output(ifp);
252     }
253
254   /* Set willingness */
255   h->willingness = message->willingness; 
256
257   if(ifp->is_wireless)
258     h->htime = htime;
259   else
260     h->htime = htime_nw;
261
262
263   memset(&h->reserved, 0, sizeof(olsr_u16_t));
264   
265   /* Set source(main) addr */
266   
267   COPY_IP(&m->v4.originator, &main_addr);
268
269   /*
270    *Loops trough all possible neighbor statuses
271    *The negbor list is grouped by status
272    *
273    */
274   /* Nighbor statuses */
275   for (i = 0; i <= MAX_NEIGH; i++) 
276     {
277       /* Link ststuses */
278       for(j = 0; j <= MAX_LINK; j++)
279         {
280
281           /*
282            *HYSTERESIS
283            *Not adding neighbors with link type HIDE
284            */
285           
286           if(j == HIDE_LINK)
287               continue;
288
289           lastpacket = sametype = 0;
290
291           outputsize = (char *)hinfo - packet;
292
293           //printf("Neighbortype %d outputsize %d\n", i, outputsize);
294
295           /*
296            *Only if we're gona chop the packet
297            */
298           if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
299             {
300               olsr_printf(1, "Chomping HELLO message\n");
301
302               msg->v4.olsr_packlen = htons(outputsize);
303               m->v4.olsr_msgtype = HELLO_MESSAGE;
304               if(ifp->is_wireless)
305                 m->v4.olsr_vtime = hello_vtime;
306               else
307                 m->v4.olsr_vtime = hello_nw_vtime;
308
309               m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
310               m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
311               hinfo->size = (char *)haddr - (char *)hinfo;
312               hinfo->size = ntohs(hinfo->size);
313           
314               m->v4.seqno = htons(get_msg_seqno());             
315           
316               net_output(ifp);
317           
318               m = (union olsr_message *)msg->v4.olsr_msg;
319               h = &m->v4.message.hello;
320               hinfo = h->hell_info;
321               haddr = (union olsr_ip_addr *)&hinfo->neigh_addr; 
322
323               npackets++;
324             }
325
326           /*
327            *Looping trough neighbors
328            */
329           for (nb = message->neighbors; nb != NULL; nb = nb->next) 
330             {
331           
332               outputsize = (char *)haddr - packet;
333           
334               /*
335                *If we're gonna chop it...again
336                */
337               if (outputsize > maxmessagesize - (int)ipsize)
338                 {
339                   olsr_printf(1, "Chomping HELLO again\n");
340
341                   msg->v4.olsr_packlen = htons(outputsize);
342                   m->v4.olsr_msgtype = HELLO_MESSAGE;
343                   if(ifp->is_wireless)
344                     m->v4.olsr_vtime = hello_vtime;
345                   else
346                     m->v4.olsr_vtime = hello_nw_vtime;
347
348                   m->v4.olsr_msgsize = (char *)haddr - (char *)m;
349                   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
350                   hinfo->size = (char *)haddr - (char *)hinfo;
351                   hinfo->size = ntohs(hinfo->size);
352               
353                   m->v4.seqno = htons(get_msg_seqno());
354               
355                   //m->v4.seqno = htons(message->mpr_seq_number);
356               
357                   net_output(ifp);
358               
359                   m = (union olsr_message *)msg->v4.olsr_msg;
360                   h = &m->v4.message.hello;
361                   hinfo = h->hell_info;
362                   haddr = (union olsr_ip_addr *)&hinfo->neigh_addr;
363
364                   memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
365                   /* Set link and status */
366                   //hinfo->link_code = j | (i<<2);
367                   hinfo->link_code = CREATE_LINK_CODE(i, j);
368
369                   //printf("Setting neighbor link status: %x\n", hinfo->link_code);
370
371               
372                   lastpacket = sametype;
373                   npackets++;
374                 }
375           
376           
377               if ((nb->status == i) && (nb->link == j))
378                 {
379                   sametype++;
380                   if (sametype == 1)
381                     {
382                       memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
383                       /* Set link and status for this group of neighbors (this is the first) */
384                       hinfo->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
385                       //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
386                     }
387
388 #ifdef DEBUG
389                   olsr_printf(5, "\tLink status of %s: ", olsr_ip_to_string(&nb->address));
390                   olsr_printf(5, "%d\n", nb->link);
391 #endif
392
393                   COPY_IP(haddr, &nb->address);
394
395                   //printf("\n\n1: %d\n", (char *)haddr - packet);
396                   /*
397                    *Point to next address
398                    */
399                   haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4];
400
401                   //printf("\n2: %d\n\n", (char *)haddr - packet); 
402                   //printf("Ipsize: %d\n", ipsize);
403
404                   //printf("Adding neighbor %s\n", olsr_ip_to_string(&nb->address));
405    
406                 }
407     
408             }/* looping trough neighbors */
409             
410
411           if (sametype && sametype > lastpacket)
412             {
413               hinfo->size = (char *)haddr - (char *)hinfo;
414               hinfo->size = ntohs(hinfo->size);
415               hinfo = (struct hellinfo *)((char *)haddr);
416               haddr = (union olsr_ip_addr *)&hinfo->neigh_addr;
417               
418             }
419         } /* for j */
420     } /* for i*/
421      
422   m->v4.seqno = htons(get_msg_seqno());
423   m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
424   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
425   m->v4.olsr_msgtype = HELLO_MESSAGE;
426   if(ifp->is_wireless)
427     m->v4.olsr_vtime = hello_vtime;
428   else
429     m->v4.olsr_vtime = hello_nw_vtime;
430
431   outputsize = (char *)hinfo - packet;
432   msg->v4.olsr_packlen = htons(outputsize);
433   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
434     {
435       net_output(ifp);
436     }
437
438
439   /*
440    * Delete the list of neighbor messages.
441    */
442      
443   nb = message->neighbors;
444      
445   while (nb)
446     {
447       prev_nb = nb;
448       nb = nb->next;
449       free(prev_nb);
450     }
451
452 }
453
454
455
456
457 /**
458  * IP version 6
459  *
460  *@param message the hello_message struct containing the info
461  *to build the hello message from.
462  *@param ifp the interface to send the message on
463  *
464  *@return nada
465  */
466
467
468 static void
469 hello_build6(struct hello_message *message, struct interface *ifp)
470 {
471   int remainsize;
472   struct hello_neighbor *nb, *prev_nb;
473   union olsr_message *m;
474   struct hellomsg6 *h6;
475   struct hellinfo6 *hinfo6;
476   union olsr_ip_addr *haddr;
477
478   int i, j, sametype, npackets = 0;
479   int lastpacket = 0; /* number of neighbors with the same
480                          greater link status in the last packet */
481   if (!message)
482     return;
483
484   if(ipversion != AF_INET6)
485     return;
486
487   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
488
489   //printf("HELLO build outputsize: %d\n", outputsize);
490
491   m = outputsize ? 
492     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
493     : (union olsr_message *) msg->v6.olsr_msg;
494   h6 = &m->v6.message.hello;
495   hinfo6 = h6->hell_info;
496   haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
497
498
499   /* Set hopcount and ttl */
500   m->v6.ttl = message->ttl;
501   m->v6.hopcnt = 0;
502
503   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
504     {
505       msg->v6.olsr_packlen = htons(outputsize); 
506       net_output(ifp);
507     }
508
509
510   /* Set willingness */
511   h6->willingness = message->willingness; 
512
513   if(ifp->is_wireless)
514     h6->htime = htime;
515   else
516     h6->htime = htime_nw;
517   
518   memset(&h6->reserved, 0, sizeof(olsr_u16_t));
519   
520   
521   /* Set source(main) addr */
522   
523   COPY_IP(&m->v6.originator, &main_addr);
524
525   /*
526    *Loops trough all possible neighbor statuses
527    *The negbor list is grouped by status
528    */
529
530   for (i = 0; i <= MAX_NEIGH; i++) 
531     {
532       for(j = 0; j <= MAX_LINK; j++)
533         {
534           
535           
536           lastpacket = sametype = 0;
537           
538           outputsize = (char *)hinfo6 - packet;
539           
540           //printf("Neighbortype %d outputsize %d\n", i, outputsize);
541           
542           /*
543            *Only if we're gona chop the packet
544            */
545           if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
546             {
547               olsr_printf(1, "Chomping HELLO message\n");
548               
549               msg->v6.olsr_packlen = htons(outputsize);
550               m->v6.olsr_msgtype = HELLO_MESSAGE;
551               if(ifp->is_wireless)
552                 m->v6.olsr_vtime = hello_vtime;
553               else
554                 m->v6.olsr_vtime = hello_nw_vtime;
555               
556               m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
557               m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
558               hinfo6->size = (char *)haddr - (char *)hinfo6;
559               hinfo6->size = ntohs(hinfo6->size);
560               
561               m->v6.seqno = htons(get_msg_seqno());             
562               
563               net_output(ifp);
564               
565               m = (union olsr_message *)msg->v6.olsr_msg;
566               h6 = &m->v6.message.hello;
567               hinfo6 = h6->hell_info;
568               haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
569               
570               npackets++;
571             }
572           
573           /*
574            *Looping trough neighbors
575            */
576           for (nb = message->neighbors; nb != NULL; nb = nb->next) 
577             {
578               
579               outputsize = (char *)haddr - packet;
580               
581               /*
582                *If we're gonna chop it...again
583                */
584               if (outputsize > maxmessagesize - (int)ipsize)
585                 {
586                   olsr_printf(1, "Chomping HELLO again\n");
587                   
588                   msg->v6.olsr_packlen = htons(outputsize);
589                   m->v6.olsr_msgtype = HELLO_MESSAGE;
590                   if(ifp->is_wireless)
591                     m->v6.olsr_vtime = hello_vtime;
592                   else
593                     m->v6.olsr_vtime = hello_nw_vtime;
594                   
595                   m->v6.olsr_msgsize = (char *)haddr - (char *)m;
596                   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
597                   hinfo6->size = (char *)haddr - (char *)hinfo6;
598                   hinfo6->size = ntohs(hinfo6->size);
599                   
600                   m->v6.seqno = htons(get_msg_seqno());
601                   
602                   //m->v6.seqno = htons(message->mpr_seq_number);
603                   
604                   net_output(ifp);
605                   
606                   m = (union olsr_message *)msg->v6.olsr_msg;
607                   h6 = &m->v6.message.hello;
608                   hinfo6 = h6->hell_info;
609                   haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
610                   
611
612                   memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
613                   /* Set link and status */
614                   hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
615           
616                   //printf("Setting neighbor link status: %d\n", nb->link);
617                   
618                   
619                   lastpacket = sametype;
620                   npackets++;
621                 }
622               
623               
624               if ((nb->status == i) && (nb->link == j))
625                 {             
626                   sametype++;
627                   if (sametype == 1)
628                     {
629                       memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
630                       /* Set link and status for this group of neighbors (this is the first) */
631                       hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
632                       //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
633                     }
634
635 #ifdef DEBUG
636                   olsr_printf(5, "\tLink status of %s: ", olsr_ip_to_string(&nb->address));
637                   olsr_printf(5, "%d\n", nb->link);
638 #endif
639
640                   COPY_IP(haddr, &nb->address);
641                   
642                   //printf("\n\n1: %d\n", (char *)haddr - packet);
643                   /*
644                    *Point to next address
645                    */
646                   haddr++;
647                   
648                   //printf("\n2: %d\n\n", (char *)haddr - packet); 
649                   //printf("Ipsize: %d\n", ipsize);
650                   
651                   //printf("Adding neighbor %s\n", olsr_ip_to_string(&nb->address));
652                   
653                 }
654               
655             }/* looping trough neighbors */
656             
657           
658           if (sametype && sametype > lastpacket)
659             {
660               hinfo6->size = (char *)haddr - (char *)hinfo6;
661               hinfo6->size = ntohs(hinfo6->size);
662               hinfo6 = (struct hellinfo6 *)((char *)haddr);
663               haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
664             }
665           
666         } /* for j */
667     } /* for i */
668
669   m->v6.seqno = htons(get_msg_seqno());
670   m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
671   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
672   m->v6.olsr_msgtype = HELLO_MESSAGE;
673   if(ifp->is_wireless)
674     m->v6.olsr_vtime = hello_vtime;
675   else
676     m->v6.olsr_vtime = hello_nw_vtime;
677
678   outputsize = (char *)hinfo6 - packet;
679   msg->v6.olsr_packlen = htons(outputsize);
680   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg6)) 
681     {
682       net_output(ifp);
683     }
684
685
686   /*
687    * Delete the list of neighbor messages.
688    */
689      
690   nb = message->neighbors;
691      
692   while (nb)
693     {
694       prev_nb = nb;
695       nb = nb->next;
696       free(prev_nb);
697     }
698
699 }
700
701
702
703
704
705 /**
706  *IP version 4
707  *
708  *@param message the tc_message struct containing the info
709  *to send
710  *@param ifp the interface to send the message on
711  *
712  *@return nada
713  */
714
715 static void
716 tc_build4(struct tc_message *message, struct interface *ifp)           
717 {
718
719   int remainsize;
720   struct tc_mpr_addr *mprs, *prev_mprs;
721   union olsr_message *m;
722   struct tcmsg *tc;
723   struct neigh_info *mprsaddr; 
724   int found = 0;
725   int msgsize;
726
727
728   if (!message)
729     return;
730
731   if (!ifp)
732     return;
733
734   if(ipversion != AF_INET)
735     return;
736
737   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
738
739   m = outputsize ? 
740     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
741     : (union olsr_message *) msg->v4.olsr_msg;
742   tc = &m->v4.message.tc;
743   mprsaddr = tc->neigh;
744   msgsize = (int)sizeof(struct olsrmsg);
745   tc->reserved = 0;
746
747   if (outputsize > maxmessagesize - msgsize) 
748     {
749       msg->v4.olsr_packlen = htons(outputsize);
750       net_output(ifp);
751     }
752             
753
754   /*Looping trough MPR selectors */
755   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
756     {
757             
758       outputsize = (char *)mprsaddr - packet;
759
760       /*If packet is to be chomped */
761       if (outputsize > maxmessagesize - (int)sizeof (mprsaddr))
762         {
763
764           olsr_printf(1, "Chomping TC!\n");
765           msg->v4.olsr_packlen = htons(outputsize);
766           m->v4.olsr_vtime = tc_vtime;
767           m->v4.olsr_msgtype = TC_MESSAGE;
768           m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
769           m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
770           m->v4.seqno = htons(get_msg_seqno());
771           m->v4.hopcnt = message->hop_count;
772           m->v4.ttl = message->ttl;
773           COPY_IP(&m->v4.originator, &message->originator);
774
775           net_output(ifp);
776                 
777           m = (union olsr_message *)msg->v4.olsr_msg;
778           tc = &m->v4.message.tc;
779
780           mprsaddr = tc->neigh;
781           found = 0;
782         }
783       found = 1;
784             
785       COPY_IP(&mprsaddr->addr, &mprs->address);
786
787       mprsaddr++;
788     }
789
790   if (found)
791     {
792             
793       outputsize = (char *)mprsaddr - packet;
794
795       msg->v4.olsr_packlen = htons(outputsize);
796       m->v4.olsr_msgtype = TC_MESSAGE;
797       m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
798       m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
799       m->v4.olsr_vtime = tc_vtime;
800       
801       m->v4.seqno = htons(get_msg_seqno());
802       tc->ansn = htons(message->ansn);
803       
804       m->v4.hopcnt = message->hop_count;
805       m->v4.ttl = message->ttl;
806
807       COPY_IP(&m->v4.originator, &message->originator);
808
809     }
810   else
811     {
812       if(!TIMED_OUT(&send_empty_tc))
813         {
814           olsr_printf(1, "TC: Sending empty package\n");
815
816             
817           outputsize = 20;
818
819           msg->v4.olsr_packlen = htons(outputsize);
820           m->v4.olsr_msgtype = TC_MESSAGE;
821           m->v4.olsr_msgsize = 16;
822           m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
823           m->v4.olsr_vtime = tc_vtime;
824           
825           m->v4.seqno = htons(get_msg_seqno());
826           tc->ansn = htons(message->ansn);
827           
828           m->v4.hopcnt = message->hop_count;
829           m->v4.ttl = message->ttl;
830           
831           COPY_IP(&m->v4.originator, &message->originator);
832         }
833     }
834
835   /*    
836   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
837     {
838       net_output(ifp);      
839     }
840   */
841
842   /*
843    * Delete the list of mprs messages
844    */
845         
846   mprs = message->multipoint_relay_selector_address;
847         
848   while (mprs)
849     {
850       prev_mprs = mprs;
851       mprs = mprs->next;
852       free(prev_mprs);
853     }
854         
855         
856 }
857
858
859
860
861 /**
862  *IP version 6
863  *
864  *@param message the tc_message struct containing the info
865  *to send
866  *@param ifp the interface to send the message on
867  *
868  *@return nada
869  */
870
871 static void
872 tc_build6(struct tc_message *message, struct interface *ifp)           
873 {
874
875   int remainsize;
876   struct tc_mpr_addr *mprs, *prev_mprs;
877   union olsr_message *m;
878   struct tcmsg6 *tc6;
879   struct neigh_info6 *mprsaddr6; 
880   int found = 0;
881   int msgsize;
882
883
884   if (!message)
885     return;
886
887   if(!ifp)
888     return;
889
890   if(ipversion != AF_INET6)
891     return;
892
893   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
894
895
896   m = outputsize ? 
897     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
898     : (union olsr_message *) msg->v6.olsr_msg;
899   tc6 = &m->v6.message.tc;
900   mprsaddr6 = tc6->neigh;
901   msgsize = (int)sizeof(struct olsrmsg6);
902   tc6->reserved = 0;
903
904   if (outputsize > maxmessagesize - msgsize) 
905     {
906
907       msg->v6.olsr_packlen = htons(outputsize);
908       
909       net_output(ifp);
910     }
911
912   
913
914   /*Looping trough MPR selectors */
915   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
916     {
917             
918       outputsize = (char *)mprsaddr6 - packet;
919
920
921       /*If packet is to be chomped */
922       if (outputsize > maxmessagesize - (int)sizeof (mprsaddr6))
923         {
924           msg->v6.olsr_packlen = htons(outputsize);
925           m->v6.olsr_msgtype = TC_MESSAGE;
926           m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
927           m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
928           m->v6.olsr_vtime = tc_vtime;
929           
930           m->v6.seqno = htons(get_msg_seqno());
931           tc6->ansn = htons(message->ansn);
932           
933           m->v6.hopcnt = message->hop_count;
934           m->v6.ttl = message->ttl;
935
936           COPY_IP(&m->v6.originator, &message->originator);
937
938           net_output(ifp);
939                 
940           m = (union olsr_message *)msg->v6.olsr_msg;
941           tc6 = &m->v6.message.tc;
942
943           mprsaddr6 = tc6->neigh;
944
945           found = 0;
946         }
947       found = 1;
948
949       //printf("mprsaddr6 is %x\n", (char *)mprsaddr6 - packet);
950       //printf("Adding MPR-selector: %s\n", olsr_ip_to_string(&mprs->address));fflush(stdout);      
951       COPY_IP(&mprsaddr6->addr, &mprs->address);
952
953       mprsaddr6++;
954     }
955         
956   if (found)
957     {
958             
959       outputsize = (char *)mprsaddr6 - packet;
960
961       msg->v6.olsr_packlen = htons(outputsize);
962       m->v6.olsr_msgtype = TC_MESSAGE;
963       m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
964       m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
965       m->v6.olsr_vtime = tc_vtime;
966
967       m->v6.seqno = htons(get_msg_seqno());
968       tc6->ansn = htons(message->ansn);
969       
970       m->v6.hopcnt = message->hop_count;
971       m->v6.ttl = message->ttl;
972
973       COPY_IP(&m->v6.originator, &message->originator);
974
975     }
976   else
977     {
978       if(!TIMED_OUT(&send_empty_tc))
979         {
980           olsr_printf(1, "TC: Sending empty package\n");
981             
982           outputsize = 32;
983
984           msg->v6.olsr_packlen = htons(outputsize);
985           m->v6.olsr_msgtype = TC_MESSAGE;
986           m->v6.olsr_msgsize = 28;
987           m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
988           m->v6.olsr_vtime = tc_vtime;
989           
990           m->v6.seqno = htons(get_msg_seqno());
991           tc6->ansn = htons(message->ansn);
992           
993           m->v6.hopcnt = message->hop_count;
994           m->v6.ttl = message->ttl;
995           
996           COPY_IP(&m->v6.originator, &message->originator);
997         }
998     }
999
1000   /*
1001   if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
1002     {
1003       net_output(ifp);
1004     }
1005   */
1006
1007   /*
1008    * Delete the list of mprs messages
1009    */
1010         
1011   mprs = message->multipoint_relay_selector_address;
1012         
1013   while (mprs)
1014     {
1015       prev_mprs = mprs;
1016       mprs = mprs->next;
1017       free(prev_mprs);
1018     }
1019         
1020         
1021 }
1022
1023
1024
1025
1026 /**
1027  *IP version 4
1028  *
1029  *<b>NO INTERNAL BUFFER</b>
1030  *@param ifn use this interfaces address as main address
1031  *@return 1 on success
1032  */
1033
1034 int
1035 mid_build4(struct interface *ifn)
1036 {
1037   int remainsize;
1038   /* preserve existing data in output buffer */
1039   union olsr_message *m;
1040   struct midaddr *addrs;
1041   struct midmsg *mmsg;
1042   struct interface *ifs;  
1043
1044   if(ipversion != AF_INET)
1045     return -1;
1046
1047   if(nbinterf <= 1)
1048     return 0;
1049
1050   //printf("\t\tGenerating mid on %s\n", ifn->int_name);
1051
1052   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
1053                              + sizeof(msg->v4.olsr_seqno));
1054
1055   m = outputsize ? 
1056     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
1057     :(union olsr_message *) msg->v4.olsr_msg;
1058
1059   mmsg = &m->v4.message.mid;
1060
1061   m->v4.hopcnt = 0;
1062   m->v4.ttl = MAX_TTL;
1063
1064   m->v4.seqno = htons(get_msg_seqno());/* seqnumber */
1065
1066   /* pad - seems we don't need this....*/
1067   //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
1068   //mmsg->mid_res = 0;
1069       
1070   /* Set main(first) address */
1071   COPY_IP(&m->v4.originator, &main_addr);
1072       
1073   addrs = mmsg->mid_addr;
1074
1075   /* Don't add the main address... it's already there */
1076   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
1077     {
1078       if(!COMP_IP(&main_addr, &ifs->ip_addr))
1079         {
1080           COPY_IP(&addrs->addr, &ifs->ip_addr);
1081           addrs++;
1082         }
1083     }
1084
1085   m->v4.olsr_msgtype = MID_MESSAGE;
1086   m->v4.olsr_msgsize = (char*)addrs - (char*)m;
1087   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
1088
1089   m->v4.olsr_vtime = mid_vtime;
1090
1091   outputsize = (char*)addrs - packet; 
1092   msg->v4.olsr_packlen = htons(outputsize);
1093
1094
1095
1096
1097   //printf("Sending MID (%d bytes)...\n", outputsize);
1098
1099
1100   return 0;
1101 }
1102
1103
1104
1105 /**
1106  *IP version 6
1107  *
1108  *<b>NO INTERNAL BUFFER</b>
1109  *@param ifn use this interfaces address as main address
1110  *@return 1 on success
1111  */
1112
1113 int
1114 mid_build6(struct interface *ifn)
1115 {
1116   int remainsize;
1117   /* preserve existing data in output buffer */
1118   union olsr_message *m;
1119   struct midaddr6 *addrs6;
1120   struct midmsg6 *mmsg6;
1121   struct interface *ifs;
1122
1123   //printf("\t\tGenerating mid on %s\n", ifn->int_name);
1124
1125
1126   if(ipversion != AF_INET6)
1127     return -1;
1128
1129   if(nbinterf <= 1)
1130     return 0;
1131
1132   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
1133                              + sizeof(msg->v6.olsr_seqno));
1134
1135   m = outputsize ? 
1136     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
1137     :(union olsr_message *) msg->v6.olsr_msg;
1138       
1139   mmsg6 = &m->v6.message.mid;
1140
1141   m->v6.hopcnt = 0;
1142   m->v6.ttl = MAX_TTL;
1143
1144   m->v6.seqno = htons(get_msg_seqno());/* seqnumber */
1145   /* pad - seems we don't need this....*/
1146   //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
1147   //mmsg->mid_res = 0;
1148       
1149   /* Set main(first) address */
1150   COPY_IP(&m->v6.originator, &main_addr);
1151       
1152   addrs6 = mmsg6->mid_addr;
1153
1154   /* Don't add the main address... it's already there */
1155   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
1156     {
1157       if(!COMP_IP(&main_addr, &ifs->ip_addr))
1158         {
1159           COPY_IP(&addrs6->addr, &ifs->ip_addr);
1160           addrs6++;
1161         }
1162     }
1163
1164   m->v6.olsr_msgtype = MID_MESSAGE;
1165   m->v6.olsr_msgsize = (char*)addrs6 - (char*)m;
1166   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
1167   m->v6.olsr_vtime = mid_vtime;
1168
1169   outputsize = (char*)addrs6 - packet;
1170   msg->v6.olsr_packlen = htons(outputsize);
1171
1172
1173   //printf("Sending MID (%d bytes)...\n", outputsize);
1174
1175
1176   return 0;
1177 }
1178
1179
1180
1181
1182 /**
1183  *IP version 4
1184  *
1185  *@param ifp the interface to send on
1186  *@return nada
1187  */
1188 static void
1189 hna_build4(struct interface *ifp)
1190 {
1191   int remainsize;
1192   /* preserve existing data in output buffer */
1193   union olsr_message *m;
1194   struct hnapair *pair;
1195   struct hnamsg *hmsg;
1196   struct local_hna_entry *h;
1197
1198   /* No hna nets */
1199   if (local_hna4_set.next == &local_hna4_set)
1200     return;
1201     
1202   remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
1203                              + sizeof(msg->v4.olsr_seqno));
1204   m = outputsize ? 
1205     (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
1206     :(union olsr_message *) msg->v4.olsr_msg;
1207
1208   hmsg = &m->v4.message.hna;
1209     
1210   COPY_IP(&m->v4.originator, &main_addr);
1211   m->v4.hopcnt = 0;
1212   m->v4.ttl = MAX_TTL;
1213
1214   m->v4.seqno = htons(get_msg_seqno());
1215
1216
1217   pair = hmsg->hna_net;
1218
1219   for(h = local_hna4_set.next;
1220       h != &local_hna4_set;
1221       h = h->next)
1222     {
1223       COPY_IP(&pair->addr, &h->A_network_addr);
1224       COPY_IP(&pair->netmask, &h->A_netmask);
1225       pair++;
1226     }
1227       
1228   m->v4.olsr_msgtype = HNA_MESSAGE;
1229   m->v4.olsr_msgsize = (char*)pair - (char*)m;
1230   m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
1231   m->v4.olsr_vtime = hna_vtime;
1232
1233   outputsize = (char*)pair - packet;
1234   msg->v4.olsr_packlen = htons(outputsize);
1235   //printf("Sending HNA (%d bytes)...\n", outputsize);
1236
1237 }
1238
1239
1240
1241
1242
1243 /**
1244  *IP version 6
1245  *
1246  *@param ifp the interface to send on
1247  *@return nada
1248  */
1249 static void
1250 hna_build6(struct interface *ifp)
1251 {
1252   int remainsize;
1253   /* preserve existing data in output buffer */
1254   union olsr_message *m;
1255   struct hnapair6 *pair6;
1256   struct hnamsg6 *hmsg6;
1257   union olsr_ip_addr tmp_netmask;
1258   struct local_hna_entry *h;
1259
1260   if(ipversion != AF_INET6)
1261     return;    
1262
1263   /* No hna nets */
1264   if (local_hna6_set.next == &local_hna6_set)
1265     return;
1266
1267   remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
1268                              + sizeof(msg->v6.olsr_seqno));
1269
1270   m = outputsize ? 
1271     (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
1272     :(union olsr_message *) msg->v6.olsr_msg;
1273
1274   hmsg6 = &m->v6.message.hna;
1275     
1276   COPY_IP(&m->v6.originator, &main_addr);
1277   m->v6.hopcnt = 0;
1278   m->v6.ttl = MAX_TTL;
1279
1280   m->v6.seqno = htons(get_msg_seqno());
1281
1282
1283   pair6 = hmsg6->hna_net;
1284
1285
1286   for(h = local_hna6_set.next;
1287       h != &local_hna6_set;
1288       h = h->next)
1289     {
1290       //printf("Adding %s\n", olsr_ip_to_string(&h->hna_net.addr));
1291       COPY_IP(&pair6->addr, &h->A_network_addr);
1292       olsr_prefix_to_netmask(&tmp_netmask, h->A_netmask.v6);
1293       COPY_IP(&pair6->netmask, &tmp_netmask);
1294       pair6++;
1295     }
1296   
1297   m->v6.olsr_msgtype = HNA_MESSAGE;
1298   m->v6.olsr_msgsize = (char*)pair6 - (char*)m;
1299   m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
1300   m->v6.olsr_vtime = hna_vtime;
1301   
1302   outputsize = (char*)pair6 - packet;
1303   msg->v6.olsr_packlen = htons(outputsize);
1304   
1305   //printf("Sending HNA (%d bytes)...\n", outputsize);
1306
1307
1308 }
1309