VOID IGMPSnooping( IN PRTMP_ADAPTER pAd, IN PUCHAR pDstMacAddr, IN PUCHAR pSrcMacAddr, IN PUCHAR pIpHeader, IN PNET_DEV pDev) { INT i; INT IpHeaderLen; UCHAR GroupType; UINT16 numOfGroup; UCHAR IgmpVerType; PUCHAR pIgmpHeader; PUCHAR pGroup; UCHAR AuxDataLen; UINT16 numOfSources; PUCHAR pGroupIpAddr; UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; if(isIgmpPkt(pDstMacAddr, pIpHeader)) { IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4; pIgmpHeader = pIpHeader + 2 + IpHeaderLen; IgmpVerType = (UCHAR)(*(pIgmpHeader)); DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType)); switch(IgmpVerType) { case IGMP_V1_MEMBERSHIP_REPORT: // IGMP version 1 membership report. case IGMP_V2_MEMBERSHIP_REPORT: // IGMP version 2 membership report. pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x
NDIS_STATUS IgmpPktInfoQuery( IN PRTMP_ADAPTER pAd, IN PUCHAR pSrcBufVA, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID, OUT INT *pInIgmpGroup, OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry) { if(IS_MULTICAST_MAC_ADDR(pSrcBufVA)) { INT32 ExcludedGroupType = -1; UINT16 EtherType = ntohs(*((UINT16 *)(pSrcBufVA + 12))); if (EtherType == ETH_P_IPV6) { ExcludedGroupType = IPv6MulticastFilterExcluded(pSrcBufVA); } else if(EtherType == ETH_P_IP) { ExcludedGroupType = IPv4MulticastFilterExcluded(pSrcBufVA); } if (ExcludedGroupType) { *ppGroupEntry = NULL; if (ExcludedGroupType == 1) *pInIgmpGroup = IGMP_PKT; } else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA, get_netdev_from_bssid(pAd, FromWhichBSSID))) == NULL) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else *pInIgmpGroup = IGMP_IN_GROUP; } else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA)) { PUCHAR pDstIpAddr = pSrcBufVA + 30; /* point to Destination of Ip address of IP header. */ UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr, get_netdev_from_bssid(pAd, FromWhichBSSID))) != NULL) { *pInIgmpGroup = IGMP_IN_GROUP; } } return NDIS_STATUS_SUCCESS; }
NDIS_STATUS IgmpPktInfoQuery( IN PRTMP_ADAPTER pAd, IN PUCHAR pSrcBufVA, IN PNDIS_PACKET pPacket, IN struct wifi_dev *wdev, OUT INT *pInIgmpGroup, OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry) { if(IS_MULTICAST_MAC_ADDR(pSrcBufVA)) { BOOLEAN IgmpMldPkt = FALSE; PUCHAR pIpHeader = pSrcBufVA + 12; if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6) IgmpMldPkt = IPv6MulticastFilterExcluded(pSrcBufVA, pIpHeader); else IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader); if (IgmpMldPkt) { *ppGroupEntry = NULL; *pInIgmpGroup = IGMP_PKT; } else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA, wdev->if_dev)) == NULL) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else *pInIgmpGroup = IGMP_IN_GROUP; } else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA)) { PUCHAR pDstIpAddr = pSrcBufVA + 30; /* point to Destination of Ip address of IP header. */ UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr, wdev->if_dev)) != NULL) { *pInIgmpGroup = IGMP_IN_GROUP; } } return NDIS_STATUS_SUCCESS; }
int Set_IgmpSn_DelEntry_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { int i, memberCnt = 0; BOOLEAN bGroupId = 1; PSTRING value; PSTRING thisChar; UCHAR IpAddr[4]; UCHAR Addr[ETH_LENGTH_OF_ADDRESS]; UCHAR GroupId[ETH_LENGTH_OF_ADDRESS]; PUCHAR *pAddr = (PUCHAR *)&Addr; PNET_DEV pDev; POS_COOKIE pObj; UCHAR ifIndex; pObj = (POS_COOKIE) pAd->OS_Cookie; ifIndex = pObj->ioctl_if; pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev); while ((thisChar = strsep((char **)&arg, "-")) != NULL) { /* refuse the Member if it's not a MAC address. */ if((bGroupId == 0) && (strlen(thisChar) != 17)) continue; if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ { for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":")) { if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) ) return FALSE; /*Invalid */ AtoH(value, &Addr[i++], 1); } if(i != 6) return FALSE; /*Invalid */ } else { for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,".")) { if((strlen(value) > 0) && (strlen(value) <= 3)) { int ii; for(ii=0; ii<strlen(value); ii++) if (!isxdigit(*(value + ii))) return FALSE; } else return FALSE; /*Invalid */ IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10); i++; } if(i != 4) return FALSE; /*Invalid */ ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP); } if(bGroupId == 1) COPY_MAC_ADDR(GroupId, Addr); else memberCnt++; if (memberCnt > 0 ) MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev); bGroupId = 0; } if(memberCnt == 0) MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev); DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n", __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5])); return TRUE; }
VOID IGMPSnooping( IN PRTMP_ADAPTER pAd, IN PUCHAR pDstMacAddr, IN PUCHAR pSrcMacAddr, IN PUCHAR pIpHeader, IN PNET_DEV pDev) { int i; int IpHeaderLen; UCHAR GroupType; UINT16 numOfGroup; UCHAR IgmpVerType; PUCHAR pIgmpHeader; PUCHAR pGroup; UCHAR AuxDataLen; UINT16 numOfSources; PUCHAR pGroupIpAddr; UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; if(isIgmpPkt(pDstMacAddr, pIpHeader)) { IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4; pIgmpHeader = pIpHeader + 2 + IpHeaderLen; IgmpVerType = (UCHAR)(*(pIgmpHeader)); DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType)); switch(IgmpVerType) { case IGMP_V1_MEMBERSHIP_REPORT: /* IGMP version 1 membership report. */ case IGMP_V2_MEMBERSHIP_REPORT: /* IGMP version 2 membership report. */ pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; case IGMP_LEAVE_GROUP: /* IGMP version 1 and version 2 leave group. */ pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev); break; case IGMP_V3_MEMBERSHIP_REPORT: /* IGMP version 3 membership report. */ numOfGroup = ntohs(*((UINT16 *)(pIgmpHeader + 6))); pGroup = (PUCHAR)(pIgmpHeader + 8); for (i=0; i < numOfGroup; i++) { GroupType = (UCHAR)(*pGroup); AuxDataLen = (UCHAR)(*(pGroup + 1)); numOfSources = ntohs(*((UINT16 *)(pGroup + 2))); pGroupIpAddr = (PUCHAR)(pGroup + 4); DBGPRINT(RT_DEBUG_TRACE, ("IGMPv3 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources)); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); do { if ((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES)) { MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; } if ((GroupType == CHANGE_TO_INCLUDE_MODE) || (GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES)) { if(numOfSources == 0) MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev); else MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; } } while(FALSE); pGroup += (8 + (numOfSources * 4) + AuxDataLen); } break; default: DBGPRINT(RT_DEBUG_TRACE, ("unknow IGMP Type=%d\n", IgmpVerType)); break; } } return; }
VOID MLDSnooping( IN PRTMP_ADAPTER pAd, IN PUCHAR pDstMacAddr, IN PUCHAR pSrcMacAddr, IN PUCHAR pIpHeader, IN PNET_DEV pDev) { int i; UCHAR GroupType; UINT16 numOfGroup; PUCHAR pGroup; UCHAR AuxDataLen; UINT16 numOfSources; PUCHAR pGroupIpAddr; UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; UINT8 MldType; PUCHAR pMldHeader; if(isMldPkt(pDstMacAddr, pIpHeader, &MldType, &pMldHeader) == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("MLD type=%0x\n", MldType)); switch(MldType) { case MLD_V1_LISTENER_REPORT: /* skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes). */ pGroupIpAddr = (PUCHAR)(pMldHeader + 8); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6); DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; case MLD_V1_LISTENER_DONE: /* skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes). */ pGroupIpAddr = (PUCHAR)(pMldHeader + 8); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6); DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev); break; case MLD_V2_LISTERNER_REPORT: /* IGMP version 3 membership report. */ numOfGroup = ntohs(*((UINT16 *)(pMldHeader + 6))); pGroup = (PUCHAR)(pMldHeader + 8); for (i=0; i < numOfGroup; i++) { GroupType = (UCHAR)(*pGroup); AuxDataLen = (UCHAR)(*(pGroup + 1)); numOfSources = ntohs(*((UINT16 *)(pGroup + 2))); pGroupIpAddr = (PUCHAR)(pGroup + 4); DBGPRINT(RT_DEBUG_TRACE, ("MLDv2 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources)); ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6); DBGPRINT(RT_DEBUG_TRACE, ("MLD Group=%02x:%02x:%02x:%02x:%02x:%02x\n", GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5])); do { if ((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES)) { MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; } if ((GroupType == CHANGE_TO_INCLUDE_MODE) || (GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES)) { if(numOfSources == 0) MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev); else MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC); break; } } while(FALSE); /* skip 4 Bytes (Record Type, Aux Data Len, Number of Sources) + a IPv6 address. */ pGroup += (4 + IPV6_ADDR_LEN + (numOfSources * 16) + AuxDataLen); } break; default: DBGPRINT(RT_DEBUG_TRACE, ("unknow MLD Type=%d\n", MldType)); break; } } return; }
INT Set_IgmpSn_AddEntry_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) { INT i; BOOLEAN bGroupId = 1; RTMP_STRING *value; RTMP_STRING *thisChar; UCHAR IpAddr[4]; UCHAR Addr[MAC_ADDR_LEN]; UCHAR GroupId[MAC_ADDR_LEN]; PUCHAR *pAddr = (PUCHAR *)&Addr; PNET_DEV pDev; POS_COOKIE pObj; UCHAR ifIndex; pObj = (POS_COOKIE) pAd->OS_Cookie; ifIndex = pObj->ioctl_if; pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].wdev.if_dev); while ((thisChar = strsep((char **)&arg, "-")) != NULL) { /* refuse the Member if it's not a MAC address. */ if((bGroupId == 0) && (strlen(thisChar) != 17)) continue; if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ { for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":")) { if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) ) return FALSE; /*Invalid */ AtoH(value, &Addr[i++], 1); } if(i != 6) return FALSE; /*Invalid */ } else { for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,".")) { if((strlen(value) > 0) && (strlen(value) <= 3)) { int ii; for(ii=0; ii<strlen(value); ii++) if (!isxdigit(*(value + ii))) return FALSE; } else return FALSE; /*Invalid */ IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10); i++; } if(i != 4) return FALSE; /*Invalid */ ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP); } if(bGroupId == 1) COPY_MAC_ADDR(GroupId, Addr); /* Group-Id must be a MCAST address. */ if((bGroupId == 1) && IS_MULTICAST_MAC_ADDR(Addr)) MulticastFilterTableInsertEntry(pAd, GroupId, NULL, pDev, MCAT_FILTER_STATIC); /* Group-Member must be a UCAST address. */ else if ((bGroupId == 0) && !IS_MULTICAST_MAC_ADDR(Addr)) MulticastFilterTableInsertEntry(pAd, GroupId, Addr, pDev, MCAT_FILTER_STATIC); else { DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X) is not a acceptable address.\n", __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5])); return FALSE; } bGroupId = 0; DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n", __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5])); } return TRUE; }