/**
 *Insert a plc peer entry in the table
 *
 *@param main_addr the main address of the new node
 *
 *@return 0 if plc peer already exists 1 if inserted
 */
struct plc_peer_entry *
insert_plc_peer_neighbor(const union olsr_ip_addr *main_addr, unsigned char *mac)
{
  uint32_t hash;
  struct plc_peer_entry *new_peer;

  hash = olsr_ip_hashing(main_addr);

  /* Check if entry exists */

  for (new_peer = plc_peer_neighbors[hash].next; new_peer != &plc_peer_neighbors[hash]; new_peer = new_peer->next) {
    if (ipequal(&new_peer->plc_peer_main_addr, main_addr))
      return 0;
  }

  //olsr_printf(3, "inserting peer\n");

  new_peer = olsr_malloc(sizeof(struct plc_peer_entry), "New peer entry");

  /* Set address, willingness and status */
  new_peer->plc_peer_main_addr = *main_addr;
  memcpy(new_peer->plc_data.mac, mac, 6);

  /* Queue */
  QUEUE_ELEM(plc_peer_neighbors[hash], new_peer);
  table_size++;
  return 1;
}
int
delete_plc_peer_neighbor(const union olsr_ip_addr *peer_addr)
{
  uint32_t hash;
  struct plc_peer_entry *entry;

  //olsr_printf(3, "inserting neighbor\n");

  hash = olsr_ip_hashing(peer_addr);

  entry = plc_peer_neighbors[hash].next;

  /*
   * Find neighbor entry
   */
  while (entry != &plc_peer_neighbors[hash]) {
    if (ipequal(&entry->plc_peer_main_addr, peer_addr))
      break;

    entry = entry->next;
  }

  if (entry == &plc_peer_neighbors[hash])
    return 0;

   /* Dequeue */
  DEQUEUE_ELEM(entry);

  free(entry);
  table_size--;
  return 1;
}
示例#3
0
/**
 * Check if there is an interface or gateway change.
 */
bool
olsr_nh_change(const struct rt_nexthop *nh1, const struct rt_nexthop *nh2)
{
  if (!ipequal(&nh1->gateway, &nh2->gateway) || (nh1->iif_index != nh2->iif_index)) {
    return true;
  }
  return false;
}
示例#4
0
/**
 * Check if there is an interface or gateway change.
 */
olsr_bool
olsr_nh_change(const struct rt_nexthop *nh1, const struct rt_nexthop *nh2)
{
  if (!ipequal(&nh1->gateway, &nh2->gateway) ||
      (nh1->iif_index != nh2->iif_index)) {
    return OLSR_TRUE;
  }
  return OLSR_FALSE;
}
示例#5
0
void dev_send_init(void)
{
    union olsr_ip_addr* addr, mask;
    struct interface* ifs;

    //------------------------------
    // reset sereadmo iptable module
    //------------------------------
    dev_add_cmd(DEV_CMD_RESET_TC,NULL,NULL,0);


    //------------------
    // send local config
    //------------------

    //main addr (ie. addr used by olsrd in links for local node)
    addr = &olsr_cnf->main_addr;

    // retreive IP mask for the main addr
    for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
    {
        if(ipequal(addr,&ifs->ip_addr) != 0)
        {
            mask.v4.s_addr = ifs->int_netmask.sin_addr.s_addr;
            break;
        }
    }

    dev_add_cmd(DEV_CMD_SET_LOCAL_ADDR,addr,&mask,0);

    //----------------
    // send addr alias
    //----------------
    for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
    {
        if(ipequal(addr,&ifs->ip_addr) == 0)
        {
            mask.v4.s_addr = ifs->int_netmask.sin_addr.s_addr;
            dev_add_cmd(DEV_CMD_SET_ALIAS_ADDR,&ifs->ip_addr,&mask,0);
        }
    }

    dev_send();
}
示例#6
0
void
olsr_cleanup_hna(union olsr_ip_addr *orig) {
    struct hna_entry *hna;

    OLSR_FOR_ALL_HNA_ENTRIES(hna) {
        if (hna->networks.next != &hna->networks && ipequal(&hna->A_gateway_addr, orig)) {
            while (!olsr_delete_hna_net_entry(hna->networks.next));
        }
    }
    OLSR_FOR_ALL_HNA_ENTRIES_END(hna)
}
示例#7
0
struct ip_prefix_list *
ip_prefix_list_find(struct ip_prefix_list *list, const union olsr_ip_addr *net, uint8_t prefix_len)
{
    struct ip_prefix_list *h;
    for (h = list; h != NULL; h = h->next) {
        if (prefix_len == h->net.prefix_len && ipequal(net, &h->net.prefix)) {
            return h;
        }
    }
    return NULL;
}
示例#8
0
/**
 *Check if a two hop neighbor is reachable via a given
 *neighbor.
 *
 *@param neighbor neighbor-entry to check via
 *@param neighbor_main_address the addres of the two hop neighbor
 *to find.
 *
 *@return a pointer to the neighbor_2_list_entry struct
 *representing the two hop neighbor if found. NULL if not found.
 */
struct neighbor_2_list_entry *
olsr_lookup_my_neighbors(const struct neighbor_entry *neighbor, const union olsr_ip_addr *neighbor_main_address)
{
  struct neighbor_2_list_entry *entry;

  for (entry = neighbor->neighbor_2_list.next; entry != &neighbor->neighbor_2_list; entry = entry->next) {

    if (ipequal(&entry->neighbor_2->neighbor_2_addr, neighbor_main_address))
      return entry;

  }
  return NULL;
}
示例#9
0
int
olsr_delete_neighbor_table(const union olsr_ip_addr *neighbor_addr)
{  
  struct  neighbor_2_list_entry *two_hop_list, *two_hop_to_delete;
  olsr_u32_t                    hash;
  struct neighbor_entry         *entry;

  //printf("inserting neighbor\n");

  hash = olsr_ip_hashing(neighbor_addr);

  entry = neighbortable[hash].next;

  /*
   * Find neighbor entry
   */
  while(entry != &neighbortable[hash])
    {
      if(ipequal(&entry->neighbor_main_addr, neighbor_addr))
	break;
      
      entry = entry->next;
    }

  if(entry == &neighbortable[hash])
    return 0;


  two_hop_list = entry->neighbor_2_list.next;

  while (two_hop_list != &entry->neighbor_2_list) {
      two_hop_to_delete = two_hop_list;
      two_hop_list = two_hop_list->next;

      two_hop_to_delete->neighbor_2->neighbor_2_pointer--;
      olsr_delete_neighbor_pointer(two_hop_to_delete->neighbor_2,
                                   &entry->neighbor_main_addr);

      olsr_del_nbr2_list(two_hop_to_delete);
    }


  /* Dequeue */
  DEQUEUE_ELEM(entry);

  free(entry);

  changes_neighborhood = OLSR_TRUE;
  return 1;

}
示例#10
0
/**
 * Lookup a network entry in a networkentry list.
 *
 * @param nets the network list to look in
 * @param net the network to look for
 * @param prefixlen the prefix length
 *
 * @return the localized entry or NULL of not found
 */
struct hna_net *
olsr_lookup_hna_net(const struct hna_net *nets, const union olsr_ip_addr *net, uint8_t prefixlen)
{
    struct hna_net *tmp;

    /* Loop trough entrys */
    for (tmp = nets->next; tmp != nets; tmp = tmp->next) {
        if (tmp->hna_prefix.prefix_len == prefixlen && ipequal(&tmp->hna_prefix.prefix, net)) {
            return tmp;
        }
    }

    /* Not found */
    return NULL;
}
示例#11
0
/**
 * lookup a nodes position
 */
static char* lookup_position_latlon(union olsr_ip_addr *ip)
{
  int hash;
  struct db_entry *entry;
  struct list_node *list_head, *list_node;

  if (ipequal(ip, &olsr_cnf->main_addr)) {
    return my_latlon_str;
  }

  for (hash = 0; hash < HASHSIZE; hash++) {
      list_head = &latlon_list[hash];
      for (list_node = list_head->next; list_node != list_head;
           list_node = list_node->next) {

          entry = list2db(list_node);

      if (entry->names && ipequal(&entry->originator, ip)) {
        return entry->names->name;
      }
    }
  }
  return NULL;
}
示例#12
0
/**
 * Delete a two hop neighbor from a neighbors two hop neighbor list.
 *
 * @param neighbor the neighbor to delete the two hop neighbor from.
 * @param address the IP address of the two hop neighbor to delete.
 *
 * @return positive if entry deleted
 */
int
olsr_delete_neighbor_2_pointer(struct neighbor_entry *neighbor, union olsr_ip_addr *address)
{
  struct neighbor_2_list_entry *nbr2_list;
  
  nbr2_list = neighbor->neighbor_2_list.next;

  while (nbr2_list != &neighbor->neighbor_2_list) {
    if (ipequal(&nbr2_list->neighbor_2->neighbor_2_addr, address)) {
      olsr_del_nbr2_list(nbr2_list);
      return 1;	  
    }
    nbr2_list = nbr2_list->next;      
  }
  return 0;
}
示例#13
0
文件: net_olsr.c 项目: OLSR/olsrd
bool
olsr_validate_address(const union olsr_ip_addr *adr)
{
  const struct deny_address_entry *deny_entry;

  for (deny_entry = deny_entries; deny_entry != NULL; deny_entry = deny_entry->next) {
    if (ipequal(adr, &deny_entry->addr)) {
      struct ipaddr_str buf;
      OLSR_PRINTF(1, "Validation of address %s failed!\n", olsr_ip_to_string(&buf, adr));
      return false;
    }
    if (&deny_entry->addr == &olsr_cnf->main_addr)
      break;
  }
  return true;
}
示例#14
0
/**
 * Lookup a gateway entry
 *
 * @param gw the address of the gateway
 * @return the located entry or NULL if not found
 */
struct hna_entry *
olsr_lookup_hna_gw(const union olsr_ip_addr *gw)
{
    struct hna_entry *tmp_hna;
    uint32_t hash = olsr_ip_hashing(gw);

    /* Check for registered entry */

    for (tmp_hna = hna_set[hash].next; tmp_hna != &hna_set[hash]; tmp_hna = tmp_hna->next) {
        if (ipequal(&tmp_hna->A_gateway_addr, gw)) {
            return tmp_hna;
        }
    }

    /* Not found */
    return NULL;
}
示例#15
0
/**
 * Add a new tc_entry to the tc tree
 *
 * @param adr (last)adr address of the entry
 * @return a pointer to the created entry
 */
static struct tc_entry *
olsr_add_tc_entry(union olsr_ip_addr *adr)
{
#ifdef DEBUG
  struct ipaddr_str buf;
#endif /* DEBUG */
  struct tc_entry *tc;

  /*
   * Safety net against loss of the last main IP address.
   */
  if (ipequal(&olsr_cnf->main_addr, &all_zero)) {
    return NULL;
  }
#ifdef DEBUG
  OLSR_PRINTF(1, "TC: add entry %s\n", olsr_ip_to_string(&buf, adr));
#endif /* DEBUG */

  tc = olsr_cookie_malloc(tc_mem_cookie);
  if (!tc) {
    return NULL;
  }

  /* Fill entry */
  tc->addr = *adr;
  tc->vertex_node.key = &tc->addr;

  /*
   * Insert into the global tc tree.
   */
  avl_insert(&tc_tree, &tc->vertex_node, AVL_DUP_NO);
  olsr_lock_tc_entry(tc);

  /*
   * Initialize subtrees for edges and prefixes.
   */
  avl_init(&tc->edge_tree, avl_comp_default);
  avl_init(&tc->prefix_tree, avl_comp_prefix_default);

  /*
   * Add a rt_path for ourselves.
   */
  olsr_insert_routing_table(adr, olsr_cnf->maxplen, adr, OLSR_RT_ORIGIN_INT);

  return tc;
}
/**
 *Lookup a peer entry in the plc_peer_neighbors based on an address.
 *
 *@param dst the IP address of the peer to look up
 *
 *@return a pointer to the neighbor struct registered on the given
 *address. NULL if not found.
 */
struct plc_peer_entry *
lookup_plc_peer_by_ip(const union olsr_ip_addr *dst)
{
  struct plc_peer_entry *entry;
  uint32_t hash = olsr_ip_hashing(dst);

  //olsr_printf(3, "\nLookup %s\n", olsr_ip_to_string(&buf, dst));
  for (entry = plc_peer_neighbors[hash].next; entry != &plc_peer_neighbors[hash]; entry = entry->next) {
    //olsr_printf(3, "Checking %s\n", olsr_ip_to_string(&buf, &entry->plc_peer_main_addr));
    if (ipequal(&entry->plc_peer_main_addr, dst))
      return entry;

  }
  //olsr_printf(3, "NOPE\n\n");

  return NULL;

}
示例#17
0
/**
 *Lookup an entry in the MPR selector table
 *based on address
 *
 *@param addr the addres to check for
 *
 *@return a pointer to the entry or NULL
 */
struct mpr_selector *
olsr_lookup_mprs_set(const union olsr_ip_addr *addr)
{
  struct mpr_selector *mprs;

  if (addr == NULL)
    return NULL;
  //OLSR_PRINTF(1, "MPRS: Lookup....");

  for (mprs = mprs_list.next; mprs != &mprs_list; mprs = mprs->next) {
    if (ipequal(&mprs->MS_main_addr, addr)) {
      //OLSR_PRINTF(1, "MATCH\n");
      return mprs;
    }
  }
  //OLSR_PRINTF(1, "NO MACH\n");
  return NULL;
}
示例#18
0
/**
 *Lookup a neighbor entry in the neighbortable based on an address.
 *
 *@param dst the IP address of the neighbor to look up
 *
 *@return a pointer to the neighbor struct registered on the given
 *address. NULL if not found.
 */
struct neighbor_entry *
olsr_lookup_neighbor_table_alias(const union olsr_ip_addr *dst)
{
  struct neighbor_entry *entry;
  uint32_t hash = olsr_ip_hashing(dst);

  //printf("\nLookup %s\n", olsr_ip_to_string(&buf, dst));
  for (entry = neighbortable[hash].next; entry != &neighbortable[hash]; entry = entry->next) {
    //printf("Checking %s\n", olsr_ip_to_string(&buf, &entry->neighbor_main_addr));
    if (ipequal(&entry->neighbor_main_addr, dst))
      return entry;

  }
  //printf("NOPE\n\n");

  return NULL;

}
/**
 *
 * Calculate the kernel route flags.
 * Called before enqueuing a change/delete operation
 *
 */
uint8_t
olsr_rt_flags(const struct rt_entry *rt)
{
  const struct rt_nexthop *nh;
  uint8_t flags = RTF_UP;

  /* destination is host */
  if (rt->rt_dst.prefix_len == olsr_cnf->maxplen) {
    flags |= RTF_HOST;
  }

  nh = olsr_get_nh(rt);

  if (!ipequal(&rt->rt_dst.prefix, &nh->gateway)) {
    flags |= RTF_GATEWAY;
  }

  return flags;
}
示例#20
0
/**
 *Insert a neighbor entry in the neighbor table
 *
 *@param main_addr the main address of the new node
 *
 *@return 0 if neighbor already exists 1 if inserted
 */
struct neighbor_entry *
olsr_insert_neighbor_table(const union olsr_ip_addr *main_addr)
{
  olsr_u32_t             hash;
  struct neighbor_entry  *new_neigh;
  
  hash = olsr_ip_hashing(main_addr);

  /* Check if entry exists */
  
  for(new_neigh = neighbortable[hash].next;
      new_neigh != &neighbortable[hash];
      new_neigh = new_neigh->next)
    {
      if(ipequal(&new_neigh->neighbor_main_addr, main_addr))
	return new_neigh;
    }
  
  //printf("inserting neighbor\n");
  
  new_neigh = olsr_malloc(sizeof(struct neighbor_entry), "New neighbor entry");
  
  /* Set address, willingness and status */
  new_neigh->neighbor_main_addr = *main_addr;
  new_neigh->willingness = WILL_NEVER;
  new_neigh->status = NOT_SYM;

  new_neigh->neighbor_2_list.next = &new_neigh->neighbor_2_list;
  new_neigh->neighbor_2_list.prev = &new_neigh->neighbor_2_list;
  
  new_neigh->linkcount = 0;
  new_neigh->is_mpr = OLSR_FALSE;
  new_neigh->was_mpr = OLSR_FALSE;

  /* Queue */
  QUEUE_ELEM(neighbortable[hash], new_neigh);

  return new_neigh;
}
示例#21
0
/**
 * Enqueue a route on a kernel add/chg/del queue.
 */
static void
olsr_enqueue_rt(struct list_node *head_node, struct rt_entry *rt)
{
  const struct rt_nexthop *nh;

  /* if this node is already on some changelist we are done */
  if (list_node_on_list(&rt->rt_change_node)) {
    return;
  }

  /*
   * For easier route dependency tracking we enqueue nexthop routes
   * at the head of the queue and non-nexthop routes at the tail of the queue.
   */
  nh = olsr_get_nh(rt);

  if (ipequal(&rt->rt_dst.prefix, &nh->gateway)) {
    list_add_after(head_node, &rt->rt_change_node);
  } else {
    list_add_before(head_node, &rt->rt_change_node);
  }
}
示例#22
0
/**
 * The main ip address has changed.
 * Do the needful.
 */
void
olsr_change_myself_tc(void)
{
  if (tc_myself) {

    /*
     * Check if there was a change.
     */
    if (ipequal(&tc_myself->addr, &olsr_cnf->main_addr)) {
      return;
    }

    /*
     * Flush our own tc_entry.
     */
    olsr_delete_tc_entry(tc_myself);
  }

  /*
   * The old entry for ourselves is gone, generate a new one and trigger SPF.
   */
  tc_myself = olsr_add_tc_entry(&olsr_cnf->main_addr);
  changes_topology = true;
}
示例#23
0
int
ip_prefix_list_remove(struct ip_prefix_list **list, const union olsr_ip_addr *net, uint8_t prefix_len)
{
    struct ip_prefix_list *h = *list, *prev = NULL;

    while (h != NULL) {
        if (ipequal(net, &h->net.prefix) && h->net.prefix_len == prefix_len) {
            /* Dequeue */
            if (prev == NULL) {
                *list = h->next;
            } else {
                prev->next = h->next;
            }
            free(h);

            /* update gateway flags */
            update_has_gateway_fields();
            return 1;
        }
        prev = h;
        h = h->next;
    }
    return 0;
}
示例#24
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;
}
示例#25
0
void
olsr_remove_interface(struct olsr_if * iface)
{
  struct interface *ifp, *tmp_ifp;
  ifp = iface->interf;

  OLSR_PRINTF(1, "Removing interface %s (%d)\n", iface->name, ifp->if_index);
  olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);

  olsr_delete_link_entry_by_ip(&ifp->ip_addr);

  /*
   *Call possible ifchange functions registered by plugins
   */
  olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_REMOVE);

  /* cleanup routes over this interface */
  olsr_delete_interface_routes(ifp->if_index);

  /* Dequeue */
  if (ifp == ifnet) {
    ifnet = ifp->int_next;
  } else {
    tmp_ifp = ifnet;
    while (tmp_ifp->int_next != ifp) {
      tmp_ifp = tmp_ifp->int_next;
    }
    tmp_ifp->int_next = ifp->int_next;
  }

  /* Remove output buffer */
  net_remove_buffer(ifp);

  /* Check main addr */
  /* deactivated to prevent change of originator IP */
#if 0
  if (ipequal(&olsr_cnf->main_addr, &ifp->ip_addr)) {
    if (ifnet == NULL) {
      /* No more interfaces */
      memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
      OLSR_PRINTF(1, "No more interfaces...\n");
    } else {
      struct ipaddr_str buf;
      olsr_cnf->main_addr = ifnet->ip_addr;
      OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
      olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
    }
  }
#endif /* 0 */
  /*
   * Deregister functions for periodic message generation
   */
  olsr_stop_timer(ifp->hello_gen_timer);
  olsr_stop_timer(ifp->tc_gen_timer);
  olsr_stop_timer(ifp->mid_gen_timer);
  olsr_stop_timer(ifp->hna_gen_timer);

  iface->configured = 0;
  iface->interf = NULL;

  /* Close olsr socket */
  remove_olsr_socket(ifp->olsr_socket, &olsr_input, NULL);
  close(ifp->olsr_socket);

  remove_olsr_socket(ifp->send_socket, &olsr_input, NULL);
  close(ifp->send_socket);

  /* Free memory */
  free(ifp->int_name);
  free(ifp);

  if ((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces)) {
    olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
    olsr_exit("No more active interfaces - exiting.\n", EXIT_FAILURE);
  }
}
示例#26
0
文件: Bmf.c 项目: Dany3R9/Proj
/* -------------------------------------------------------------------------
 * Function   : BmfTunPacketCaptured
 * Description: Handle an IP packet, captured outgoing on the tuntap interface
 * Input      : encapsulationUdpData - space for the encapsulation header, followed by
 *                the captured outgoing IP packet
 * Output     : none
 * Return     : none
 * Data Used  : none
 * Notes      : The packet is assumed to be captured on a socket of family
 *              PF_PACKET and type SOCK_DGRAM (cooked).
 * ------------------------------------------------------------------------- */
static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData)
{
  union olsr_ip_addr srcIp;
  union olsr_ip_addr dstIp;
  union olsr_ip_addr broadAddr;
  struct TBmfInterface* walker;
  unsigned char* ipPacket;
  u_int16_t ipPacketLen;
  struct ip* ipHeader;
  u_int32_t crc32;
  struct TEncapHeader* encapHdr;
#ifndef NODEBUG
  struct ipaddr_str srcIpBuf, dstIpBuf;
#endif
  ipPacket = GetIpPacket(encapsulationUdpData);
  ipPacketLen = GetIpTotalLength(ipPacket);
  ipHeader = GetIpHeader(encapsulationUdpData);

  dstIp.v4 = ipHeader->ip_dst;
  broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);

  /* Only forward multicast packets. If configured, also forward local broadcast packets */
  if (IsMulticast(&dstIp) ||
      (EnableLocalBroadcast != 0 && ipequal(&dstIp, &broadAddr)))
  {
    /* continue */
  }
  else
  {
    return;
  }

  srcIp.v4 = ipHeader->ip_src;

  OLSR_PRINTF(
    8,
    "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n",
    PLUGIN_NAME_SHORT,
    (long)ipPacketLen,
    EtherTunTapIfName,
    olsr_ip_to_string(&srcIpBuf, &srcIp),
    olsr_ip_to_string(&dstIpBuf, &dstIp));

  /* Calculate packet fingerprint */
  crc32 = PacketCrc32(ipPacket, ipPacketLen);

  /* Check if this packet was seen recently */
  if (CheckAndMarkRecentPacket(crc32))
  {
    OLSR_PRINTF(
      8,
      "%s: --> discarding: packet is duplicate\n",
      PLUGIN_NAME_SHORT);
    return;
  }

  /* Compose encapsulation header */
  encapHdr = (struct TEncapHeader*) encapsulationUdpData;
  memset (encapHdr, 0, ENCAP_HDR_LEN);
  encapHdr->type = BMF_ENCAP_TYPE;
  encapHdr->len = BMF_ENCAP_LEN;
  encapHdr->reserved = 0;
  encapHdr->crc32 = htonl(crc32);

  /* Check with each network interface what needs to be done on it */
  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
  {
    /* Is the forwarding interface OLSR-enabled? */
    if (walker->olsrIntf != NULL)
    {
      /* On an OLSR interface: encapsulate and forward packet. */
      EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL);
    }
    else
    {
      /* On a non-OLSR interface: what to do?
       * Answer 1: nothing. Multicast routing between non-OLSR interfaces
       * is to be done by other protocols (e.g. PIM, DVMRP).
       * Answer 2 (better): Forward it. */
      ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded from non-OLSR to non-OLSR interface");
    } /* if */
  } /* for */
} /* BmfTunPacketCaptured */
示例#27
0
文件: Bmf.c 项目: Dany3R9/Proj
/* -------------------------------------------------------------------------
 * Function   : BmfPacketCaptured
 * Description: Handle a captured IP packet
 * Input      : intf - the network interface on which the packet was captured
 *              sllPkttype - the type of packet. Either PACKET_OUTGOING,
 *                PACKET_BROADCAST or PACKET_MULTICAST.
 *              encapsulationUdpData - space for the encapsulation header, followed by
 *                the captured IP packet
 * Output     : none
 * Return     : none
 * Data Used  : BmfInterfaces
 * Notes      : The IP packet is assumed to be captured on a socket of family
 *              PF_PACKET and type SOCK_DGRAM (cooked).
 * ------------------------------------------------------------------------- */
