ARM crosscompiler fixes
[olsrd.git] / src / build_msg.c
index 8a7f229..d8b569b 100644 (file)
@@ -2,21 +2,24 @@
  * OLSR ad-hoc routing table management protocol
  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
  *
- * This file is part of olsrd-unik.
+ * This file is part of the olsr.org OLSR daemon.
  *
- * UniK olsrd is free software; you can redistribute it and/or modify
+ * olsr.org is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * UniK olsrd is distributed in the hope that it will be useful,
+ * olsr.org is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with olsrd-unik; if not, write to the Free Software
+ * along with olsr.org; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ * 
+ * $Id: build_msg.c,v 1.17 2004/10/20 19:43:04 kattemat Exp $
  *
  */
 
 #include "olsr.h"
 
 
+/* All these functions share this buffer */
+
+static char msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
+
 /* Begin:
  * Prototypes for internal functions 
  */
@@ -39,7 +46,7 @@ hello_build4(struct hello_message *, struct interface *);
 static void
 tc_build4(struct tc_message *, struct interface *);
 
-static int
+static void
 mid_build4(struct interface *);
 
 static void
@@ -53,7 +60,7 @@ hello_build6(struct hello_message *, struct interface *);
 static void
 tc_build6(struct tc_message *, struct interface *);
 
-static int
+static void
 mid_build6(struct interface *);
 
 static void
@@ -89,7 +96,7 @@ hna_build6(struct interface *);
 void
 hello_build(struct hello_message *message, struct interface *ifp)
 {
-  switch(ipversion)
+  switch(olsr_cnf->ip_version)
     {
     case(AF_INET):
       hello_build4(message, ifp);
@@ -127,7 +134,7 @@ hello_build(struct hello_message *message, struct interface *ifp)
 void
 tc_build(struct tc_message *message, struct interface *ifp)           
 {
-  switch(ipversion)
+  switch(olsr_cnf->ip_version)
     {
     case(AF_INET):
       tc_build4(message, ifp);
@@ -150,21 +157,21 @@ tc_build(struct tc_message *message, struct interface *ifp)
  *@return 1 on success
  */
 
-int
+void
 mid_build(struct interface *ifn)
 {
-  switch(ipversion)
+  switch(olsr_cnf->ip_version)
     {
     case(AF_INET):
-      return mid_build4(ifn);
+      mid_build4(ifn);
       break;
     case(AF_INET6):
-      return mid_build6(ifn);
+      mid_build6(ifn);
       break;
     default:
-      return -1;
+      return;
     }
-  return -1;
+  return;
 }
 
 
@@ -178,7 +185,7 @@ mid_build(struct interface *ifn)
 void
 hna_build(struct interface *ifp)
 {
-  switch(ipversion)
+  switch(olsr_cnf->ip_version)
     {
     case(AF_INET):
       hna_build4(ifp);
@@ -212,28 +219,33 @@ hna_build(struct interface *ifp)
 static void
 hello_build4(struct hello_message *message, struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   struct hello_neighbor *nb, *prev_nb;
   union olsr_message *m;
   struct hellomsg *h;
   struct hellinfo *hinfo;
   union olsr_ip_addr *haddr;
-  int i, j, sametype, npackets = 0;
+  int i, j, sametype;
   int lastpacket = 0; /* number of neighbors with the same
                         greater link status in the last packet */
-  if (!message)
-    return;
-
-  if(ipversion != AF_INET)
+  if((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET))
     return;
 
-  remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
+  remainsize = net_outbuffer_bytes_left(ifp);
 
   //printf("HELLO build outputsize: %d\n", outputsize);
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
-    : (union olsr_message *) msg->v4.olsr_msg;
+  m = (union olsr_message *)msg_buffer;
+
+  curr_size = 12; /* OLSR message header */
+  curr_size += 4; /* Hello header */
+
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
 
   h = &m->v4.message.hello;
   hinfo = h->hell_info;
@@ -241,30 +253,21 @@ hello_build4(struct hello_message *message, struct interface *ifp)
   
   //printf("Neighbor addr: %s\n", olsr_ip_to_string(haddr));fflush(stdout);
 
-  /* Set hopcount and ttl */
+  /* Fill message header */
   m->v4.ttl = message->ttl;
   m->v4.hopcnt = 0;
+  m->v4.olsr_msgtype = HELLO_MESSAGE;
+  /* Set source(main) addr */
+  COPY_IP(&m->v4.originator, &main_addr);
 
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
-    {
-      msg->v4.olsr_packlen = htons(outputsize);
-      net_output(ifp);
-    }
+  m->v4.olsr_vtime = ifp->valtimes.hello;
 
-  /* Set willingness */
+  /* Fill HELLO header */
   h->willingness = message->willingness; 
-
-  if(ifp->is_wireless)
-    h->htime = htime;
-  else
-    h->htime = htime_nw;
-
+  h->htime = ifp->hello_etime;
 
   memset(&h->reserved, 0, sizeof(olsr_u16_t));
   
-  /* Set source(main) addr */
-  
-  COPY_IP(&m->v4.originator, &main_addr);
 
   /*
    *Loops trough all possible neighbor statuses
@@ -288,107 +291,107 @@ hello_build4(struct hello_message *message, struct interface *ifp)
 
          lastpacket = sametype = 0;
 
-         outputsize = (char *)hinfo - packet;
-
          //printf("Neighbortype %d outputsize %d\n", i, outputsize);
 
-         /*
-          *Only if we're gona chop the packet
-          */
-         if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
-           {
-             olsr_printf(1, "Chomping HELLO message\n");
-
-             msg->v4.olsr_packlen = htons(outputsize);
-             m->v4.olsr_msgtype = HELLO_MESSAGE;
-             if(ifp->is_wireless)
-               m->v4.olsr_vtime = hello_vtime;
-             else
-               m->v4.olsr_vtime = hello_nw_vtime;
-
-             m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
-             m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-             hinfo->size = (char *)haddr - (char *)hinfo;
-             hinfo->size = ntohs(hinfo->size);
-         
-             m->v4.seqno = htons(get_msg_seqno());             
-         
-             net_output(ifp);
-         
-             m = (union olsr_message *)msg->v4.olsr_msg;
-             h = &m->v4.message.hello;
-             hinfo = h->hell_info;
-             haddr = (union olsr_ip_addr *)&hinfo->neigh_addr; 
-
-             npackets++;
-           }
-
          /*
           *Looping trough neighbors
           */
          for (nb = message->neighbors; nb != NULL; nb = nb->next) 
-           {
-         
-             outputsize = (char *)haddr - packet;
-         
-             /*
-              *If we're gonna chop it...again
-              */
-             if (outputsize > maxmessagesize - (int)ipsize)
-               {
-                 olsr_printf(1, "Chomping HELLO again\n");
-
-                 msg->v4.olsr_packlen = htons(outputsize);
-                 m->v4.olsr_msgtype = HELLO_MESSAGE;
-                 if(ifp->is_wireless)
-                   m->v4.olsr_vtime = hello_vtime;
-                 else
-                   m->v4.olsr_vtime = hello_nw_vtime;
-
-                 m->v4.olsr_msgsize = (char *)haddr - (char *)m;
-                 m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-                 hinfo->size = (char *)haddr - (char *)hinfo;
-                 hinfo->size = ntohs(hinfo->size);
-             
-                 m->v4.seqno = htons(get_msg_seqno());
-             
-                 //m->v4.seqno = htons(message->mpr_seq_number);
-             
-                 net_output(ifp);
-             
-                 m = (union olsr_message *)msg->v4.olsr_msg;
-                 h = &m->v4.message.hello;
-                 hinfo = h->hell_info;
-                 haddr = (union olsr_ip_addr *)&hinfo->neigh_addr;
-
-                 memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
-                 /* Set link and status */
-                 //hinfo->link_code = j | (i<<2);
-                 hinfo->link_code = CREATE_LINK_CODE(i, j);
-
-                 //printf("Setting neighbor link status: %x\n", hinfo->link_code);
-
-             
-                 lastpacket = sametype;
-                 npackets++;
-               }
-         
-         
+           {     
              if ((nb->status == i) && (nb->link == j))
                {
                  sametype++;
                  if (sametype == 1)
                    {
+
+                     /*
+                      * If there is not enough room left 
+                      * for the data in tho outputbuffer
+                      * we must send a partial HELLO and
+                      * continue building the rest of the
+                      * data in a new HELLO message
+                      * Add ipsize in check since there is
+                      * no use sending just the type header
+                      */
+                     if((curr_size + 4 + ipsize) > remainsize)
+                       {
+                         /* Only send partial HELLO if it contains data */
+                         if(curr_size > (12 + 4))
+                           {
+                             /* Complete the headers */
+                             m->v4.seqno = htons(get_msg_seqno());
+                             m->v4.olsr_msgsize = htons(curr_size);
+                             
+                             hinfo->size = (char *)haddr - (char *)hinfo;
+                             hinfo->size = ntohs(hinfo->size);
+                             
+                             /* Send partial packet */
+                             net_outbuffer_push(ifp, msg_buffer, curr_size);
+
+                             curr_size = 12; /* OLSR message header */
+                             curr_size += 4; /* Hello header */
+                             
+                             h = &m->v4.message.hello;
+                             hinfo = h->hell_info;
+                             haddr = (union olsr_ip_addr *)hinfo->neigh_addr;
+                           }
+
+                         net_output(ifp);                        
+                         /* Reset size and pointers */
+                         remainsize = net_outbuffer_bytes_left(ifp);
+                       }
                      memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
                      /* Set link and status for this group of neighbors (this is the first) */
                      hinfo->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
                      //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
+                     curr_size += 4; /* HELLO type section header */
                    }
 
 #ifdef DEBUG
                  olsr_printf(5, "\tLink status of %s: ", olsr_ip_to_string(&nb->address));
                  olsr_printf(5, "%d\n", nb->link);
 #endif
+                 
+                 /*
+                  * If there is not enough room left 
+                  * for the data in tho outputbuffer
+                  * we must send a partial HELLO and
+                  * continue building the rest of the
+                  * data in a new HELLO message
+                  */
+                 if((curr_size + ipsize) > remainsize)
+                   {
+                     /* If we get here the message contains data
+                      * - no need to check 
+                      */
+                     /* Complete the headers */
+                     m->v4.seqno = htons(get_msg_seqno());
+                     m->v4.olsr_msgsize = htons(curr_size);
+                     
+                     hinfo->size = (char *)haddr - (char *)hinfo;
+                     hinfo->size = ntohs(hinfo->size);
+                     
+                     /* Send partial packet */
+                     net_outbuffer_push(ifp, msg_buffer, curr_size);
+                     net_output(ifp);
+                     
+                     /* Reset size and pointers */
+                     remainsize = net_outbuffer_bytes_left(ifp);
+                     curr_size = 12; /* OLSR message header */
+                     curr_size += 4; /* Hello header */
+                     
+                     h = &m->v4.message.hello;
+                     hinfo = h->hell_info;
+                     haddr = (union olsr_ip_addr *)hinfo->neigh_addr;
+                     
+                     /* Rebuild TYPE header */
+                     memset(&hinfo->reserved, 0, sizeof(olsr_u8_t));
+                     /* Set link and status for this group of neighbors (this is the first) */
+                     hinfo->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
+                     //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
+                     curr_size += 4; /* HELLO type section header */
+                     
+                   }
 
                  COPY_IP(haddr, &nb->address);
 
@@ -397,6 +400,7 @@ hello_build4(struct hello_message *message, struct interface *ifp)
                   *Point to next address
                   */
                  haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4];
+                 curr_size += ipsize; /* IP address added */
 
                  //printf("\n2: %d\n\n", (char *)haddr - packet); 
                  //printf("Ipsize: %d\n", ipsize);
@@ -420,21 +424,9 @@ hello_build4(struct hello_message *message, struct interface *ifp)
     } /* for i*/
      
   m->v4.seqno = htons(get_msg_seqno());
-  m->v4.olsr_msgsize = (char *)hinfo - (char *)m;
-  m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-  m->v4.olsr_msgtype = HELLO_MESSAGE;
-  if(ifp->is_wireless)
-    m->v4.olsr_vtime = hello_vtime;
-  else
-    m->v4.olsr_vtime = hello_nw_vtime;
-
-  outputsize = (char *)hinfo - packet;
-  msg->v4.olsr_packlen = htons(outputsize);
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
-    {
-      net_output(ifp);
-    }
-
+  m->v4.olsr_msgsize = htons(curr_size);
+  
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
 
   /*
    * Delete the list of neighbor messages.
@@ -468,59 +460,59 @@ hello_build4(struct hello_message *message, struct interface *ifp)
 static void
 hello_build6(struct hello_message *message, struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   struct hello_neighbor *nb, *prev_nb;
   union olsr_message *m;
   struct hellomsg6 *h6;
   struct hellinfo6 *hinfo6;
   union olsr_ip_addr *haddr;
 
-  int i, j, sametype, npackets = 0;
+  int i, j, sametype;
   int lastpacket = 0; /* number of neighbors with the same
                         greater link status in the last packet */
-  if (!message)
+  if((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET6))
     return;
 
-  if(ipversion != AF_INET6)
-    return;
 
-  remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
+  remainsize = net_outbuffer_bytes_left(ifp);
 
   //printf("HELLO build outputsize: %d\n", outputsize);
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
-    : (union olsr_message *) msg->v6.olsr_msg;
+  m = (union olsr_message *)msg_buffer;
+
+  curr_size = 24; /* OLSR message header */
+  curr_size += 4; /* Hello header */
+
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
+
+  //printf("HELLO build outputsize: %d\n", outputsize);
   h6 = &m->v6.message.hello;
   hinfo6 = h6->hell_info;
   haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
 
 
-  /* Set hopcount and ttl */
+  /* Fill message header */
   m->v6.ttl = message->ttl;
   m->v6.hopcnt = 0;
+  /* Set source(main) addr */
+  COPY_IP(&m->v6.originator, &main_addr);
+  m->v6.olsr_msgtype = HELLO_MESSAGE;
 
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
-    {
-      msg->v6.olsr_packlen = htons(outputsize); 
-      net_output(ifp);
-    }
-
-
-  /* Set willingness */
+  m->v6.olsr_vtime = ifp->valtimes.hello;
+  
+  /* Fill packet header */
   h6->willingness = message->willingness; 
 
-  if(ifp->is_wireless)
-    h6->htime = htime;
-  else
-    h6->htime = htime_nw;
-  
+  h6->htime = ifp->hello_etime;
+
   memset(&h6->reserved, 0, sizeof(olsr_u16_t));
   
   
-  /* Set source(main) addr */
-  
-  COPY_IP(&m->v6.originator, &main_addr);
 
   /*
    *Loops trough all possible neighbor statuses
@@ -535,101 +527,50 @@ hello_build6(struct hello_message *message, struct interface *ifp)
          
          lastpacket = sametype = 0;
          
-         outputsize = (char *)hinfo6 - packet;
          
          //printf("Neighbortype %d outputsize %d\n", i, outputsize);
-         
-         /*
-          *Only if we're gona chop the packet
-          */
-         if (outputsize > maxmessagesize - (int)sizeof (struct hellinfo)) 
-           {
-             olsr_printf(1, "Chomping HELLO message\n");
-             
-             msg->v6.olsr_packlen = htons(outputsize);
-             m->v6.olsr_msgtype = HELLO_MESSAGE;
-             if(ifp->is_wireless)
-               m->v6.olsr_vtime = hello_vtime;
-             else
-               m->v6.olsr_vtime = hello_nw_vtime;
-             
-             m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
-             m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-             hinfo6->size = (char *)haddr - (char *)hinfo6;
-             hinfo6->size = ntohs(hinfo6->size);
-             
-             m->v6.seqno = htons(get_msg_seqno());             
-             
-             net_output(ifp);
-             
-             m = (union olsr_message *)msg->v6.olsr_msg;
-             h6 = &m->v6.message.hello;
-             hinfo6 = h6->hell_info;
-             haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
-             
-             npackets++;
-           }
-         
+                 
          /*
           *Looping trough neighbors
           */
          for (nb = message->neighbors; nb != NULL; nb = nb->next) 
-           {
-             
-             outputsize = (char *)haddr - packet;
-             
-             /*
-              *If we're gonna chop it...again
-              */
-             if (outputsize > maxmessagesize - (int)ipsize)
-               {
-                 olsr_printf(1, "Chomping HELLO again\n");
-                 
-                 msg->v6.olsr_packlen = htons(outputsize);
-                 m->v6.olsr_msgtype = HELLO_MESSAGE;
-                 if(ifp->is_wireless)
-                   m->v6.olsr_vtime = hello_vtime;
-                 else
-                   m->v6.olsr_vtime = hello_nw_vtime;
-                 
-                 m->v6.olsr_msgsize = (char *)haddr - (char *)m;
-                 m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-                 hinfo6->size = (char *)haddr - (char *)hinfo6;
-                 hinfo6->size = ntohs(hinfo6->size);
-                 
-                 m->v6.seqno = htons(get_msg_seqno());
-                 
-                 //m->v6.seqno = htons(message->mpr_seq_number);
-                 
-                 net_output(ifp);
-                 
-                 m = (union olsr_message *)msg->v6.olsr_msg;
-                 h6 = &m->v6.message.hello;
-                 hinfo6 = h6->hell_info;
-                 haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
-                 
-
-                 memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
-                 /* Set link and status */
-                 hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
-         
-                 //printf("Setting neighbor link status: %d\n", nb->link);
-                 
-                 
-                 lastpacket = sametype;
-                 npackets++;
-               }
-             
-             
+           {         
              if ((nb->status == i) && (nb->link == j))
                {             
                  sametype++;
                  if (sametype == 1)
                    {
+                     /* Check if there is room for header + one address */
+                     if((curr_size + 4 + ipsize) > remainsize)
+                       {
+                         /* Only send partial HELLO if it contains data */
+                         if(curr_size > (24 + 4))
+                           {
+                             /* Complete the headers */
+                             m->v6.seqno = htons(get_msg_seqno());
+                             m->v6.olsr_msgsize = htons(curr_size);
+                             
+                             hinfo6->size = (char *)haddr - (char *)hinfo6;
+                             hinfo6->size = ntohs(hinfo6->size);
+                             
+                             /* Send partial packet */
+                             net_outbuffer_push(ifp, msg_buffer, curr_size);
+                             curr_size = 24; /* OLSR message header */
+                             curr_size += 4; /* Hello header */
+                             
+                             h6 = &m->v6.message.hello;
+                             hinfo6 = h6->hell_info;
+                             haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
+                           }
+                         net_output(ifp);
+                         /* Reset size and pointers */
+                         remainsize = net_outbuffer_bytes_left(ifp);
+                       }
                      memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
                      /* Set link and status for this group of neighbors (this is the first) */
                      hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
                      //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
+                     curr_size += 4; /* HELLO type section header */
                    }
 
 #ifdef DEBUG
@@ -637,6 +578,47 @@ hello_build6(struct hello_message *message, struct interface *ifp)
                  olsr_printf(5, "%d\n", nb->link);
 #endif
 
+                 /*
+                  * If there is not enough room left 
+                  * for the data in the outputbuffer
+                  * we must send a partial HELLO and
+                  * continue building the rest of the
+                  * data in a new HELLO message
+                  */
+                 if((curr_size + ipsize) > remainsize)
+                   {
+                     /* If we get here the message contains data
+                      * - no need to check 
+                      */
+                     /* Complete the headers */
+                     m->v6.seqno = htons(get_msg_seqno());
+                     m->v6.olsr_msgsize = htons(curr_size);
+                     
+                     hinfo6->size = (char *)haddr - (char *)hinfo6;
+                     hinfo6->size = ntohs(hinfo6->size);
+                     
+                     /* Send partial packet */
+                         net_outbuffer_push(ifp, msg_buffer, curr_size);
+                     curr_size = 24; /* OLSR message header */
+                     curr_size += 4; /* Hello header */
+                     
+                     h6 = &m->v6.message.hello;
+                     hinfo6 = h6->hell_info;
+                     haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
+                     
+                     /* Rebuild TYPE header */
+                     memset(&hinfo6->reserved, 0, sizeof(olsr_u8_t));
+                     /* Set link and status for this group of neighbors (this is the first) */
+                     hinfo6->link_code = CREATE_LINK_CODE(i, j);//j | (i<<2);
+                     //printf("(2)Setting neighbor link status: %x\n", hinfo->link_code);
+                     curr_size += 4; /* HELLO type section header */
+
+                     net_output(ifp);                
+                     /* Reset size */
+                     remainsize = net_outbuffer_bytes_left(ifp);
+                     
+                   }
+
                  COPY_IP(haddr, &nb->address);
                  
                  //printf("\n\n1: %d\n", (char *)haddr - packet);
@@ -644,7 +626,7 @@ hello_build6(struct hello_message *message, struct interface *ifp)
                   *Point to next address
                   */
                  haddr++;
-                 
+                 curr_size += ipsize; /* IP address added */ 
                  //printf("\n2: %d\n\n", (char *)haddr - packet); 
                  //printf("Ipsize: %d\n", ipsize);
                  
@@ -667,21 +649,9 @@ hello_build6(struct hello_message *message, struct interface *ifp)
     } /* for i */
 
   m->v6.seqno = htons(get_msg_seqno());
-  m->v6.olsr_msgsize = (char *)hinfo6 - (char *)m;
-  m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-  m->v6.olsr_msgtype = HELLO_MESSAGE;
-  if(ifp->is_wireless)
-    m->v6.olsr_vtime = hello_vtime;
-  else
-    m->v6.olsr_vtime = hello_nw_vtime;
-
-  outputsize = (char *)hinfo6 - packet;
-  msg->v6.olsr_packlen = htons(outputsize);
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg6)) 
-    {
-      net_output(ifp);
-    }
+  m->v6.olsr_msgsize = htons(curr_size);
 
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
 
   /*
    * Delete the list of neighbor messages.
@@ -716,128 +686,104 @@ static void
 tc_build4(struct tc_message *message, struct interface *ifp)           
 {
 
-  int remainsize;
+  int remainsize, curr_size;
   struct tc_mpr_addr *mprs, *prev_mprs;
   union olsr_message *m;
   struct tcmsg *tc;
   struct neigh_info *mprsaddr; 
-  int found = 0;
-  int msgsize;
-
-
-  if (!message)
-    return;
+  int found = 0, partial_sent = 0;
 
-  if (!ifp)
+  if((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET))
     return;
 
-  if(ipversion != AF_INET)
-    return;
+  remainsize = net_outbuffer_bytes_left(ifp);
 
-  remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) + sizeof(msg->v4.olsr_seqno));
+  m = (union olsr_message *)msg_buffer;
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
-    : (union olsr_message *) msg->v4.olsr_msg;
   tc = &m->v4.message.tc;
+
+
   mprsaddr = tc->neigh;
-  msgsize = (int)sizeof(struct olsrmsg);
-  tc->reserved = 0;
+  curr_size = 12; /* OLSR message header */
+  curr_size += 4; /* TC header */
 
-  if (outputsize > maxmessagesize - msgsize) 
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
     {
-      msg->v4.olsr_packlen = htons(outputsize);
       net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
     }
-            
+
+  /* Fill header */
+  m->v4.olsr_vtime = ifp->valtimes.tc;
+  m->v4.olsr_msgtype = TC_MESSAGE;
+  m->v4.hopcnt = message->hop_count;
+  m->v4.ttl = message->ttl;
+  COPY_IP(&m->v4.originator, &message->originator);
+
+  /* Fill TC header */
+  tc->ansn = htons(message->ansn);
+  tc->reserved = 0;
+  
 
   /*Looping trough MPR selectors */
   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
     {
-           
-      outputsize = (char *)mprsaddr - packet;
-
       /*If packet is to be chomped */
-      if (outputsize > maxmessagesize - (int)sizeof (mprsaddr))
+      if((curr_size + ipsize) > remainsize)
        {
 
-         olsr_printf(1, "Chomping TC!\n");
-         msg->v4.olsr_packlen = htons(outputsize);
-         m->v4.olsr_vtime = tc_vtime;
-         m->v4.olsr_msgtype = TC_MESSAGE;
-         m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
-         m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-         m->v4.seqno = htons(get_msg_seqno());
-         m->v4.hopcnt = message->hop_count;
-         m->v4.ttl = message->ttl;
-         COPY_IP(&m->v4.originator, &message->originator);
+         /* Only add TC message if it contains data */
+         if(curr_size > (12 + 4 ))
+           {
+             m->v4.olsr_msgsize = htons(curr_size);
+             m->v4.seqno = htons(get_msg_seqno());
+
+             net_outbuffer_push(ifp, msg_buffer, curr_size);
+             
+             /* Reset stuff */
+             mprsaddr = tc->neigh;
+             curr_size = 12; /* OLSR message header */
+             curr_size += 4; /* TC header */
+             found = 0;
+             partial_sent = 1;
+           }
 
          net_output(ifp);
-               
-         m = (union olsr_message *)msg->v4.olsr_msg;
-         tc = &m->v4.message.tc;
+         remainsize = net_outbuffer_bytes_left(ifp);
 
-         mprsaddr = tc->neigh;
-         found = 0;
        }
       found = 1;
-           
+      
       COPY_IP(&mprsaddr->addr, &mprs->address);
 
+      curr_size += ipsize;
       mprsaddr++;
     }
 
   if (found)
     {
            
-      outputsize = (char *)mprsaddr - packet;
-
-      msg->v4.olsr_packlen = htons(outputsize);
-      m->v4.olsr_msgtype = TC_MESSAGE;
-      m->v4.olsr_msgsize = (char *)mprsaddr - (char *)m;
-      m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-      m->v4.olsr_vtime = tc_vtime;
-      
+      m->v4.olsr_msgsize = htons(curr_size);
       m->v4.seqno = htons(get_msg_seqno());
-      tc->ansn = htons(message->ansn);
       
-      m->v4.hopcnt = message->hop_count;
-      m->v4.ttl = message->ttl;
-
-      COPY_IP(&m->v4.originator, &message->originator);
+      net_outbuffer_push(ifp, msg_buffer, curr_size);
 
     }
   else
     {
-      if(!TIMED_OUT(&send_empty_tc))
+      if((!partial_sent) && (!TIMED_OUT(&send_empty_tc)))
        {
          olsr_printf(1, "TC: Sending empty package\n");
 
-           
-         outputsize = 20;
-
-         msg->v4.olsr_packlen = htons(outputsize);
-         m->v4.olsr_msgtype = TC_MESSAGE;
-         m->v4.olsr_msgsize = 16;
-         m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-         m->v4.olsr_vtime = tc_vtime;
-         
+         m->v4.olsr_msgsize = htons(curr_size);
          m->v4.seqno = htons(get_msg_seqno());
-         tc->ansn = htons(message->ansn);
-         
-         m->v4.hopcnt = message->hop_count;
-         m->v4.ttl = message->ttl;
-         
-         COPY_IP(&m->v4.originator, &message->originator);
+
+         net_outbuffer_push(ifp, msg_buffer, curr_size);
+
        }
     }
 
-  /*   
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
-    {
-      net_output(ifp);     
-    }
-  */
 
   /*
    * Delete the list of mprs messages
@@ -872,137 +818,100 @@ static void
 tc_build6(struct tc_message *message, struct interface *ifp)           
 {
 
-  int remainsize;
+  int remainsize, curr_size;
   struct tc_mpr_addr *mprs, *prev_mprs;
   union olsr_message *m;
   struct tcmsg6 *tc6;
   struct neigh_info6 *mprsaddr6; 
-  int found = 0;
-  int msgsize;
-
+  int found = 0, partial_sent = 0;
 
-  if (!message)
+  if ((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET6))
     return;
 
-  if(!ifp)
-    return;
-
-  if(ipversion != AF_INET6)
-    return;
+  remainsize = net_outbuffer_bytes_left(ifp);
 
-  remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) + sizeof(msg->v6.olsr_seqno));
+  m = (union olsr_message *)msg_buffer;
 
-
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
-    : (union olsr_message *) msg->v6.olsr_msg;
   tc6 = &m->v6.message.tc;
+
   mprsaddr6 = tc6->neigh;
-  msgsize = (int)sizeof(struct olsrmsg6);
-  tc6->reserved = 0;
+  curr_size = 24; /* OLSR message header */
+  curr_size += 4; /* TC header */
 
-  if (outputsize > maxmessagesize - msgsize) 
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
     {
-
-      msg->v6.olsr_packlen = htons(outputsize);
-      
       net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
     }
 
+  /* Fill header */
+  m->v6.olsr_vtime = ifp->valtimes.tc;
+  m->v6.olsr_msgtype = TC_MESSAGE;
+  m->v6.hopcnt = message->hop_count;
+  m->v6.ttl = message->ttl;
+  COPY_IP(&m->v6.originator, &message->originator);
+
+  /* Fill TC header */
+  tc6->ansn = htons(message->ansn);
+  tc6->reserved = 0;
   
 
   /*Looping trough MPR selectors */
   for (mprs = message->multipoint_relay_selector_address; mprs != NULL;mprs = mprs->next) 
     {
            
-      outputsize = (char *)mprsaddr6 - packet;
-
-
       /*If packet is to be chomped */
-      if (outputsize > maxmessagesize - (int)sizeof (mprsaddr6))
+      if((curr_size + ipsize) > remainsize)
        {
-         msg->v6.olsr_packlen = htons(outputsize);
-         m->v6.olsr_msgtype = TC_MESSAGE;
-         m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
-         m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-         m->v6.olsr_vtime = tc_vtime;
-         
-         m->v6.seqno = htons(get_msg_seqno());
-         tc6->ansn = htons(message->ansn);
-         
-         m->v6.hopcnt = message->hop_count;
-         m->v6.ttl = message->ttl;
-
-         COPY_IP(&m->v6.originator, &message->originator);
-
+         /* Only add TC message if it contains data */
+         if(curr_size > (24 + 4 ))
+           {
+             m->v6.olsr_msgsize = htons(curr_size);
+             m->v6.seqno = htons(get_msg_seqno());
+
+             net_outbuffer_push(ifp, msg_buffer, curr_size);
+             mprsaddr6 = tc6->neigh;
+             curr_size = 24; /* OLSR message header */
+             curr_size += 4; /* TC header */
+             found = 0;
+             partial_sent = 1;
+           }
          net_output(ifp);
+         remainsize = net_outbuffer_bytes_left(ifp);
                
-         m = (union olsr_message *)msg->v6.olsr_msg;
-         tc6 = &m->v6.message.tc;
-
-         mprsaddr6 = tc6->neigh;
 
-         found = 0;
        }
       found = 1;
 
       //printf("mprsaddr6 is %x\n", (char *)mprsaddr6 - packet);
       //printf("Adding MPR-selector: %s\n", olsr_ip_to_string(&mprs->address));fflush(stdout);     
       COPY_IP(&mprsaddr6->addr, &mprs->address);
+      curr_size += ipsize;
 
       mprsaddr6++;
     }
        
   if (found)
     {
-           
-      outputsize = (char *)mprsaddr6 - packet;
-
-      msg->v6.olsr_packlen = htons(outputsize);
-      m->v6.olsr_msgtype = TC_MESSAGE;
-      m->v6.olsr_msgsize = (char *)mprsaddr6 - (char *)m;
-      m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-      m->v6.olsr_vtime = tc_vtime;
-
+      m->v6.olsr_msgsize = htons(curr_size);
       m->v6.seqno = htons(get_msg_seqno());
-      tc6->ansn = htons(message->ansn);
-      
-      m->v6.hopcnt = message->hop_count;
-      m->v6.ttl = message->ttl;
 
-      COPY_IP(&m->v6.originator, &message->originator);
+      net_outbuffer_push(ifp, msg_buffer, curr_size);
 
     }
   else
     {
-      if(!TIMED_OUT(&send_empty_tc))
+      if((!partial_sent) && (!TIMED_OUT(&send_empty_tc)))
        {
          olsr_printf(1, "TC: Sending empty package\n");
            
-         outputsize = 32;
-
-         msg->v6.olsr_packlen = htons(outputsize);
-         m->v6.olsr_msgtype = TC_MESSAGE;
-         m->v6.olsr_msgsize = 28;
-         m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-         m->v6.olsr_vtime = tc_vtime;
-         
+         m->v6.olsr_msgsize = htons(curr_size);
          m->v6.seqno = htons(get_msg_seqno());
-         tc6->ansn = htons(message->ansn);
-         
-         m->v6.hopcnt = message->hop_count;
-         m->v6.ttl = message->ttl;
-         
-         COPY_IP(&m->v6.originator, &message->originator);
-       }
-    }
 
-  /*
-  if (outputsize > maxmessagesize - (int)sizeof (struct olsrmsg)) 
-    {
-      net_output(ifp);
+         net_outbuffer_push(ifp, msg_buffer, curr_size);
+       }
     }
-  */
 
   /*
    * Delete the list of mprs messages
@@ -1027,77 +936,84 @@ tc_build6(struct tc_message *message, struct interface *ifp)
  *IP version 4
  *
  *<b>NO INTERNAL BUFFER</b>
- *@param ifn use this interfaces address as main address
+ *@param ifp use this interfaces address as main address
  *@return 1 on success
  */
 
-int
-mid_build4(struct interface *ifn)
+static void
+mid_build4(struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   /* preserve existing data in output buffer */
   union olsr_message *m;
   struct midaddr *addrs;
-  struct midmsg *mmsg;
   struct interface *ifs;  
 
-  if(ipversion != AF_INET)
-    return -1;
+  if((olsr_cnf->ip_version != AF_INET) || (!ifp) || (ifnet == NULL || ifnet->int_next == NULL))
+    return;
 
-  if(nbinterf <= 1)
-    return 0;
 
-  //printf("\t\tGenerating mid on %s\n", ifn->int_name);
+  remainsize = net_outbuffer_bytes_left(ifp);
 
-  remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
-                            + sizeof(msg->v4.olsr_seqno));
+  m = (union olsr_message *)msg_buffer;
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
-    :(union olsr_message *) msg->v4.olsr_msg;
+  curr_size = 12; /* OLSR message header */
 
-  mmsg = &m->v4.message.mid;
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
 
+  /* Fill header */
   m->v4.hopcnt = 0;
   m->v4.ttl = MAX_TTL;
-
-  m->v4.seqno = htons(get_msg_seqno());/* seqnumber */
-
-  /* pad - seems we don't need this....*/
-  //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
-  //mmsg->mid_res = 0;
-      
   /* Set main(first) address */
   COPY_IP(&m->v4.originator, &main_addr);
-      
-  addrs = mmsg->mid_addr;
+  m->v4.olsr_msgtype = MID_MESSAGE;
+  m->v4.olsr_vtime = ifp->valtimes.mid;
+  addrs = m->v4.message.mid.mid_addr;
 
   /* Don't add the main address... it's already there */
   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
     {
       if(!COMP_IP(&main_addr, &ifs->ip_addr))
        {
+
+         if((curr_size + ipsize) > remainsize)
+           {
+             /* Only add MID message if it contains data */
+             if(curr_size > 12)
+               {
+                 /* set size */
+                 m->v4.olsr_msgsize = htons(curr_size);
+                 m->v4.seqno = htons(get_msg_seqno());/* seqnumber */
+                 
+                 net_outbuffer_push(ifp, msg_buffer, curr_size);
+                 curr_size = 12; /* OLSR message header */
+                 addrs = m->v4.message.mid.mid_addr;
+               }
+             net_output(ifp);
+             remainsize = net_outbuffer_bytes_left(ifp);
+           }
+         
          COPY_IP(&addrs->addr, &ifs->ip_addr);
          addrs++;
+         curr_size += ipsize;
        }
     }
 
-  m->v4.olsr_msgtype = MID_MESSAGE;
-  m->v4.olsr_msgsize = (char*)addrs - (char*)m;
-  m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-
-  m->v4.olsr_vtime = mid_vtime;
-
-  outputsize = (char*)addrs - packet; 
-  msg->v4.olsr_packlen = htons(outputsize);
-
-
 
+  m->v4.seqno = htons(get_msg_seqno());/* seqnumber */
+  m->v4.olsr_msgsize = htons(curr_size);
 
   //printf("Sending MID (%d bytes)...\n", outputsize);
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
 
 
-  return 0;
+  return;
 }
 
 
@@ -1106,74 +1022,84 @@ mid_build4(struct interface *ifn)
  *IP version 6
  *
  *<b>NO INTERNAL BUFFER</b>
- *@param ifn use this interfaces address as main address
+ *@param ifp use this interfaces address as main address
  *@return 1 on success
  */
 
-int
-mid_build6(struct interface *ifn)
+static void
+mid_build6(struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   /* preserve existing data in output buffer */
   union olsr_message *m;
   struct midaddr6 *addrs6;
-  struct midmsg6 *mmsg6;
   struct interface *ifs;
 
   //printf("\t\tGenerating mid on %s\n", ifn->int_name);
 
 
-  if(ipversion != AF_INET6)
-    return -1;
+  if((olsr_cnf->ip_version != AF_INET6) || (!ifp) || (ifnet == NULL || ifnet->int_next == NULL))
+    return;
 
-  if(nbinterf <= 1)
-    return 0;
+  remainsize = net_outbuffer_bytes_left(ifp);
 
-  remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
-                            + sizeof(msg->v6.olsr_seqno));
+  curr_size = 24; /* OLSR message header */
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
-    :(union olsr_message *) msg->v6.olsr_msg;
-      
-  mmsg6 = &m->v6.message.mid;
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
 
+  m = (union olsr_message *)msg_buffer;
+    
+  /* Build header */
   m->v6.hopcnt = 0;
-  m->v6.ttl = MAX_TTL;
-
-  m->v6.seqno = htons(get_msg_seqno());/* seqnumber */
-  /* pad - seems we don't need this....*/
-  //memset(mmsg->mid_res, 0, sizeof(mmsg->mid_res));
-  //mmsg->mid_res = 0;
-      
+  m->v6.ttl = MAX_TTL;      
+  m->v6.olsr_msgtype = MID_MESSAGE;
+  m->v6.olsr_vtime = ifp->valtimes.mid;
   /* Set main(first) address */
   COPY_IP(&m->v6.originator, &main_addr);
-      
-  addrs6 = mmsg6->mid_addr;
+   
+
+  addrs6 = m->v6.message.mid.mid_addr;
 
   /* Don't add the main address... it's already there */
   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
     {
       if(!COMP_IP(&main_addr, &ifs->ip_addr))
        {
+         if((curr_size + ipsize) > remainsize)
+           {
+             /* Only add MID message if it contains data */
+             if(curr_size > 24)
+               {
+                 /* set size */
+                 m->v6.olsr_msgsize = htons(curr_size);
+                 m->v6.seqno = htons(get_msg_seqno());/* seqnumber */
+                 
+                 net_outbuffer_push(ifp, msg_buffer, curr_size);
+                 curr_size = 24; /* OLSR message header */
+                 addrs6 = m->v6.message.mid.mid_addr;
+               }
+             net_output(ifp);
+             remainsize = net_outbuffer_bytes_left(ifp);
+           }
+
          COPY_IP(&addrs6->addr, &ifs->ip_addr);
          addrs6++;
+         curr_size += ipsize;
        }
     }
 
-  m->v6.olsr_msgtype = MID_MESSAGE;
-  m->v6.olsr_msgsize = (char*)addrs6 - (char*)m;
-  m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-  m->v6.olsr_vtime = mid_vtime;
-
-  outputsize = (char*)addrs6 - packet;
-  msg->v6.olsr_packlen = htons(outputsize);
-
+  m->v6.olsr_msgsize = htons(curr_size);
+  m->v6.seqno = htons(get_msg_seqno());/* seqnumber */
 
   //printf("Sending MID (%d bytes)...\n", outputsize);
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
 
-
-  return 0;
+  return;
 }
 
 
@@ -1188,52 +1114,70 @@ mid_build6(struct interface *ifn)
 static void
 hna_build4(struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   /* preserve existing data in output buffer */
   union olsr_message *m;
   struct hnapair *pair;
-  struct hnamsg *hmsg;
-  struct local_hna_entry *h;
+  struct hna4_entry *h = olsr_cnf->hna4_entries;
 
   /* No hna nets */
-  if (local_hna4_set.next == &local_hna4_set)
+  if((olsr_cnf->ip_version != AF_INET) || (!ifp) || h == NULL)
     return;
     
-  remainsize = outputsize - (sizeof(msg->v4.olsr_packlen) 
-                            + sizeof(msg->v4.olsr_seqno));
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v4.olsr_msg + remainsize)
-    :(union olsr_message *) msg->v4.olsr_msg;
-
-  hmsg = &m->v4.message.hna;
-    
+  remainsize = net_outbuffer_bytes_left(ifp);
+  
+  curr_size = 12; /* OLSR message header */
+  
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
+  
+  m = (union olsr_message *)msg_buffer;
+  
+  
+  /* Fill header */
   COPY_IP(&m->v4.originator, &main_addr);
   m->v4.hopcnt = 0;
   m->v4.ttl = MAX_TTL;
+  m->v4.olsr_msgtype = HNA_MESSAGE;
+  m->v4.olsr_vtime = ifp->valtimes.hna;
+  
 
-  m->v4.seqno = htons(get_msg_seqno());
-
-
-  pair = hmsg->hna_net;
-
-  for(h = local_hna4_set.next;
-      h != &local_hna4_set;
-      h = h->next)
+  pair = m->v4.message.hna.hna_net;
+  
+  while(h)
     {
-      COPY_IP(&pair->addr, &h->A_network_addr);
-      COPY_IP(&pair->netmask, &h->A_netmask);
+      if((curr_size + (2 * ipsize)) > remainsize)
+       {
+         /* Only add HNA message if it contains data */
+         if(curr_size > 12)
+           {
+             m->v4.seqno = htons(get_msg_seqno());
+             m->v4.olsr_msgsize = htons(curr_size);
+             net_outbuffer_push(ifp, msg_buffer, curr_size);
+             curr_size = 12; /* OLSR message header */
+             pair = m->v4.message.hna.hna_net;
+           }
+         net_output(ifp);
+         remainsize = net_outbuffer_bytes_left(ifp);
+       }
+      COPY_IP(&pair->addr, &h->net);
+      COPY_IP(&pair->netmask, &h->netmask);
       pair++;
+      curr_size += (2 * ipsize);
+      h = h->next;
     }
-      
-  m->v4.olsr_msgtype = HNA_MESSAGE;
-  m->v4.olsr_msgsize = (char*)pair - (char*)m;
-  m->v4.olsr_msgsize = htons(m->v4.olsr_msgsize);
-  m->v4.olsr_vtime = hna_vtime;
 
-  outputsize = (char*)pair - packet;
-  msg->v4.olsr_packlen = htons(outputsize);
-  //printf("Sending HNA (%d bytes)...\n", outputsize);
+  m->v4.seqno = htons(get_msg_seqno());
+  m->v4.olsr_msgsize = htons(curr_size);
 
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
+
+  //printf("Sending HNA (%d bytes)...\n", outputsize);
+  return;
 }
 
 
@@ -1249,61 +1193,74 @@ hna_build4(struct interface *ifp)
 static void
 hna_build6(struct interface *ifp)
 {
-  int remainsize;
+  int remainsize, curr_size;
   /* preserve existing data in output buffer */
   union olsr_message *m;
   struct hnapair6 *pair6;
-  struct hnamsg6 *hmsg6;
   union olsr_ip_addr tmp_netmask;
-  struct local_hna_entry *h;
-
-  if(ipversion != AF_INET6)
-    return;    
-
+  struct hna6_entry *h = olsr_cnf->hna6_entries;
+  
   /* No hna nets */
-  if (local_hna6_set.next == &local_hna6_set)
+  if((olsr_cnf->ip_version != AF_INET6) || (!ifp) || h == NULL)
     return;
 
-  remainsize = outputsize - (sizeof(msg->v6.olsr_packlen) 
-                            + sizeof(msg->v6.olsr_seqno));
+    
+  remainsize = net_outbuffer_bytes_left(ifp);
+
+  curr_size = 24; /* OLSR message header */
 
-  m = outputsize ? 
-    (union olsr_message *)((char *)msg->v6.olsr_msg + remainsize)
-    :(union olsr_message *) msg->v6.olsr_msg;
+  /* Send pending packet if not room in buffer */
+  if(curr_size > remainsize)
+    {
+      net_output(ifp);
+      remainsize = net_outbuffer_bytes_left(ifp);
+    }
 
-  hmsg6 = &m->v6.message.hna;
-    
+  m = (union olsr_message *)msg_buffer;   
+
+  /* Fill header */
   COPY_IP(&m->v6.originator, &main_addr);
   m->v6.hopcnt = 0;
   m->v6.ttl = MAX_TTL;
+  m->v6.olsr_msgtype = HNA_MESSAGE;
+  m->v6.olsr_vtime = ifp->valtimes.hna;
 
-  m->v6.seqno = htons(get_msg_seqno());
-
-
-  pair6 = hmsg6->hna_net;
+  pair6 = m->v6.message.hna.hna_net;
 
 
-  for(h = local_hna6_set.next;
-      h != &local_hna6_set;
-      h = h->next)
+  while(h)
     {
+      if((curr_size + (2 * ipsize)) > remainsize)
+       {
+         /* Only add HNA message if it contains data */
+         if(curr_size > 24)
+           {
+             m->v6.seqno = htons(get_msg_seqno());
+             m->v6.olsr_msgsize = htons(curr_size);
+             net_outbuffer_push(ifp, msg_buffer, curr_size);
+             curr_size = 24; /* OLSR message header */
+             pair6 = m->v6.message.hna.hna_net;
+           }
+         net_output(ifp);
+         remainsize = net_outbuffer_bytes_left(ifp);
+       }
+      
       //printf("Adding %s\n", olsr_ip_to_string(&h->hna_net.addr));
-      COPY_IP(&pair6->addr, &h->A_network_addr);
-      olsr_prefix_to_netmask(&tmp_netmask, h->A_netmask.v6);
+      COPY_IP(&pair6->addr, &h->net);
+      olsr_prefix_to_netmask(&tmp_netmask, h->prefix_len);
       COPY_IP(&pair6->netmask, &tmp_netmask);
       pair6++;
+      curr_size += (2 * ipsize);
+      h = h->next;
     }
   
-  m->v6.olsr_msgtype = HNA_MESSAGE;
-  m->v6.olsr_msgsize = (char*)pair6 - (char*)m;
-  m->v6.olsr_msgsize = htons(m->v6.olsr_msgsize);
-  m->v6.olsr_vtime = hna_vtime;
+  m->v6.olsr_msgsize = htons(curr_size);
+  m->v6.seqno = htons(get_msg_seqno());
   
-  outputsize = (char*)pair6 - packet;
-  msg->v6.olsr_packlen = htons(outputsize);
+  net_outbuffer_push(ifp, msg_buffer, curr_size);
   
   //printf("Sending HNA (%d bytes)...\n", outputsize);
-
+  return;
 
 }