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

📄 bmf.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 4 页
字号:
          skfd,          rxBuffer,          BMF_BUFFER_SIZE,          0,          (struct sockaddr*)&pktAddr,          &addrLen);        if (nBytes < 0)        {          BmfPError("recvfrom() error on \"%s\"", walker->ifName);          continue; /* for */        } /* if (nBytes < 0) */        /* Check if the received packet is actually directed to another         * node on the LAN */        if (pktAddr.sll_pkttype != PACKET_OTHERHOST)        {          /* No, the packet is directed to this node. In that case it will           * be, or will already have been received, via the encapsulating           * socket. Discard it here. */          continue; /* for */        } /* if (pktAddr.sll_pkttype ...) */        /* Check if the received packet is UDP - BMF port */        ipHeader = (struct ip*)rxBuffer;        if (ipHeader->ip_p != SOL_UDP)        {          /* Not UDP */          continue; /* for */        }        udpHeader = (struct udphdr*)(rxBuffer + GetIpHeaderLength(rxBuffer));        destPort = ntohs(udpHeader->dest);        if (destPort != BMF_ENCAP_PORT)        {          /* Not BMF */          continue; /* for */        }        /* Check if the number of received bytes is large enough for a minimal BMF         * encapsulation packet, at least:         * - the IP header of the encapsulation IP packet         * - the UDP header of the encapsulation IP packet         * - the encapsulation header         * - a minimum IP header inside the encapsulated packet         * Note: 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. */        minimumLength =          GetIpHeaderLength(rxBuffer) +          sizeof(struct udphdr) +          ENCAP_HDR_LEN +          sizeof(struct ip);        if (nBytes < minimumLength)        {          olsr_printf(            1,            "%s: captured a too short encapsulation packet (%d bytes) on \"%s\"\n",            PLUGIN_NAME,            nBytes,            walker->ifName);          continue; /* for */        }        COPY_IP(&forwardedBy, &ipHeader->ip_src);        COPY_IP(&forwardedTo, &ipHeader->ip_dst);        BmfEncapsulationPacketReceived(          walker,          &forwardedBy,          &forwardedTo,          rxBuffer + GetIpHeaderLength(rxBuffer) + sizeof(struct udphdr));      } /* if (skfd >= 0 && (FD_ISSET...)) */    } /* for */    /* Check if a packet was received on the encapsulating socket (if any)     * of each network interface */    for (walker = BmfInterfaces; walker != NULL; walker = walker->next)    {      int skfd = walker->encapsulatingSkfd;      if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))      {        struct sockaddr_in from;        socklen_t fromLen = sizeof(from);        int nBytes;        int minimumLength;        union olsr_ip_addr forwardedBy;        /* An encapsulated packet was received */        nFdBitsSet--;        nBytes = recvfrom(          skfd,          rxBuffer,          BMF_BUFFER_SIZE,          0,          (struct sockaddr*)&from,          &fromLen);        if (nBytes < 0)        {          BmfPError("recvfrom() error on \"%s\"", walker->ifName);          continue; /* for */        } /* if (nBytes < 0) */        COPY_IP(&forwardedBy, &from.sin_addr.s_addr);        /* Check if the number of received bytes is large enough for a minimal BMF         * encapsulation packet, at least:         * - the encapsulation header         * - a minimum IP header inside the encapsulated packet */        minimumLength =          ENCAP_HDR_LEN +          sizeof(struct ip);        if (nBytes < minimumLength)        {          olsr_printf(            1,            "%s: received a too short encapsulation packet (%d bytes) from %s on \"%s\"\n",            PLUGIN_NAME,            nBytes,            olsr_ip_to_string(&forwardedBy),            walker->ifName);          continue; /* for */        }        /* Unfortunately, the recvfrom call does not return the destination         * of the encapsulation packet (the destination may be either the         * my unicast or my local broadcast address). Therefore we fill in 'NULL'         * for the 'forwardedTo' parameter. */        BmfEncapsulationPacketReceived(walker, &forwardedBy, NULL, rxBuffer);      } /* if (skfd >= 0 && (FD_ISSET...)) */    } /* for */    if (nFdBitsSet > 0 && FD_ISSET(EtherTunTapFd, &rxFdSet))    {      /* Check if an application has sent a packet out via the tuntap       * network interface */      int nBytes;      unsigned char* ipPacket;      unsigned char* bufferToRead;      size_t nBytesToRead;      nFdBitsSet--;      /* Receive the packet, leaving space for the BMF encapsulation header */      ipPacket = GetIpPacket(rxBuffer);          bufferToRead = ipPacket;      nBytesToRead = BMF_BUFFER_SIZE - ENCAP_HDR_LEN;      nBytes = read(EtherTunTapFd, bufferToRead, nBytesToRead);      if (nBytes < 0)      {        BmfPError("recvfrom() error on \"%s\"", EtherTunTapIfName);      }      else      {        /* Check if the number of received bytes is large enough for an IP         * packet which contains at least a minimum-size IP header */        if (nBytes < (int)sizeof(struct ip))        {          olsr_printf(            1,            "%s: captured packet too short (%d bytes) on \"%s\"\n",            PLUGIN_NAME,            nBytes,            EtherTunTapIfName);        }        else        {          /* An outbound packet was captured */          BmfTunPacketCaptured(rxBuffer);        } /* if (nBytes < ... */      } /* if (nBytes < 0) */    } /* if (nFdBitsSet > 0 && ... */  } /* while (nFdBitsSet > 0) */} /* DoBmf *//* ------------------------------------------------------------------------- * Function   : BmfSignalHandler * Description: Signal handler function * Input      : signo - signal being handled * Output     : none * Return     : none * Data Used  : BmfThreadRunning * ------------------------------------------------------------------------- */static void BmfSignalHandler(int signo __attribute__((unused))){  BmfThreadRunning = 0;} /* BmfSignalHandler *//* ------------------------------------------------------------------------- * Function   : BmfRun * Description: Receiver thread function * Input      : useless - not used * Output     : none * Return     : not used * Data Used  : BmfThreadRunning * Notes      : Another thread can gracefully stop this thread by sending *              a SIGALRM signal. * ------------------------------------------------------------------------- */static void* BmfRun(void* useless __attribute__((unused))){  /* Mask all signals except SIGALRM */  sigset_t blockedSigs;  sigfillset(&blockedSigs);  sigdelset(&blockedSigs, SIGALRM);  if (pthread_sigmask(SIG_BLOCK, &blockedSigs, NULL) != 0)  {    BmfPError("pthread_sigmask() error");  }  /* Set up the signal handler for the process: use SIGALRM to terminate   * the BMF thread. Only if a signal handler is specified, does a blocking   * system call return with errno set to EINTR; if a signal hander is not   * specified, any system call in which the thread may be waiting will not   * return. Note that the BMF thread is usually blocked in the select()   * function (see DoBmf()). */  if (signal(SIGALRM, BmfSignalHandler) == SIG_ERR)  {    BmfPError("signal() error");  }  /* Call the thread function until flagged to exit */  while (BmfThreadRunning != 0)  {    DoBmf();  }  return NULL;} /* BmfRun *//* ------------------------------------------------------------------------- * Function   : InterfaceChange * Description: Callback function passed to OLSRD for it to call whenever a *              network interface has been added, removed or updated * Input      : interf - the network interface to deal with *              action - indicates if the specified network interface was *                added, removed or updated. * Output     : none * Return     : always 0 * Data Used  : none * ------------------------------------------------------------------------- */int InterfaceChange(struct interface* interf, int action){  switch (action)  {  case (IFCHG_IF_ADD):    AddInterface(interf);    olsr_printf(1, "%s: interface %s added\n", PLUGIN_NAME, interf->int_name);    break;  case (IFCHG_IF_REMOVE):    /* We cannot just remove the interface, because the receive-thread is likely     * to be waiting in select(...) for packets coming in via the interface.     * Therefore we first close BMF (CloseBmf()), interrupting and kiling the     * receive-thread so that it is safe to remove this (and all other)     * interfaces. After that, BMF is re-started (InitBmf(interf)). */    CloseBmf();    InitBmf(interf);    olsr_printf(1, "%s: interface %s removed\n", PLUGIN_NAME, interf->int_name);    break;  case (IFCHG_IF_UPDATE):    olsr_printf(1, "%s: interface %s updated\n", PLUGIN_NAME, interf->int_name);    break;        default:    olsr_printf(      1,      "%s: interface %s: error - unknown action (%d)\n",      PLUGIN_NAME,      interf->int_name, action);    break;  }  return 0;} /* InterfaceChange *//* ------------------------------------------------------------------------- * Function   : InitBmf * Description: Initialize the BMF plugin * Input      : skipThisIntf - specifies which network interface should not *              be enabled for BMF. Pass NULL if not applicable. * Output     : none * Return     : fail (0) or success (1) * Data Used  : BmfThreadRunning, BmfThread * ------------------------------------------------------------------------- */int InitBmf(struct interface* skipThisIntf){  CreateBmfNetworkInterfaces(skipThisIntf);  /* Start running the multicast packet processing thread */  BmfThreadRunning = 1;  if (pthread_create(&BmfThread, NULL, BmfRun, NULL) != 0)  {    BmfPError("pthread_create() error");    return 0;  }  if (EtherTunTapFd >= 0)  {    /* Deactivate IP spoof filter for EtherTunTap interface */    DeactivateSpoofFilter();    /* If the BMF network interface has a sensible IP address, it is a good idea     * to route all multicast traffic through that interface */    if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)    {      AddMulticastRoute();    }  }  return 1;} /* InitBmf *//* ------------------------------------------------------------------------- * Function   : CloseBmf * Description: Close the BMF plugin and clean up * Input      : none * Output     : none * Return     : none * Data Used  : BmfThread * ------------------------------------------------------------------------- */void CloseBmf(void){  if (EtherTunTapFd >= 0)  {    /* If there is a multicast route, try to delete it first */    DeleteMulticastRoute();    /* Restore IP spoof filter for EtherTunTap interface */    RestoreSpoofFilter();  }  if (BmfThreadRunning)  {    /* Signal BmfThread to exit */    /* Strangely enough, all running threads receive the SIGALRM signal. But only the     * BMF thread is affected by this signal, having specified a handler for this     * signal in its thread entry function BmfRun(...). */    if (pthread_kill(BmfThread, SIGALRM) != 0)    {      BmfPError("pthread_kill() error");    }    /* Wait for BmfThread to acknowledge */    if (pthread_join(BmfThread, NULL) != 0)    {      BmfPError("pthread_join() error");    }  }  /* Clean up after the BmfThread has been killed */  CloseBmfNetworkInterfaces();} /* CloseBmf */

⌨️ 快捷键说明

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