📄 cardif_windows_wireless.c
字号:
}
else if (ctx->conn->association.pairwise_keys & (CRYPT_FLAGS_WEP40 | CRYPT_FLAGS_WEP104))
{
wctx->pairwiseKeyType = CIPHER_WEP104;
}
}
} else if ((config_ssid_get_ssid_abilities(ctx->intTypeData) & WPA_IE) ||
((config_ssid_find_by_name(wctx, wctx->cur_essid) == NULL) &&
((ctx->conn != NULL) && (ctx->conn->association.association_type == ASSOC_TYPE_WPA1))))
{
wctx->assoc_type = ASSOC_TYPE_WPA1;
// We are doing WPA1.
if (ctx->conn->association.auth_type != AUTH_PSK)
{
debug_printf(DEBUG_INT, "(Associate) Set auth mode. (WPA-802.1X)\n");
if (cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeWPA, TRUE) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't set the authentication mode to WPA-Enterprise on interface '%s'.\n",
ctx->desc);
return;
}
}
else
{
debug_printf(DEBUG_INT, "(Associate) Set auth mode. (WPA-PSK)\n");
if (cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeWPAPSK, TRUE) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't set the authentication mode to WPA-PSK on interface '%s'.\n",
ctx->desc);
return;
}
}
if (ctx->conn->association.pairwise_keys == 0)
{
wctx->groupKeyType = wpa_get_group_crypt(ctx);
wctx->pairwiseKeyType = wpa_get_pairwise_crypt(ctx);
if (wctx->pairwiseKeyType == 0xff)
{
debug_printf(DEBUG_NORMAL, "Couldn't determine cipher type. Forcing to TKIP.\n");
wctx->pairwiseKeyType = CIPHER_TKIP;
}
}
else
{
debug_printf(DEBUG_INT, "Key type hard set to %d.\n", ctx->conn->association.pairwise_keys);
if (ctx->conn->association.pairwise_keys & CRYPT_FLAGS_CCMP)
{
wctx->pairwiseKeyType = CIPHER_CCMP;
}
else if (ctx->conn->association.pairwise_keys & CRYPT_FLAGS_TKIP)
{
wctx->pairwiseKeyType = CIPHER_TKIP;
}
else if (ctx->conn->association.pairwise_keys & (CRYPT_FLAGS_WEP40 | CRYPT_FLAGS_WEP104))
{
wctx->pairwiseKeyType = CIPHER_WEP104;
}
}
}
enc_mode = cardif_windows_wireless_cipher(wctx->pairwiseKeyType);
debug_printf(DEBUG_INT, "(Associate) Set encryption mode. (%d, %d, %d)\n", enc_mode,
Ndis802_11Encryption2Enabled, Ndis802_11Encryption3Enabled);
if (cardif_windows_set_enc_mode(ctx, enc_mode, TRUE) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set encryption mode failed on interface '%s'.\n",
ctx->desc);
return;
}
wctx = (wireless_ctx *)ctx->intTypeData;
if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return;
debug_printf(DEBUG_INT, "(Associate) Set SSID (%s).\n", wctx->cur_essid);
if (cardif_windows_wireless_set_ssid(ctx, wctx->cur_essid) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set the SSID failed on interface '%s'.\n",
ctx->desc);
return;
}
return;
}
// Windows doesn't seem to distinguish between WEP40 and WEP104. So, "DOES_WEP" defines both.
#define DOES_WEP (DOES_WEP40 | DOES_WEP104)
/**
* Determine the types of encryption supported.
**/
void cardif_windows_enc_mode_supported(NDIS_802_11_ENCRYPTION_STATUS es, uint32_t *enc)
{
switch (es)
{
// The values below should never come up in the results.
case Ndis802_11EncryptionNotSupported:
case Ndis802_11EncryptionDisabled:
case Ndis802_11Encryption1KeyAbsent:
case Ndis802_11Encryption2KeyAbsent:
case Ndis802_11Encryption3KeyAbsent:
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown/Invalid encryption method. (%d)\n", es);
break;
case Ndis802_11Encryption1Enabled:
(*enc) |= (DOES_WEP);
break;
case Ndis802_11Encryption2Enabled:
(*enc) |= (DOES_WEP | DOES_TKIP);
break;
case Ndis802_11Encryption3Enabled:
(*enc) |= (DOES_WEP | DOES_TKIP | DOES_CCMP);
break;
}
}
/**
* Determine the authentication modes supported.
**/
void cardif_windows_auth_mode_supported(NDIS_802_11_AUTHENTICATION_MODE am, uint32_t *capa)
{
switch (am)
{
// Don't currently care about these.
case Ndis802_11AuthModeOpen:
case Ndis802_11AuthModeShared:
case Ndis802_11AuthModeAutoSwitch:
break;
case Ndis802_11AuthModeWPA:
case Ndis802_11AuthModeWPAPSK:
case Ndis802_11AuthModeWPANone:
(*capa) |= DOES_WPA;
break;
case Ndis802_11AuthModeWPA2:
case Ndis802_11AuthModeWPA2PSK:
(*capa) |= DOES_WPA2;
break;
default:
fprintf(stderr, "Unknown authentication mode %d!\n", am);
break;
}
}
/**
* \brief Attempt to check the encryption capabilities on the interface.
*
* @param[in,out] ctx The context for the interface that we are trying to determine the
* encryption capabilities of.
**/
void cardif_windows_wireless_enc_capabilities_secondary(context *ctx)
{
wireless_ctx *wctx = NULL;
if (ctx->intType != ETH_802_11_INT) return;
wctx = (wireless_ctx *)ctx->intTypeData;
// First, check encryption modes.
if (cardif_windows_set_enc_mode(ctx, Ndis802_11Encryption3Enabled, FALSE) == 0)
{
wctx->enc_capa |= (DOES_WEP | DOES_TKIP | DOES_CCMP);
}
else if (cardif_windows_set_enc_mode(ctx, Ndis802_11Encryption2Enabled, FALSE) == 0)
{
wctx->enc_capa |= (DOES_WEP | DOES_TKIP);
}
else if (cardif_windows_set_enc_mode(ctx, Ndis802_11Encryption1Enabled, FALSE) == 0)
{
wctx->enc_capa |= DOES_WEP;
}
else
{
wctx->enc_capa = 0;
}
cardif_windows_set_enc_mode(ctx, Ndis802_11EncryptionDisabled, FALSE);
}
/**
* \brief Attempt to determine the authentication modes supported by the wireless interface.
*
* @param[in,out] ctx The context for the interface we are attempting to determine the
* authentication mode for.
**/
void cardif_windows_wireless_auth_capabilities_secondary(context *ctx)
{
wireless_ctx *wctx = NULL;
if (ctx->intType != ETH_802_11_INT) return;
wctx = (wireless_ctx *)ctx->intTypeData;
// Then authentication modes.
if (cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeWPA, FALSE) == 0)
{
wctx->enc_capa |= DOES_WPA;
}
if (cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeWPA2, FALSE) == 0)
{
wctx->enc_capa |= DOES_WPA2;
}
cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeOpen, FALSE);
}
/**
* \brief Attempt the alternate way of getting the capabilities of the wireless interface.
*
* @param[in,out] ctx The context for the interface that we are trying to determine the
* capabilities of.
**/
void cardif_windows_wireless_capabilities_secondary(context *ctx)
{
if (ctx->intType != ETH_802_11_INT) return;
cardif_windows_wireless_enc_capabilities_secondary(ctx);
cardif_windows_wireless_auth_capabilities_secondary(ctx);
}
/**
* Determine the encryption capabilities for this driver/interface.
**/
void cardif_windows_wireless_enc_capabilities(context *ctx)
{
struct win_sock_data *sockData = NULL;
DWORD BytesReturned = 0;
UCHAR QueryBuffer[1024];
PNDISPROT_QUERY_OID pQueryOid = NULL;
PNDIS_802_11_CAPABILITY pCapa = NULL;
int i = 0;
wireless_ctx *wctx = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return;
wctx = (wireless_ctx *)ctx->intTypeData;
if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return;
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_802_11_CAPABILITY;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE, &QueryBuffer[0],
sizeof(QueryBuffer), &QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned) == FALSE)
{
debug_printf(DEBUG_INT, "Couldn't determine capabilities the normal way, trying the icky way.\n");
// Attempt the secondary way. :-/
cardif_windows_wireless_capabilities_secondary(ctx);
return;
}
pCapa = (PNDIS_802_11_CAPABILITY)&pQueryOid->Data[0];
for (i=0; i < (int)pCapa->NoOfAuthEncryptPairsSupported; i++)
{
cardif_windows_auth_mode_supported(pCapa->AuthenticationEncryptionSupported[i].AuthModeSupported, &wctx->enc_capa);
cardif_windows_enc_mode_supported(pCapa->AuthenticationEncryptionSupported[i].EncryptStatusSupported, &wctx->enc_capa);
}
}
/**
* Delete any keys that are currently installed in the driver/interface.
**/
int cardif_windows_wireless_delete_key(context *ctx, int key_idx, int set_tx)
{
struct win_sock_data *sockData = NULL;
DWORD BytesReturned = 0;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(NDIS_802_11_REMOVE_KEY)];
PNDISPROT_SET_OID pSetOid = NULL;
PNDIS_802_11_REMOVE_KEY pRkey = NULL;
LPVOID lpMsgBuf = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_REMOVE_KEY;
pRkey = (PNDIS_802_11_REMOVE_KEY)&pSetOid->Data[0];
pRkey->Length = sizeof(NDIS_802_11_REMOVE_KEY);
pRkey->KeyIndex = 0;
pRkey->KeyIndex = key_idx;
if (set_tx == TRUE)
{
memcpy(pRkey->BSSID, &ctx->dest_mac[0], 6);
pRkey->KeyIndex |= (1 << 30);
}
else
{
memset(pRkey->BSSID, 0xff, 6);
}
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Remove Key IOCTL failed on interface '%s'. Reason was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
return XENONE;
}
/**
* Enable the filter that only allows for EAPoL frames to get through.
**/
int cardif_windows_wireless_drop_unencrypted(context *ctx, char endis)
{
struct win_sock_data *sockData = NULL;
DWORD BytesReturned = 0;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(NDIS_802_11_PRIVACY_FILTER)];
PNDISPROT_SET_OID pSetOid = NULL;
DWORD *filter = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_PRIVACY_FILTER;
filter = (DWORD *)&pSetOid->Data[0];
if (endis == TRUE)
{
(*filter) = Ndis802_11PrivFilter8021xWEP;
}
else
{
(*filter) = Ndis802_11PrivFilterAcceptAll;
}
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE, &Buffer[0],
sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Couldn't set privacy filter status for interface '%s'.\n",
ctx->desc);
return -1;
}
return XENONE;
}
/**
* Take the RSSI value that Windows returns, and convert it to a percentage. This
* call will only return something valid if the interface is associated. If the
* interface isn't associated, then this function will return -1.
**/
int cardif_windows_wireless_get_percent(context *ctx)
{
struct win_sock_data *sockData = NULL;
DWORD BytesReturned = 0;
UCHAR QueryBuffer[1024];
PNDISPROT_QUERY_OID pQueryOid = NULL;
NDIS_802_11_RSSI *pRssi = NULL;
int i = 0;
int percentage = -1;
wireless_ctx *wctx = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
wctx = (wireless_ctx *)ctx->intTypeData;
if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return -1;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_802_11_RSSI;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE, &QueryBuffer[0],
sizeof(QueryBuffer), &QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Couldn't determine the RSSI value for interface '%s'.\n",
ctx->desc);
return -1;
}
pRssi = (NDIS_802_11_RSSI *)&pQueryOid->Data[0];
// According to the windows documentation, the RSSI should vary between
// -10 and -200 dBm. So, we need to figure out a percentage based on that.
// However, many examples on the net show that valid ranges will run from -50 to -100.
percentage = (((*pRssi) + 100)*2); // Make the dBm a positive number, and the lowest value
// equal to 0. (So, the range will now be 0 - 190.)
if (percentage > 100) percentage = 100; // Some cards may have a percentage > 100 depending on their sensativity. In those cases, only return 100. ;)
return percentage;
}
/**
* \brief Set the operational state for the interface.
*
* The set_operstate call was originally intended to be used only with Linux, however it
* is also a good place to implement calls for other OSes to control DHCP setting, or
* other IP address related setting calls.
*
* @param[in] ctx The context for the interface whose operational state we want to change.
* @param
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -