Exemplo n.º 1
0
static void
ipc_print_neigh_link(struct autobuf *abuf, const struct neighbor_entry *neighbor)
{
  static const char DASHED[] = "dashed";
  static const char SOLID[] = "solid";

  struct ipaddr_str mainaddrstrbuf, strbuf;
  olsr_linkcost etx = 0.0;
  const char *style;
  const char *adr = olsr_ip_to_string(&mainaddrstrbuf, &olsr_cnf->main_addr);
  struct link_entry *the_link;
  struct lqtextbuffer lqbuffer;

  if (neighbor->status == 0) {  /* non SYM */
    style = DASHED;
  } else {
    the_link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
    if (the_link) {
      etx = the_link->linkcost;
    }
    style = SOLID;
  }

  abuf_appendf(abuf, "\"%s\" -> \"%s\"[label=\"%s\", style=%s];\n", adr, olsr_ip_to_string(&strbuf, &neighbor->neighbor_main_addr),
               get_linkcost_text(etx, false, &lqbuffer), style);

  if (neighbor->is_mpr) {
    abuf_appendf(abuf, "\"%s\"[shape=box];\n", adr);
  }
}
Exemplo n.º 2
0
/**
 *Prints the registered neighbors and two hop neighbors
 *to STDOUT.
 *
 *@return nada
 */
void
olsr_print_neighbor_table(void)
{
#ifdef NODEBUG
  /* The whole function doesn't do anything else. */
#ifndef NODEBUG
  const int iplen = olsr_cnf->ip_version == AF_INET ? 15 : 39;
#endif
  int idx;
  OLSR_PRINTF(1,
              "\n--- %02d:%02d:%02d.%02d ------------------------------------------------ NEIGHBORS\n\n"
              "%*s  LQ     NLQ    SYM   MPR   MPRS  will\n", nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec, (int)now.tv_usec / 10000,
              iplen, "IP address");

  for (idx = 0; idx < HASHSIZE; idx++) {
    struct neighbor_entry *neigh;
    for (neigh = neighbortable[idx].next; neigh != &neighbortable[idx]; neigh = neigh->next) {
      struct link_entry *lnk = get_best_link_to_neighbor(&neigh->neighbor_main_addr);
      if (lnk) {
        struct ipaddr_str buf;
        OLSR_PRINTF(1, "%-*s  %5.3f  %5.3f  %s  %s  %s  %d\n", iplen, olsr_ip_to_string(&buf, &neigh->neighbor_main_addr),
                    lnk->loss_link_quality, lnk->neigh_link_quality, neigh->status == SYM ? "YES " : "NO  ",
                    neigh->is_mpr ? "YES " : "NO  ", olsr_lookup_mprs_set(&neigh->neighbor_main_addr) == NULL ? "NO  " : "YES ",
                    neigh->willingness);
      }
    }
  }
#endif
}
Exemplo n.º 3
0
void
olsr_print_neighbor_table(void)
{
  /* The whole function doesn't do anything else. */
  const int iplen = olsr_cnf->ip_version == AF_INET ? (INET_ADDRSTRLEN - 1) : (INET6_ADDRSTRLEN - 1);
  int idx;

  OLSR_PRINTF(1,
              "\n--- %s ------------------------------------------------ NEIGHBORS\n\n"
              "%*s\tHyst\tLQ\tETX\tSYM   MPR   MPRS  will\n", olsr_wallclock_string(),
              iplen, "IP address");

  for (idx = 0; idx < HASHSIZE; idx++) {
    struct neighbor_entry *neigh;
    for (neigh = neighbortable[idx].next; neigh != &neighbortable[idx]; neigh = neigh->next) {
      struct link_entry *lnk = get_best_link_to_neighbor(&neigh->neighbor_main_addr);
      if (lnk) {
        struct ipaddr_str buf;
        struct lqtextbuffer lqbuffer1, lqbuffer2;

        OLSR_PRINTF(1, "%-*s\t%5.3f\t%s\t%s\t%s  %s  %s  %d\n", iplen, olsr_ip_to_string(&buf, &neigh->neighbor_main_addr),
                    (double)lnk->L_link_quality,
                    get_link_entry_text(lnk, '/', &lqbuffer1),
                    get_linkcost_text(lnk->linkcost,false, &lqbuffer2),
                    neigh->status == SYM ? "YES " : "NO  ",
                    neigh->is_mpr ? "YES " : "NO  ",
                    olsr_lookup_mprs_set(&neigh->neighbor_main_addr) == NULL ? "NO  " : "YES ",
                    neigh->willingness);
      }
    }
  }
}
Exemplo n.º 4
0
Arquivo: Bmf.c Projeto: 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 */
Exemplo n.º 5
0
/**
 *Processes an list of neighbors from an incoming HELLO message.
 *@param neighbor the neighbor who sent the message.
 *@param message the HELLO message
 *@return nada
 */
