📄 build_msg.c
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of olsr.org, olsrd nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: build_msg.c,v 1.36 2007/04/25 22:08:07 bernd67 Exp $ */#include "defs.h"#include "olsr.h"#include "log.h"#include "build_msg.h"#include "local_hna_set.h"#include "mantissa.h"#define BMSG_DBGLVL 5#define OLSR_IPV4_HDRSIZE 12#define OLSR_IPV6_HDRSIZE 24#define OLSR_HELLO_IPV4_HDRSIZE (OLSR_IPV4_HDRSIZE + 4) #define OLSR_HELLO_IPV6_HDRSIZE (OLSR_IPV6_HDRSIZE + 4)#define OLSR_TC_IPV4_HDRSIZE (OLSR_IPV4_HDRSIZE + 4)#define OLSR_TC_IPV6_HDRSIZE (OLSR_IPV6_HDRSIZE + 4)#define OLSR_MID_IPV4_HDRSIZE OLSR_IPV4_HDRSIZE#define OLSR_MID_IPV6_HDRSIZE OLSR_IPV6_HDRSIZE#define OLSR_HNA_IPV4_HDRSIZE OLSR_IPV4_HDRSIZE#define OLSR_HNA_IPV6_HDRSIZE OLSR_IPV6_HDRSIZE/* All these functions share this buffer */static olsr_u8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];static clock_t send_empty_tc; /* TC empty message sending *//* Prototypes for internal functions *//* IPv4 */static olsr_boolserialize_hello4(struct hello_message *, struct interface *);static olsr_boolserialize_tc4(struct tc_message *, struct interface *);static olsr_boolserialize_mid4(struct interface *);static olsr_boolserialize_hna4(struct interface *);/* IPv6 */static olsr_boolserialize_hello6(struct hello_message *, struct interface *);static olsr_boolserialize_tc6(struct tc_message *, struct interface *);static olsr_boolserialize_mid6(struct interface *);static olsr_boolserialize_hna6(struct interface *);/** * Set the timer that controls the generation of * empty TC messages */voidset_empty_tc_timer(clock_t empty_tc_new){ send_empty_tc = empty_tc_new;}/** * Get the timer that controls the generation of * empty TC messages */clock_tget_empty_tc_timer(void){ return send_empty_tc;}/** * Generate HELLO packet with the contents of the parameter "message". * If this won't fit in one packet, chop it up into several. * Send the packet if the size of the data contained in the output buffer * reach maxmessagesize. Can generate an empty HELLO packet if the * neighbor table is empty. * * *@param message the hello_message struct containing the info *to build the hello message from. *@param ifp the interface to send the message on * *@return nada */olsr_boolqueue_hello(struct hello_message *message, struct interface *ifp){#ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Building HELLO on %s\n-------------------\n", ifp->int_name);#endif switch(olsr_cnf->ip_version) { case(AF_INET): return serialize_hello4(message, ifp); case(AF_INET6): return serialize_hello6(message, ifp); } return OLSR_FALSE;}/* * Generate TC packet with the contents of the parameter "message". * If this won't fit in one packet, chop it up into several. * Send the packet if the size of the data contained in the output buffer * reach maxmessagesize. * *@param message the tc_message struct containing the info *to send *@param ifp the interface to send the message on * *@return nada */olsr_boolqueue_tc(struct tc_message *message, struct interface *ifp) {#ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Building TC on %s\n-------------------\n", ifp->int_name);#endif switch(olsr_cnf->ip_version) { case(AF_INET): return serialize_tc4(message, ifp); case(AF_INET6): return serialize_tc6(message, ifp); } return OLSR_FALSE;}/** *Build a MID message to the outputbuffer * *<b>NO INTERNAL BUFFER</b> *@param ifn use this interfaces address as main address *@return 1 on success */olsr_boolqueue_mid(struct interface *ifp){#ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Building MID on %s\n-------------------\n", ifp->int_name);#endif switch(olsr_cnf->ip_version) { case(AF_INET): return serialize_mid4(ifp); case(AF_INET6): return serialize_mid6(ifp); } return OLSR_FALSE;}/** *Builds a HNA message in the outputbuffer *<b>NB! Not internal packetformat!</b> * *@param ifp the interface to send on *@return nada */olsr_boolqueue_hna(struct interface *ifp){#ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Building HNA on %s\n-------------------\n", ifp->int_name);#endif switch(olsr_cnf->ip_version) { case(AF_INET): return serialize_hna4(ifp); case(AF_INET6): return serialize_hna6(ifp); } return OLSR_FALSE;}/* * Protocol specific versions */static voidcheck_buffspace(int msgsize, int buffsize, char *type){ if(msgsize > buffsize) { OLSR_PRINTF(1, "%s build, outputbuffer to small(%d/%d)!\n", type, msgsize, buffsize); olsr_syslog(OLSR_LOG_ERR, "%s build, outputbuffer to small(%d/%d)!\n", type, msgsize, buffsize); olsr_exit(__func__, EXIT_FAILURE); }}/** * IP version 4 * *@param message the hello_message struct containing the info *to build the hello message from. *@param ifp the interface to send the message on * *@return nada */static olsr_boolserialize_hello4(struct hello_message *message, struct interface *ifp){ olsr_u16_t remainsize, curr_size; struct hello_neighbor *nb; union olsr_message *m; struct hellomsg *h; struct hellinfo *hinfo; union olsr_ip_addr *haddr; int i, j; olsr_bool first_entry; if((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET)) return OLSR_FALSE; remainsize = net_outbuffer_bytes_left(ifp); m = (union olsr_message *)msg_buffer; curr_size = OLSR_HELLO_IPV4_HDRSIZE; /* Send pending packet if not room in buffer */ if(curr_size > remainsize) { net_output(ifp); remainsize = net_outbuffer_bytes_left(ifp); } /* Sanity check */ check_buffspace(curr_size, remainsize, "HELLO"); h = &m->v4.message.hello; hinfo = h->hell_info; haddr = (union olsr_ip_addr *)hinfo->neigh_addr; /* 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, &olsr_cnf->main_addr); m->v4.olsr_vtime = ifp->valtimes.hello; /* Fill HELLO header */ h->willingness = message->willingness; h->htime = double_to_me(ifp->hello_etime); memset(&h->reserved, 0, sizeof(olsr_u16_t)); /* *Loops trough all possible neighbor statuses *The negbor list is grouped by status * */ /* Nighbor statuses */ for (i = 0; i <= MAX_NEIGH; i++) { /* Link statuses */ for(j = 0; j <= MAX_LINK; j++) { /* HYSTERESIS - Not adding neighbors with link type HIDE */ if(j == HIDE_LINK) continue; first_entry = OLSR_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(&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_IPV4_HDRSIZE) {#ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize);#endif /* Complete the headers */ m->v4.seqno = htons(get_msg_seqno()); m->v4.olsr_msgsize = htons(curr_size); hinfo->size = htons((char *)haddr - (char *)hinfo); /* Send partial packet */ net_outbuffer_push(ifp, msg_buffer, curr_size); curr_size = OLSR_HELLO_IPV4_HDRSIZE; h = &m->v4.message.hello; hinfo = h->hell_info; haddr = (union olsr_ip_addr *)hinfo->neigh_addr; /* Make sure typeheader is added */ first_entry = OLSR_TRUE; } net_output(ifp); /* Reset size and pointers */ remainsize = net_outbuffer_bytes_left(ifp); /* Sanity check */ check_buffspace(curr_size + olsr_cnf->ipsize + 4, remainsize, "HELLO2"); } if (first_entry) { 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); curr_size += 4; /* HELLO type section header */ } COPY_IP(haddr, &nb->address); /* Point to next address */ haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4]; curr_size += olsr_cnf->ipsize; /* IP address added */ first_entry = OLSR_FALSE; } if(!first_entry)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -