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

📄 zl5011xpacketrx.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
         break;

      default:
         l2tpHeaderPos = 0;
         cookieOffset = 0;
         break;
   }

   /* if using non-IP protocol, then set the IPv4 flag to true to force using templates
      from just one part of the table */
   switch (par->protocolType)
   {
      case ZL5011X_CD :
      case ZL5011X_PW :
      case ZL5011X_MPLS :
      case ZL5011X_MPLS_PW :
      case ZL5011X_MPLS_MPLS_PW :
      case ZL5011X_MPLS_PW_RTP :
      case ZL5011X_MPLS_RTCP_CTRL :
      case ZL5011X_ETHERNET :
      case ZL5011X_CUSTOM8_PW :
      case ZL5011X_CUSTOM8_RTP_PW :
      case ZL5011X_CUSTOM8_PW_RTP :
         /* all of the non IP protocols */
         par->ipVer4 = ZL5011X_TRUE;
         ipv4Header = ZL5011X_FALSE;
         udpHeader = ZL5011X_FALSE;
         break;

      case ZL5011X_IP_UDP :
      case ZL5011X_IP_UDP_PW :
      case ZL5011X_IP_UDP_CD :
      case ZL5011X_IP_UDP_RTP :
      case ZL5011X_IP_UDP_RTP_PW :
      case ZL5011X_IP_UDP_RTP_PW_ALT :
      case ZL5011X_IP_UDP_L2TPV2_PW :
      case ZL5011X_IP_UDP_RTCP_CTRL :
      case ZL5011X_IP_UDP_L2TPV2_CTRL :
         /* all of the IP->UDP protocols */
         ipv4Header = par->ipVer4;
         udpHeader = ZL5011X_TRUE;

         if (ipv4Header == ZL5011X_TRUE)
         {
            udpPos = ZL5011X_PKT_ETHERNET_HDR_LEN + ZL5011X_PKT_IPV4_HDR_LEN;
         }
         else
         {
            udpPos = ZL5011X_PKT_ETHERNET_HDR_LEN + ZL5011X_PKT_IPV6_HDR_LEN;
         }
         break;

      default:
         /* all of the IP protocols */
         ipv4Header = par->ipVer4;
         udpHeader = ZL5011X_FALSE;
         break;
   }

   /* Check to see if this protocol stack is already in use for this device. First try to find the device in the list
      by matching the device structure pointer */
   for (deviceIndex = 0; deviceIndex < ZL5011X_MAX_NUMBER_DEVICES; deviceIndex++)
   {
      if (Zl5011xProtocolTable[deviceIndex].paramStructPointer == zl5011xParams)
      {
         break;
      }
   }

   /* If it got to the end of the list and didn't match one, then create one
      with the first available null pointer in the list */
   if (deviceIndex == ZL5011X_MAX_NUMBER_DEVICES)
   {
      for (deviceIndex = 0; deviceIndex < ZL5011X_MAX_NUMBER_DEVICES; deviceIndex++)
      {
         if (Zl5011xProtocolTable[deviceIndex].paramStructPointer == NULL)
         {
            Zl5011xProtocolTable[deviceIndex].paramStructPointer = zl5011xParams;
            for (n = 0; n < ZL5011X_PKT_NUM_PROTOCOL_STACKS; n++)
            {
               Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[0][0] = (Uint32T)ZL5011X_INVALID;
               Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[0][1] = (Uint32T)ZL5011X_INVALID;
               Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[1][0] = (Uint32T)ZL5011X_INVALID;
               Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[1][1] = (Uint32T)ZL5011X_INVALID;
            }

            for (n = 0; n < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES; n++)
            {
               Zl5011xProtocolTable[deviceIndex].entry[n].contextDescriptorOffset = (Uint16T)ZL5011X_INVALID;
               Zl5011xProtocolTable[deviceIndex].entry[n].protocol = ZL5011X_INVALID_PROTOCOL;
            }
            break;
         }
      }

      if (deviceIndex == ZL5011X_MAX_NUMBER_DEVICES)
      {
         /* No free slot was found for the new device */
         return(ZL5011X_ERROR);
      }
   }

   /* Have a look to see if this protocol stack has been set up already */
   if ((par->protocolType == ZL5011X_CD) || (par->protocolType == ZL5011X_IP_CD) ||
      (par->protocolType == ZL5011X_IP_UDP_CD))
   {
      /* Prevent use of conficting protocol stacks simultaneously */
      if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] == ZL5011X_PKT_INCOMPATIBLE_HEADER)
      {
         /* this header cannot be setup, due to a conflicting protocol that has already been set */
         return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
      }
      /* CD Protocol stacks are a special case because they may be setup but with different pre-classification data - this will
         depend on the offset of the CD header. If there is a pre-classification entry of the same protocol stack and the CD
         offset is the same then this match can be used. */
      if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
      {
         /* This means that the wanted CD stack has been used at least once. Now check the per pre-classification CD offset array
            to see if any of them have matches. */
         for (n = 0; n < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES; n++)
         {
            if ((Uint8T)par->contextDescriptorOffset > (par->headerLength - ZL5011X_PKT_CD_HDR_LEN))
            {
               realContextDescriptorOffset = (par->headerLength - ZL5011X_PKT_CD_HDR_LEN);
            }
            else
            {
               realContextDescriptorOffset = par->contextDescriptorOffset;
            }

            realContextDescriptorOffset -= snapOffset;

            /* check if the protocol has already been setup with this CD offset */
            if ((Zl5011xProtocolTable[deviceIndex].entry[n].protocol == par->protocolType) &&
               (Zl5011xProtocolTable[deviceIndex].entry[n].enableVlan == par->enableVlan) &&
               (Zl5011xProtocolTable[deviceIndex].entry[n].contextDescriptorOffset == realContextDescriptorOffset))
            {
               if ((par->protocolType == ZL5011X_CD) || (Zl5011xProtocolTable[deviceIndex].entry[n].ipVer4 == par->ipVer4))
               {
                 if (par->enableSnap == ZL5011X_TRUE)
                 {
                   par->contextDescriptorOffset = realContextDescriptorOffset + ZL5011X_PKT_SNAP_FIELD_LEN;
                 }
                 else
                 {
                   par->contextDescriptorOffset = realContextDescriptorOffset;
                 }
                 par->protocolMatchNumber = n;
                 return(ZL5011X_OK);
               }
            }
         }
      }
   }
   else
   {
      if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] == ZL5011X_PKT_INCOMPATIBLE_HEADER)
      {
         /* this header cannot be setup, due to a conflicting protocol that has already been set */
         return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
      }
      else
      {
         if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
         {
            par->protocolMatchNumber = Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4];

            if ((par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) || (par->protocolType == ZL5011X_IP_L2TPV3_RTCP_CTRL))
            {
               if (Zl5011xProtocolTable[deviceIndex].entry[par->protocolMatchNumber].enableL2TPCookie != par->enableL2TPCookie)
               {
                  /* the protocol has already been setup, but with a different setting for
                     the cookie so return an error */
                  return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
               }
            }

            if ((par->protocolType == ZL5011X_IP_UDP_RTP_PW) ||
               (par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) ||
               (par->protocolType == ZL5011X_MPLS_PW_RTP) ||
               (par->protocolType == ZL5011X_IP_UDP_RTP_PW_ALT))
            {
               if (Zl5011xProtocolTable[deviceIndex].entry[par->protocolMatchNumber].rtpForceSeqNumber != par->rtpForceSeqNumber)
               {
                  /* the protocol has already been setup, but with a different setting for
                     the RTP sequence number, so return an error */
                  return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
               }
            }
            /* found the protocol already defined, return OK */
            return(ZL5011X_OK);
         }
      }
   }

   /* Some of the protocol stacks have specific requirements. These are checked here. */
   /* ZL5011X_PW can only be used if VLAN is enabled. This is because the ethernet and PW fields do not provide
      for any classification tags. This is not a recoverable error, so return a failure. */
   if ((par->protocolType == ZL5011X_PW) && (par->enableVlan != ZL5011X_TRUE))
   {
      ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: Protocol Stack ZL5011X_PW requires VLAN to be enabled.",0,0,0,0,0,0);
      return(ZL5011X_PARAMETER_INVALID);
   }

   /* if setting up an IP->L2TPv3->RTP header, then need to check that the cookie
      setting is the same for both the data and control setups */
   if ((par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) || (par->protocolType == ZL5011X_IP_L2TPV3_RTCP_CTRL))
   {
      if (par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW)
      {
         temp = Zl5011xProtocolTable[deviceIndex].protocol[ZL5011X_IP_L2TPV3_RTCP_CTRL].matchNum[par->enableVlan][par->ipVer4];
      }
      else
      {
         temp = Zl5011xProtocolTable[deviceIndex].protocol[ZL5011X_IP_L2TPV3_RTP_PW].matchNum[par->enableVlan][par->ipVer4];
      }

      if (temp < (Sint32T)ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
      {
         /* the other type has already been setup, so check the cookie setting */
         if (Zl5011xProtocolTable[deviceIndex].entry[temp].enableL2TPCookie != par->enableL2TPCookie)
         {
            /* Return the protocol match this conflicted with in the structure referenced */
            par->protocolMatchNumber = temp;
            return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
         }
      }
   }

   /* The header length should be a determinable value which can be checked - for non-CD
      headers (arbitrary padding may be present for CD header). If headerLength does differ,
      then use the local value. */
   headerLength = zl5011xGetHeaderLength(par);

   if ((par->protocolType != ZL5011X_CD) && (par->protocolType != ZL5011X_IP_CD) &&
      (par->protocolType != ZL5011X_IP_UDP_CD))
   {
      if (headerLength != par->headerLength)
      {
         ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: protocol header length should be %ld, not %ld.",
               headerLength, par->headerLength, 0, 0, 0, 0);
         ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: Warning, using calculated header length.",0,0,0,0,0,0);

         par->headerLength = (Uint8T)headerLength;
      }
   }

   lanRxSetProtocolMatch = (zl5011xLanRxSetProtocolMatchS *)OS_CALLOC(1,sizeof(zl5011xLanRxSetProtocolMatchS));
   if (lanRxSetProtocolMatch  == NULL)
   {
      return(ZL5011X_RTOS_MEMORY_FAIL);
   }

   /* Initialise the structure. */
   status = zl5011xLanRxSetProtocolMatchStructInit(zl5011xParams, lanRxSetProtocolMatch);
   lanRxSetProtocolMatch->osExclusionEnable = par->osExclusionEnable;

   if (status != ZL5011X_OK)
   {
      OS_FREE(lanRxSetProtocolMatch);
      return(status);
   }

   /* Take account of IP version */
   if (par->ipVer4 == ZL5011X_TRUE)
   {
      templateInUse = &(zl5011xPacketRxTemplatesIPv4[par->protocolType]);
   }
   else

⌨️ 快捷键说明

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