示例#1
0
static bool
serialize_mid6(struct interface *ifp)
{
  uint16_t remainsize, curr_size, needsize;
  /* preserve existing data in output buffer */
  union olsr_message *m;
  struct midaddr6 *addrs6;
  struct interface *ifs;

  //printf("\t\tGenerating mid on %s\n", ifn->int_name);

  if ((olsr_cnf->ip_version != AF_INET6) || (!ifp) || (ifnet == NULL) || ((ifnet->int_next == NULL) && (ipequal(&olsr_cnf->main_addr, &ifnet->ip_addr))))
    return false;

  remainsize = net_outbuffer_bytes_left(ifp);

  curr_size = OLSR_MID_IPV6_HDRSIZE;

  /* calculate size needed for HNA */
  needsize = curr_size;
  for (ifs = ifnet; ifs != NULL; ifs = ifs->int_next) {
    needsize += olsr_cnf->ipsize*2;
  }

  /* Send pending packet if not room in buffer */
  if (needsize > remainsize) {
    net_output(ifp);
    remainsize = net_outbuffer_bytes_left(ifp);
  }
  check_buffspace(curr_size, remainsize, "MID");

  m = (union olsr_message *)msg_buffer;

  /* Build header */
  m->v6.hopcnt = 0;
  m->v6.ttl = MAX_TTL;
  m->v6.olsr_msgtype = MID_MESSAGE;
  m->v6.olsr_vtime = ifp->valtimes.mid;
  /* Set main(first) address */
  m->v6.originator = olsr_cnf->main_addr.v6;

  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 (!ipequal(&olsr_cnf->main_addr, &ifs->ip_addr)) {
#ifdef DEBUG
      struct ipaddr_str buf;
#endif
      if ((curr_size + olsr_cnf->ipsize) > remainsize) {
        /* Only add MID message if it contains data */
        if (curr_size > OLSR_MID_IPV6_HDRSIZE) {
#ifdef DEBUG
          OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize);
#endif
          /* 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 = OLSR_MID_IPV6_HDRSIZE;
          addrs6 = m->v6.message.mid.mid_addr;
        }
        net_output(ifp);
        remainsize = net_outbuffer_bytes_left(ifp);
        check_buffspace(curr_size + olsr_cnf->ipsize, remainsize, "MID2");
      }
#ifdef DEBUG
      OLSR_PRINTF(BMSG_DBGLVL, "\t%s(%s)\n", olsr_ip_to_string(&buf, &ifs->ip_addr), ifs->int_name);
#endif

      addrs6->addr = ifs->ip_addr.v6;
      addrs6++;
      curr_size += olsr_cnf->ipsize;
    }
  }

  m->v6.olsr_msgsize = htons(curr_size);
  m->v6.seqno = htons(get_msg_seqno()); /* seqnumber */

  //printf("Sending MID (%d bytes)...\n", outputsize);
  if (curr_size > OLSR_MID_IPV6_HDRSIZE)
    net_outbuffer_push(ifp, msg_buffer, curr_size);

  return true;
}
示例#2
0
/**
 *IP version 4
 *
 *@param ifp the interface to send on
 *@return nada
 */
static bool
serialize_hna4(struct interface *ifp)
{
  uint16_t remainsize, curr_size, needsize;
  /* preserve existing data in output buffer */
  union olsr_message *m;
  struct hnapair *pair;
  struct ip_prefix_list *h;

  /* No hna nets */
  if (ifp == NULL) {
    return false;
  }
  if (olsr_cnf->ip_version != AF_INET) {
    return false;
  }
  h = olsr_cnf->hna_entries;
  if (h == NULL) {
    return false;
  }

  remainsize = net_outbuffer_bytes_left(ifp);

  curr_size = OLSR_HNA_IPV4_HDRSIZE;

  /* calculate size needed for HNA */
  needsize = curr_size;
  while (h) {
    needsize += olsr_cnf->ipsize*2;
    h = h->next;
  }

  h = olsr_cnf->hna_entries;

  /* Send pending packet if not room in buffer */
  if (needsize > remainsize) {
    net_output(ifp);
    remainsize = net_outbuffer_bytes_left(ifp);
  }
  check_buffspace(curr_size, remainsize, "HNA");

  m = (union olsr_message *)msg_buffer;

  /* Fill header */
  m->v4.originator = olsr_cnf->main_addr.v4.s_addr;
  m->v4.hopcnt = 0;
  m->v4.ttl = MAX_TTL;
  m->v4.olsr_msgtype = HNA_MESSAGE;
  m->v4.olsr_vtime = ifp->valtimes.hna;

  pair = m->v4.message.hna.hna_net;

  for (; h != NULL; h = h->next) {
    union olsr_ip_addr ip_addr;
    if ((curr_size + (2 * olsr_cnf->ipsize)) > remainsize) {
      /* Only add HNA message if it contains data */
      if (curr_size > OLSR_HNA_IPV4_HDRSIZE) {
#ifdef DEBUG
        OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize);
#endif
        m->v4.seqno = htons(get_msg_seqno());
        m->v4.olsr_msgsize = htons(curr_size);
        net_outbuffer_push(ifp, msg_buffer, curr_size);
        curr_size = OLSR_HNA_IPV4_HDRSIZE;
        pair = m->v4.message.hna.hna_net;
      }
      net_output(ifp);
      remainsize = net_outbuffer_bytes_left(ifp);
      check_buffspace(curr_size + (2 * olsr_cnf->ipsize), remainsize, "HNA2");
    }
#ifdef DEBUG
    OLSR_PRINTF(BMSG_DBGLVL, "\tNet: %s\n", olsr_ip_prefix_to_string(&h->net));
#endif

    olsr_prefix_to_netmask(&ip_addr, h->net.prefix_len);
#ifdef linux
    if (olsr_cnf->smart_gw_active && is_prefix_inetgw(&h->net)) {
      /* this is the default route, overwrite it with the smart gateway */
      olsr_modifiy_inetgw_netmask(&ip_addr, h->net.prefix_len);
    }
#endif
    pair->addr = h->net.prefix.v4.s_addr;
    pair->netmask = ip_addr.v4.s_addr;
    pair++;
    curr_size += (2 * olsr_cnf->ipsize);
  }

  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 false;
}
示例#3
0
static bool
serialize_tc6(struct tc_message *message, struct interface *ifp)
{
#ifdef DEBUG
  struct ipaddr_str buf;
#endif
  uint16_t remainsize, curr_size;
  struct tc_mpr_addr *mprs;
  union olsr_message *m;
  struct olsr_tcmsg6 *tc6;
  struct neigh_info6 *mprsaddr6;
  bool found = false, partial_sent = false;

  if ((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET6))
    return false;

  remainsize = net_outbuffer_bytes_left(ifp);

  m = (union olsr_message *)msg_buffer;

  tc6 = &m->v6.message.tc;

  mprsaddr6 = tc6->neigh;
  curr_size = OLSR_TC_IPV6_HDRSIZE;

  /* Send pending packet if not room in buffer */
  if (curr_size > remainsize) {
    net_output(ifp);
    remainsize = net_outbuffer_bytes_left(ifp);
  }
  check_buffspace(curr_size, remainsize, "TC");

  /* 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;
  m->v6.originator = message->originator.v6;

  /* 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) {

    /*If packet is to be chomped */
    if ((curr_size + olsr_cnf->ipsize) > remainsize) {
      /* Only add TC message if it contains data */
      if (curr_size > OLSR_TC_IPV6_HDRSIZE) {
#ifdef DEBUG
        OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize);
#endif
        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 = OLSR_TC_IPV6_HDRSIZE;
        found = false;
        partial_sent = true;
      }
      net_output(ifp);
      remainsize = net_outbuffer_bytes_left(ifp);
      check_buffspace(curr_size + olsr_cnf->ipsize, remainsize, "TC2");

    }
    found = true;
#ifdef DEBUG
    OLSR_PRINTF(BMSG_DBGLVL, "\t%s\n", olsr_ip_to_string(&buf, &mprs->address));
#endif
    mprsaddr6->addr = mprs->address.v6;
    curr_size += olsr_cnf->ipsize;

    mprsaddr6++;
  }

  if (found) {
    m->v6.olsr_msgsize = htons(curr_size);
    m->v6.seqno = htons(get_msg_seqno());

    net_outbuffer_push(ifp, msg_buffer, curr_size);

  } else {
    if ((!partial_sent) && (!TIMED_OUT(send_empty_tc))) {
      OLSR_PRINTF(1, "TC: Sending empty package\n");

      m->v6.olsr_msgsize = htons(curr_size);
      m->v6.seqno = htons(get_msg_seqno());

      net_outbuffer_push(ifp, msg_buffer, curr_size);

      found = true;
    }
  }

  return found;
}
示例#4
0
static bool
serialize_hello6(struct hello_message *message, struct interface *ifp)
{
  uint16_t remainsize, curr_size;
  struct hello_neighbor *nb;
  union olsr_message *m;
  struct hellomsg6 *h6;
  struct hellinfo6 *hinfo6;
  union olsr_ip_addr *haddr;
  int i, j;
  bool first_entry;

  if ((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET6))
    return false;

  remainsize = net_outbuffer_bytes_left(ifp);
  m = (union olsr_message *)msg_buffer;

  curr_size = OLSR_HELLO_IPV6_HDRSIZE;  /* OLSR message header */

  /* Send pending packet if not room in buffer */
  if (curr_size > remainsize) {
    net_output(ifp);
    remainsize = net_outbuffer_bytes_left(ifp);
  }
  check_buffspace(curr_size + olsr_cnf->ipsize + 4, remainsize, "HELLO");

  h6 = &m->v6.message.hello;
  hinfo6 = h6->hell_info;
  haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;

  /* Fill message header */
  m->v6.ttl = message->ttl;
  m->v6.hopcnt = 0;
  /* Set source(main) addr */
  m->v6.originator = olsr_cnf->main_addr.v6;
  m->v6.olsr_msgtype = HELLO_MESSAGE;

  m->v6.olsr_vtime = ifp->valtimes.hello;

  /* Fill packet header */
  h6->willingness = message->willingness;
  h6->htime = reltime_to_me(ifp->hello_etime);
  memset(&h6->reserved, 0, sizeof(uint16_t));

  /*
   *Loops trough all possible neighbor statuses
   *The negbor list is grouped by status
   */

  for (i = 0; i <= MAX_NEIGH; i++) {
    for (j = 0; j <= MAX_LINK; j++) {
#ifdef DEBUG
      struct ipaddr_str buf;
#endif
      first_entry = true;

      /*
       *Looping trough neighbors
       */
      for (nb = message->neighbors; nb != NULL; nb = nb->next) {
        if ((nb->status != i) || (nb->link != j))
          continue;

#ifdef DEBUG
        OLSR_PRINTF(BMSG_DBGLVL, "\t%s - ", olsr_ip_to_string(&buf, &nb->address));
        OLSR_PRINTF(BMSG_DBGLVL, "L:%d N:%d\n", j, i);
#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 this is the first neighbor in
         * a group, we must check for an extra
         * 4 bytes
         */
        if ((curr_size + olsr_cnf->ipsize + (first_entry ? 4 : 0)) > remainsize) {
          /* Only send partial HELLO if it contains data */
          if (curr_size > OLSR_HELLO_IPV6_HDRSIZE) {
#ifdef DEBUG
            OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize);
#endif
            /* 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 = htons(hinfo6->size);

            /* Send partial packet */
            net_outbuffer_push(ifp, msg_buffer, curr_size);
            curr_size = OLSR_HELLO_IPV6_HDRSIZE;

            h6 = &m->v6.message.hello;
            hinfo6 = h6->hell_info;
            haddr = (union olsr_ip_addr *)hinfo6->neigh_addr;
            /* Make sure typeheader is added */
            first_entry = true;
          }
          net_output(ifp);
          /* Reset size and pointers */
          remainsize = net_outbuffer_bytes_left(ifp);

          check_buffspace(curr_size + olsr_cnf->ipsize + 4, remainsize, "HELLO2");

        }

        if (first_entry) {
          memset(&hinfo6->reserved, 0, sizeof(uint8_t));
          /* Set link and status for this group of neighbors (this is the first) */
          hinfo6->link_code = CREATE_LINK_CODE(i, j);
          curr_size += 4;       /* HELLO type section header */
        }

        *haddr = nb->address;

        /* Point to next address */
        haddr++;
        curr_size += olsr_cnf->ipsize;  /* IP address added */

        first_entry = false;
      }                         /* looping trough neighbors */

      if (!first_entry) {
        hinfo6->size = htons((char *)haddr - (char *)hinfo6);
        hinfo6 = (struct hellinfo6 *)((char *)haddr);
        haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr;
      }

    }                           /* for j */
  }                             /* for i */

  m->v6.seqno = htons(get_msg_seqno());
  m->v6.olsr_msgsize = htons(curr_size);

  net_outbuffer_push(ifp, msg_buffer, curr_size);

  /* HELLO is always buildt */
  return true;
}
示例#5
0
/**
 Convert a nmeaINFO structure into an OLSR message.

 @param nmeaInfo
 A pointer to a nmeaINFO structure
 @param olsrMessage
 A pointer to an OLSR message in which to place the converted information
 @param olsrMessageSize
 The maximum number of bytes available for the olsrMessage
 @param validityTime
 the validity time of the message in seconds

 @return
 - the aligned size of the converted information
 - 0 (zero) in case of an error
 */
