📄 cardif_windows_dot11.c
字号:
sockData = (struct win_sock_data *)ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return -1;
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_802_11_BSSID;
result = devioctl(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE,
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer),
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned);
if ((result != WAIT_OBJECT_0) && (result != WAIT_IO_COMPLETION))
{
if (result == 0xffffffff)
{
debug_printf(DEBUG_INT, "IOCTL returned that no BSSID is currently valid!\n");
debug_printf(DEBUG_INT, "Are you associated to a network!?\n");
return -1;
}
debug_printf(DEBUG_NORMAL, "Get BSSID IOCTL failed. (%x)\n", result);
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_GETTING_BSSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
// Otherwise, pQueryOid->Data should contain the BSSID.
memcpy(bssid_dest, pQueryOid->Data, 6);
return XENONE;
}
/**
* Ask the wireless card for the ESSID that we are currently connected to. If
* this is not a wireless card, or the information is not available, we should
* return an error.
**/
int cardif_windows_dot11_get_ssid(context *ctx, char *ssid_name, unsigned int ssidsize)
{
DWORD BytesReturned;
DWORD result;
UCHAR QueryBuffer[sizeof(NDIS_OID) + sizeof(NDIS_802_11_SSID)];
PNDISPROT_QUERY_OID pQueryOid;
struct win_sock_data *sockData;
PNDIS_802_11_SSID pSsid;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (!xsup_assert((ssid_name != NULL), "ssid_name != NULL", FALSE))
return -1;
sockData = (struct win_sock_data *)ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return -1;
if (ctx->intType != ETH_802_11_INT)
{
// We want to verify that the interface is in fact, not wireless, and
// not that we are in a situation where the interface has just been
// down.
debug_printf(DEBUG_NORMAL, "This interface isn't wireless!\n");
return XENOWIRELESS;
}
// If we get here, and isWireless == FALSE, then we need to double
// check that our interface is really not wireless.
#if 0
if (ctx->intType != ETH_802_11_INT)
{
if (cardif_int_is_wireless(ctx) == TRUE)
{
ctx->
SET_FLAG(ctx->flags, IS_WIRELESS);
}
else
{
UNSET_FLAG(ctx->flags, IS_WIRELESS);
}
if (!TEST_FLAG(ctx->flags, IS_WIRELESS))
{
UNSET_FLAG(ctx->flags, WAS_DOWN);
}
}
#endif
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_802_11_SSID;
result = devioctl(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE,
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer),
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned);
if ((result != WAIT_OBJECT_0) && (result != WAIT_IO_COMPLETION))
{
if (result == 0xffffffff)
{
debug_printf(DEBUG_INT, "IOCTL returned that no SSID is currently valid!\n");
debug_printf(DEBUG_INT, "Are you associated to a network!?\n");
return -1;
}
debug_printf(DEBUG_NORMAL, "Get SSID IOCTL failed. (%x)\n", result);
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_GETTING_SSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
pSsid = (PNDIS_802_11_SSID)&pQueryOid->Data[0];
if (Strncpy(ssid_name, ssidsize, pSsid->Ssid, pSsid->SsidLength+1) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't copy SSID in %s() at %d!\n",
__FUNCTION__, __LINE__);
return -1;
}
ssid_name[pSsid->SsidLength+1] = 0x00;
return XENONE;
}
/**
* This function is called when we roam, or disassociate. It should
* reset the card to a state where it can associate with a new AP.
*
* For Windows, the zero_keys value does nothing.
**/
int cardif_windows_dot11_wep_associate(context *ctx, int zero_keys)
{
wireless_ctx *wctx;
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;
debug_printf(DEBUG_INT, "(WEP Associate) Set infra mode.\n");
if (cardif_windows_dot11_set_infra_mode(ctx) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set infrastructure mode failed.\n");
return -1;
}
debug_printf(DEBUG_INT, "(WEP Associate) Set auth mode.\n");
if (cardif_windows_dot11_set_auth_mode(ctx, Ndis802_11AuthModeOpen) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set the authentication mode to Open failed.\n");
return -1;
}
wctx->assoc_type = ASSOC_TYPE_OPEN;
if (ctx->conn->association.auth_type == AUTH_NONE)
{
debug_printf(DEBUG_INT, "(WEP Associate) Disable encryption.\n");
if (cardif_windows_dot11_set_enc_mode(ctx, Ndis802_11EncryptionDisabled) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set encryption mode failed.\n");
return -1;
}
}
else
{
debug_printf(DEBUG_INT, "(WEP Associate) Set encryption mode.\n");
if (cardif_windows_dot11_set_enc_mode(ctx, Ndis802_11Encryption1Enabled) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set encryption mode failed.\n");
return -1;
}
}
wctx = (wireless_ctx *)ctx->intTypeData;
if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return -1;
debug_printf(DEBUG_INT, "(WEP Associate) Set SSID.\n");
if (cardif_windows_dot11_set_ssid(ctx, wctx->cur_essid) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set the SSID failed.\n");
return -1;
}
return XENONE;
}
/**
* Send a disassociate request to the AP we are currently connected to.
**/
int cardif_windows_dot11_disassociate(context *ctx, int reason)
{
wireless_ctx *wctx;
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;
// Probably need to fix this to something else.
// This will clear any keys in the key cache.
cardif_windows_dot11_set_infra_mode(ctx);
cardif_windows_dot11_set_ssid(ctx, "unlikelyssid");
// Set our association mode back to unknown.
wctx->assoc_type = ASSOC_TYPE_UNKNOWN;
// Sending a disassociate turns off the radio, which is probably not what we want!
#if 0
DWORD BytesReturned;
DWORD result;
UCHAR QueryBuffer[sizeof(NDISPROT_QUERY_OID)];
PNDISPROT_QUERY_OID pQueryOid;
struct win_sock_data *sockData;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
sockData = (struct win_sock_data *)ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return -1;
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_802_11_DISASSOCIATE;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer),
(LPVOID)&QueryBuffer[0], sizeof(QueryBuffer), &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Disassociate failed.\n");
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
#endif
return XENONE;
}
// Windows uses higher order bits in the key index to determine what type of key it is.
// These defines just make the code a little more readable.
#define TX_KEY BIT(31)
#define PAIRWISE_KEY BIT(30)
#define MANUAL_RSC BIT(29)
#define AUTHENTICATOR_KEY BIT(28)
/**
* Set a WEP key. Also, based on the index, we may change the transmit
* key.
**/
int cardif_windows_dot11_set_WEP_key(context *ctx, uint8_t *key,
int keylen, int keyidx)
{
struct win_sock_data *sockData;
DWORD BytesReturned;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(NDIS_802_11_WEP)+13];
PNDISPROT_SET_OID pSetOid;
PNDIS_802_11_WEP pKey;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
if (!xsup_assert((key != NULL), "key != 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_ADD_WEP;
pKey = (PNDIS_802_11_WEP)&pSetOid->Data[0];
pKey->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + keylen;
pKey->KeyIndex = (keyidx & 0x7f);
if ((keyidx & 0x80) == 0x80) pKey->KeyIndex |= TX_KEY;
pKey->KeyLength = keylen;
memcpy(&pKey->KeyMaterial[0], key, keylen);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Set WEP Key IOCTL failed.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_WEP_KEY, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
return XENONE;
}
/**
* Push an encryption key down to the driver/card. Windows differentiates between WEP/TKIP/CCMP
* by the length of the key data. Because of this, the variable "alg" isn't used. It is only
* left here to keep this code similar to the other interface handlers. (And will probably be
* removed at some point in the future.)
**/
int cardif_windows_dot11_set_key_ext(context *ctx, int alg,
unsigned char *addr, int keyidx, int settx,
char *seq, int seqlen, char *key,
int keylen)
{
struct win_sock_data *sockData;
DWORD BytesReturned;
UCHAR Buffer[sizeof(NDIS_OID)+FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + 32];
PNDISPROT_SET_OID pSetOid;
PNDIS_802_11_KEY pKey;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return -1;
if (!xsup_assert((key != NULL), "key != NULL", FALSE)) return -1;
if (alg == ALG_WEP)
{
// The caller should call cardif_windows_dot11_set_wep directly, but this is
// just in case they do something stupid. ;)
return cardif_windows_dot11_set_WEP_key(ctx, key, keylen, keyidx);
}
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return -1;
memset(&Buffer[0], 0x00, sizeof(Buffer));
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_ADD_KEY;
pKey = (PNDIS_802_11_KEY)&pSetOid->Data[0];
pKey->Length = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + keylen;
pKey->KeyIndex = keyidx;
pKey->KeyLength = keylen;
debug_printf(DEBUG_INT, "Key Index = %d\n", pKey->KeyIndex);
debug_printf(DEBUG_INT, "Key Length = %d\n", pKey->KeyLength);
if (alg == ALG_TKIP)
{
// Need to swap the MICs (back) so Windows can handle it the way it wants.
wpa_common_swap_rx_tx_mic(key);
}
if (seq == NULL)
{
pKey->KeyIndex |= MANUAL_RSC;
memset((UCHAR *)&pKey->KeyRSC, 0x00, sizeof(NDIS_802_11_KEY_RSC));
}
else
{
pKey->KeyIndex |= MANUAL_RSC;
memcpy(&pKey->KeyRSC, seq, seqlen);
}
if (addr != NULL)
{
memcpy(pKey->BSSID, addr, 6);
}
else
{
memset(pKey->BSSID, 0xff, 6);
}
if (settx == TRUE)
{
debug_printf(DEBUG_INT, "TX key!\n");
pKey->KeyIndex |= (TX_KEY | PAIRWISE_KEY);
//pKey->KeyIndex |= TX_KEY;
}
memcpy(&pKey->KeyMaterial, key, keylen);
debug_printf(DEBUG_INT, "Key : ");
debug_hex_printf(DEBUG_INT, pKey->KeyMaterial, keylen);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Set Key IOCTL failed.\n");
switch (alg)
{
case ALG_TKIP:
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_TKIP_KEY, ctx->desc);
break;
case ALG_CCMP:
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_CCMP_KEY, ctx->desc);
break;
default:
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_UNKNOWN_KEY, ctx->desc);
break;
}
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
return XENONE;
}
/**
* Push a TKIP key down to the wireless card.
**/
int cardif_windows_dot11_set_tkip_key(context *ctx,
unsigned char *addr, int keyidx, int settx,
char *key, int keylen)
{
char seq[6] = {0x00,0x00,0x00,0x00,0x00,0x00};
return cardif_windows_dot11_set_key_ext(ctx, ALG_TKIP, addr, keyidx, settx,
seq, 6, key, keylen);
}
/**
* Push a CCMP key down to the wireless card.
**/
int cardif_windows_dot11_set_ccmp_key(context *ctx,
unsigned char *addr, int keyidx, int settx,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -