⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cardif_windows_dot11.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 4 页
字号:
/**
 * Windows wireless (ExtSta) interface.
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file cardif_windows_dot11.c
 *
 * \authors chris@open1x.org
 *
 * \par CVS Status Information:
 * \code
 * $Id: cardif_windows_dot11.c,v 1.1.2.3 2007/04/08 02:39:26 chessing Exp $
 * $Date: 2007/04/08 02:39:26 $
 * \endcode
 *
 */

#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <winsock2.h>

#include <NtDDNdis.h>
#include <windot11.h>

// The nuiouser.h file is included with the Windows DDK.  Please 
// download the DDK and copy the file to the proper location.
#include "../../../vs2005/ndis_proto_driver/nuiouser.h"

#include "../../xsup_common.h"
#include "../../../lib/libxsupconfig/xsupconfig.h"
#include "../../../lib/libxsupconfig/xsupconfig_structs.h"
#include "../../context.h"
#include "../../config_ssid.h"
#include "../../xsup_debug.h"
#include "../../xsup_err.h"
#include "../../wpa.h"
#include "../../wpa2.h"
#include "../../wpa_common.h"
#include "../../cardif/cardif.h"
#include "../../ipc_events.h"
#include "../../ipc_events_index.h"
#include "../../ipc_callout.h"
#include "cardif_windows.h"
#include "cardif_windows_dot11.h"
#include "../../wireless_sm.h"
#include "../../timer.h"
#include "../../wpa.h"
#include "../../wpa2.h"

#ifdef USE_EFENCE
#include <efence.h>
#endif

// In DDK 3790.1830 these values aren't defined.  So, define them.
#ifndef OID_802_11_CAPABILITY
#define OID_802_11_CAPABILITY    0x0D010122

// If the capability #define doesn't exist, then these values probably
// don't either.  If you have build errors complaining that these are
// already defined, then comment them out.
#define Ndis802_11AuthModeWPA2      6
#define Ndis802_11AuthModeWPA2PSK   7

typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
{
  NDIS_802_11_AUTHENTICATION_MODE  AuthModeSupported;
  NDIS_802_11_ENCRYPTION_STATUS  EncryptStatusSupported;
} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;

typedef struct _NDIS_802_11_CAPABILITY
{
  ULONG  Length;
  ULONG  Version;
  ULONG  NoOfPMKIDs;
  ULONG  NoOfAuthEncryptPairsSupported;
  NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
#endif

/**
 * This will be called ~7 seconds after a request to scan.  According to
 * the Windows documentation, you need to wait at least 6 seconds before
 * requesting scan data, which is where 7 seconds comes from. ;)
 **/
void cardif_windows_dot11_scan_timeout(context *ctx)
{
  DWORD BytesReturned;
  UCHAR Buffer[65535];  // 64k of scan data is a *LOT*!
  PNDISPROT_QUERY_OID pQueryOid;
  PNDIS_802_11_BSSID_LIST_EX pBssidList;
  PNDIS_WLAN_BSSID_EX pBssidEx;
  PNDIS_802_11_SSID pSsid;
  UCHAR *ofs;
  char rssi;
  int i;
  char ssid[33];
  struct win_sock_data *sockData;
  LPVOID lpMsgBuf;
  wireless_ctx *wctx;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return;

  if (ipc_events_scan_complete(ctx) != IPC_SUCCESS)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't send scan complete event to IPC listeners.\n");
  }

  timer_cancel(ctx, SCANCHECK_TIMER);

  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;

  memset(&Buffer[0], 0x00, sizeof(Buffer));
  pQueryOid = (PNDISPROT_QUERY_OID)&Buffer[0];
  pQueryOid->Oid = OID_802_11_BSSID_LIST;

  if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE, 
					(LPVOID)&Buffer[0], sizeof(Buffer), (LPVOID)&Buffer[0],
					sizeof(Buffer), &BytesReturned) == FALSE)
  {
	  debug_printf(DEBUG_NORMAL, "Attempt to get scan data results failed!\n");
	  ipc_events_error(ctx, IPC_EVENT_ERROR_GETTING_SCAN_DATA, ctx->desc);
  		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
		LocalFree(lpMsgBuf);
	  return;
  }

  // Only clear our cache if we have new data.  This allows us to handle situations where
  // stale scan data provides a means to authenticate to a connection that associates slowly
  // (such as the IPW3945 with Trpz APs.)
  config_ssid_clear(wctx);


  pBssidList = (PNDIS_802_11_BSSID_LIST_EX)&pQueryOid->Data[0];

  debug_printf(DEBUG_INT, "Got %d result(s).\n", pBssidList->NumberOfItems);

  pBssidEx = (PNDIS_WLAN_BSSID_EX)&pBssidList->Bssid[0];
  ofs = (UCHAR *)pBssidEx;

  for (i = 0; i < (int)pBssidList->NumberOfItems; i++)
  {
	  pBssidEx = (PNDIS_WLAN_BSSID_EX)ofs;

	  pSsid = (PNDIS_802_11_SSID)&pBssidEx->Ssid;

	  memset(&ssid, 0x00, sizeof(ssid));
	  if (strncpy_s((void *)&ssid, sizeof(ssid), pSsid->Ssid, pSsid->SsidLength) != 0)
	  {
		  debug_printf(DEBUG_NORMAL, "Couldn't make a copy of the SSID in %s() at %d!\n",
			  __FUNCTION__, __LINE__);
		  goto bad_strncpy;
	  }

	  debug_printf(DEBUG_INT, "Found SSID : %s\n", ssid);
	  config_ssid_add_ssid_name(wctx, ssid);

	  debug_printf(DEBUG_INT, "BSSID : ");
	  debug_hex_printf(DEBUG_INT, pBssidEx->MacAddress, 6);
	  config_ssid_add_bssid(wctx, pBssidEx->MacAddress);

	  rssi = pBssidEx->Rssi;
	  debug_printf(DEBUG_INT, "RSSI : %d\n", rssi);
	  config_ssid_add_qual(wctx, 0, rssi, 0);

	  debug_printf(DEBUG_INT, "Privacy : %d\n", pBssidEx->Privacy);
	  if (pBssidEx->Privacy == 1) config_ssid_update_abilities(wctx, ENC);

	  cardif_windows_dot11_parse_ies(ctx, (uint8_t *)&pBssidEx->IEs[sizeof(NDIS_802_11_FIXED_IEs)], pBssidEx->IELength);

bad_strncpy:
	  ofs += pBssidEx->Length;
  }

  UNSET_FLAG(wctx->flags, WIRELESS_SCANNING);

  return;
}

