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 + -
显示快捷键?