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

📄 cardif_windows_wireless.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
		  }
		  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 + -