cardif_windows.c

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

C
2,063
字号

	FREE(myconfdesc);
}

/**
 * \brief Set the wireless cardif_funcs structure to use the driver that the user
 *        has requested.
 *
 * \note This call is provided in Windows for completeness only.  It doesn't actually
 *       do anything.
 *
 * @param[in] driver   An integer that defines the driver to be used for this
 *                     interface.
 **/
void cardif_set_driver(char driver)
{
	// Windows only has one driver API interface.
}

//void cardif_windows_get_events(void *pValue);

/**
 * \brief Prepare an interface to send and receive frames.
 *
 * Do whatever is needed to get the interface in to a state that we can send
 * and recieve frames on the network.  Any information that we need to later
 * use should be stored in the context structure.
 *
 * @param[in] ctx   A pointer to the context that contains the interface that we
 *                  need to get ready to send and receive frames.
 * @param[in] driver   An integer that defines the driver to be used for this
 *                     interface.  (Not used on Windows!)
 *
 * \retval XEMALLOC on memory allocation failure
 * \retval XEGENERROR on generic error
 * \retval XENOSOCK if there is no socket available to work with
 * \retval XENONE on success
 **/
int cardif_init(context *ctx, char driver)
{
	struct config_globals *globals = NULL;
    struct win_sock_data *sockData = NULL;
	struct xsup_interfaces *confints = NULL;
	LPVOID lpMsgBuf = NULL;
	char *mac = NULL;
	char *intdesc = NULL;

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

	globals = config_get_globals();

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

    debug_printf(DEBUG_INIT | DEBUG_INT, "Initializing socket for interface %s..\n",
        	       ctx->intName);
  
	// Allocate memory for the things we need.
	ctx->sockData = (void *)Malloc(sizeof(struct win_sock_data));
	if (ctx->sockData == NULL)
	{
      debug_printf(DEBUG_NORMAL, "Error allocating memory!\n");
	  ipc_events_error(ctx, IPC_EVENT_ERROR_MALLOC, __FUNCTION__);
      return XEMALLOC;
    }

	sockData = ctx->sockData;

	// Indicate that we don't know the WMI index of this interface.
	sockData->wmiIntIdx = INVALID_WMI_IDX;

	sockData->devHandle = GetHandle(NdisDev);
	if (sockData->devHandle == NULL)
	{
		debug_printf(DEBUG_NORMAL, "Couldn't get a handle to device '%s'.  This interface may not exist on this system.\n", ctx->desc);
		ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_TO_GET_HANDLE, ctx->desc);
		return XEGENERROR;
	}

	sockData->hEvent = INVALID_HANDLE_VALUE;

	if (BindNDISDevice(sockData->devHandle, ctx->intName) == 0)
	{
		ipc_events_error(ctx, IPC_EVENT_ERROR_FAILED_TO_BIND, ctx->desc);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Failed to bind interface %s to device "
			"handle.  Error was : %s\n", ctx->intName, lpMsgBuf);
		
		LocalFree(lpMsgBuf);
		CloseHandle(sockData->devHandle);
		return XENOSOCK;
	}

	mac = getmac(sockData->devHandle);
	if (mac == NULL)
	{
		ipc_events_error(ctx, IPC_EVENT_ERROR_GET_MAC, ctx->desc);
		lpMsgBuf = GetLastErrorStr(GetLastError());
		debug_printf(DEBUG_NORMAL, "Couldn't get MAC address for "
			"interface %s!  Error was : %s\n", ctx->desc, lpMsgBuf);

		LocalFree(lpMsgBuf);
		CloseHandle(sockData->devHandle);
		return XENOSOCK;
	}

	memcpy(ctx->source_mac, mac, 6);

    if (cardif_int_is_wireless(ctx) == TRUE)
    {
	  debug_printf(DEBUG_INT, "Interface is wireless.\n");
	  ctx->intType = ETH_802_11_INT;

		// Disable WZC (if it is running.)
		if (wzc_ctrl_disable_wzc(ctx->intName) != 0)
		{
			debug_printf(DEBUG_NORMAL, "Unable to disable WZC for interface %s.\n", ctx->intName);
		}

	  if (context_create_wireless_ctx((wireless_ctx **)&ctx->intTypeData, 0) != XENONE)
	  {
		  debug_printf(DEBUG_NORMAL, "Couldn't create wireless context for interface '%s'!\n", ctx->desc);
		  ipc_events_error(ctx, IPC_EVENT_ERROR_CANT_CREATE_WIRELESS_CTX, ctx->desc);
		  FREE(mac);
		  return -1;
	  }
	  
      // If we have our destination set to AUTO, then preset our destination
      // address.
      if (globals->destination == DEST_AUTO)
		{
			cardif_GetBSSID(ctx, ctx->dest_mac);
		}

	  // And make sure we don't have any stray connections hanging around.
	  cardif_disassociate(ctx, 0);
    }
	else
	{
		// Disable the Windows 802.1X stack on a wired interface.
		if (windows_eapol_ctrl_disable(ctx->desc, ctx->intName) != 0)
		{
			debug_printf(DEBUG_NORMAL, "Unable to configure the interface '%s'.\n", ctx->desc);
		}
	}


	if (SetMulticastAddress(sockData->devHandle) == FALSE)
	{
		debug_printf(DEBUG_NORMAL, "Couldn't get driver layer to give us access to the "
			"needed multicast frames on interface '%s'!\n", ctx->desc);
		FREE(mac);
		return XENOSOCK;
	}

  ctx->sendframe = Malloc(FRAMESIZE);
  if (ctx->sendframe == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store frames "
		   "to be sent.\n");
	  ipc_events_malloc_failed(ctx);
	  FREE(mac);
      return XEMALLOC;
    }

  wireless = &cardif_windows_wireless_driver;
#if 0
  switch (cardif_windows_use_new_ioctls(ctx))
  {
  case 0:
  case 1:
	debug_printf(DEBUG_INT, "It appears your card only supports the old interface.  Using that.\n");
	wireless = &cardif_windows_wireless_driver;
	break;

  case 2:
	debug_printf(DEBUG_INT, "It appears your card supports the new API!  Life is good!\n");
	wireless = &cardif_windows_dot11_driver;
	break;
  }
#endif

  if (cardif_windows_wmi_get_idx(ctx, &intdesc) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't determine the WMI interface caption for interface '%s'!\n",
		  ctx->desc);
  }
  else
  {
	// Verify that we know about the interface.  MAC address, description, etc.
	confints = config_get_config_ints();

	while ((confints != NULL) && (memcmp(mac, confints->mac, 6) != 0))
		confints = confints->next;
	
	if (confints != NULL)  // If it isn't found, then we have nothing to worry about.
	{
		if (strcmp(confints->description, intdesc) != 0)
		{
			// The interface has a MAC address match, but a different description.
			// Rewrite the configuration data in memory to allow this interface to be used.
			debug_printf(DEBUG_NORMAL, "Interface '%s' has a MAC address match, but the descriptions don't match.  Attempting to fix...\n", intdesc);
			cardif_windows_fixup_config(confints->description, intdesc);

			FREE(ctx->desc);
			ctx->desc = _strdup(intdesc);
		}
	}
  }
  FREE(mac);
  FREE(intdesc);

  event_core_register(sockData->devHandle, ctx, &cardif_handle_frame, 2, "frame handler");

  return XENONE;
}

/**
 * \brief Tell the wireless card to start scanning for wireless networks.
 *
 * @param[in] ctx   The context for the interface that we want to start scanning.
 * @param[in] passive   Should it be a passive scan?  (Not supported on Windows!)
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_do_wireless_scan(context *ctx, char passive)
{
	wireless_ctx *wctx = NULL;
	int resval = 0;

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

  if (wireless == NULL) 
    {
      debug_printf(DEBUG_INT, "No valid wireless calls struct! (%s:%d)\n",
		   __FUNCTION__, __LINE__);
      return XEMALLOC;
    }

  wctx = (wireless_ctx *)ctx->intTypeData;
  if (!xsup_assert((wctx != NULL), "wctx != NULL", FALSE)) return XEMALLOC;

  // If we are already scanning, then we shouldn't get here, but go ahead 
  // and ignore it anyway.
  if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING) )
    {
      debug_printf(DEBUG_INT, "Got a request to start a new scan when one is"
		   " already in progress!  Ignoring!\n");
      return XENONE;
    }

  SET_FLAG(wctx->flags, WIRELESS_SCANNING);

  // Don't clear the scan cache until we have new data.  This allows us to handle situations
  // where the association is slow, and happens while we are waiting for scan data.  (Such as
  // the behavior of the IPW3945 and Trpz APs.)

  resval = wireless->scan(ctx, passive);

  if (resval != XENONE)
  {
	  // We had an error trying to scan, so clear the scanning flag.
	  UNSET_FLAG(wctx->flags, WIRELESS_SCANNING);
  }

  return resval;
}

/**
 * \brief Send a disassociate request.
 *
 * @param[in] ctx   The context for the interface that we want to send a disassociate
 *                  request for.
 * @param[in] reason_code   The reason code as identified by the 802.11 standards. (Not
 *                          used on Windows.)
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_disassociate(context *ctx, int reason_code)
{
  if (!xsup_assert((ctx != NULL), "thisint != NULL", FALSE))
    return XEMALLOC;

  debug_printf(DEBUG_NORMAL, "We have requested a disassociate on interface '%s'.\n", ctx->desc);

  if (wireless == NULL) return XEMALLOC;

  debug_printf(DEBUG_INT, "Called %s\n", __FUNCTION__);
  return wireless->disassociate(ctx, reason_code);
}

/**
 * \brief Return the socket number for functions that need it.
 *
 * @param[in] ctx   The context for the interface we want to get the socket number
 *                  from.
 *
 * \retval XENOSOCK because this isn't supported on Windows.
 **/