static void
process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_message *message)
{
  struct hello_neighbor *message_neighbors;

  for (message_neighbors = message->neighbors; message_neighbors != NULL; message_neighbors = message_neighbors->next) {
    union olsr_ip_addr *neigh_addr;
    struct neighbor_2_entry *two_hop_neighbor;

    /*
     *check all interfaces
     *so that we don't add ourselves to the
     *2 hop list
     *IMPORTANT!
     */
    if (if_ifwithaddr(&message_neighbors->address) != NULL)
      continue;

    /* Get the main address */
    neigh_addr = mid_lookup_main_addr(&message_neighbors->address);

    if (neigh_addr != NULL) {
      message_neighbors->address = *neigh_addr;
    }

    if (((message_neighbors->status == SYM_NEIGH) || (message_neighbors->status == MPR_NEIGH))) {
      struct neighbor_2_list_entry *two_hop_neighbor_yet = olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);

      if (two_hop_neighbor_yet != NULL) {
        /* Updating the holding time for this neighbor */
        olsr_set_timer(&two_hop_neighbor_yet->nbr2_list_timer, message->vtime, OLSR_NBR2_LIST_JITTER, OLSR_TIMER_ONESHOT,
                       &olsr_expire_nbr2_list, two_hop_neighbor_yet, 0);
        two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;

        /*
         * For link quality OLSR, reset the path link quality here.
         * The path link quality will be calculated in the second pass, below.
         * Keep the saved_path_link_quality for reference.
         */

        if (olsr_cnf->lq_level > 0) {
          /*
           * loop through the one-hop neighbors that see this
           * 'two_hop_neighbor'
           */

          struct neighbor_list_entry *walker;

          for (walker = two_hop_neighbor->neighbor_2_nblist.next; walker != &two_hop_neighbor->neighbor_2_nblist;
               walker = walker->next) {
            /*
             * have we found the one-hop neighbor that sent the
             * HELLO message that we're current processing?
             */

            if (walker->neighbor == neighbor) {
              walker->path_linkcost = LINK_COST_BROKEN;
            }
          }
        }
      } else {
        two_hop_neighbor = olsr_lookup_two_hop_neighbor_table(&message_neighbors->address);
        if (two_hop_neighbor == NULL) {
          changes_neighborhood = true;
          changes_topology = true;

          two_hop_neighbor = olsr_malloc(sizeof(struct neighbor_2_entry), "Process HELLO");

          two_hop_neighbor->neighbor_2_nblist.next = &two_hop_neighbor->neighbor_2_nblist;

          two_hop_neighbor->neighbor_2_nblist.prev = &two_hop_neighbor->neighbor_2_nblist;

          two_hop_neighbor->neighbor_2_pointer = 0;

          two_hop_neighbor->neighbor_2_addr = message_neighbors->address;

          olsr_insert_two_hop_neighbor_table(two_hop_neighbor);

          linking_this_2_entries(neighbor, two_hop_neighbor, message->vtime);
        } else {
          /*
             linking to this two_hop_neighbor entry
           */
          changes_neighborhood = true;
          changes_topology = true;

          linking_this_2_entries(neighbor, two_hop_neighbor, message->vtime);
        }
      }
    }
  }

  /* Separate, second pass for link quality OLSR */
  /* Separate, second and third pass for link quality OLSR */

  if (olsr_cnf->lq_level > 0) {
    olsr_linkcost first_hop_pathcost;
    struct link_entry *lnk = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);

    if (!lnk)
      return;

    /* calculate first hop path quality */
    first_hop_pathcost = lnk->linkcost;
    /*
     *  Second pass for link quality OLSR: calculate the best 2-hop
     * path costs to all the 2-hop neighbors indicated in the
     * HELLO message. Since the same 2-hop neighbor may be listed
     * more than once in the same HELLO message (each at a possibly
     * different quality) we want to select only the best one, not just
     * the last one listed in the HELLO message.
     */

    for (message_neighbors = message->neighbors; message_neighbors != NULL; message_neighbors = message_neighbors->next) {
      if (if_ifwithaddr(&message_neighbors->address) != NULL)
        continue;

      if (((message_neighbors->status == SYM_NEIGH) || (message_neighbors->status == MPR_NEIGH))) {
        struct neighbor_list_entry *walker;
        struct neighbor_2_entry *two_hop_neighbor;
        struct neighbor_2_list_entry *two_hop_neighbor_yet = olsr_lookup_my_neighbors(neighbor,
                                                                                      &message_neighbors->address);

        if (!two_hop_neighbor_yet)
          continue;

        two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;

        /*
         *  loop through the one-hop neighbors that see this
         * 'two_hop_neighbor'
         */

        for (walker = two_hop_neighbor->neighbor_2_nblist.next; walker != &two_hop_neighbor->neighbor_2_nblist;
             walker = walker->next) {
          /*
           * have we found the one-hop neighbor that sent the
           * HELLO message that we're current processing?
           */

          if (walker->neighbor == neighbor) {
            olsr_linkcost new_second_hop_linkcost, new_path_linkcost;

            // the link cost between the 1-hop neighbour and the
            // 2-hop neighbour

            new_second_hop_linkcost = message_neighbors->cost;

            // the total cost for the route
            // "us --- 1-hop --- 2-hop"

            new_path_linkcost = first_hop_pathcost + new_second_hop_linkcost;

            // Only copy the link quality if it is better than what we have
            // for this 2-hop neighbor
            if (new_path_linkcost < walker->path_linkcost) {
              walker->second_hop_linkcost = new_second_hop_linkcost;
              walker->path_linkcost = new_path_linkcost;

              walker->saved_path_linkcost = new_path_linkcost;

              changes_neighborhood = true;
              changes_topology = true;
            }
          }
        }
      }
    }
  }
}