cardif_windows.c

来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 2,063 行 · 第 1/5 页

C
2,063
字号
 * \retval XENONE on success
 **/
int cardif_set_tkip_key(context *ctx, char *addr, int keyidx, int settx, 
						char *key, int keylen)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->set_tkip_key == NULL) return XEMALLOC;

  return wireless->set_tkip_key(ctx, (uint8_t *) addr, keyidx, settx, 
				key, keylen);
}

/**
 * \brief Set a CCMP (AES) key
 *
 * @param[in] ctx   The context that contains the interface that we want to set
 *                  a CCMP key on.
 * @param[in] addr   The BSSID (MAC address) of the AP that this key should be used
 *                   with.
 * @param[in] keyidx   The index for the key slot that this key should be used in.
 * @param[in] settx   A TRUE or FALSE value that identifies if this key should be used
 *                    as a transmit key.
 * @param[in] key   A pointer to a byte string that is to be used as the CCMP key.
 * @param[in] keylen   The length of the byte string pointed to by "key".  (This should
 *                     be 16.)
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_set_ccmp_key(context *ctx, char *addr, int keyidx,
			int settx, char *key, int keylen)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->set_ccmp_key == NULL) return XEMALLOC;

  return wireless->set_ccmp_key(ctx, (uint8_t *) addr, keyidx, settx,
				key, keylen);
}

/**
 * \brief Delete a key from an interface.
 *
 * @param[in] ctx   The context that contains the interface that we want to delete
 *                  a key from.
 * @param[in] key_idx   The index for the key that we want to delete.
 * @param[in] set_tx   A TRUE or FALSE value that identifies if this key was a
 *                     transmit key.
 **/
int cardif_delete_key(context *intdata, int key_idx, int set_tx)
{
  if (!xsup_assert((intdata != NULL), "intdata != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return -1;

  if (wireless->delete_key == NULL) return -1;

  return wireless->delete_key(intdata, key_idx, set_tx);
}

/**
 * \brief Do whatever we need to do in order to associate based on the flags in
 *        the ssids_list struct.
 *
 * @param[in] ctx   The context that contains the interface that we want to try to
 *                  associate with.
 **/
void cardif_associate(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

  if (wireless->associate == NULL) return;

  wireless->associate(ctx);
}

/**
 * \brief Request that the card/driver tell us which ESSID we are connected to.
 *
 * 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.
 *
 * @param[in] ctx   The context that contains the interface that we want to get the
 *                  ESSID from.
 * @param[out] ssid_name   A buffer that is large enough to hold the resulting ESSID
 *                        name.
 * @param[in] ssidsize   The size of buffer that "ssid_name" points to.
 * 
 * \retval XENONE on success
 * \retval XEMALLOC on memory allocation error
 **/
int cardif_GetSSID(context *ctx, char *ssid_name, unsigned int ssidsize)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

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

  if (wireless == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "No valid call to get SSID for this driver!"
		   "\n");
      return XEMALLOC;
    }

  if ((ctx == NULL) || (ssid_name == NULL)) 
  {
    debug_printf(DEBUG_INT, "NULL value passed to %s!\n", __FUNCTION__);
    return XEMALLOC;
  }

  return wireless->get_ssid(ctx, ssid_name, ssidsize);
}

/**
 * \brief Request that the card/driver return the BSSID (MAC Address) of the AP we
 *        are connected to.
 *
 * 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   A context that contains the interface that we want to query to 
 *                  determine the BSSID of the interface.
 * @param[out] bssid_dest   A pointer to a buffer of at least 6 bytes that the BSSID
 *                          can be written to.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_GetBSSID(context *ctx, char *bssid_dest)
{
	if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
		return XEMALLOC;

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

	return cardif_windows_wireless_get_bssid(ctx, bssid_dest);
}

/**
 * \brief Determine if an interface is up or down.
 *
 * Set the flag in the state machine that indicates if this interface is up
 * or down.  If there isn't an interface, we should return an error.
 *
 * @param[in] ctx   A pointer to the context that contains the interface that we want
 *                  to determine the up/down state of.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval TRUE if the interface is up.
 * \retval FALSE if the interface is down.
 **/
int cardif_get_if_state(context *ctx)
{
  int retVal = 0;
  DWORD result = 0, *state = NULL;
  struct win_sock_data *sockData = NULL;
  UCHAR QueryBuffer[sizeof(NDIS_OID) + 4];
  DWORD BytesReturned = 0;
  PNDISPROT_QUERY_OID pQueryOid = NULL;

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

  sockData = ctx->sockData;

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

  pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
  pQueryOid->Oid = OID_GEN_HARDWARE_STATUS;

  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))
    {
        debug_printf(DEBUG_INT, "Get interface state IOCTL failed.  (%x) --  Assuming the interface is down.\n", result);

        return FALSE;
    }

  state = (DWORD *)&pQueryOid->Data[0];

  result = (*state);

  if (result == NdisHardwareStatusReady)
    {
      return TRUE;
    } 
	
  return FALSE;
}

/**
 * \brief Get the link state of an interface.
 *
 * Return the link state of the interface.  On Windows, this indicates that link is up/down
 * on a wired interface, but also indicates associated/unassociated state on wireless.
 *
 * @param[in] ctx   The context for the interface that we want to determine the link
 *                  state of an interface for.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval TRUE if link is up
 * \retval FALSE if link is down
 **/