int cardif_get_socket(context *ctx)
{
	debug_printf(DEBUG_NORMAL, "%s() makes no sense for Windows!\n", __FUNCTION__);
	return XENOSOCK;
}

/**
 * \brief Clean up anything that was created during the initialization and operation
 *        of the interface.  This will be called before the program terminates.
 *
 * @param[in] ctx   The context for the interface that we want to clean up.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_deinit(context *ctx)
{
  uint16_t int16 = 0;
  struct win_sock_data *sockData = NULL;
  uint8_t all0s[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

  FREE(ctx->sendframe);
  
  sockData = ctx->sockData;

  debug_printf(DEBUG_DEINIT | DEBUG_INT, "Cleaning up interface %s...\n", ctx->intName);

  if (ctx->intType == ETH_802_11_INT)
  {
    // Remove all of the keys that we have set.
    if (!TEST_FLAG(ctx->flags, INT_GONE)) cardif_clear_keys(ctx);

    debug_printf(DEBUG_DEINIT | DEBUG_INT, "Turning off WPA support/state.\n");

    // Clear the WPA IE.
    //cardif_set_wpa_ie(ctx, NULL, 0);

    if (!TEST_FLAG(ctx->flags, INT_GONE)) cardif_disable_wpa_state(ctx);

	if (!TEST_FLAG(ctx->flags, INT_GONE)) cardif_disassociate(ctx, 0);
  }

  if (CloseHandle(sockData->hEvent) == 0)
  {
	  debug_printf(DEBUG_NORMAL, "Unable to close event handle.  Error was : %d\n", GetLastError());
  }

  FREE(sockData->frame);

  if (CloseHandle(sockData->devHandle) == 0)
  {
	  debug_printf(DEBUG_NORMAL, "Unable to close device handle.  Error was : %d\n", GetLastError());
  }

  // Free the memory used for the Caption.
  FREE(sockData->caption);

  // Now clean up the memory.
  FREE(ctx->sockData);

  return XENONE;
}

/**
 * \brief Set a WEP key.  Also, based on the index, we may change the transmit
 *        key.
 *
 * @param[in] ctx   The context for the interface that we want to change the WEP key
 *                  on.
 * @param[in] key   A pointer to a byte array that identifies the key to be installed.
 * @param[in] keylen   The length of the key data pointed to by "key".
 * @param[in] index   The index for the key.  If (index & 0x80) then the key is a 
 *                    transmit key, and will be treated as such.
 *
 * \retval XEMALLOC on memory allocation error.
 * \retval XENONE on success
 **/
int cardif_set_wep_key(context *ctx, uint8_t *key, 
		       int keylen, int index)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

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

  if (wireless == NULL) return XEMALLOC;

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

  return wireless->set_wep_key(ctx, key, keylen, index);
}

/**
 * \brief Set a TKIP key. 
 *
 * @param[in] ctx   The context that contains the interface that we want to set a
 *                  TKIP key on.
 * @param[in] addr   The BSSID (MAC address) of the AP that this key is set for.  If
 *                   the key is a broadcast key, it should be set to ff:ff:ff:ff:ff:ff.
 * @param[in] keyidex   The index that this key should be used in.
 * @param[in] settx   A TRUE or FALSE value that indicates if this key should be used
 *                    as the transmit key.
 * @param[in] key   A pointer to a string of bytes that represent the TKIP key to use.
 * @param[in] keylen   The number of bytes that make up the key.  (Should be 32 on TKIP.)
 *
 * \retval XEMALLOC on memory allocation error

⌨️ 快捷键说明

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