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

📄 bmf.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        walker->nBmfPacketsTx++;        OLSR_PRINTF(          8,          "%s: --> unpacked and forwarded on \"%s\"\n",          PLUGIN_NAME_SHORT,          walker->ifName);      }    } /* if (walker->olsrIntf == NULL) */    /* To an OLSR interface: forward the packet, but only if this node is     * selected as MPR by the forwarding node */    else if (iAmMpr)    {      struct TBestNeighbors bestNeighborLinks;      int nPossibleNeighbors;      int nBytesWritten;      int nPacketsToSend;      int i;      /* Retrieve at most two best neigbors to forward the packet to */      GetBestTwoNeighbors(        &bestNeighborLinks,        walker,        &mcSrc,        forwardedBy,        forwardedTo,        &nPossibleNeighbors);      if (nPossibleNeighbors <= 0)      {        OLSR_PRINTF(          8,          "%s: --> not forwarding on \"%s\": there is no neighbor that needs my retransmission\n",          PLUGIN_NAME_SHORT,          walker->ifName);        continue; /* for */      }      /* Compose destination of encapsulation packet.       * Start by filling in the local broadcast address. */      COPY_IP(&forwardTo.sin_addr.s_addr, &walker->broadAddr);      /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one       *   packet (to the best neighbor). Other neighbors listen promiscuously.       * - If the BMF mechanism is BM_BROADCAST,       *   - send one unicast packet if there is one possible neighbor,       *   - send two unicast packets if there are two possible neighbors, and       *   - only if there are more than two possible neighbors, then send an       *     (WLAN-air-expensive, less reliable) broadcast packet. */      if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors < 2)      {        nPacketsToSend = 1;      }      else /* BmfMechanism == BM_BROADCAST && nPossibleNeighbors >= 2 */      {        nPacketsToSend = 2;      }      for (i = 0; i < nPacketsToSend; i++)      {        if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors <= 2)        {          /* For unicast, overwrite the local broadcast address which was filled in           * above */          COPY_IP(&forwardTo.sin_addr.s_addr, &bestNeighborLinks.links[i]->neighbor_iface_addr);        }        /* Forward the BMF packet via the encapsulation socket */        nBytesWritten = sendto(          walker->encapsulatingSkfd,          encapsulationUdpData,          encapsulationUdpDataLen,          MSG_DONTROUTE,          (struct sockaddr*) &forwardTo,          sizeof(forwardTo));                           /* Evaluate and display result */        if (nBytesWritten != encapsulationUdpDataLen)        {          BmfPError("sendto() error forwarding encapsulated pkt on \"%s\"", walker->ifName);        }        else        {          /* Increase counter */          walker->nBmfPacketsTx++;          OLSR_PRINTF(            8,            "%s: --> forwarded on \"%s\" to %s\n",            PLUGIN_NAME_SHORT,            walker->ifName,            inet_ntoa(forwardTo.sin_addr));        } /* if */      } /* for */    }  /* else if (iAmMpr) */    else /* walker->olsrIntf != NULL && !iAmMpr */    {      /* 'walker' is an OLSR interface, but I am not selected as MPR. In that       * case, don't forward. */      OLSR_PRINTF(        8,        "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n",        PLUGIN_NAME_SHORT,        walker->ifName,        olsr_ip_to_string(forwardedBy));    } /* else */  } /* for */} /* BmfEncapsulationPacketReceived *//* ------------------------------------------------------------------------- * 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;  ipPacket = GetIpPacket(encapsulationUdpData);  ipPacketLen = GetIpTotalLength(ipPacket);  ipHeader = GetIpHeader(encapsulationUdpData);  /* Only forward multicast packets. If configured, also forward local broadcast packets */  COPY_IP(&dstIp, &ipHeader->ip_dst);  broadAddr.v4 = htonl(EtherTunTapIpBroadcast);  if (IsMulticast(&dstIp) ||      (EnableLocalBroadcast != 0 && COMP_IP(&dstIp, &broadAddr)))  {    /* continue */  }  else  {    return;  }  COPY_IP(&srcIp, &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(&srcIp),    olsr_ip_to_string(&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);    }    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. */      int nBytesWritten;      struct sockaddr_ll dest;      /* If the encapsulated IP packet is a local broadcast packet,       * update its destination address to match the subnet of the network       * interface on which the packet is being sent. */      CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);      memset(&dest, 0, sizeof(dest));      dest.sll_family = AF_PACKET;      dest.sll_protocol = htons(ETH_P_IP);      dest.sll_ifindex = if_nametoindex(walker->ifName);      dest.sll_halen = IFHWADDRLEN;      /* Use all-ones as destination MAC address. When the IP destination is       * a multicast address, the destination MAC address should normally also       * be a multicast address. E.g., when the destination IP is 224.0.0.1,       * the destination MAC should be 01:00:5e:00:00:01. However, it does not       * seem to matter when the destination MAC address is set to all-ones       * in that case. */      memset(dest.sll_addr, 0xFF, IFHWADDRLEN);      nBytesWritten = sendto(        walker->capturingSkfd,        ipPacket,        ipPacketLen,        0,        (struct sockaddr*) &dest,        sizeof(dest));      if (nBytesWritten != ipPacketLen)      {        BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);      }      else      {        /* Increase counter */        walker->nBmfPacketsTx++;        OLSR_PRINTF(          8,          "%s: --> forwarded from non-OLSR to non-OLSR \"%s\"\n",          PLUGIN_NAME_SHORT,          walker->ifName);      } /* if */    } /* if */  } /* for */} /* BmfTunPacketCaptured *//* ------------------------------------------------------------------------- * Function   : DoBmf * Description: Wait (blocking) for IP packets, then call the handler for each *              received packet * Input      : none * Output     : none * Return     : none * Data Used  : BmfInterfaces * ------------------------------------------------------------------------- */static void DoBmf(void){  int nFdBitsSet;  unsigned char rxBuffer[BMF_BUFFER_SIZE];  fd_set rxFdSet;  assert(HighestSkfd >= 0);  /* Make a local copy of the set of file descriptors that select() can   * modify to indicate which descriptors actually changed status */  rxFdSet = InputSet;  /* Wait (blocking) for packets received on any of the sockets.   * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */  nFdBitsSet = select(HighestSkfd + 1, &rxFdSet, NULL, NULL, NULL);  if (nFdBitsSet < 0)  {    if (errno != EINTR)    {      BmfPError("select() error");    }    return;  }  while (nFdBitsSet > 0)  {    struct TBmfInterface* walker;    /* Check if a packet was received on the capturing socket (if any)     * of each network interface */    for (walker = BmfInterfaces; walker != NULL; walker = walker->next)    {      int skfd = walker->capturingSkfd;      if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))      {        struct sockaddr_ll pktAddr;        socklen_t addrLen = sizeof(pktAddr);        int nBytes;        unsigned char* ipPacket;        /* A packet was captured. */        nFdBitsSet--;        /* Receive the captured Ethernet frame, leaving space for the BMF         * encapsulation header */        ipPacket = GetIpPacket(rxBuffer);        nBytes = recvfrom(          skfd,          ipPacket,          BMF_BUFFER_SIZE - ENCAP_HDR_LEN,          0,          (struct sockaddr*)&pktAddr,          &addrLen);        if (nBytes < 0)        {          BmfPError("recvfrom() error on \"%s\"", walker->ifName);          continue; /* for */        } /* if (nBytes < 0) */        /* Check if the number of received bytes is large enough for an IP         * packet which contains at least a minimum-size IP header.         * Note: There is an apparent bug in the packet socket implementation in         * combination with VLAN interfaces. On a VLAN interface, the value returned         * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value         * returned on a non-VLAN interface, for the same ethernet frame. */        if (nBytes < (int)sizeof(struct ip))        {          olsr_printf(            1,            "%s: captured frame too short (%d bytes) on \"%s\"\n",            PLUGIN_NAME,            nBytes,            walker->ifName);          continue; /* for */        }        if (pktAddr.sll_pkttype == PACKET_OUTGOING ||            pktAddr.sll_pkttype == PACKET_MULTICAST ||            pktAddr.sll_pkttype == PACKET_BROADCAST)        {          /* A multicast or broadcast packet was captured */          BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);        } /* if (pktAddr.sll_pkttype == ...) */      } /* if (skfd >= 0 && (FD_ISSET...)) */    } /* for */        /* Check if a BMF encapsulation packet was received on the listening     * socket (if any) of each network interface */    for (walker = BmfInterfaces; walker != NULL; walker = walker->next)    {      int skfd = walker->listeningSkfd;      if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))      {        struct sockaddr_ll pktAddr;        socklen_t addrLen = sizeof(pktAddr);        int nBytes;        int minimumLength;        struct ip* ipHeader;        struct udphdr* udpHeader;        u_int16_t destPort;        union olsr_ip_addr forwardedBy;        union olsr_ip_addr forwardedTo;        /* Heard a BMF packet */        nFdBitsSet--;        nBytes = recvfrom(

⌨️ 快捷键说明

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