⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lq_packet.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2003, Andreas T鴑nesen (andreto@olsr.org) *               2004, Thomas Lopatic (thomas@lopatic.de) *               2006, for some fixups, sven-ola(gmx.de) * 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: lq_packet.c,v 1.28 2007/08/29 23:08:54 bernd67 Exp $ */#include "olsr_protocol.h"#include "defs.h"#include "lq_packet.h"#include "interfaces.h"#include "link_set.h"#include "neighbor_table.h"#include "mpr_selector_set.h"#include "mid_set.h"#include "mantissa.h"#include "process_package.h" // XXX - remove#include "two_hop_neighbor_table.h"#include "hysteresis.h"#include "olsr.h"#include "build_msg.h"olsr_bool lq_tc_pending = OLSR_FALSE;static unsigned char msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];static inline void        pkt_get_u8(const olsr_u8_t **p, olsr_u8_t  *var)         { *var =       *(olsr_u8_t *)(*p);   *p += sizeof(olsr_u8_t); }static inline void       pkt_get_u16(const olsr_u8_t **p, olsr_u16_t *var)         { *var = ntohs(*(olsr_u16_t *)(*p)); *p += sizeof(olsr_u16_t); }static inline void       pkt_get_u32(const olsr_u8_t **p, olsr_u32_t *var)         { *var = ntohl(*(olsr_u32_t *)(p));  *p += sizeof(olsr_u32_t); }static inline void        pkt_get_s8(const olsr_u8_t **p, olsr_8_t  *var)          { *var =       *(olsr_8_t *)(*p);    *p += sizeof(olsr_8_t); }static inline void       pkt_get_s16(const olsr_u8_t **p, olsr_16_t *var)          { *var = ntohs(*(olsr_16_t *)(*p));  *p += sizeof(olsr_16_t); }static inline void       pkt_get_s32(const olsr_u8_t **p, olsr_32_t *var)          { *var = ntohl(*(olsr_32_t *)(*p));  *p += sizeof(olsr_32_t); }static inline void    pkt_get_double(const olsr_u8_t **p, double *var)             { *var = me_to_double(**p);          *p += sizeof(olsr_u8_t); }static inline void pkt_get_ipaddress(const olsr_u8_t **p, union olsr_ip_addr *var) { COPY_IP(var, *p);                  *p += olsr_cnf->ipsize; }static inline void        pkt_get_lq(const olsr_u8_t **p, double *var)             { *var = (double)**p / 255.0;        *p += sizeof(olsr_u8_t); }static inline void        pkt_ignore_u8(const olsr_u8_t **p) { *p += sizeof(olsr_u8_t); }static inline void       pkt_ignore_u16(const olsr_u8_t **p) { *p += sizeof(olsr_u16_t); }static inline void       pkt_ignore_u32(const olsr_u8_t **p) { *p += sizeof(olsr_u32_t); }static inline void        pkt_ignore_s8(const olsr_u8_t **p) { *p += sizeof(olsr_8_t); }static inline void       pkt_ignore_s16(const olsr_u8_t **p) { *p += sizeof(olsr_16_t); }static inline void       pkt_ignore_s32(const olsr_u8_t **p) { *p += sizeof(olsr_32_t); }static inline void pkt_ignore_ipaddress(const olsr_u8_t **p) { *p += olsr_cnf->ipsize; }static inline void        pkt_put_u8(olsr_u8_t **p, const olsr_u8_t  var)         { *(olsr_u8_t *)(*p)  = var;        *p += sizeof(olsr_u8_t); }static inline void       pkt_put_u16(olsr_u8_t **p, const olsr_u16_t var)         { *(olsr_u16_t *)(*p) = htons(var); *p += sizeof(olsr_u16_t); }static inline void       pkt_put_u32(olsr_u8_t **p, const olsr_u32_t var)         { *(olsr_u32_t *)(*p) = htonl(var); *p += sizeof(olsr_u32_t); }static inline void        pkt_put_s8(olsr_u8_t **p, const olsr_8_t  var)          { *(olsr_8_t *)(*p)   = var;        *p += sizeof(olsr_8_t); }static inline void       pkt_put_s16(olsr_u8_t **p, const olsr_16_t var)          { *(olsr_16_t *)(*p)  = htons(var); *p += sizeof(olsr_16_t); }static inline void       pkt_put_s32(olsr_u8_t **p, const olsr_32_t var)          { *(olsr_32_t *)(*p)  = htonl(var); *p += sizeof(olsr_32_t); }static inline void    pkt_put_double(olsr_u8_t **p, const double var)             { **p = double_to_me(var);          *p += sizeof(olsr_u8_t); }static inline void pkt_put_ipaddress(olsr_u8_t **p, const union olsr_ip_addr var) { COPY_IP(*p, &var);                *p += olsr_cnf->ipsize; }static inline void        pkt_put_lq(olsr_u8_t **p, const double var)             { **p  = var * 255.0;               *p += sizeof(olsr_u8_t); }static voidcreate_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif){  struct link_entry *walker;  // initialize the static fields  lq_hello->comm.type = LQ_HELLO_MESSAGE;  lq_hello->comm.vtime = me_to_double(outif->valtimes.hello);  lq_hello->comm.size = 0;  COPY_IP(&lq_hello->comm.orig, &olsr_cnf->main_addr);  lq_hello->comm.ttl = 1;  lq_hello->comm.hops = 0;  lq_hello->comm.seqno = get_msg_seqno();  lq_hello->htime = outif->hello_etime;  lq_hello->will = olsr_cnf->willingness;  lq_hello->neigh = NULL;    // loop through the link set  for (walker = get_link_set(); walker != NULL; walker = walker->next)    {      // allocate a neighbour entry      struct lq_hello_neighbor *neigh = olsr_malloc(sizeof (struct lq_hello_neighbor), "Build LQ_HELLO");      // a) this neighbor interface IS NOT visible via the output interface      if(!COMP_IP(&walker->local_iface_addr, &outif->ip_addr))        neigh->link_type = UNSPEC_LINK;            // b) this neighbor interface IS visible via the output interface      else        neigh->link_type = lookup_link_status(walker);      // set the entry's link quality      neigh->link_quality = walker->loss_link_quality;      neigh->neigh_link_quality = walker->neigh_link_quality;      // set the entry's neighbour type      if(walker->neighbor->is_mpr)        neigh->neigh_type = MPR_NEIGH;      else if (walker->neighbor->status == SYM)        neigh->neigh_type = SYM_NEIGH;      else if (walker->neighbor->status == NOT_SYM)        neigh->neigh_type = NOT_NEIGH;        // set the entry's neighbour interface address      COPY_IP(&neigh->addr, &walker->neighbor_iface_addr);            // queue the neighbour entry      neigh->next = lq_hello->neigh;      lq_hello->neigh = neigh;    }}static voiddestroy_lq_hello(struct lq_hello_message *lq_hello){  struct lq_hello_neighbor *walker, *aux;  // loop through the queued neighbour entries and free them  for (walker = lq_hello->neigh; walker != NULL; walker = aux)    {      aux = walker->next;      free(walker);    }  lq_hello->neigh = NULL;}static voidcreate_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif){  int i;  static int ttl_list[] = { 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1, MAX_TTL-1, 0};  // remember that we have generated an LQ TC message; this is  // checked in net_output()  lq_tc_pending = OLSR_TRUE;  // initialize the static fields  lq_tc->comm.type = LQ_TC_MESSAGE;  lq_tc->comm.vtime = me_to_double(outif->valtimes.tc);  lq_tc->comm.size = 0;  COPY_IP(&lq_tc->comm.orig, &olsr_cnf->main_addr);  if (olsr_cnf->lq_fish > 0)  {    // Sven-Ola: Too lazy to find the different iface inits. This will do it too.    if (outif->ttl_index >= (int)(sizeof(ttl_list) / sizeof(ttl_list[0])))      outif->ttl_index = 0;        if (ttl_list[outif->ttl_index] == 0)      outif->ttl_index = 0;      lq_tc->comm.ttl = ttl_list[outif->ttl_index++];    OLSR_PRINTF(3, "Creating LQ TC with TTL %d.\n", lq_tc->comm.ttl);  }  else    lq_tc->comm.ttl = MAX_TTL;  lq_tc->comm.hops = 0;  lq_tc->comm.seqno = get_msg_seqno();  COPY_IP(&lq_tc->from, &olsr_cnf->main_addr);  lq_tc->ansn = get_local_ansn();  lq_tc->neigh = NULL;   // loop through all neighbours    for(i = 0; i < HASHSIZE; i++)    {      struct neighbor_entry *walker;      struct tc_mpr_addr    *neigh;      for(walker = neighbortable[i].next; walker != &neighbortable[i];          walker = walker->next)        {          struct link_entry *lnk;          // only consider symmetric neighbours          if(walker->status != SYM)            continue;          // TC redundancy == 1: only consider MPRs and MPR selectors          if (olsr_cnf->tc_redundancy == 1 && !walker->is_mpr &&              olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)            continue;          // TC redundancy == 0: only consider MPR selectors          if (olsr_cnf->tc_redundancy == 0 &&              olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)            continue;          // allocate a neighbour entry                    neigh = olsr_malloc(sizeof (struct tc_mpr_addr), "Build LQ_TC");          // set the entry's main address          COPY_IP(&neigh->address, &walker->neighbor_main_addr);          // set the entry's link quality          lnk = get_best_link_to_neighbor(&neigh->address);          if (lnk) {            neigh->link_quality = lnk->loss_link_quality;            neigh->neigh_link_quality = lnk->neigh_link_quality;          }          // queue the neighbour entry          neigh->next = lq_tc->neigh;          lq_tc->neigh = neigh;        }    }}static voiddestroy_lq_tc(struct lq_tc_message *lq_tc){  struct tc_mpr_addr *walker, *aux;  // loop through the queued neighbour entries and free them  for (walker = lq_tc->neigh; walker != NULL; walker = aux)    {      aux = walker->next;      free(walker);    }}static int common_size(void){  // return the size of the header shared by all OLSR messages  return (olsr_cnf->ip_version == AF_INET) ?    sizeof (struct olsr_header_v4) : sizeof (struct olsr_header_v6);}static void serialize_common(struct olsr_common *comm){  if (olsr_cnf->ip_version == AF_INET)    {      // serialize an IPv4 OLSR message header      struct olsr_header_v4 *olsr_head_v4 = (struct olsr_header_v4 *)msg_buffer;      olsr_head_v4->type = comm->type;      olsr_head_v4->vtime = double_to_me(comm->vtime);      olsr_head_v4->size = htons(comm->size);      COPY_IP(&olsr_head_v4->orig, &comm->orig);      olsr_head_v4->ttl = comm->ttl;      olsr_head_v4->hops = comm->hops;      olsr_head_v4->seqno = htons(comm->seqno);    }  else    {      // serialize an IPv6 OLSR message header      struct olsr_header_v6 *olsr_head_v6 = (struct olsr_header_v6 *)msg_buffer;      olsr_head_v6->type = comm->type;      olsr_head_v6->vtime = double_to_me(comm->vtime);      olsr_head_v6->size = htons(comm->size);      COPY_IP(&olsr_head_v6->orig, &comm->orig);      olsr_head_v6->ttl = comm->ttl;      olsr_head_v6->hops = comm->hops;      olsr_head_v6->seqno = htons(comm->seqno);    }}static voidserialize_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif){  int rem, size, req;  struct lq_hello_info_header *info_head;  struct lq_hello_neighbor *neigh;  unsigned char *buff;  int is_first;  int i;  // leave space for the OLSR header  int off = common_size();  // initialize the LQ_HELLO header  struct lq_hello_header *head = (struct lq_hello_header *)(msg_buffer + off);  head->reserved = 0;  head->htime = double_to_me(lq_hello->htime);  head->will = lq_hello->will;   // 'off' is the offset of the byte following the LQ_HELLO header  off += sizeof (struct lq_hello_header);  // our work buffer starts at 'off'...  buff = msg_buffer + off;  // ... that's why we start with a 'size' of 0 and subtract 'off' from  // the remaining bytes in the output buffer  size = 0;  rem = net_outbuffer_bytes_left(outif) - off;  // initially, we want to put at least an info header, an IP address,  // and the corresponding link quality into the message  // force signed comparison  if (rem < (int)(sizeof (struct lq_hello_info_header) + olsr_cnf->ipsize + 4))  {    net_output(outif);    rem = net_outbuffer_bytes_left(outif) - off;  }  info_head = NULL;  // iterate through all neighbor types ('i') and all link types ('j')  for (i = 0; i <= MAX_NEIGH; i++)     {      static const int LINK_ORDER[] = {SYM_LINK, UNSPEC_LINK, ASYM_LINK, LOST_LINK};      unsigned int j;      for(j = 0; j < sizeof(LINK_ORDER) / sizeof(LINK_ORDER[0]); j++)        {          is_first = 1;          // loop through neighbors          for (neigh = lq_hello->neigh; neigh != NULL; neigh = neigh->next)            {                if (neigh->neigh_type != i || neigh->link_type != LINK_ORDER[j])                continue;              // we need space for an IP address plus link quality              // information              req = olsr_cnf->ipsize + 4;              // no, we also need space for an info header, as this is the              // first neighbor with the current neighor type and link type              if (is_first != 0)                req += sizeof (struct lq_hello_info_header);              // we do not have enough space left              // force signed comparison

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -