📄 cardif_windows_wireless.c
字号:
/**
* 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_wireless_enc_disable(context *ctx)
{
return cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeOpen, TRUE);
}
/**
* 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_wireless_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 = 0;
char done = 0;
wireless_ctx *wctx = NULL;
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_wireless_get_wpa_ie(context *ctx,
char *iedata, int *ielen)
{
uint8_t ie_buf[65535];
unsigned int ie_size = 65535;
uint8_t len = 0;
(*ielen) = 0;
if (cardif_windows_wireless_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_wireless_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_wireless_enc_open(context *ctx)
{
return cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeOpen, TRUE);
}
/**
* Set the SSID of the wireless card.
**/
int cardif_windows_wireless_set_ssid(context *ctx, char *ssid_name)
{
DWORD BytesReturned = 0;
DWORD result = 0;
UCHAR Buffer[sizeof(NDIS_OID) + sizeof(NDIS_802_11_SSID)];
PNDISPROT_SET_OID pSetOid = NULL;
struct win_sock_data *sockData = NULL;
PNDIS_802_11_SSID pSsid = NULL;
LPVOID lpMsgBuf = NULL;
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);
SetLastError(0);
if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE,
(LPVOID)&Buffer[0], sizeof(Buffer), NULL, 0, &BytesReturned) == FALSE)
{
// Only complain if we believe the card was ready when we asked for this.
if (GetLastError() != ERROR_NOT_READY)
{
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_SSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Set SSID IOCTL failed on interface '%s'. Reason was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
}
else
{
debug_printf(DEBUG_NORMAL, "'%s' reported it wasn't ready. We will try again later.\n");
}
return -1;
}
return XENONE;
}
/**
* Set the Broadcast SSID (MAC address) of the AP we are connected to.
**/
int cardif_windows_wireless_set_bssid(context *ctx, uint8_t *bssid)
{
DWORD BytesReturned = 0;
DWORD result = 0;
UCHAR Buffer[sizeof(NDIS_OID) + 6];
PNDISPROT_SET_OID pSetOid = NULL;
struct win_sock_data *sockData = NULL;
LPVOID lpMsgBuf = NULL;
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)
{
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_SETTING_BSSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Set BSSID IOCTL failed on interface '%s'. Reason was : %s\n",
ctx->desc, 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.
*
* @param[in] ctx The context for the interface we want to get the BSSID for.
* @param[out] bssid_dest The BSSID (MAC address) of the wireless device we are
* associated with.
*
* \retval XENONE on success
* \retval -1 on error
**/
int cardif_windows_wireless_get_bssid(context *ctx,
char *bssid_dest)
{
DWORD BytesReturned = 0;
DWORD result = 0;
UCHAR QueryBuffer[sizeof(NDIS_OID) + 6];
PNDISPROT_QUERY_OID pQueryOid = NULL;
struct win_sock_data *sockData = NULL;
LPVOID lpMsgBuf = NULL;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (!xsup_assert((bssid_dest != NULL), "bssid_dest != 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_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;
}
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_GETTING_BSSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Get BSSID IOCTL failed on interface '%s'. Reason was : %s\n",
ctx->desc, 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_wireless_get_ssid(context *ctx, char *ssid_name, unsigned int ssidsize)
{
DWORD BytesReturned = 0;
DWORD result = 0;
UCHAR QueryBuffer[sizeof(NDIS_OID) + sizeof(NDIS_802_11_SSID)];
PNDISPROT_QUERY_OID pQueryOid = NULL;
struct win_sock_data *sockData = NULL;
PNDIS_802_11_SSID pSsid = NULL;
LPVOID lpMsgBuf = NULL;
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)
{
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;
}
ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_GETTING_SSID, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Get SSID IOCTL failed on interface '%s'. Reason was : %s\n",
ctx->desc, 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_wireless_wep_associate(context *ctx, int zero_keys)
{
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;
debug_printf(DEBUG_INT, "(WEP Associate) Set infra mode.\n");
if (cardif_windows_set_infra_mode(ctx) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set infrastructure mode on interface '%s' failed.\n",
ctx->desc);
return -1;
}
debug_printf(DEBUG_INT, "(WEP Associate) Set auth mode.\n");
if (cardif_windows_set_auth_mode(ctx, Ndis802_11AuthModeOpen, TRUE) != 0)
{
debug_printf(DEBUG_NORMAL, "Request to set the authentication mode to Open failed on interface '%s'.\n",
ctx->desc);
return -1;
}
wctx->assoc_type = ASSOC_TYPE_OPEN;
if ((ctx->conn->association.auth_type == AUTH_NONE) &&
(ctx->conn->association.txkey == 0))
{
debug_printf(DEBUG_INT, "(WEP Associate) Disable encryption.\n");
if (cardif_windows_set_enc_mode(ctx, Ndis802_11EncryptionDisabled, TRUE) != 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -