📄 cardif_windows_dot11.c
字号:
{
debug_printf(DEBUG_NORMAL, "IE block didn't contain a valid WPA2 IE!\n");
}
return -1;
}
debug_printf(DEBUG_INT, "WPA2 IE (%d) : ", in_ie[i+1]);
debug_hex_printf(DEBUG_INT, &in_ie[i], in_ie[i+1]+2);
(*out_size) = in_ie[i+1]+2;
memcpy(out_ie, &in_ie[i], (*out_size));
return XENONE;
}
/**
* Get the WPA2 Information Element.
**/
int cardif_windows_dot11_get_wpa2_ie(context *ctx, char *iedata, int *ielen)
{
char ie_buf[65535];
int ie_size = 65535;
if (cardif_windows_dot11_get_ies(ctx, ie_buf, &ie_size) != XENONE)
return -1;
debug_printf(DEBUG_INT, "IEs returned (Length : %d) :\n", ie_size);
debug_hex_printf(DEBUG_INT, ie_buf, ie_size);
if (cardif_windows_dot11_find_wpa2_ie(ctx, ie_buf, ie_size, iedata, ielen) != XENONE)
return -1;
return XENONE;
}
/**
* Scan through whatever was returned by the scan, and pull
* out any interesting IEs.
**/
void cardif_windows_dot11_parse_ies(context *ctx, uint8_t *iedata, int ielen)
{
int i = 0;
int wpalen;
uint8_t wpaie[255];
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return;
if (!xsup_assert((iedata != NULL), "iedata != NULL", FALSE))
return;
if (!xsup_assert((ielen > 0), "ielen > 0", FALSE))
return;
if (!xsup_assert((ielen < 256), "ielen < 256", FALSE))
return;
if (cardif_windows_dot11_find_wpa_ie(ctx, iedata, ielen, wpaie, &wpalen) == XENONE)
{
// We have a valid IE, save it.
config_ssid_update_abilities(ctx->intTypeData, WPA_IE);
config_ssid_add_wpa_ie(ctx->intTypeData, wpaie, wpalen);
}
if (cardif_windows_dot11_find_wpa2_ie(ctx, iedata, ielen, wpaie, &wpalen) == XENONE)
{
// We have a valid IE, save it.
config_ssid_update_abilities(ctx->intTypeData, RSN_IE);
config_ssid_add_rsn_ie(ctx->intTypeData, wpaie, wpalen);
}
}
/**
* Set the authentication (as in 802.11, not 802.1X) mode that we will be using to
* create an association with the AP.
**/
int cardif_windows_dot11_set_auth_mode(context *ctx, DWORD authmode)
{
DWORD Bytes;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid;
struct win_sock_data *sockData;
DWORD *mode;
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_AUTHENTICATION_MODE;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = authmode;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &Bytes) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Attempt to set authentication mode failed!\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_AUTH_MODE, ctx->desc);
return -1;
}
return XENONE;
}
/**
* Set the encryption mode. On Windows, this sets which encryption methods are allowed.
*
* From the Windows DDK documentation :
*
* Encryption modes define the set of cipher suites that can be enabled on the 802.11 device:
*
* Encryption1
* WEP encryption is supported and enabled on the device. The device either does not support TKIP and AES or these cipher suites are disabled.
* The WEP cipher suite as defined through this OID uses either 40 bit or 104 bit key lengths. Other extended key lengths are not supported for the WEP cipher suite.
*
* Encryption2
* WEP and TKIP encryption are supported and enabled on the device. The device either does not support AES or this cipher suite is disabled.
*
* Encryption3
* WEP, TKIP, and AES encryption are supported and enabled on the device.
* The AES cipher suite as defined through this OID is AES-CCMP. If the device supports other variants of the AES cipher suite, it cannot advertise support for the Encryption3 encryption mode unless the device also supports AES-CCMP.
**/
int cardif_windows_dot11_set_enc_mode(context *ctx, DWORD encmode)
{
DWORD BytesReturned;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid;
struct win_sock_data *sockData;
DWORD *mode;
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_ENCRYPTION_STATUS;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = encmode;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Attempt to set encryption mode failed!\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_ENC_MODE, ctx->desc);
return -1;
}
return XENONE;
}
/**
* Set the card in to infrastructure mode. This will case all keys to be deleted.
**/
int cardif_windows_dot11_set_infra_mode(context *ctx)
{
DWORD BytesReturned;
UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DWORD)];
PNDISPROT_SET_OID pSetOid;
struct win_sock_data *sockData;
DWORD *mode;
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_INFRASTRUCTURE_MODE;
mode = (DWORD *)&pSetOid->Data[0];
(*mode) = Ndis802_11Infrastructure;
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Attempt to set infrastructure mode failed!\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_802_11_INFRA_MODE, ctx->desc);
return -1;
}
return XENONE;
}
/**
* Disable encryption on the wireless card. This is used in cases
* where we roam to a different AP and the card needs to have WEP
* disabled.
**/
int cardif_windows_dot11_enc_disable(context *ctx)
{
return cardif_windows_dot11_set_auth_mode(ctx, Ndis802_11AuthModeOpen);
}
/**
* Take a block of IE data specified by "in_ie" and parse it, looking for a
* WPA1 information element. The WPA information element will be returned in
* "out_ie", if the return value of the function is XENONE.
*
* Since a WPA1 information element is a variable length field, we will determine
* that we are looking at a WPA IE by matching against the static fields that are found
* at the beginning of the IE. The IE should be in the format of :
*
* 0xdd XX 0x00 0x50 0xf2 0x01 0x01 0x00 0x00 0x50 0xf2 (Followed by variable length stuff.)
*
* The value for XX needs to be at least 11 for it to be a valid IE.
**/
int cardif_windows_dot11_find_wpa_ie(context *ctx, uint8_t *in_ie, unsigned int in_size,
uint8_t *out_ie, uint8_t *out_size)
{
const char wpaoui[3] = {0x00, 0x50, 0xf2};
unsigned int i;
char done;
wireless_ctx *wctx;
i = 0;
done = FALSE;
while ((i < in_size) && (done == FALSE))
{
if (in_ie[i] == 0xdd)
{
// It may be a WPA 1 IE.
if (in_ie[i+1] >= 11)
{
// Looking good..
if (memcmp(&in_ie[i+2], &wpaoui[0], 3) == 0)
{
if ((in_ie[i+5] == 0x01) && (in_ie[i+6] == 0x01) && (in_ie[i+7] == 0x00))
{
// Very likely. ;)
if (memcmp(&in_ie[i+8], &wpaoui[0], 3) == 0)
{
done = TRUE;
}
}
}
}
}
if (done == FALSE) i+=(unsigned char)(in_ie[i+1]+2);
}
if (done == FALSE)
{
wctx = (wireless_ctx *)ctx->intTypeData;
if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return -1;
// If we are scanning, then not finding an IE is no big deal. Otherwise, it is
// probably an error worth reporting.
if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
{
debug_printf(DEBUG_INT, "IE block didn't contain a valid WPA1 IE!\n");
}
else
{
debug_printf(DEBUG_NORMAL, "IE block didn't contain a valid WPA1 IE!\n");
}
return -1;
}
debug_printf(DEBUG_INT, "WPA1 IE (%d) : ", in_ie[i+1]);
debug_hex_printf(DEBUG_INT, &in_ie[i], in_ie[i+1]+2);
(*out_size) = in_ie[i+1]+2;
memcpy(out_ie, &in_ie[i], (*out_size));
return XENONE;
}
/**
* Generate the WPA1 Information Element
**/
int cardif_windows_dot11_get_wpa_ie(context *ctx,
char *iedata, int *ielen)
{
uint8_t ie_buf[65535];
unsigned int ie_size = 65535;
uint8_t len;
(*ielen) = 0;
if (cardif_windows_dot11_get_ies(ctx, ie_buf, &ie_size) != XENONE)
return -1;
debug_printf(DEBUG_INT, "IEs returned (Length : %d) :\n", (*ielen));
debug_hex_printf(DEBUG_INT, ie_buf, *ielen);
if (cardif_windows_dot11_find_wpa_ie(ctx, ie_buf, ie_size, iedata, &len) != XENONE)
return -1;
(*ielen) = len;
return XENONE;
}
/**
* Set encryption to open on the wireless card.
**/
int cardif_windows_dot11_enc_open(context *ctx)
{
return cardif_windows_dot11_set_auth_mode(ctx, Ndis802_11AuthModeOpen);
}
/**
* Set the SSID of the wireless card.
**/
int cardif_windows_dot11_set_ssid(context *ctx, char *ssid_name)
{
DWORD BytesReturned;
DWORD result;
UCHAR Buffer[sizeof(NDIS_OID) + sizeof(NDIS_802_11_SSID)];
PNDISPROT_SET_OID pSetOid;
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;
}
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_SSID;
pSsid = (PNDIS_802_11_SSID)&pSetOid->Data[0];
if (strncpy_s(pSsid->Ssid, sizeof(pSsid->Ssid), ssid_name, strlen(ssid_name)) != 0)
{
debug_printf(DEBUG_NORMAL, "Failed to copy SSID in %s() at %d!\n",
__FUNCTION__, __LINE__);
return -1;
}
pSsid->SsidLength = strlen(ssid_name);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Set SSID IOCTL failed.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_SSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
return XENONE;
}
/**
* Set the Broadcast SSID (MAC address) of the AP we are connected to.
**/
int cardif_windows_dot11_set_bssid(context *ctx, uint8_t *bssid)
{
DWORD BytesReturned;
DWORD result;
UCHAR Buffer[sizeof(NDIS_OID) + 6];
PNDISPROT_SET_OID pSetOid;
struct win_sock_data *sockData;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (!xsup_assert((bssid != NULL), "bssid != NULL", FALSE))
return -1;
sockData = (struct win_sock_data *)ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return -1;
pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
pSetOid->Oid = OID_802_11_BSSID;
memcpy(&Buffer[sizeof(NDIS_OID)], bssid, 6);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
debug_printf(DEBUG_NORMAL, "Set BSSID IOCTL failed.\n");
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_BSSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
return XENONE;
}
/**
* Get the Broadcast SSID (MAC address) of the Access Point we are 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_bssid(context *ctx,
char *bssid_dest)
{
DWORD BytesReturned;
DWORD result;
UCHAR QueryBuffer[sizeof(NDIS_OID) + 6];
PNDISPROT_QUERY_OID pQueryOid;
struct win_sock_data *sockData;
LPVOID lpMsgBuf;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (!xsup_assert((bssid_dest != NULL), "bssid_dest != NULL", FALSE))
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -