📄 dot11rsnlib.c
字号:
* dot11RsnFree - Cleans up the DOT11_RNS_OBJ structure** This routine frees all memory and resources allocated in dot11RsnInit().** RETURNS: OK, or ERROR** ERRNO: N/A*/LOCAL STATUS dot11RsnFree ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { dot11TimerDel(pDot11->dpe->groupRekeyTimer); return OK; }/****************************************************************************** dot11RsnIeCreate - Returns a filled in RSN Information Element** This routine takes the known security policies of this station and the* policies of the remote station and generates a RSN IE if supported.* The IE is written into the buffer provided and the number of bytes written* are returned. If RSN is not supported by the current policy, then* zero bytes will be written.** If both 802.11i and WPA are supported, then it is the responsibility of the * calling routine to ensure that they are presented in the appropriate order * (numerical IE order)** Note that no assumption on the alignment of buffer can be made. ** pKsl is used to determine if this packet should contain all of the device's* supported capabilities, or just those that were chosen for a particular* connected device (pKsl)** RETURNS: Number of bytes written to buffer, or 0 on ERROR** ERRNO: N/A*/LOCAL INT32 dot11RsnIeCreate ( DOT11_FW * pDot11, /* Pointer to device structure */ DOT11_KSL_ENTRY * pKsl, /* KSL entry for destination STA */ DOT11_BSS * pBss, /* BSS to create IE for */ UINT8 * buffer, /* Pre-alloc buffer into which to create */ int type /* DOT11_SECPOL_WPA or DOT11_SECPOL_RSN */ ) { int length = 0; /* Length currently written to buffer */ UINT8 * pBug; /* Bug for keeping track of current place */ UINT8 * pLength; /* Pointer to going back to modify length */ UINT8 thisOui[3]; int i; if ((pKsl == NULL) && (pBss == NULL)) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_RSN, ("dot11RsnIeCreate: NULL pKsl and pBss\n",0,0,0,0,0,0)); return 0; } if (((pBss->secPol & type) == 0) || ((type != DOT11_SECPOL_11i) && (type != DOT11_SECPOL_WPA))) { /* If RSN is not supported, then just return 0 */ return 0; } if (type == DOT11_SECPOL_WPA) { thisOui[0] = DOT11_WPA_OUI_0; thisOui[1] = DOT11_WPA_OUI_1; thisOui[2] = DOT11_WPA_OUI_2; } else { thisOui[0] = DOT11_RSN_OUI_0; thisOui[1] = DOT11_RSN_OUI_1; thisOui[2] = DOT11_RSN_OUI_2; } /* Set the bug to point to the start of the buffer */ pBug = buffer; /* Byte 0 : element ID */ if (type == DOT11_SECPOL_WPA) { *pBug = DOT11_ELEMID_WPA; } else { *pBug = DOT11_ELEMID_RSN; } pBug ++; length ++; /* Byte 1 : length */ /* DEFER this field until the length is known - at the end */ pBug ++; length ++; if (type == DOT11_SECPOL_WPA) { /* The WPA specification states that four bytes should be added before the version (as opposed to the 802.11i spec) */ ((DOT11_RSN_SUITE *)pBug)->oui[0] = DOT11_WPA_OUI_0; ((DOT11_RSN_SUITE *)pBug)->oui[1] = DOT11_WPA_OUI_1; ((DOT11_RSN_SUITE *)pBug)->oui[2] = DOT11_WPA_OUI_2; ((DOT11_RSN_SUITE *)pBug)->suiteType = DOT11_WPA_SUITE_ADVERTISEMENT; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } /* Version (remember, can't assume alignment) */ *pBug++ = DOT11_RSN_IE_VERSION; *pBug++ = 0x00; length += sizeof(UINT16); /* Group Cipher Suite */ ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; if (pKsl != NULL) { ((DOT11_RSN_SUITE *)pBug)->suiteType = dot11RsnCiphToSuite[pKsl->groupPol]; } else { ((DOT11_RSN_SUITE *)pBug)->suiteType = dot11RsnCiphToSuite[pBss->multiEncryptType]; } length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); /* Pairwise cipher suite count */ if (pKsl != NULL) { *pBug++ = 1; /* Max one unicast cipher on response */ *pBug++ = 0x00; length += sizeof(UINT16); ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; ((DOT11_RSN_SUITE *)pBug)->suiteType = dot11RsnCiphToSuite[pKsl->uniEncryptType]; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } else { pLength = pBug; *pBug++ = dot11RsnBitCount(pBss->ciphPol); *pBug++ = 0x00; length += sizeof(UINT16); /* Pairwise suite list */ for (i = 1; i < DOT11_CIPHPOL_MAX; i <<= 1) { if ((pBss->ciphPol & i) != 0) { /* If we're not in a TSN, then disallow WEP */ if (((i == DOT11_KEY_TYPE_WEP40) || (i == DOT11_KEY_TYPE_WEP104)) && ((pBss->secPol & DOT11_SECPOL_TSN) == 0)) { *pLength = *pLength - 1; continue; } ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; ((DOT11_RSN_SUITE *)pBug)->suiteType = dot11RsnCiphToSuite[i]; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } } } /* Authentication and Key management suite count */ if (pKsl != NULL) { /* We're only allowed one suite is we're a sta, ie pKsl != NULL */ *pBug++ = 1; *pBug++ = 0x00; length += 2; ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; ((DOT11_RSN_SUITE *)pBug)->suiteType = pKsl->negAuthPol; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } else { *pBug++ = dot11RsnBitCount(pBss->authPol); *pBug++ = 0x00; length += sizeof(UINT16); /* Authentication and Key management suite list */ if ((pBss->authPol & DOT11_AUTHPOL_PSK) != 0) { ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; ((DOT11_RSN_SUITE *)pBug)->suiteType = DOT11_RSN_SUITE_PSK; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } if ((pBss->authPol & DOT11_AUTHPOL_8021X) != 0) { ((DOT11_RSN_SUITE *)pBug)->oui[0] = thisOui[0]; ((DOT11_RSN_SUITE *)pBug)->oui[1] = thisOui[1]; ((DOT11_RSN_SUITE *)pBug)->oui[2] = thisOui[2]; ((DOT11_RSN_SUITE *)pBug)->suiteType = DOT11_RSN_SUITE_8021X; length += sizeof(DOT11_RSN_SUITE); pBug += sizeof(DOT11_RSN_SUITE); } } if (type == DOT11_SECPOL_11i) { /* RSN Capabilities. This is hardcoded to one of each type of replay counter and no pre-authentication. */ *pBug++ = 0x00; *pBug++ = 0x00; length += sizeof(UINT16); /* Since pre-authentication is not supported, we won't support the PMKID count and PMKID fields */ } /* Fill in the IE length, which is the total length written minus the elemId and length fields */ *(buffer + 1) = length - DOT11_IE_HEADER_SIZE; return length; }/****************************************************************************** dot11RsnIeProcess - Records the information in a remote station's RSN/WPA IE** This routine is called when a RSN or WPA Information Element is found in a* remote stations probes, beacons or association packets. It records the * information for future use when replying to that station.** RETURNS: OK, or ERROR** ERRNO: N/A*/LOCAL STATUS dot11RsnSecIeProcess ( DOT11_FW * pDot11, /* Pointer to device structure */ DOT11_KSL_ENTRY * pKsl, /* KSL entry for destination STA */ UINT8 * buffer /* Buffer containing IE */ ) { UINT8 * pBug; INT32 length; int numSuites; STATUS status = OK; DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Called\n", 0, 0, 0, 0, 0, 0)); if (pKsl == NULL) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: NULL KSL\n", 0, 0, 0, 0, 0, 0)); return ERROR; } /* Get the KSL Lock */ if (pDot11->sme->ksl.lock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Cannot get KSL lock \n", 0,0,0,0,0,0)); return ERROR; } pBug = buffer; /* First, check the element ID and store the IE in the correct slot for future comparisons */ if (*pBug == DOT11_ELEMID_RSN) { /* Check if this type of IE is even supported by the current security policy */ if ((pKsl->pBss->secPol & DOT11_SECPOL_11i) == 0) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Not an allowed security IE\n", 0, 0, 0, 0, 0, 0)); pDot11->sme->ksl.unlock(pDot11); /* Return OK, since some vendor proprietary IEs use this elemId as well */ return OK; } } else if (*pBug == DOT11_ELEMID_WPA) { /* Check if this type of IE is even supported by the current security policy */ if ((pKsl->pBss->secPol & DOT11_SECPOL_WPA) == 0) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Not an allowed security IE\n", 0, 0, 0, 0, 0, 0)); pDot11->sme->ksl.unlock(pDot11); /* Return OK, since some vendor proprietary IEs use this elemId as well */ return OK; } } else { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Not a security IE: 0x%02x\n", *pBug, 0, 0, 0, 0, 0)); pDot11->sme->ksl.unlock(pDot11); return OK; } pBug ++; /* Next, retrieve the length of the rest of the IE */ length = *pBug++; /* If this is a WPA IE, then we need to skip the next four bytes, since WPA inserts a OUI and version number. */ if (*buffer == DOT11_ELEMID_WPA) { if ((*(pBug + 0) != DOT11_WPA_OUI_0) || (*(pBug + 1) != DOT11_WPA_OUI_1) || (*(pBug + 2) != DOT11_WPA_OUI_2) || (*(pBug + 3) != 1)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnSecIeProcess: Dropping WPA OUI %02x:%02x:%02x:" "%02x as not supported!\n", *(pBug + 0), *(pBug + 1),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -