| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- #include "headers.h"
- static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header);
- static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header);
- static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header);
- static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
- UCHAR *pucNextHeader, bool *bParseDone, USHORT *pusPayloadLength)
- {
- UCHAR *pucRetHeaderPtr = NULL;
- UCHAR *pucPayloadPtr = NULL;
- USHORT usNextHeaderOffset = 0;
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- if ((ppucPayload == NULL) || (*pusPayloadLength == 0) ||
- (*bParseDone)) {
- *bParseDone = TRUE;
- return NULL;
- }
- pucRetHeaderPtr = *ppucPayload;
- pucPayloadPtr = *ppucPayload;
- if (!pucRetHeaderPtr || !pucPayloadPtr) {
- *bParseDone = TRUE;
- return NULL;
- }
- /* Get the Nextt Header Type */
- *bParseDone = false;
- switch (*pucNextHeader) {
- case IPV6HDR_TYPE_HOPBYHOP:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 HopByHop Header");
- usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr);
- break;
- case IPV6HDR_TYPE_ROUTING:
- {
- struct bcm_ipv6_routing_hdr *pstIpv6RoutingHeader;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Routing Header");
- pstIpv6RoutingHeader =
- (struct bcm_ipv6_routing_hdr *)pucPayloadPtr;
- usNextHeaderOffset += sizeof(struct bcm_ipv6_routing_hdr);
- usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses *
- IPV6_ADDRESS_SIZEINBYTES;
- }
- break;
- case IPV6HDR_TYPE_FRAGMENTATION:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Fragmentation Header");
- usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr);
- break;
- case IPV6HDR_TYPE_DESTOPTS:
- {
- struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr =
- (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr;
- int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 DestOpts Header Header");
- usNextHeaderOffset += sizeof(struct bcm_ipv6_dest_options_hdr);
- usNextHeaderOffset += nTotalOptions *
- IPV6_DESTOPTS_HDR_OPTIONSIZE;
- }
- break;
- case IPV6HDR_TYPE_AUTHENTICATION:
- {
- struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr =
- (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr;
- int nHdrLen = pstIpv6AuthHdr->ucLength;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Authentication Header");
- usNextHeaderOffset += nHdrLen * 4;
- }
- break;
- case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Encrypted Security Payload Header");
- *bParseDone = TRUE;
- break;
- case IPV6_ICMP_HDR_TYPE:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nICMP Header");
- *bParseDone = TRUE;
- break;
- case TCP_HEADER_TYPE:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nTCP Header");
- *bParseDone = TRUE;
- break;
- case UDP_HEADER_TYPE:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nUDP Header");
- *bParseDone = TRUE;
- break;
- default:
- *bParseDone = TRUE;
- break;
- }
- if (*bParseDone == false) {
- if (*pusPayloadLength <= usNextHeaderOffset) {
- *bParseDone = TRUE;
- } else {
- *pucNextHeader = *pucPayloadPtr;
- pucPayloadPtr += usNextHeaderOffset;
- (*pusPayloadLength) -= usNextHeaderOffset;
- }
- }
- *ppucPayload = pucPayloadPtr;
- return pucRetHeaderPtr;
- }
- static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
- USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader)
- {
- UCHAR *pIpv6HdrScanContext = pucPayload;
- bool bDone = false;
- UCHAR ucHeaderType = 0;
- UCHAR *pucNextHeader = NULL;
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- if (!pucPayload || (usPayloadLength == 0))
- return 0;
- *pusSrcPort = *pusDestPort = 0;
- ucHeaderType = ucNextHeader;
- while (!bDone) {
- pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,
- &ucHeaderType,
- &bDone,
- &usPayloadLength);
- if (bDone) {
- if ((ucHeaderType == TCP_HEADER_TYPE) ||
- (ucHeaderType == UDP_HEADER_TYPE)) {
- *pusSrcPort = *((PUSHORT)(pucNextHeader));
- *pusDestPort = *((PUSHORT)(pucNextHeader+2));
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",
- ntohs(*pusSrcPort),
- ntohs(*pusDestPort));
- }
- break;
- }
- }
- return ucHeaderType;
- }
- /*
- * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver control
- * structure
- * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet
- */
- USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
- struct bcm_classifier_rule *pstClassifierRule)
- {
- USHORT ushDestPort = 0;
- USHORT ushSrcPort = 0;
- UCHAR ucNextProtocolAboveIP = 0;
- struct bcm_ipv6_hdr *pstIpv6Header = NULL;
- bool bClassificationSucceed = false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "IpVersion6 ==========>\n");
- pstIpv6Header = pcIpHeader;
- DumpIpv6Header(pstIpv6Header);
- /*
- * Try to get the next higher layer protocol
- * and the Ports Nos if TCP or UDP
- */
- ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader +
- sizeof(struct bcm_ipv6_hdr)),
- &ushSrcPort,
- &ushDestPort,
- pstIpv6Header->usPayloadLength,
- pstIpv6Header->ucNextHeader);
- do {
- if (pstClassifierRule->ucDirection == 0) {
- /*
- * cannot be processed for classification.
- * it is a down link connection
- */
- break;
- }
- if (!pstClassifierRule->bIpv6Protocol) {
- /*
- * We are looking for Ipv6 Classifiers
- * Lets ignore this classifier and try the next one
- */
- break;
- }
- bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule,
- pstIpv6Header);
- if (!bClassificationSucceed)
- break;
- bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule,
- pstIpv6Header);
- if (!bClassificationSucceed)
- break;
- /*
- * Match the protocol type.
- * For IPv6 the next protocol at end of
- * Chain of IPv6 prot headers
- */
- bClassificationSucceed = MatchProtocol(pstClassifierRule,
- ucNextProtocolAboveIP);
- if (!bClassificationSucceed)
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Protocol Matched");
- if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) ||
- (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) {
- /* Match Src Port */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",
- ntohs(ushSrcPort));
- bClassificationSucceed = MatchSrcPort(pstClassifierRule,
- ntohs(ushSrcPort));
- if (!bClassificationSucceed)
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Src Port Matched");
- /* Match Dest Port */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Destination Port:%x\n",
- ntohs(ushDestPort));
- bClassificationSucceed = MatchDestPort(pstClassifierRule,
- ntohs(ushDestPort));
- if (!bClassificationSucceed)
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Dest Port Matched");
- }
- } while (0);
- if (bClassificationSucceed == TRUE) {
- INT iMatchedSFQueueIndex = 0;
- iMatchedSFQueueIndex = SearchSfid(Adapter,
- pstClassifierRule->ulSFID);
- if ((iMatchedSFQueueIndex >= NO_OF_QUEUES) ||
- (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false))
- bClassificationSucceed = false;
- }
- return bClassificationSucceed;
- }
- static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header)
- {
- UINT uiLoopIndex = 0;
- UINT uiIpv6AddIndex = 0;
- UINT uiIpv6AddrNoLongWords = 4;
- ULONG aulSrcIP[4];
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- union u_ip_address *src_addr = &pstClassifierRule->stSrcIpAddress;
- /*
- * This is the no. of Src Addresses ie Range of IP Addresses contained
- * in the classifier rule for which we need to match
- */
- UINT uiCountIPSrcAddresses =
- (UINT)pstClassifierRule->ucIPSourceAddressLength;
- if (uiCountIPSrcAddresses == 0)
- return TRUE;
- /* First Convert the Ip Address in the packet to Host Endian order */
- for (uiIpv6AddIndex = 0;
- uiIpv6AddIndex < uiIpv6AddrNoLongWords;
- uiIpv6AddIndex++)
- aulSrcIP[uiIpv6AddIndex] =
- ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
- for (uiLoopIndex = 0;
- uiLoopIndex < uiCountIPSrcAddresses;
- uiLoopIndex += uiIpv6AddrNoLongWords) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Src Ipv6 Address In Received Packet :\n ");
- DumpIpv6Address(aulSrcIP);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Src Ipv6 Mask In Classifier Rule:\n");
- DumpIpv6Address(&src_addr->ulIpv6Mask[uiLoopIndex]);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Src Ipv6 Address In Classifier Rule :\n");
- DumpIpv6Address(&src_addr->ulIpv6Addr[uiLoopIndex]);
- for (uiIpv6AddIndex = 0;
- uiIpv6AddIndex < uiIpv6AddrNoLongWords;
- uiIpv6AddIndex++) {
- if ((src_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] &
- aulSrcIP[uiIpv6AddIndex]) !=
- src_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
- /*
- * Match failed for current Ipv6 Address
- * Try next Ipv6 Address
- */
- break;
- }
- if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
- /* Match Found */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "Ipv6 Src Ip Address Matched\n");
- return TRUE;
- }
- }
- }
- return false;
- }
- static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header)
- {
- UINT uiLoopIndex = 0;
- UINT uiIpv6AddIndex = 0;
- UINT uiIpv6AddrNoLongWords = 4;
- ULONG aulDestIP[4];
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress;
- /*
- * This is the no. of Destination Addresses
- * ie Range of IP Addresses contained in the classifier rule
- * for which we need to match
- */
- UINT uiCountIPDestinationAddresses =
- (UINT)pstClassifierRule->ucIPDestinationAddressLength;
- if (uiCountIPDestinationAddresses == 0)
- return TRUE;
- /* First Convert the Ip Address in the packet to Host Endian order */
- for (uiIpv6AddIndex = 0;
- uiIpv6AddIndex < uiIpv6AddrNoLongWords;
- uiIpv6AddIndex++)
- aulDestIP[uiIpv6AddIndex] =
- ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
- for (uiLoopIndex = 0;
- uiLoopIndex < uiCountIPDestinationAddresses;
- uiLoopIndex += uiIpv6AddrNoLongWords) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Destination Ipv6 Address In Received Packet :\n ");
- DumpIpv6Address(aulDestIP);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Destination Ipv6 Mask In Classifier Rule :\n");
- DumpIpv6Address(&dest_addr->ulIpv6Mask[uiLoopIndex]);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "\n Destination Ipv6 Address In Classifier Rule :\n");
- DumpIpv6Address(&dest_addr->ulIpv6Addr[uiLoopIndex]);
- for (uiIpv6AddIndex = 0;
- uiIpv6AddIndex < uiIpv6AddrNoLongWords;
- uiIpv6AddIndex++) {
- if ((dest_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] &
- aulDestIP[uiIpv6AddIndex]) !=
- dest_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
- /*
- * Match failed for current Ipv6 Address.
- * Try next Ipv6 Address
- */
- break;
- }
- if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
- /* Match Found */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "Ipv6 Destination Ip Address Matched\n");
- return TRUE;
- }
- }
- }
- return false;
- }
- VOID DumpIpv6Address(ULONG *puIpv6Address)
- {
- UINT uiIpv6AddrNoLongWords = 4;
- UINT uiIpv6AddIndex = 0;
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- for (uiIpv6AddIndex = 0;
- uiIpv6AddIndex < uiIpv6AddrNoLongWords;
- uiIpv6AddIndex++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- ":%lx", puIpv6Address[uiIpv6AddIndex]);
- }
- }
- static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header)
- {
- UCHAR ucVersion;
- UCHAR ucPrio;
- struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "----Ipv6 Header---");
- ucVersion = pstIpv6Header->ucVersionPrio & 0xf0;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Version : %x\n", ucVersion);
- ucPrio = pstIpv6Header->ucVersionPrio & 0x0f;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Priority : %x\n", ucPrio);
- /*
- * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0);
- */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Payload Length : %x\n",
- ntohs(pstIpv6Header->usPayloadLength));
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Next Header : %x\n", pstIpv6Header->ucNextHeader);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Hop Limit : %x\n", pstIpv6Header->ucHopLimit);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Src Address :\n");
- DumpIpv6Address(pstIpv6Header->ulSrcIpAddress);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "Dest Address :\n");
- DumpIpv6Address(pstIpv6Header->ulDestIpAddress);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
- "----Ipv6 Header End---");
- }
|