cardif_windows.c
来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 2,063 行 · 第 1/5 页
C
2,063 行
case WAIT_IO_COMPLETION:
debug_printf(DEBUG_NORMAL, "WAIT_IO_COMPLETION\n");
break;
case WAIT_OBJECT_0:
// The send was probably successful. Double check GetLastError() to be sure.
success = GetLastError();
// ERROR_IO_PENDING means that there is another handler waiting to be triggered
// on the same device. Since we will always have a read handle pending, we should
// always get an ERROR_IO_PENDING following a send.
if ((success != ERROR_SUCCESS) && (success != ERROR_IO_PENDING))
{
ipc_events_error(ctx, IPC_EVENT_ERROR_SEND_FAILED, ctx->desc);
lpMsgBuf = GetLastErrorStr(success);
debug_printf(DEBUG_NORMAL, "Send was not entirely successful in interface '%s'. Error was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
result = XEGENERROR;
}
break;
case WAIT_TIMEOUT:
success = GetLastError();
if ((success != ERROR_SUCCESS) && (success != ERROR_IO_PENDING))
{
lpMsgBuf = GetLastErrorStr(success);
debug_printf(DEBUG_NORMAL, "Attempt to send the frame timed out on interface '%s'! Error was : %s\n", ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
ipc_events_error(ctx, IPC_EVENT_ERROR_SEND_FAILED, ctx->desc);
retval = XEGENERROR;
}
else
{
debug_printf(DEBUG_NORMAL, "Frame was delayed on interface '%s' while trying to be sent. (This should be harmless.)\n", ctx->desc);
retval = XENONE;
}
break;
case WAIT_FAILED:
ipc_events_error(ctx, IPC_EVENT_ERROR_SEND_FAILED, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Wait for frame to be sent failed on interface '%s'! Error was : %s\n", ctx->desc,
lpMsgBuf);
LocalFree(lpMsgBuf);
retval = XEGENERROR;
break;
default:
ipc_events_error(ctx, IPC_EVENT_ERROR_SEND_FAILED, ctx->desc);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Unknown failure code returned on interface '%s'. Error was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
retval = XEGENERROR;
break;
}
CloseHandle(hEvent);
memset(ctx->sendframe, 0x00, FRAMESIZE);
ctx->send_size = 0;
// Clear out the receive buffer so we don't accidently try to process it
// again.
if (ctx->recvframe != NULL)
{
memset(ctx->recvframe, 0x00, FRAMESIZE);
ctx->recv_size = 0;
}
return retval;
}
/**
* \brief Verify that the frame we got is something we care about. If not, discard it.
*
* @param[in] ctx The context that contains the interface that we want to receive
* a frame on.
*
* \retval XENOFRAMES there are no frames available to process
* \retval XEMALLOC there was a memory allocation error
* \retval >0 the number of bytes returned
*
* \todo Fix up 888e check to allow preauth data to come through as well.
**/
int cardif_getframe(context *ctx)
{
char dot1x_default_dest[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03};
struct config_globals *globals = NULL;
wireless_ctx *wctx = 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;
wctx = (wireless_ctx *)ctx->intTypeData;
if (wctx != NULL)
{
if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
{
// This message would probably freak out most users, so only display
// it in debug mode.
debug_printf(DEBUG_INT, "Got a frame while scanning.. Checking if we can auth.\n");
// If we already have information in the SSID cache about this network, then we should
// cancel the scan in progress, and do the authentication. Also, because we won't ever
// have information in the scan cache about hidden networks, if we believe the network is
// hidden, we should also move on. Otherwise, we should allow the scan to continue.
debug_printf(DEBUG_INT, "Known SSID : %s\n", wctx->cur_essid);
if ((config_ssid_ssid_known(wctx, wctx->cur_essid) == TRUE) || (TEST_FLAG(ctx->flags, CONFIG_NET_IS_HIDDEN)))
{
debug_printf(DEBUG_INT, "We know enough to authenticate. Canceling scan.\n");
timer_cancel(ctx, SCANCHECK_TIMER);
UNSET_FLAG(wctx->flags, WIRELESS_SCANNING);
wireless_sm_change_state(ASSOCIATED, ctx);
}
else
{
debug_printf(DEBUG_INT, "We don't know enough to complete an authentication. Discarding.\n");
ctx->recv_size = 0;
return XENONE;
}
}
}
if ((ctx->recvframe == NULL)) return XENOFRAMES;
// Make sure that the frame we got is for us..
if ((memcmp(&ctx->source_mac[0], &ctx->recvframe[0], 6) == 0) ||
((memcmp(&ctx->recvframe[0], &dot1x_default_dest[0], 6) == 0) &&
(memcmp(&ctx->recvframe[6], &ctx->source_mac[0], 6) != 0)))
{
// Since we now know this frame is for us, record the address it
// came from.
snmp_dot1xSuppLastEapolFrameSource((uint8_t *)&ctx->recvframe[6]);
switch (globals->destination)
{
case DEST_AUTO:
// If it is a wired interface, only change the destination if
// the recieved frame destination isn't the multicast address.
if (ctx->intType != ETH_802_11_INT)
{
if (memcmp(&ctx->recvframe[0], dot1x_default_dest, 6) == 0)
{
break;
}
// Otherwise, fall through.
}
case DEST_SOURCE:
if (memcmp(ctx->dest_mac, &ctx->recvframe[6], 6) != 0)
{
debug_printf(DEBUG_INT, "Changing destination mac to source on '%s'.\n", ctx->desc);
}
memcpy(ctx->dest_mac, &ctx->recvframe[6], 6);
break;
case DEST_MULTICAST:
memcpy(ctx->dest_mac, dot1x_default_dest, 6);
break;
case DEST_BSSID:
cardif_GetBSSID(ctx, ctx->dest_mac);
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown destination mode on interface '%s'!\n", ctx->desc);
break;
}
// Make sure it is 888e.
if ((ctx->recvframe[12] != 0x88) || (ctx->recvframe[13] != 0x8e))
{
debug_printf(DEBUG_INT, "An invalid frame managed to sneak "
"through interface '%s'! Killing it!\n", ctx->desc);
debug_hex_dump(DEBUG_INT, ctx->recvframe, 16);
FREE(ctx->recvframe);
ctx->recv_size = 0;
return XENOFRAMES;
}
debug_printf(DEBUG_INT, "Got Frame of size %d on interface '%s' : \n", ctx->recv_size, ctx->desc);
debug_hex_dump(DEBUG_INT, ctx->recvframe, ctx->recv_size);
snmp_dot1xSuppEapolFramesRx();
return ctx->recv_size;
}
// Otherwise it isn't for us.
debug_printf(DEBUG_INT, "Got a frame, not for us.\n");
debug_hex_dump(DEBUG_INT, ctx->recvframe, 16);
return XENOFRAMES;
}
/**
* \brief Set up an event handler to let us know when we got a frame from the network.
*
* @param[in] ctx The context that contains the interface that we want to
* receive data on.
*
* \retval XEMALLOC on memory allocation error
* \retval XEGENERROR on general error
* \retval XENONE on success
**/
int cardif_setup_recv(context *ctx)
{
int newsize=0;
struct win_sock_data *sockData = NULL;
uint8_t *resultframe = NULL;
int resultsize = 0;
struct config_globals *globals = NULL;
LPVOID lpMsgBuf = NULL;
ULONG breadd = 0;
LPOVERLAPPED lovr;
DWORD result = 0;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return XEMALLOC;
globals = config_get_globals();
if (!xsup_assert((globals != NULL), "globals != NULL", FALSE))
return XEMALLOC;
sockData = ctx->sockData;
if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
return XEMALLOC;
resultsize = FRAMESIZE;
lovr = event_core_get_ovr(sockData->devHandle);
if (lovr == NULL)
{
debug_printf(DEBUG_NORMAL, "The device handle doesn't appear to have an event handler "
"registered on interface '%s'!\n", ctx->desc);
ipc_events_error(ctx, IPC_EVENT_ERROR_EVENT_HANDLE_FAILED, ctx->desc);
return XEMALLOC;
}
if (HasOverlappedIoCompleted(lovr) == FALSE)
{
// The last I/O request we had set up never finished. So, we don't want to schedule a
// a new one. (Or weird things happen.)
debug_printf(DEBUG_NORMAL, "Windows reported that an overlapped I/O had not completed on interface '%s' even though the object was signaled. Please attempt your authentication again. If the problem persists, please report it to the Open1X mailing list.\n",
ctx->desc);
return XENONE;
}
// Clear the existing frame storage buffer. (If needed.)
// FREE(sockData->frame);
sockData->size = 0;
if (sockData->frame == NULL)
{
sockData->frame = Malloc(FRAMESIZE);
if (sockData->frame == NULL)
{
debug_printf(DEBUG_INT, "Couldn't allocate memory for incoming frame!\n");
ipc_events_malloc_failed(ctx);
return XEMALLOC;
}
}
if (sockData->hEvent == INVALID_HANDLE_VALUE)
{
// Establish an event that will trigger to let us know that we have data.
sockData->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (sockData->hEvent == INVALID_HANDLE_VALUE)
{
debug_printf(DEBUG_NORMAL, "Couldn't create a valid event handle on interface '%s'!\n", ctx->desc);
ipc_events_error(ctx, IPC_EVENT_ERROR_EVENT_HANDLE_FAILED, ctx->desc);
FREE(sockData->frame);
return XEGENERROR;
}
memset(lovr, 0x00, sizeof(OVERLAPPED));
lovr->hEvent = sockData->hEvent;
event_core_bind_hevent(sockData->devHandle, sockData->hEvent);
}
else
{
if (ResetEvent(sockData->hEvent) == 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't reset event handler for interface '%s'.\n", ctx->desc);
FREE(sockData->frame);
return XEGENERROR;
}
lovr->hEvent = sockData->hEvent;
}
if (resultsize != FRAMESIZE)
{
debug_printf(DEBUG_NORMAL, "The desired frame size has change from when we originally set it. This could indicate a memory corruption error. Please report it to the Open1X mailing list!\n");
}
if (ReadFile(sockData->devHandle, sockData->frame, resultsize, &sockData->size, lovr) != 0)
{
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Error setting up frame listener on interface '%s'. Error was : %s\n",
ctx->desc, lpMsgBuf);
LocalFree(lpMsgBuf);
FREE(sockData->frame);
return XEGENERROR;
}
return XENONE;
}
/**
* \brief Set the state needed to associate to a WPA enabled AP, and actually
* do a WPA authentication.
*
* @param[in] ctx The context that contains the interface that we want to enable
* WPA set for.
*
* \retval XEMALLOC on memory allocation error
* \retval XENONE on success
**/
int cardif_enable_wpa_state(context *ctx)
{
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return XEMALLOC;
if (wireless == NULL) return XEMALLOC;
if (wireless->wpa_state == NULL) return XEMALLOC;
debug_printf(DEBUG_INT, "WPA: Enabling WPA state on interface %s.\n", ctx->intName);
return wireless->wpa_state(ctx, TRUE);
}
/**
* \brief Clear the state needed to associate to a WPA enabled AP, and actually
* do a WPA authentication.
*
* @param[in] ctx The context that contains the interface that we want to clear
* WPA state on.
*
* \retval XEMALLOC a memory allocation error occurred
* \retval XENONE on success
**/
int cardif_disable_wpa_state(context *ctx)
{
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return XEMALLOC;
if (wireless == NULL) return XEMALLOC;
if (wireless->wpa_state == NULL) return XEMALLOC;
return wireless->wpa_state(ctx, FALSE);
}
/**
* \brief Enable WPA support on an interface.
*
* Windows already should have WPA enabled, so this function is only needed as a stub.
*
* @param[in] ctx The context that contains the interface to enable WPA on.
*
* \retval XENONE always returned for Windows
**/
int cardif_enable_wpa(context *ctx)
{
return XENONE;
}
/**
* \brief Call this when we roam to a different AP, or disassociate from an AP.
*
* @param[in] ctx The context for the interface that we want to use WEP to
* associate with.
*
* \retval XEMALLOC on memory allocation errors
* \retval XENONE on success
**/
int cardif_wep_associate(context *ctx, int zeros)
{
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return XEMALLOC;
if (wireless == NULL) return XEMALLOC;
if (!config_ssid_using_wep(ctx->intTypeData))
{
debug_printf(DEBUG_INT, "Doing WPA/WPA2 mode! Not "
"setting/unsetting keys.\n");
return XENONE;
}
return wireless->wep_associate(ctx, zeros);
}
/**
* \brief Validate an interface. (Basically, see if it is an interface we know how
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?