int cardif_get_link_state(context *ctx)
{
  int retVal = 0;
  DWORD result = 0, *state = NULL;
  struct win_sock_data *sockData = NULL;
  UCHAR QueryBuffer[sizeof(NDIS_OID) + 4];
  DWORD BytesReturned = 0;
  PNDISPROT_QUERY_OID pQueryOid = NULL;

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

  if (TEST_FLAG(ctx->flags, INT_GONE)) return FALSE;  // The interface isn't there, so it can't be up. ;)

  sockData = ctx->sockData;

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

  pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
  pQueryOid->Oid = OID_GEN_MEDIA_CONNECT_STATUS;

  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 we can't make this call, assume link is down.
		return FALSE;
    }

  state = (DWORD *)&pQueryOid->Data[0];

  result = (*state);

  if (result == 0)
    {
      return TRUE;
    } 
	
  return FALSE;
}

/**
 * \brief Manually check any events that need to be checked on Windows.
 *
 * @param[in] ctx   The context for the interface that we need to check for events.
 **/
void cardif_check_events(context *ctx)
{
	wireless_ctx *wctx = NULL;
	uint8_t link = 0, assoc = 0;

	TRACE

	xsup_assert((ctx != NULL), "ctx != NULL", TRUE);

#if 0
	//  It is possible that wctx will end up being NULL!
	//   You should test that it is valid before attempting to use it!
	wctx = (wireless_ctx *)ctx->intTypeData;

	link = cardif_get_link_state(ctx);
	assoc = cardif_check_associated(ctx);
	
	if ((link == TRUE) && (assoc == IS_ASSOCIATED))
	{
		// If this is a wired interface, we won't have a value for "wctx".  So be sure we don't
		// segfault.
		if (wctx != NULL)	
		{
			if (!TEST_FLAG(wctx->flags, WIRELESS_SM_STALE_ASSOCIATION))
				SET_FLAG(wctx->flags, WIRELESS_SM_ASSOCIATED);
		}
	}
	else
	{
		if (wctx != NULL) 
		{
			UNSET_FLAG(wctx->flags, WIRELESS_SM_ASSOCIATED);
			UNSET_FLAG(wctx->flags, WIRELESS_SM_STALE_ASSOCIATION);
	
			// *DO NOT* change the value of wctx->assoc_type here!  We should only
			// change that value when we go to UNASSOCIATED state!
		}
	}
#endif
}

/**
 * \brief Send a frame out a network interface.
 *
 * Send a frame out of the network card interface.  If there isn't an 
 * interface, we should return an error.  We should return a different error
 * if we have a problem sending the frame.
 *
 * @param[in] ctx   The context that contains the interface that we want to send a
 *                  frame out of.
 *
 * \retval XEMALLOC on memory allocation failure
 * \retval XEGENERROR a general error occurred
 * \retval XENONE on success
 **/
int cardif_sendframe(context *ctx)
{
  char nomac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  int retval = 0;
  struct win_sock_data *sockData = NULL;
  struct config_network *network_data  = NULL;
  uint16_t pad = 0;
  OVERLAPPED ovr;
  LPVOID lpMsgBuf = NULL;
  HANDLE hEvent = INVALID_HANDLE_VALUE;
  DWORD result = 0, success = 0, bwritten = 0;

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

  sockData = ctx->sockData;

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

  if (ctx->send_size == 0) 
    {
      debug_printf(DEBUG_INT, "%s:%d -- Nothing to send!\n",
		   __FUNCTION__, __LINE__);
      return XENONE;
    }

  memset(&ovr, 0x00, sizeof(OVERLAPPED));

  hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (hEvent == INVALID_HANDLE_VALUE)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't establish event handle for interface '%s'!\n", ctx->desc);
	  ipc_events_error(ctx, IPC_EVENT_ERROR_EVENT_HANDLE_FAILED, ctx->desc);
	  return XEGENERROR;
  }

  ovr.hEvent = hEvent;

  // The frame we are handed in shouldn't have a src/dest, so put it in.
  memcpy(&ctx->sendframe[0], &ctx->dest_mac[0], 6);
  memcpy(&ctx->sendframe[6], &ctx->source_mac[0], 6);

  if (ctx->conn != NULL)
    {
		if (memcmp(nomac, (char *)&ctx->conn->dest_mac[0], 6) != 0)
	  {
	    debug_printf(DEBUG_INT, "Static MAC address defined!  Using it!\n");
		memcpy(&ctx->sendframe[0], &ctx->conn->dest_mac[0], 6);
	  }
    }

  // Make sure the frame is large enough.
  if (ctx->send_size < 64)
    {
      pad = 64 - ctx->send_size;
      debug_printf(DEBUG_INT, "Padding frame to 64 bytes by adding %d byte"
		   "(s).\n", pad);
      memset(&ctx->sendframe[ctx->send_size+1], 0x00, pad);
      ctx->send_size += pad;
    }

  debug_printf(DEBUG_INT, "Frame to be sent (%d) : \n",
	       ctx->send_size);
  debug_hex_dump(DEBUG_INT, ctx->sendframe, ctx->send_size);

  snmp_dot1xSuppEapolFramesTx();

  if (WriteFile(sockData->devHandle, ctx->sendframe, ctx->send_size, &bwritten, &ovr) != 0)
  {
	  ipc_events_error(ctx, IPC_EVENT_ERROR_SEND_FAILED, ctx->desc);
	  lpMsgBuf = GetLastErrorStr(GetLastError());
	  debug_printf(DEBUG_NORMAL, "Couldn't send frame to the authenticator on interface '%s'!   Error was : %s\n", 
		  ctx->desc, lpMsgBuf);
	  LocalFree(lpMsgBuf);
	  CloseHandle(hEvent);
	  retval = XEGENERROR;
  }

  result = WaitForSingleObjectEx(hEvent, 1000, FALSE);
  
  switch (result)
  {
  case WAIT_ABANDONED:
	  debug_printf(DEBUG_NORMAL, "WaitForSingleObjectEx() returned WAIT_ABANDONED!\n");
	  retval = XEGENERROR;
	  break;

⌨️ 快捷键说明

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