static void BmfPacketCaptured(
  struct TBmfInterface* intf,
  unsigned char sllPkttype,
  unsigned char* encapsulationUdpData)
{
  union olsr_ip_addr src; /* Source IP address in captured packet */
  union olsr_ip_addr dst; /* Destination IP address in captured packet */
  union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
  struct TBmfInterface* walker;
  int isFromOlsrIntf;
  int isFromOlsrNeighbor;
  int iAmMpr;
  unsigned char* ipPacket; /* The captured IP packet... */
  u_int16_t ipPacketLen; /* ...and its length */
  struct ip* ipHeader; /* The IP header inside the captured IP packet */
  u_int32_t crc32;
  struct TEncapHeader* encapHdr;
#ifndef NODEBUG
  struct ipaddr_str srcBuf, dstBuf;
#endif
  ipHeader = GetIpHeader(encapsulationUdpData);

  dst.v4 = ipHeader->ip_dst;

  /* Only forward multicast packets. If configured, also forward local broadcast packets */
  if (IsMulticast(&dst) ||
      (EnableLocalBroadcast != 0 && ipequal(&dst, &intf->broadAddr)))
  {
    /* continue */
  }
  else
  {
    return;
  }

  ipPacket = GetIpPacket(encapsulationUdpData);

  /* Don't forward fragments of IP packets: there is no way to distinguish fragments
   * of BMF encapsulation packets from other fragments.
   * Well yes, there is the IP-ID, which can be kept in a list to relate a fragment
   * to earlier sent BMF packets, but... sometimes the second fragment comes in earlier
   * than the first fragment, so that the list is not yet up to date and the second
   * fragment is not recognized as a BMF packet.
   * Also, don't forward OLSR packets (UDP port 698) and BMF encapsulated packets */
  if (IsIpFragment(ipPacket) || IsOlsrOrBmfPacket(ipPacket))
  {
    return;
  }

  /* Increase counter */
  intf->nBmfPacketsRx++;

  /* Check if the frame is captured on an OLSR-enabled interface */
  isFromOlsrIntf = (intf->olsrIntf != NULL);

  /* Retrieve the length of the captured packet */
  ipPacketLen = GetIpTotalLength(ipPacket);

  src.v4 = ipHeader->ip_src;

  OLSR_PRINTF(
    8,
    "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n",
    PLUGIN_NAME_SHORT,
    sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming",
    (long)ipPacketLen,
    isFromOlsrIntf ? "OLSR" : "non-OLSR",
    intf->ifName,
    olsr_ip_to_string(&srcBuf, &src),
    olsr_ip_to_string(&dstBuf, &dst));

  /* Lookup main address of source in the MID table of OLSR */
  origIp = MainAddressOf(&src);

  /* Calculate packet fingerprint */
  crc32 = PacketCrc32(ipPacket, ipPacketLen);

  /* Check if this packet was seen recently */
  if (CheckAndMarkRecentPacket(crc32))
  {
    /* Increase counter */
    intf->nBmfPacketsRxDup++;

    OLSR_PRINTF(
      8,
      "%s: --> discarding: packet is duplicate\n",
      PLUGIN_NAME_SHORT);
    return;
  }

  /* Compose encapsulation header */
  encapHdr = (struct TEncapHeader*) encapsulationUdpData;
  memset (encapHdr, 0, ENCAP_HDR_LEN);
  encapHdr->type = BMF_ENCAP_TYPE;
  encapHdr->len = BMF_ENCAP_LEN;
  encapHdr->reserved = 0;
  encapHdr->crc32 = htonl(crc32);

  /* Check if the frame is captured on an OLSR interface from an OLSR neighbor.
   * TODO: get_best_link_to_neighbor() may be very CPU-expensive, a simpler call
   * would do here (something like 'get_any_link_to_neighbor()'). */
  isFromOlsrNeighbor =
    (isFromOlsrIntf /* The frame is captured on an OLSR interface... */
    && get_best_link_to_neighbor(origIp) != NULL); /* ...from an OLSR neighbor */ 

  /* Check with OLSR if I am MPR for that neighbor */
  iAmMpr = olsr_lookup_mprs_set(origIp) != NULL;

  /* Check with each network interface what needs to be done on it */
  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
  {
    /* Is the forwarding interface OLSR-enabled? */
    int isToOlsrIntf = (walker->olsrIntf != NULL);

    /* Depending on certain conditions, we decide whether or not to forward
     * the packet, and if it is forwarded, in which form (encapsulated
     * or not, TTL decreased or not). These conditions are:
     * - is the packet is coming in on an OLSR interface or not? (isFromOlsrIntf)
     * - is the packet going out on an OLSR interface or not? (isToOlsrIntf)
     * - if the packet if coming in on an OLSR interface:
     *   - is the node that forwarded the packet my OLSR-neighbor? (isFromOlsrNeighbor)
     *   - has the node that forwarded the packet selected me as MPR? (iAmMpr)
     *
     * Based on these conditions, the following cases can be distinguished:
     *
     * - Case 1: Packet coming in on an OLSR interface. What to
     *   do with it on an OLSR interface?
     *   Answer:
     *   - Case 1.1: If the forwarding node is an OLSR neighbor that has *not*
     *     selected me as MPR: don't forward the packet.
     *   - Case 1.2: If the forwarding node is an OLSR neighbor that has selected
     *     me as MPR: encapsulate and forward the packet.
     *   - Case 1.3: If the forwarding node is not an OLSR neighbor: encapsulate
     *     and forward the packet.
     *     NOTE: Case 1.3 is a special case. In the perfect world, we expect to
     *     see only OLSR-neighbors on OLSR-enabled interfaces. Sometimes, however,
     *     ignorant users will connect a host not running OLSR, to a LAN in
     *     which there are hosts running OLSR. Of course these ignorant users,
     *     expecting magic, want to see their multicast packets being forwarded
     *     through the network.
     *
     * - Case 2: Packet coming in on an OLSR interface. What to do with it on a
     *   non-OLSR interface?
     *   Answer: Forward it.
     *
     * - Case 3: Packet coming in on a non-OLSR interface. What to
     *   do with it on an OLSR interface?
     *   Answer: Encapsulate and forward it.
     *
     * - Case 4: Packet coming in on non-OLSR interface. What to do with it on a
     *   non-OLSR interface?
     *   Answer 1: nothing. Multicast routing between non-OLSR interfaces
     *   is to be done by other protocols (e.g. PIM, DVMRP).
     *   Answer 2 (better): Forward it.
     */

    if (isFromOlsrIntf && isToOlsrIntf)
    {
      /* Case 1: Forward from an OLSR interface to an OLSR interface */

      if (isFromOlsrNeighbor && !iAmMpr)
      {
        /* Case 1.1 */
        {
#ifndef NODEBUG
          struct ipaddr_str buf;
#endif
          OLSR_PRINTF(
            8,
            "%s: --> not encap-forwarding on \"%s\": I am not selected as MPR by neighbor %s\n",
            PLUGIN_NAME_SHORT,
            walker->ifName,
            olsr_ip_to_string(&buf, &src));
        }    
      }
      else if (sllPkttype == PACKET_OUTGOING && intf == walker)
      {
        OLSR_PRINTF(
          8,
          "%s: --> not encap-forwarding on \"%s\": pkt was captured on that interface\n",
          PLUGIN_NAME_SHORT,
          walker->ifName);
      }
      else
      {
        /* Case 1.2 and 1.3 */
        EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL);
      }
    } /* if (isFromOlsrIntf && isToOlsrIntf) */

    else if (isFromOlsrIntf && !isToOlsrIntf)
    {
      /* Case 2: Forward from OLSR interface to non-OLSR interface */
      ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded to non-OLSR interface");
    } /* else if (isFromOlsrIntf && !isToOlsrIntf) */

    else if (!isFromOlsrIntf && isToOlsrIntf)
    {
      /* Case 3: Forward from a non-OLSR interface to an OLSR interface.
       * Encapsulate and forward packet. */
      EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL);
    } /* else if (!isFromOlsrIntf && isToOlsrIntf) */

    else
    {
      /* Case 4: Forward from non-OLSR interface to non-OLSR interface. */

      /* Don't forward on interface on which packet was received */
      if (intf == walker)
      {
        OLSR_PRINTF(
          8,
          "%s: --> not forwarding on \"%s\": pkt was captured on that interface\n",
          PLUGIN_NAME_SHORT,
          walker->ifName);
      }

      else
      {
        ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded from non-OLSR to non-OLSR interface");
      } /* if (intf == walker) */
    } /* if */
  } /* for */
} /* BmfPacketCaptured */
示例#28
0
int
olsrd_sanity_check_cnf(struct olsrd_config *cnf)
{
  struct olsr_if *in = cnf->interfaces;
  struct if_config_options *io;

  /* Debug level */
  if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
    fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
    return -1;
  }

  /* IP version */
  if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
    fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
    return -1;
  }

  /* TOS range */
  if (cnf->tos > MAX_TOS) {
    fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
    return -1;
  }

  /* TOS ECN */
  if (cnf->tos & 0x03) {
    fprintf(stderr, "TOS %d has set ECN bits, not allowed\n", cnf->tos);
    return -1;
  }

  if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
    fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
    return -1;
  }

  /* Hysteresis */
  if (cnf->use_hysteresis == true) {
    if (cnf->hysteresis_param.scaling < (float)MIN_HYST_PARAM || cnf->hysteresis_param.scaling > (float)MAX_HYST_PARAM) {
      fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", (double)cnf->hysteresis_param.scaling);
      return -1;
    }

    if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
      fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", (double)cnf->hysteresis_param.thr_high,
    		  (double)cnf->hysteresis_param.thr_low);
      return -1;
    }

    if (cnf->hysteresis_param.thr_high < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > (float)MAX_HYST_PARAM) {
      fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_high);
      return -1;
    }

    if (cnf->hysteresis_param.thr_low < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > (float)MAX_HYST_PARAM) {
      fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_low);
      return -1;
    }
  }

  /* Pollrate */
  if (cnf->pollrate < (float)MIN_POLLRATE || cnf->pollrate > (float)MAX_POLLRATE) {
    fprintf(stderr, "Pollrate %0.2f is not allowed\n", (double)cnf->pollrate);
    return -1;
  }

  /* NIC Changes Pollrate */

  if (cnf->nic_chgs_pollrate < (float)MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > (float)MAX_NICCHGPOLLRT) {
    fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", (double)cnf->nic_chgs_pollrate);
    return -1;
  }

  /* TC redundancy */
  if (cnf->tc_redundancy != 2) {
    fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. "
        "It was discovered late in the stable tree development and cannot "
        "be solved without a difficult change in the dijkstra code. "
        "Feel free to contact the olsr-user mailinglist "
        "(http://www.olsr.org/?q=mailing-lists) to learn more "
        "about the problem. The next version of OLSR will have working "
        "tc-redundancy again.\n");
    return -1;
  }

  /* MPR coverage */
  if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
    fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
    return -1;
  }

  /* Link Q and hysteresis cannot be activated at the same time */
  if (cnf->use_hysteresis == true && cnf->lq_level) {
    fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
    return -1;
  }

  /* Link quality level */
  if (cnf->lq_level != 0 && cnf->lq_level != 2) {
    fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
    return -1;
  }

  /* Link quality window size */
  if (cnf->lq_level && (cnf->lq_aging < (float)MIN_LQ_AGING || cnf->lq_aging > (float)MAX_LQ_AGING)) {
    fprintf(stderr, "LQ aging factor %f is not allowed\n", (double)cnf->lq_aging);
    return -1;
  }

  /* NAT threshold value */
  if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1f || cnf->lq_nat_thresh > 1.0f)) {
    fprintf(stderr, "NAT threshold %f is not allowed\n", (double)cnf->lq_nat_thresh);
    return -1;
  }

#ifdef __linux__
#if !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION
#error "Both LINUX_VERSION_CODE and KERNEL_VERSION need to be defined"
#else /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) {
    fprintf(stderr, "Smart gateways are not supported for linux kernel < 2.6.24 and ipv6\n");
    return -1;
  }
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
#endif /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */

  /* this rtpolicy settings are also currently only used in Linux */
  if (olsrd_sanity_check_rtpolicy(cnf)) {
    return -1;
  }

#endif /* __linux__ */

  if (in == NULL) {
    fprintf(stderr, "No interfaces configured!\n");
    return -1;
  }

  if (cnf->min_tc_vtime < 0.0f) {
    fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
    return -1;
  }
  if (cnf->min_tc_vtime > 0.0f) {
	  fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
  }

#ifdef __linux__
  if ((cnf->smart_gw_use_count < MIN_SMARTGW_USE_COUNT_MIN) || (cnf->smart_gw_use_count > MAX_SMARTGW_USE_COUNT_MAX)) {
    fprintf(stderr, "Error, bad gateway use count %d, outside of range [%d, %d]\n",
        cnf->smart_gw_use_count, MIN_SMARTGW_USE_COUNT_MIN, MAX_SMARTGW_USE_COUNT_MAX);
    return -1;
  }

  if (cnf->smart_gw_use_count > 1) {
    struct sgw_egress_if * sgwegressif = cnf->smart_gw_egress_interfaces;

    if (!cnf->smart_gw_policyrouting_script) {
      fprintf(stderr, "Error, no policy routing script configured in multi-gateway mode\n");
      return -1;
    }

    {
      struct stat statbuf;

      int r = stat(cnf->smart_gw_policyrouting_script, &statbuf);
      if (r) {
        fprintf(stderr, "Error, policy routing script not found: %s\n", strerror(errno));
        return -1;
      }

      if (!S_ISREG(statbuf.st_mode)) {
        fprintf(stderr, "Error, policy routing script not a regular file\n");
        return -1;
      }

      if (statbuf.st_uid) {
        fprintf(stderr, "Error, policy routing script must be owned by root\n");
        return -1;
      }

      if (!(statbuf.st_mode & (S_IRUSR | S_IXUSR))) {
        fprintf(stderr, "Error, policy routing script is not executable\n");
        return -1;
      }
    }

    /* egress interface(s) must be set */
    if (!sgwegressif) {
      fprintf(stderr, "Error, no egress interfaces configured in multi-gateway mode\n");
      return -1;
    }

    /* an egress interface must not be an OLSR interface */
    while (sgwegressif) {
      struct olsr_if * olsrif = cnf->interfaces;
      while (olsrif) {
        if (!strcmp(olsrif->name, sgwegressif->name)) {
          fprintf(stderr, "Error, egress interface %s already is an OLSR interface\n", sgwegressif->name);
          return -1;
        }
        olsrif = olsrif->next;
      }
      cnf->smart_gw_egress_interfaces_count++;
      sgwegressif = sgwegressif->next;
    }

    if (cnf->smart_gw_egress_interfaces_count > MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX) {
      fprintf(stderr, "Error, egress interface count %u not in range [1, %u]\n",
          cnf->smart_gw_egress_interfaces_count, MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX);
      return -1;
    }

    {
      uint8_t egressLow = cnf->smart_gw_mark_offset_egress;
      uint8_t egressHigh = egressLow + cnf->smart_gw_egress_interfaces_count - 1;
      uint8_t tunnelsLow = cnf->smart_gw_mark_offset_tunnels;
      uint8_t tunnelsHigh = tunnelsLow + cnf->smart_gw_use_count - 1;
      bool overlap = false;

      /* check that the egress interface marks range does not overflow */
      if (egressLow > (UINT8_MAX - cnf->smart_gw_egress_interfaces_count)) {
        fprintf(stderr, "Error, egress interface mark offset %u together with egress interface count %u overflows range [0, %u]\n",
            egressLow, cnf->smart_gw_egress_interfaces_count, UINT8_MAX);
        return -1;
      }

      /* check that the tunnel interface marks range does not overflow */
      if (tunnelsLow > (UINT8_MAX - cnf->smart_gw_use_count)) {
        fprintf(stderr, "Error, tunnel interface mark offset %u together with use count %u overflows range [0, %u]\n",
            tunnelsLow, cnf->smart_gw_use_count, UINT8_MAX);
        return -1;
      }

      /* check that the egress and tunnel marks ranges do not overlap */
      overlap =            ((tunnelsLow <= egressLow)   && (egressLow   <= tunnelsHigh));
      overlap = overlap || ((tunnelsLow <= egressHigh)  && (egressHigh  <= tunnelsHigh));
      overlap = overlap || ((egressLow  <= tunnelsLow)  && (tunnelsLow  <= egressHigh));
      overlap = overlap || ((egressLow  <= tunnelsHigh) && (tunnelsHigh <= egressHigh));
      if (overlap) {
        fprintf(stderr, "Error, egress interface mark range [%u, %u] overlaps with tunnel interface mark range [%u, %u]\n",
            egressLow, egressHigh, tunnelsLow, tunnelsHigh);
        return -1;
      }
    }
  }

  if (cnf->smart_gw_period < MIN_SMARTGW_PERIOD || cnf->smart_gw_period > MAX_SMARTGW_PERIOD) {
    fprintf(stderr, "Error, bad gateway period: %d msec (should be %d-%d)\n",
        cnf->smart_gw_period, MIN_SMARTGW_PERIOD, MAX_SMARTGW_PERIOD);
    return -1;
  }
  if (cnf->smart_gw_stablecount < MIN_SMARTGW_STABLE || cnf->smart_gw_stablecount > MAX_SMARTGW_STABLE) {
    fprintf(stderr, "Error, bad gateway stable count: %d (should be %d-%d)\n",
        cnf->smart_gw_stablecount, MIN_SMARTGW_STABLE, MAX_SMARTGW_STABLE);
    return -1;
  }
  if (((cnf->smart_gw_thresh < MIN_SMARTGW_THRES) || (cnf->smart_gw_thresh > MAX_SMARTGW_THRES)) && (cnf->smart_gw_thresh != 0)) {
    fprintf(stderr, "Smart gateway threshold %d is not allowed (should be %d-%d)\n", cnf->smart_gw_thresh,
            MIN_SMARTGW_THRES, MAX_SMARTGW_THRES);
    return -1;
  }

  /* no checks are needed on:
   * - cnf->smart_gw_weight_exitlink_up
   * - cnf->smart_gw_weight_exitlink_down
   * - cnf->smart_gw_weight_etx
   * - cnf->smart_gw_divider_etx
   */

  if (cnf->smart_gw_type >= GW_UPLINK_CNT) {
    fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type);
    return -1;
  }
  if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) {
    fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n",
        cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
    return -1;
  }
  if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) {
    fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n",
        cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
    return -1;
  }
#endif /* __linux__ */

  if (cnf->interface_defaults == NULL) {
    /* get a default configuration if the user did not specify one */
    cnf->interface_defaults = get_default_if_config();
  } else {
    olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false);
    olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name);
  }

  /* Interfaces */
  while (in) {
    struct olsr_lq_mult *mult, *mult_orig;

    assert(in->cnf);
    assert(in->cnfi);

    io = in->cnf;

    olsrd_print_interface_cnf(in->cnf, in->cnfi, false);

    /*apply defaults*/
    {
      size_t pos;
      struct olsr_lq_mult *mult_temp, *mult_orig_walk;
      uint8_t *cnfptr = (uint8_t*)in->cnf;
      uint8_t *cnfiptr = (uint8_t*)in->cnfi;
      uint8_t *defptr = (uint8_t*)cnf->interface_defaults;

      /*save interface specific lqmults, as they are merged togehter later*/
      mult_orig = io->lq_mult;

      for (pos = 0; pos < sizeof(*in->cnf); pos++) {
        if (cnfptr[pos] != cnfiptr[pos]) {
          cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
        }
        else cnfiptr[pos]=0xFF;
      }

      io->lq_mult=NULL;
      /*copy default lqmults into this interface*/
      for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
        /*search same lqmult in orig_list*/
        for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
          if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
            break;
          }
        }
        if (mult_orig_walk == NULL) {
          mult_temp=malloc(sizeof(struct olsr_lq_mult));
          memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
          mult_temp->next=io->lq_mult;
          io->lq_mult=mult_temp;
        }
      }
    }

    if (in->name == NULL || !strlen(in->name)) {
      fprintf(stderr, "Interface has no name!\n");
      return -1;
    }

    if (io == NULL) {
      fprintf(stderr, "Interface %s has no configuration!\n", in->name);
      return -1;
    }

    /*merge lqmults*/
    if (mult_orig!=NULL) {
      io->orig_lq_mult_cnt=1;
      /*search last of interface specific lqmults*/
      mult = mult_orig;
      while (mult->next!=NULL) {
        mult=mult->next;
      }
      /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
      mult->next=io->lq_mult;
      io->lq_mult=mult_orig;
    }

    if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1;

    in = in->next;
  }

  return 0;
}
示例#29
0
void
olsr_hello_tap(struct hello_message *message, struct interface *in_if, const union olsr_ip_addr *from_addr)
{
  struct neighbor_entry *neighbor;

  /*
   * Update link status
   */
  struct link_entry *lnk = update_link_entry(&in_if->ip_addr, from_addr, message, in_if);

  /*check alias message->source_addr*/
  if (!ipequal(&message->source_addr,from_addr)){
    /*new alias of new neighbour are thrown in the mid table to speed up routing*/
    if (olsr_validate_address(from_addr)) {
      union olsr_ip_addr * main_addr = mid_lookup_main_addr(from_addr);
      if ((main_addr==NULL)||(ipequal(&message->source_addr, main_addr))){
        /*struct ipaddr_str srcbuf, origbuf;
        olsr_syslog(OLSR_LOG_INFO, "got hello from unknown alias ip of direct neighbour: ip: %s main-ip: %s",
                    olsr_ip_to_string(&origbuf,&message->source_addr),
                    olsr_ip_to_string(&srcbuf,from_addr));*/
        insert_mid_alias(&message->source_addr, from_addr, message->vtime);
      }
      else
      {
        struct ipaddr_str srcbuf, origbuf;
        olsr_syslog(OLSR_LOG_INFO, "got hello with invalid from and originator adress pair (%s, %s) Duplicate Ips?\n",
                    olsr_ip_to_string(&origbuf,&message->source_addr),
                    olsr_ip_to_string(&srcbuf,from_addr));
      }
    }
  }

  if (olsr_cnf->lq_level > 0) {
    struct hello_neighbor *walker;
    /* just in case our neighbor has changed its HELLO interval */
    olsr_update_packet_loss_hello_int(lnk, message->htime);

    /* find the input interface in the list of neighbor interfaces */
    for (walker = message->neighbors; walker != NULL; walker = walker->next) {
      if (walker->link != UNSPEC_LINK
          && ipequal(&walker->address, &in_if->ip_addr)) {
        break;
      }
    }

    /*
     * memorize our neighbour's idea of the link quality, so that we
     * know the link quality in both directions
     *
     * walker is NULL if there the current interface was not included in
     * the message (or was included as an UNSPEC_LINK)
     */
    olsr_memorize_foreign_hello_lq(lnk, walker);

    /* update packet loss for link quality calculation */
    olsr_received_hello_handler(lnk);
  }

  neighbor = lnk->neighbor;

  /*
   * Hysteresis
   */
  if (olsr_cnf->use_hysteresis) {
    /* Update HELLO timeout */
    /* printf("MESSAGE HTIME: %f\n", message->htime); */
    olsr_update_hysteresis_hello(lnk, message->htime);
  }

  /* Check if we are chosen as MPR */
  if (lookup_mpr_status(message, in_if))
    /* source_addr is always the main addr of a node! */
    olsr_update_mprs_set(&message->source_addr, message->vtime);

  /* Check willingness */
  if (neighbor->willingness != message->willingness) {
    struct ipaddr_str buf;
    OLSR_PRINTF(1, "Willingness for %s changed from %d to %d - UPDATING\n", olsr_ip_to_string(&buf, &neighbor->neighbor_main_addr),
                neighbor->willingness, message->willingness);
    /*
     *If willingness changed - recalculate
     */
    neighbor->willingness = message->willingness;
    changes_neighborhood = true;
    changes_topology = true;
  }

  /* Don't register neighbors of neighbors that announces WILL_NEVER */
  if (neighbor->willingness != WILL_NEVER)
    process_message_neighbors(neighbor, message);

  /* Process changes immedeatly in case of MPR updates */
  olsr_process_changes();

  olsr_free_hello_packet(message);

  return;
}
示例#30
0
int
olsrd_sanity_check_cnf(struct olsrd_config *cnf)
{
    struct olsr_if *in = cnf->interfaces;
    struct if_config_options *io;

    /* Debug level */
    if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) {
        fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level);
        return -1;
    }

    /* IP version */
    if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) {
        fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version);
        return -1;
    }

    /* TOS */
    if (cnf->tos > MAX_TOS) {
        fprintf(stderr, "TOS %d is not allowed\n", cnf->tos);
        return -1;
    }

    if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) {
        fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness);
        return -1;
    }

    /* Hysteresis */
    if (cnf->use_hysteresis == true) {
        if (cnf->hysteresis_param.scaling < MIN_HYST_PARAM || cnf->hysteresis_param.scaling > MAX_HYST_PARAM) {
            fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling);
            return -1;
        }

        if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) {
            fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high,
                    cnf->hysteresis_param.thr_low);
            return -1;
        }

        if (cnf->hysteresis_param.thr_high < MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > MAX_HYST_PARAM) {
            fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high);
            return -1;
        }

        if (cnf->hysteresis_param.thr_low < MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > MAX_HYST_PARAM) {
            fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low);
            return -1;
        }
    }

    /* Pollrate */
    if (cnf->pollrate < MIN_POLLRATE || cnf->pollrate > MAX_POLLRATE) {
        fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate);
        return -1;
    }

    /* NIC Changes Pollrate */

    if (cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT) {
        fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", cnf->nic_chgs_pollrate);
        return -1;
    }

    /* TC redundancy */
    if (cnf->tc_redundancy != 2) {
        fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. "
                "It was discovered late in the stable tree development and cannot "
                "be solved without a difficult change in the dijkstra code. "
                "Feel free to contact the olsr-user mailinglist "
                "(http://www.olsr.org/?q=mailing-lists) to learn more "
                "about the problem. The next version of OLSR will have working "
                "tc-redundancy again.\n");
        return -1;
    }

    /* MPR coverage */
    if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) {
        fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage);
        return -1;
    }

    /* Link Q and hysteresis cannot be activated at the same time */
    if (cnf->use_hysteresis == true && cnf->lq_level) {
        fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n");
        return -1;
    }

    /* Link quality level */
    if (cnf->lq_level != 0 && cnf->lq_level != 2) {
        fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level);
        return -1;
    }

    /* Link quality window size */
    if (cnf->lq_level && (cnf->lq_aging < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING)) {
        fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging);
        return -1;
    }

    /* NAT threshold value */
    if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0)) {
        fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh);
        return -1;
    }

#if defined linux
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) {
        fprintf(stderr, "Smart gateways are not supported for linux kernel 2.4 and ipv6\n");
        return -1;
    }
#endif

    /* this rtpolicy settings are also currently only used in Linux */
    if (olsrd_sanity_check_rtpolicy(cnf)) {
        return -1;
    }

#endif

    if (in == NULL) {
        fprintf(stderr, "No interfaces configured!\n");
        return -1;
    }

    if (cnf->min_tc_vtime < 0.0) {
        fprintf(stderr, "Error, negative minimal tc time not allowed.\n");
        return -1;
    }
    if (cnf->min_tc_vtime > 0.0) {
        fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
    }

    if (cnf->smart_gw_type >= GW_UPLINK_CNT) {
        fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type);
        return -1;
    }
    if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) {
        fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n",
                cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
        return -1;
    }
    if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) {
        fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n",
                cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED);
        return -1;
    }

    if (cnf->interface_defaults == NULL) {
        /* get a default configuration if the user did not specify one */
        cnf->interface_defaults = get_default_if_config();
    } else {
        olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false);
        olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name);
    }

    /* Interfaces */
    while (in) {
        struct olsr_lq_mult *mult, *mult_orig;

        io = in->cnf;

        olsrd_print_interface_cnf(in->cnf, in->cnfi, false);

        /*apply defaults*/
        {
            size_t pos;
            struct olsr_lq_mult *mult_temp, *mult_orig_walk;
            uint8_t *cnfptr = (uint8_t*)in->cnf;
            uint8_t *cnfiptr = (uint8_t*)in->cnfi;
            uint8_t *defptr = (uint8_t*)cnf->interface_defaults;

            /*save interface specific lqmults, as they are merged togehter later*/
            mult_orig = io->lq_mult;

            assert(in->cnf);
            assert(in->cnfi);
            for (pos = 0; pos < sizeof(*in->cnf); pos++) {
                if (cnfptr[pos] != cnfiptr[pos]) {
                    cnfptr[pos] = defptr[pos];
                    cnfiptr[pos]=0x00;
                }
                else cnfiptr[pos]=0xFF;
            }

            io->lq_mult=NULL;
            /*copy default lqmults into this interface*/
            for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
                /*search same lqmult in orig_list*/
                for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
                    if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
                        break;
                    }
                }
                if (mult_orig_walk == NULL) {
                    mult_temp=malloc(sizeof(struct olsr_lq_mult));
                    memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
                    mult_temp->next=io->lq_mult;
                    io->lq_mult=mult_temp;
                }
            }
        }

        if (in->name == NULL || !strlen(in->name)) {
            fprintf(stderr, "Interface has no name!\n");
            return -1;
        }

        if (io == NULL) {
            fprintf(stderr, "Interface %s has no configuration!\n", in->name);
            return -1;
        }

        /*merge lqmults*/
        if (mult_orig!=NULL) {
            io->orig_lq_mult_cnt=1;
            /*search last of interface specific lqmults*/
            mult = mult_orig;
            while (mult->next!=NULL) {
                mult=mult->next;
            }
            /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
            mult->next=io->lq_mult;
            io->lq_mult=mult_orig;
        }

        if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1;

        in = in->next;
    }

    return 0;
}