int cardif_windows_dot11_get_extsta_capabilities(context *ctx, DOT11_EXTSTA_CAPABILITY *capa)
{
  DWORD BytesReturned;
  UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DOT11_EXTSTA_CAPABILITY)];
  PNDISPROT_QUERY_OID pQueryOid;
  struct win_sock_data *sockData;
  LPVOID lpMsgBuf;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return XEMALLOC;

  sockData = ctx->sockData;

  if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return XEMALLOC;

  memset(&Buffer, 0x00, sizeof(Buffer));
  pQueryOid = (PNDISPROT_QUERY_OID)&Buffer[0];
 
  pQueryOid->Oid = OID_DOT11_EXTSTA_CAPABILITY;

  if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE, (LPVOID)&Buffer[0], sizeof(Buffer), 
					(LPVOID)&Buffer[0], sizeof(Buffer), &BytesReturned) == FALSE)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't get interface capabilities!\n");
	  //ipc_events_error(ctx, IPC_EVENT_LOG_CANT_GET_CAPABILITIES, ctx->desc, NULL);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
		LocalFree(lpMsgBuf);
	  return -1;
  }

  memcpy(capa, &Buffer[sizeof(NDIS_OID)], sizeof(DOT11_EXTSTA_CAPABILITY));

  return XENONE;
}

int cardif_windows_dot11_get_mode_capabilities(context *ctx)
{
  DWORD BytesReturned;
  UCHAR Buffer[sizeof(NDIS_OID)+sizeof(DOT11_OPERATION_MODE_CAPABILITY)+10];
  PNDISPROT_QUERY_OID pQueryOid;
  struct win_sock_data *sockData;
  LPVOID lpMsgBuf;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return XEMALLOC;

  sockData = ctx->sockData;

  if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return XEMALLOC;

  memset(&Buffer, 0x00, sizeof(Buffer));
  pQueryOid = (PNDISPROT_QUERY_OID)&Buffer[0];
 
  pQueryOid->Oid = OID_DOT11_EXTSTA_CAPABILITY;

  if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE, (LPVOID)&Buffer[0], sizeof(Buffer), 
					(LPVOID)&Buffer[0], sizeof(Buffer), &BytesReturned) == FALSE)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't get interface capabilities!\n");
	  //ipc_events_error(ctx, IPC_EVENT_LOG_CANT_GET_CAPABILITIES, ctx->desc, NULL);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
		LocalFree(lpMsgBuf);
	  return -1;
  }

//  memcpy(capa, &Buffer[sizeof(NDIS_OID)], sizeof(DOT11_EXTSTA_CAPABILITY));

  return XENONE;
}

/**
 * Tell the wireless card to scan for wireless networks.
 **/
