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

📄 bmf.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 4 页
字号:
     *     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 */        {          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(&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);      }    } /* if (isFromOlsrIntf && isToOlsrIntf) */    else if (isFromOlsrIntf && !isToOlsrIntf)    {      /* Case 2: Forward from OLSR interface to non-OLSR interface */      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 on \"%s\"\n", PLUGIN_NAME_SHORT, walker->ifName);      }    } /* 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);    } /* 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      {        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 on non-OLSR \"%s\"\n",            PLUGIN_NAME_SHORT,            walker->ifName);        }      } /* if (intf == walker) */    } /* if */  } /* for */} /* BmfPacketCaptured *//* ------------------------------------------------------------------------- * Function   : BmfEncapsulationPacketReceived * Description: Handle a received BMF-encapsulation packet * Input      : intf - the network interface on which the packet was received *              forwardedBy - the IP node that forwarded the packet to me *              forwardedTo - the destination IP address of the encapsulation *                packet, in case the packet was received promiscuously. *                Pass NULL if the packet is received normally (unicast or *                broadcast). *              encapsulationUdpData - the encapsulating IP UDP data, containting *                the BMF encapsulation header, followed by the encapsulated *                IP packet * Output     : none * Return     : none * Data Used  : BmfInterfaces * ------------------------------------------------------------------------- */static void BmfEncapsulationPacketReceived(  struct TBmfInterface* intf,  union olsr_ip_addr* forwardedBy,  union olsr_ip_addr* forwardedTo,  unsigned char* encapsulationUdpData){  int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */  struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */  unsigned char* ipPacket; /* The encapsulated IP packet */  u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */  struct ip* ipHeader; /* IP header inside the encapsulated IP packet */  union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */  union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */  struct TEncapHeader* encapsulationHdr;  u_int16_t encapsulationUdpDataLen;  struct TBmfInterface* walker;  /* Are we talking to ourselves? */  if (if_ifwithaddr(forwardedBy) != NULL)  {    return;  }  /* Discard encapsulated packets received on a non-OLSR interface */  if (intf->olsrIntf == NULL)  {    return;  }  /* Retrieve details about the encapsulated IP packet */  ipPacket = GetIpPacket(encapsulationUdpData);  ipPacketLen = GetIpTotalLength(ipPacket);  ipHeader = GetIpHeader(encapsulationUdpData);  COPY_IP(&mcSrc, &ipHeader->ip_src);  COPY_IP(&mcDst, &ipHeader->ip_dst);  /* Increase counter */  intf->nBmfPacketsRx++;  /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */  OLSR_PRINTF(    8,    "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n",    PLUGIN_NAME_SHORT,    (long)ipPacketLen,    intf->ifName,    olsr_ip_to_string(&mcSrc),    olsr_ip_to_string(&mcDst),    olsr_ip_to_string(forwardedBy),    forwardedTo != NULL ? olsr_ip_to_string(forwardedTo) : "me");  /* Get encapsulation header */  encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData;  /* Verify correct format of BMF encapsulation header */  if (encapsulationHdr->type != BMF_ENCAP_TYPE ||      encapsulationHdr->len != BMF_ENCAP_LEN ||      ntohs(encapsulationHdr->reserved != 0))  {    OLSR_PRINTF(      8,      "%s: --> discarding: format of BMF encapsulation header not recognized\n",      PLUGIN_NAME_SHORT);    return;  }  /* Check if this packet was seen recently */  if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32)))  {    /* Increase counter */    intf->nBmfPacketsRxDup++;    OLSR_PRINTF(      8,      "%s: --> discarding: packet is duplicate\n",      PLUGIN_NAME_SHORT);    return;  }  if (EtherTunTapFd >= 0)  {    /* Unpack the encapsulated IP packet and deliver it locally, by sending     * a copy into the local IP stack via the EtherTunTap interface */    union olsr_ip_addr broadAddr;    int nBytesToWrite, nBytesWritten;    unsigned char* bufferToWrite;    /* If the encapsulated IP packet is a local broadcast packet,     * update its destination address to match the subnet of the EtherTunTap     * interface */    broadAddr.v4 = htonl(EtherTunTapIpBroadcast);    CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr);    bufferToWrite = ipPacket;    nBytesToWrite = ipPacketLen;    /* Write the packet into the EtherTunTap interface for local delivery */    nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);    if (nBytesWritten != nBytesToWrite)    {      BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName);    }    else    {      OLSR_PRINTF(        8,        "%s: --> unpacked and delivered locally on \"%s\"\n",        PLUGIN_NAME_SHORT,        EtherTunTapIfName);    }  } /* if (EtherTunTapFd >= 0) */  /* Check if I am MPR for the forwarder */  /* TODO: olsr_lookup_mprs_set() is not thread-safe! */  iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL);  /* Compose destination address for next hop */  memset(&forwardTo, 0, sizeof(forwardTo));  forwardTo.sin_family = AF_INET;  forwardTo.sin_port = htons(BMF_ENCAP_PORT);  /* Retrieve the number of bytes to be forwarded via the encapsulation socket */  encapsulationUdpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);  /* Check with each network interface what needs to be done on it */  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)  {    /* What to do with the packet on a non-OLSR interface? Unpack     * encapsulated packet, and forward it.     *     * What to do with the packet on an OLSR interface? Forward it only     * if the forwarding node has selected us as MPR (iAmMpr).     *     * Note that the packet is always coming in on an OLSR interface, because     * it is an encapsulated BMF packet. */    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */    if (walker->olsrIntf == NULL)    {      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 unpacked encapsulated pkt on \"%s\"", walker->ifName);      }      else      {        /* Increase counter */

⌨️ 快捷键说明

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