BOOLEAN hs20IsGratuitousArp( IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb ) { PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; PUINT_8 pucSenderMac = ((PUINT_8)prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); #if CFG_HS20_DEBUG && 0 // UINT_8 aucIpAllZero[4] = {0,0,0,0}; // UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; PUINT_8 pucTargetMac = ((PUINT_8)prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); #endif #if CFG_HS20_DEBUG && 0 PUINT_16 pu2ArpOper = (PUINT_16)((PUINT_8)prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); kalPrint("SENDER["MACSTR"] [%d:%d:%d:%d]\n", MAC2STR(pucSenderMac), *pucSenderIP, *(pucSenderIP+1), *(pucSenderIP+2), *(pucSenderIP+3)); kalPrint("TARGET["MACSTR"] [%d:%d:%d:%d]\n", MAC2STR(pucTargetMac), *pucTargetIP, *(pucTargetIP+1), *(pucTargetIP+2), *(pucTargetIP+3)); #endif // IsGratuitousArp if(!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { kalPrint("Drop Gratuitous ARP from ["MACSTR"] [%d:%d:%d:%d]\n", MAC2STR(pucSenderMac), *pucTargetIP, *(pucTargetIP+1), *(pucTargetIP+2), *(pucTargetIP+3)); return TRUE; } return FALSE; }
/*----------------------------------------------------------------------------*/ VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) { PUINT_8 cp; PNDIS_802_11_ASSOCIATION_INFORMATION prNdisAssocInfo; UINT_32 u4AvailableAssocRespIEBufLen; ASSERT(u4FrameBodyLen >= MIN_REASSOC_RESP_BODY_LEN); if (u4FrameBodyLen < MIN_REASSOC_RESP_BODY_LEN) { return; } prNdisAssocInfo = &prGlueInfo->rNdisAssocInfo; cp = pucFrameBody; /* Update the fixed information elements. */ prNdisAssocInfo->AvailableResponseFixedIEs = NDIS_802_11_AI_RESFI_CAPABILITIES | NDIS_802_11_AI_RESFI_STATUSCODE | NDIS_802_11_AI_RESFI_ASSOCIATIONID; kalMemCopy(&prNdisAssocInfo->ResponseFixedIEs.Capabilities, cp, 2); cp += 2; kalMemCopy(&prNdisAssocInfo->ResponseFixedIEs.StatusCode, cp, 2); cp += 2; kalMemCopy(&prNdisAssocInfo->ResponseFixedIEs.AssociationId, cp, 2); cp += 2; u4FrameBodyLen -= 6; /* Update the variable length information elements. */ u4AvailableAssocRespIEBufLen = (sizeof(prGlueInfo->aucNdisAssocInfoIEs) > prNdisAssocInfo->RequestIELength) ? sizeof(prGlueInfo->aucNdisAssocInfoIEs) - prNdisAssocInfo->RequestIELength : 0; if (u4FrameBodyLen > u4AvailableAssocRespIEBufLen) { ASSERT(u4FrameBodyLen <= u4AvailableAssocRespIEBufLen); u4FrameBodyLen = u4AvailableAssocRespIEBufLen; } prNdisAssocInfo->ResponseIELength = u4FrameBodyLen; prNdisAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + prNdisAssocInfo->RequestIELength; if (u4FrameBodyLen) { #if BUILD_WMM UINT_32 len = 0; UINT_8 elemLen = 0, elemId = 0, wifiElemId = 221; UINT_8 wifiOuiWMM[] = { 0x00, 0x50, 0xF2, 0x02 }; #endif kalMemCopy(&prGlueInfo->aucNdisAssocInfoIEs[prNdisAssocInfo->RequestIELength], cp, u4FrameBodyLen); #if BUILD_WMM prGlueInfo->supportWMM = FALSE; while (len < u4FrameBodyLen) { elemId = *cp; elemLen = *(cp + 1); if (elemId == wifiElemId && (elemLen > sizeof(wifiOuiWMM))) { if (kalMemCmp(cp + 2, wifiOuiWMM, sizeof(wifiOuiWMM)) == 0) { prGlueInfo->supportWMM = TRUE; #if DBG /* DbgPrint("WMM AP\n"); */ #endif break; } } len += elemLen + 2; cp += elemLen + 2; } #endif } } /* kalUpdateReAssocRspInfo */
/*----------------------------------------------------------------------------*/ int priv_set_struct ( IN struct net_device *prNetDev, IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra ) { UINT_32 u4SubCmd = 0; UINT_8 aucOidBuf[4096] = {0}; int status = 0; //WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; //UINT_32 u4CmdLen = 0; P_GLUE_INFO_T prGlueInfo = NULL; UINT_32 u4BufLen = 0; ASSERT(prNetDev); //ASSERT(prIwReqInfo); ASSERT(prIwReqData); //ASSERT(pcExtra); if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) { return -EINVAL; } prGlueInfo = (P_GLUE_INFO_T)netdev_priv(prNetDev); u4SubCmd = (UINT_32)prIwReqData->data.flags; #if 0 printk(KERN_INFO DRV_NAME"priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", prIwReqInfo->cmd, u4SubCmd ); #endif switch (u4SubCmd) { #if 0 //PTA_ENABLED case PRIV_CMD_BT_COEXIST: u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) { return -EFAULT; } if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { status = -EFAULT; //return -EFAULT; break; } rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); if (WLAN_STATUS_SUCCESS != rStatus) { status = -EFAULT; } break; case PRIV_CUSTOM_BWCS_CMD: u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) { return -EFAULT; } if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { status = -EFAULT; //return -EFAULT; break; } status = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); if (WLAN_STATUS_SUCCESS != rStatus) { status = -EFAULT; } break; #endif /* end of BUILD_PTA */ #if SUPPORT_WAPI case PRIV_SEC_MSG_OID: { int msg_in_len =0; int msg_out_len = 0; unsigned char msg_out[1024]; DBGLOG(WAPI, TRACE, ("Set msg private ioctl!!!\n")); if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { //+2 status = -EFAULT; break; } msg_in_len = prIwReqData->data.length; if(aucOidBuf[0] == 0x01) { handle_sec_msg_1(aucOidBuf, msg_in_len, msg_out , &msg_out_len); prIwReqData->data.length = msg_out_len; if (copy_to_user(prIwReqData->data.pointer, &(prIwReqData->data.length), sizeof(__u16))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } if (copy_to_user((char *)prIwReqData->data.pointer + sizeof(__u16), &msg_out[0], prIwReqData->data.length)) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } } else if(aucOidBuf[0] == 0x02){ handle_sec_msg_2(aucOidBuf, msg_in_len, msg_out , &msg_out_len); prIwReqData->data.length = 0; if (copy_to_user(prIwReqData->data.pointer, &(prIwReqData->data.length), sizeof(__u16))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } } else if(aucOidBuf[0] == 0x03){ handle_sec_msg_3(aucOidBuf, msg_in_len, msg_out , &msg_out_len); prIwReqData->data.length = 0; if (copy_to_user(prIwReqData->data.pointer, &(prIwReqData->data.length), sizeof(__u16))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } } else if(aucOidBuf[0] == 0x04){ handle_sec_msg_4(aucOidBuf, msg_in_len, msg_out , &msg_out_len); prIwReqData->data.length = 0; if (copy_to_user(prIwReqData->data.pointer, &(prIwReqData->data.length), sizeof(__u16))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } } else if(aucOidBuf[0] == 0x05){ handle_sec_msg_5(aucOidBuf, msg_in_len, msg_out , &msg_out_len); prIwReqData->data.length = 0; if (copy_to_user(prIwReqData->data.pointer, &(prIwReqData->data.length), sizeof(__u16))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; break; } } } break; #endif case PRIV_CMD_OID: if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { status = -EFAULT; break; } if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) { printk(KERN_INFO DRV_NAME"pcExtra buffer is valid\n"); } else printk(KERN_INFO DRV_NAME"pcExtra 0x%p\n", pcExtra); /* Execute this OID */ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT)&aucOidBuf[0], &u4BufLen); /* Copy result to user space */ ((P_NDIS_TRANSPORT_STRUCT)&aucOidBuf[0])->outNdisOidLength = u4BufLen; if (copy_to_user(prIwReqData->data.pointer, &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { printk(KERN_NOTICE "copy_to_user oidBuf fail\n"); status = -EFAULT; } break; default: return -EOPNOTSUPP; } return status; }
/*----------------------------------------------------------------------------*/ BOOLEAN kalBowFrameClassifier(IN P_GLUE_INFO_T prGlueInfo, IN P_NATIVE_PACKET prPacket, OUT PBOOLEAN pfgIs1X) { UINT_32 u4PacketLen; UINT_16 u2EtherTypeLen; struct sk_buff *prSkb = (struct sk_buff *)prPacket; PUINT_8 aucLookAheadBuf = NULL; UINT_8 ucEthTypeLenOffset = ETHER_HEADER_LEN - ETHER_TYPE_LEN; PUINT_8 pucNextProtocol = NULL; UINT_8 aucLLC[] = ETH_LLC; UINT_8 aucSnapBtOui[] = ETH_SNAP_BT_SIG_OUI; UINT_8 ucMinLength = ucEthTypeLenOffset + ETHER_TYPE_LEN + ETH_LLC_LEN + ETH_SNAP_LEN; DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); u4PacketLen = prSkb->len; if (u4PacketLen < ETHER_HEADER_LEN) { DBGLOG(INIT, WARN, ("Invalid Ether packet length: %lu\n", u4PacketLen)); return FALSE; } aucLookAheadBuf = prSkb->data; *pfgIs1X = FALSE; /* 4 <0> Obtain Ether Type/Len */ WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen); /* 4 <1> Skip 802.1Q header (VLAN Tagging) */ if (u2EtherTypeLen == ETH_P_VLAN) { ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN; WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen); } /* 4 <2> Obtain next protocol pointer */ pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + ETHER_TYPE_LEN]; /* 4 <3> Handle ethernet format */ if (u2EtherTypeLen > ETH_802_3_MAX_LEN) { /* Not BoW frame */ return FALSE; } /* 4 <4> Check for PAL (BT over Wi-Fi) */ /* BoW LLC/SNAP header check */ if (u4PacketLen >= ucMinLength && !kalMemCmp(pucNextProtocol, aucLLC, ETH_LLC_LEN) && !kalMemCmp(pucNextProtocol + ETH_LLC_LEN, aucSnapBtOui, ETH_SNAP_OUI_LEN)) { UINT_16 u2LocalCode; WLAN_GET_FIELD_BE16(pucNextProtocol + ETH_LLC_LEN + ETH_SNAP_OUI_LEN, &u2LocalCode); if (u2LocalCode == BOW_PROTOCOL_ID_SECURITY_FRAME) { *pfgIs1X = TRUE; } return TRUE; } return FALSE; } /* end of kalBoWFrameClassifier() */