unsigned int gpsToOlsr(nmeaINFO *nmeaInfo, union olsr_message *olsrMessage,
		unsigned int olsrMessageSize, unsigned long long validityTime) {
	unsigned int aligned_size;
	unsigned int aligned_size_remainder;
	size_t nodeLength;
	nodeIdBinaryType * nodeIdBinary = NULL;

	PudOlsrPositionUpdate * olsrGpsMessage =
			getOlsrMessagePayload(olsr_cnf->ip_version, olsrMessage);

	/*
	 * Compose message contents
	 */
	memset(olsrGpsMessage, 0, sizeof (PudOlsrPositionUpdate));

	setPositionUpdateVersion(olsrGpsMessage, PUD_WIRE_FORMAT_VERSION);
	setValidityTime(&olsrGpsMessage->validityTime, validityTime);
	setPositionUpdatePresent(olsrGpsMessage, nmeaInfo->present & ~PUD_PRESENT_GATEWAY);

	/* utc is always present, we make sure of that elsewhere, so just use it */
	setPositionUpdateTime(olsrGpsMessage, nmeaInfo->utc.hour, nmeaInfo->utc.min,
			nmeaInfo->utc.sec);

	if (likely(nmea_INFO_is_present(nmeaInfo->present, LAT))) {
		setPositionUpdateLatitude(olsrGpsMessage, nmeaInfo->lat);
	} else {
		setPositionUpdateLatitude(olsrGpsMessage, 0.0);
	}

	if (likely(nmea_INFO_is_present(nmeaInfo->present, LON))) {
		setPositionUpdateLongitude(olsrGpsMessage, nmeaInfo->lon);
	} else {
		setPositionUpdateLongitude(olsrGpsMessage, 0.0);
	}

	if (likely(nmea_INFO_is_present(nmeaInfo->present, ELV))) {
		setPositionUpdateAltitude(olsrGpsMessage, nmeaInfo->elv);
	} else {
		setPositionUpdateAltitude(olsrGpsMessage, 0.0);
	}

	if (likely(nmea_INFO_is_present(nmeaInfo->present, SPEED))) {
		setPositionUpdateSpeed(olsrGpsMessage, nmeaInfo->speed);
	} else {
		setPositionUpdateSpeed(olsrGpsMessage, 0.0);
	}

	if (likely(nmea_INFO_is_present(nmeaInfo->present, TRACK))) {
		setPositionUpdateTrack(olsrGpsMessage, nmeaInfo->track);
	} else {
		setPositionUpdateTrack(olsrGpsMessage, 0);
	}

	if (likely(nmea_INFO_is_present(nmeaInfo->present, HDOP))) {
		setPositionUpdateHdop(olsrGpsMessage, nmeaInfo->HDOP);
	} else {
		setPositionUpdateHdop(olsrGpsMessage, PUD_HDOP_MAX);
	}

	nodeIdBinary = getNodeIdBinary();
	nodeLength = setPositionUpdateNodeInfo(olsr_cnf->ip_version, olsrGpsMessage,
			olsrMessageSize, getNodeIdTypeNumber(),
			(unsigned char *) &nodeIdBinary->buffer, nodeIdBinary->length);

	/*
	 * Messages in OLSR are 4-byte aligned: align
	 */

	/* size = type, string, string terminator */
	aligned_size = PUD_OLSRWIREFORMATSIZE + nodeLength;
	aligned_size_remainder = (aligned_size % 4);
	if (aligned_size_remainder != 0) {
		aligned_size += (4 - aligned_size_remainder);
	}

	/*
	 * Fill message headers (fill ALL fields, except message)
	 * Note: olsr_vtime is currently unused, we use it for our validity time.
	 */

	if (olsr_cnf->ip_version == AF_INET) {
		/* IPv4 */

		olsrMessage->v4.olsr_msgtype = PUD_OLSR_MSG_TYPE;
		olsrMessage->v4.olsr_vtime = reltime_to_me(validityTime * 1000);
		/* message->v4.olsr_msgsize at the end */
		olsrMessage->v4.originator = olsr_cnf->main_addr.v4.s_addr;
		olsrMessage->v4.ttl = getOlsrTtl();
		olsrMessage->v4.hopcnt = 0;
		olsrMessage->v4.seqno = htons(get_msg_seqno());

		/* add length of message->v4 fields */
		aligned_size += (sizeof(olsrMessage->v4)
				- sizeof(olsrMessage->v4.message));
		olsrMessage->v4.olsr_msgsize = htons(aligned_size);
	} else {
		/* IPv6 */

		olsrMessage->v6.olsr_msgtype = PUD_OLSR_MSG_TYPE;
		olsrMessage->v6.olsr_vtime = reltime_to_me(validityTime * 1000);
		/* message->v6.olsr_msgsize at the end */
		olsrMessage->v6.originator = olsr_cnf->main_addr.v6;
		olsrMessage->v6.ttl = getOlsrTtl();
		olsrMessage->v6.hopcnt = 0;
		olsrMessage->v6.seqno = htons(get_msg_seqno());

		/* add length of message->v6 fields */
		aligned_size += (sizeof(olsrMessage->v6)
				- sizeof(olsrMessage->v6.message));
		olsrMessage->v6.olsr_msgsize = htons(aligned_size);
	}

	/* pad with zeroes */
	if (aligned_size_remainder != 0) {
		memset(&(((char *) &olsrGpsMessage->nodeInfo.nodeIdType)[nodeLength]),
				0, (4 - aligned_size_remainder));
	}

	return aligned_size;
}
void
build_hello_msg(struct olsrv2 *olsr, olsr_pktbuf_t *pktbuf,
        union olsr_ip_addr *local_iface_addr
        )
{
  //olsr_u8_t *msg, *msg_head;
  //struct packet_header *p_header;
  //static olsr_pktbuf_t *msg_tlv_buf = NULL;
  //static olsr_pktbuf_t *addr_block_buf = NULL;
  //static olsr_pktbuf_t *local_addr_block_buf = NULL;
   olsr_pktbuf_t *msg_tlv_buf = NULL;
   olsr_pktbuf_t *addr_block_buf = NULL;
   olsr_pktbuf_t *local_addr_block_buf = NULL;

  // initialize buffers
  if (!msg_tlv_buf)
    msg_tlv_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(msg_tlv_buf);

  if (!addr_block_buf)
    addr_block_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(addr_block_buf);

  if(!local_addr_block_buf)
    local_addr_block_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(local_addr_block_buf);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building TLV for Validity Time.\n");
  }
  // build message TLVs
  build_message_tlv_validity_time(msg_tlv_buf,
                   double_to_me((double)olsr->qual_cnf->neighbor_hold_time));

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building TLV for Interval Time.\n");
  }
  build_message_tlv_interval_time(msg_tlv_buf,
                       double_to_me((double)olsr->qual_cnf->hello_interval));

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building TLV for Willingness.\n");
  }
  build_message_tlv_willingness(msg_tlv_buf, WILL_DEFAULT);


//codexxx
  if(DEBUG_OLSRV2)
	{
		olsr_printf("Building TLV for queue length info.\n");
	}
	build_message_tlv_queue(msg_tlv_buf, olsr->localqueuelen);

  // end codexxx

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building local interface address block.\n");
  }
  //build local interface address block
  build_local_addr_block(olsr, local_addr_block_buf,
             local_iface_addr);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building {<addr-block> <tlv-block>}*.\n");
  }
  // build {<addr-block> <tlv-block>}*
  address_compress(olsr, addr_block_buf, HELLO_MESSAGE, SIMPLE_COMPRESS,
      local_iface_addr);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append <msg-header> and <msg-header-info>.\n");
  }
  // append <msg-header> and <msg-header-info>
  build_message_header(olsr,
               pktbuf,
               (olsr_u16_t)(2 + msg_tlv_buf->len +
               local_addr_block_buf->len +
               addr_block_buf->len),// 2 is <tlv-length>
               HELLO_MESSAGE,
               local_iface_addr,
               1, 0, get_msg_seqno(olsr)); // wiss: TTL=1 hopcount=0 

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append <tlv-block>.\n");
  }
  // append msg <tlv-block>  wiss: to pkt buf ( to header and header info ya3ni) 
  olsr_pktbuf_append_u16(pktbuf, (olsr_u16_t)msg_tlv_buf->len);
  olsr_pktbuf_append_pktbuf(pktbuf, msg_tlv_buf);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append local interface address block.\n");
  }
  // append local interface address block
  olsr_pktbuf_append_pktbuf(pktbuf, local_addr_block_buf);

  if(DEBUG_OLSRV2)
  {
    olsr_printf("Append {<addr-block> <tlv-block>}*.\n");
  }
  // append {<addr-block> <tlv-block>}*
  if(addr_block_buf != NULL)
    olsr_pktbuf_append_pktbuf(pktbuf, addr_block_buf);

  free(msg_tlv_buf->data);
  free(msg_tlv_buf);
  free(addr_block_buf->data);
  free(addr_block_buf);
  free(local_addr_block_buf->data);
  free(local_addr_block_buf);
}
void
build_tc_msg(struct olsrv2 *olsr, olsr_pktbuf_t *pktbuf,
    union olsr_ip_addr *local_iface_addr
    )
{
  //olsr_u8_t *msg, *msg_head;
  //struct packet_header *p_header;
  //static olsr_pktbuf_t *msg_tlv_buf = NULL;
  //static olsr_pktbuf_t *addr_block_buf = NULL;
  //static olsr_pktbuf_t *local_addr_block_buf = NULL;
  olsr_pktbuf_t *msg_tlv_buf = NULL;
  olsr_pktbuf_t *addr_block_buf = NULL;
  olsr_pktbuf_t *local_addr_block_buf = NULL;

  // initialize buffers
  if (!msg_tlv_buf)
    msg_tlv_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(msg_tlv_buf);

  if (!addr_block_buf)
    addr_block_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(addr_block_buf);

  if(!local_addr_block_buf)
    local_addr_block_buf = olsr_pktbuf_alloc_with_capa(64);
  olsr_pktbuf_clear(local_addr_block_buf);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building TLV for Validity Time.\n");
  }
  // build message TLVs
  build_message_tlv_validity_time(msg_tlv_buf,
                   double_to_me((double)olsr->qual_cnf->topology_hold_time));

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building TLV for Interval Time.\n");
  }
  build_message_tlv_interval_time(msg_tlv_buf,
                          double_to_me((double)olsr->qual_cnf->tc_interval));

  if(DEBUG_OLSRV2)
  {
    olsr_printf("Building TLV for Content Sequence Number.\n");
  }
  build_message_tlv_content_seq_num(msg_tlv_buf, get_local_assn(olsr));


  /*//codexxx'
  if(DEBUG_OLSRV2)
	{
		olsr_printf("Building TLV for queue length info.\n");
	}
	build_message_tlv_queue(msg_tlv_buf, olsr->localqueuelen);

  // end codexxx'
  */

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building local interface address block.\n");
  }
  //build local interface address block
  build_local_addr_block(olsr, local_addr_block_buf,
             NULL);


  if(DEBUG_OLSRV2)
  {
      olsr_printf("Advertize attached network address.\n");
  }
  //advertize attached network address //wiss: bass haydi el partie jdide bel TC
  create_attached_network_address_block(olsr, addr_block_buf, TC_MESSAGE,
                    SIMPLE_COMPRESS,
                    local_iface_addr
                    );

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Building {<addr-block> <tlv-block>}*.\n");
  }
  // build {<addr-block> <tlv-block>}*
  address_compress(olsr, addr_block_buf, TC_MESSAGE, SIMPLE_COMPRESS,
      local_iface_addr
      );

  /* build message header */  //wiss: append <msg-header> and <msg-header-info>
  build_message_header(olsr,
               pktbuf,
               (olsr_u16_t)(2 + msg_tlv_buf->len +
               local_addr_block_buf->len +
               addr_block_buf->len),    // 2 is <tlv-length>
               TC_MESSAGE,
               local_iface_addr,
               MAX_TTL, 0, get_msg_seqno(olsr));  //wiss: TTL bten2as kell ma yente2el men hop lal teni

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append <tlv-block>.\n");
  }
  // append <tlv-block>
  olsr_pktbuf_append_u16(pktbuf, (olsr_u16_t)msg_tlv_buf->len);
  olsr_pktbuf_append_pktbuf(pktbuf, msg_tlv_buf);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append local interface address block.\n");
  }
  // append local interface address block
  olsr_pktbuf_append_pktbuf(pktbuf, local_addr_block_buf);

  if(DEBUG_OLSRV2)
  {
      olsr_printf("Append {<addr-block> <tlv-block>}*.\n");
  }
  // append {<addr-block> <tlv-block>}*
  olsr_pktbuf_append_pktbuf(pktbuf, addr_block_buf);

  free(msg_tlv_buf->data);
  free(msg_tlv_buf);
  free(addr_block_buf->data);
  free(addr_block_buf);
  free(local_addr_block_buf->data);
  free(local_addr_block_buf);
}