int cardif_windows_dot11_scan(context *ctx, char passive)
{
  DWORD BytesReturned;
  UCHAR Buffer[sizeof(NDIS_OID)+4];
  PNDISPROT_SET_OID pSetOid;
  struct win_sock_data *sockData;
  LPVOID lpMsgBuf;
  DOT11_EXTSTA_CAPABILITY capa;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return XEMALLOC;

  if (passive == TRUE)
  {
	  // Windows XP doesn't do passive, so for now, return an error.
	  return XECANTPASSIVE;
  }

  sockData = ctx->sockData;

  if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE)) return XEMALLOC;

	cardif_windows_dot11_get_mode_capabilities(ctx);

  if (cardif_windows_dot11_get_extsta_capabilities(ctx, &capa) != XEMALLOC)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't get interface capabilities!\n");
	  return XEGENERROR;
  }
  else
  {
	  // Display some information.
	  printf("SSID Scan List Size = %ld\n", capa.uScanSSIDListSize);
	  printf("Desired SSID List Size = %ld\n", capa.uDesiredSSIDListSize);
	  printf("Desired BSSID List Size = %ld\n", capa.uDesiredBSSIDListSize);
  }

  memset(&Buffer, 0x00, sizeof(Buffer));
  pSetOid = (PNDISPROT_SET_OID)&Buffer[0];
 
  pSetOid->Oid = OID_DOT11_SCAN_REQUEST;

  if (devioctl_blk(sockData->devHandle, IOCTL_NDISPROT_SET_OID_VALUE, (LPVOID)&Buffer[0], sizeof(NDISPROT_QUERY_OID)+4, 
					NULL, 0, &BytesReturned) == FALSE)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't start a scan!\n");
	  ipc_events_error(ctx, IPC_EVENT_ERROR_CANT_START_SCAN, ctx->desc);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
		LocalFree(lpMsgBuf);
	  return -1;
  }

  // Once we had done that, we need to wait for at least 6 seconds to get full scan data back.
  // So set a timer to check in 8 seconds.
  timer_add_timer(ctx, SCANCHECK_TIMER, 8, NULL, cardif_windows_dot11_scan_timeout);
  return XENONE;
}

/**
 *  Get the list of IEs that we used to associate.
 *
 *  When this function is called, "ie_size" should be the size of the buffer defined by
 *  "ies".  On return, "ie_size" will be the length of the IE block copied in to the buffer.
 **/
int cardif_windows_dot11_get_ies(context *ctx, char *ies, int *ie_size)
{
    DWORD  BytesReturned;
    DWORD  result;
    UCHAR  QueryBuffer[65535];              // Unlikely that we would have a result this size!
    PNDISPROT_QUERY_OID pQueryOid;
	PNDIS_802_11_ASSOCIATION_INFORMATION pInfo;
	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;

	memset(&QueryBuffer, 0x00, sizeof(QueryBuffer));
	pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
	pQueryOid->Oid = OID_802_11_ASSOCIATION_INFORMATION;

	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 association information is available.\n");
			debug_printf(DEBUG_INT, "Are you associated to a network!?\n");
			return -1;
		}

        debug_printf(DEBUG_NORMAL, "Get association information failed.  (%x)\n", result);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Reason was : %s\n", lpMsgBuf);
		LocalFree(lpMsgBuf);
        return -1;
    }

	pInfo = (PNDIS_802_11_ASSOCIATION_INFORMATION)&pQueryOid->Data[0];

	if (pInfo->RequestIELength > (*ie_size))
	{
		debug_printf(DEBUG_NORMAL, "Insufficient buffer space to store resulting IEs!\n");
		return -1;
	}

	memcpy(ies, &pQueryOid->Data[pInfo->OffsetRequestIEs], pInfo->RequestIELength);
	(*ie_size) = pInfo->RequestIELength;

	return XENONE;
}

/**
 *  Take a block of IE data specified by "in_ie" and parse it, looking for a
 *  WPA2 information element.  The WPA2 information element will be returned in 
 *  "out_ie", if the return value of the function is XENONE.
 *
 *  Since a WPA2 information element is a variable length field, we will determine
 *  that we are looking at a WPA2 IE by matching against the static fields that are found
 *  at the beginning of the IE.  The IE should be in the format of :
 *
 *  0x30 XX 0x01 0x00 0x00 0x0f 0xac GG  (Followed by variable length stuff.)
 *   
 *  The value for XX needs to be at least 8 for it to be a valid IE.
 **/
int cardif_windows_dot11_find_wpa2_ie(context *ctx, char *in_ie, int in_size,
										char *out_ie, int *out_size)
{
	const char wpa2oui[3] = {0x00, 0x0f, 0xac};
	unsigned int i;
	char done;
	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;

	i = 0;
	done = FALSE;

	while ((i < in_size) && (done == FALSE))
	{
		if (in_ie[i] == 0x30)
		{
			// It may be a WPA 2 IE.
			if (in_ie[i+1] >= 8)
			{
				// Looking good..
				if ((in_ie[i+2] == 0x01) && (in_ie[i+3] == 0x00))
				{
					if (memcmp(&in_ie[i+4], &wpa2oui, 3) == 0)
					{
						done = TRUE;
					}
				}
			}
		}
		if (done == FALSE) i+=(unsigned char)(in_ie[i+1]+2);
	}

	if (done == FALSE)
	{
		// 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 WPA2 IE!\n");
		}
		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -