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