cardif_windows.c
来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 2,063 行 · 第 1/5 页
C
2,063 行
* \retval HANDLE a handle to the device, or INVALID_HANDLE_VALUE on error.
**/
HANDLE GetHandle(char *devName)
{
HANDLE retHandle = INVALID_HANDLE_VALUE;
LPVOID lpMsgBuf = NULL;
int result = 0;
DWORD BytesWritten = 0;
if (devName == NULL)
{
debug_printf(DEBUG_NORMAL, "Invalid device name in %s()!\n", __FUNCTION__);
return INVALID_HANDLE_VALUE;
}
retHandle = CreateFile(devName,
FILE_READ_DATA | FILE_WRITE_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
if (retHandle == INVALID_HANDLE_VALUE)
{
lpMsgBuf = GetLastErrorStr(GetLastError());
fprintf(stderr, "Couldn't establish a connection to the Open1X "
"protocol service!\n Error was : %s", lpMsgBuf);
LocalFree(lpMsgBuf);
}
if (devioctl7(retHandle, IOCTL_NDISPROT_BIND_WAIT, NULL, 0,
NULL, 0, &BytesWritten) != 0)
{
debug_printf(DEBUG_NORMAL, "Device handle bind wait failed. Returned %d. We will try to continue anyway.\n", result);
}
return retHandle;
}
// This function is found in mschapv2.c, but we need it here, so
// prototype it, and let the linker figure it out. ;)
char *to_unicode(char *);
/**
* \brief Bind an NDIS device to a specific device handle. This allows
* us to perform read/write operations on the device. (Basically,
* it lets us send and receive frames.)
*
* @param[in] devHandle A handle created by a call to \ref GetHandle(). After this
* call, the handle will refer to a specific interface, instead
* of the "file" that connects to the protocol handler.
*
* @param[in] devName A non-unicode string that identifies the device that we want
* to bind to.
*
* \retval FALSE on error
* \retval TRUE on success
**/
int BindNDISDevice(HANDLE devHandle, char *devName)
{
WCHAR *uniDevName = NULL;
int NameLen = 0;
DWORD retbytes = 0;
DWORD result = 0;
NameLen = strlen(devName);
uniDevName = (WCHAR *)to_unicode(devName);
debug_printf(DEBUG_INT, "Trying to bind to network interface : %ws\n",
uniDevName);
result = devioctl(devHandle, IOCTL_NDISPROT_OPEN_DEVICE,
uniDevName, NameLen * 2, NULL, 0, &retbytes);
FREE(uniDevName);
if ((result != WAIT_OBJECT_0) && (result != WAIT_IO_COMPLETION))
{
return FALSE;
}
return TRUE;
}
/**
* \brief Determine if the named interface is wireless.
*
* @param[in] intname A non-unicode string that identifies the device that we
* want to check.
*
* \retval -1 on error
* \retval FALSE if interface is no wireless
* \retval TRUE if interface is wireless
**/
char is_wireless(char *intname)
{
int retVal;
DWORD result, *state;
UCHAR QueryBuffer[sizeof(NDIS_OID) + 4000];
DWORD BytesReturned;
PNDISPROT_QUERY_OID pQueryOid;
LPVOID lpMsgBuf;
HANDLE temphandle = INVALID_HANDLE_VALUE;
temphandle = GetHandle((char *)&NdisDev);
if (temphandle == INVALID_HANDLE_VALUE)
return -1;
if (BindNDISDevice(temphandle, intname) == 0)
{
ipc_events_error(NULL, IPC_EVENT_ERROR_FAILED_TO_BIND, intname);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Failed to bind interface %s to device "
"handle. Error was : %s\n", intname, lpMsgBuf);
LocalFree(lpMsgBuf);
CloseHandle(temphandle);
return -1;
}
pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
pQueryOid->Oid = OID_GEN_PHYSICAL_MEDIUM;
result = devioctl(temphandle, 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 (result == 0xffffffff)
{
// The IOCTL isn't supported.
debug_printf(DEBUG_INT, "The IOCTL to determine if this interface is wireless "
"does not appear to be implemented in this driver! Assuming it is "
"wired.\n");
CloseHandle(temphandle);
return FALSE;
}
debug_printf(DEBUG_NORMAL, "Get physical media type IOCTL failed on interface '%s'.\n", intname);
// Assume the interface is wired, so we don't try to do anything fancy with it.
return FALSE;
}
state = (DWORD *)&pQueryOid->Data[0];
result = (*state);
#if 0
if (result == NdisPhysicalMediumBluetooth)
{
debug_printf(DEBUG_INT, "Interface appears to be BLUETOOTH!\n");
CloseHandle(temphandle);
return FALSE;
}
#endif
if ((result == NdisPhysicalMediumWirelessLan) || (result == NdisPhysicalMediumNative802_11))
{
debug_printf(DEBUG_INT, "Interface appears to be wireless!\n");
CloseHandle(temphandle);
return TRUE;
}
debug_printf(DEBUG_INT, "Interface is wired, or unknown.\n");
CloseHandle(temphandle);
return FALSE;
}
/**
* \brief Obtain the hardware (MAC) address for the given interface.
*
* @param[in] devHandle A handle for an interface that has been bound using the
* BindNDISDevice() call.
*
* \retval NULL on error
* \retval ptr to the MAC address for the interface specified by \ref devHandle.
**/
char *getmac(HANDLE devHandle)
{
PNDISPROT_QUERY_OID pOidData = NULL;
CHAR *pStr = NULL;
char *mac = NULL;
DWORD bytesreturned = 0, result = 0;
pStr = Malloc(sizeof(NDISPROT_QUERY_OID)+6);
if (pStr == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory!\n");
ipc_events_error(NULL, IPC_EVENT_ERROR_MALLOC, __FUNCTION__);
return NULL;
}
pOidData = (PNDISPROT_QUERY_OID) pStr;
pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
result = devioctl(devHandle, IOCTL_NDISPROT_QUERY_OID_VALUE,
pStr, (sizeof(NDISPROT_QUERY_OID)+6),
pStr, (sizeof(NDISPROT_QUERY_OID)+6),
&bytesreturned);
if ((result != WAIT_OBJECT_0) && (result != WAIT_IO_COMPLETION))
{
debug_printf(DEBUG_NORMAL, "Unable to request the MAC address for an interface!\n");
return NULL;
}
mac = Malloc(6);
if (mac == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store interface MAC address!\n");
return NULL;
}
memcpy(mac, pOidData->Data, 6);
debug_printf(DEBUG_INT, "MAC : %02X:%02X:%02X:%02X:%02X:%02X\n", pOidData->Data[0], pOidData->Data[1], pOidData->Data[2],
pOidData->Data[3], pOidData->Data[4], pOidData->Data[5]);
FREE(pStr);
return mac;
}
/**
* \brief Determine if the interface pointed to by "ctx" is wireless.
*
* @param[in] ctx A pointer to the context that contains the interface to check
* for wirelessness.
*
* \retval XEMALLOC on memory allocation error
* \retval TRUE on success
* \retval FALSE on failure
**/
int cardif_int_is_wireless(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_PHYSICAL_MEDIUM;
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 (result == 0xffffffff)
{
// The IOCTL isn't supported.
debug_printf(DEBUG_INT, "The IOCTL to determine if this interface is wireless "
"does not appear to be implemented in this driver! Assuming it is "
"wired.\n");
return FALSE;
}
debug_printf(DEBUG_NORMAL, "Get physical media type IOCTL failed on interface '%s'.\n", ctx->desc);
// Assume the interface is wired, so we don't try to do anything fancy with it.
return FALSE;
}
state = (DWORD *)&pQueryOid->Data[0];
result = (*state);
if ((result == NdisPhysicalMediumWirelessLan) || (result == NdisPhysicalMediumNative802_11))
{
debug_printf(DEBUG_INT, "Interface appears to be wireless!\n");
return TRUE;
}
debug_printf(DEBUG_INT, "Interface is wired, or unknown.\n");
return FALSE;
}
/**
* \brief Clear all keys, and accept unencrypted traffic again.
*
* @param[in] ctx The context that contains the interface that we want to
* reset.
**/
void cardif_windows_clear_keys(context *ctx)
{
debug_printf(DEBUG_INT, "Allowing unencrypted frames again.\n");
cardif_drop_unencrypted(ctx, 0);
// In Windows, setting the card to infrastructure mode will automatically clear
// all of the keys in the key cache. This is more efficient than making an IOCTL
// for every key we might have, and has the added bonus that it doesn't cause
// bogus error messages when using the Intel 3945 driver! ;)
cardif_windows_set_infra_mode(ctx);
}
/**
* \brief Determine if an interface is currently associated.
*
* @param[in] ctx The context that contains the interface that we want to check
* the association state of.
*
* \note If this call is made against an interface that isn't wireless, the result
* is undefined. (Most likely, it will return IS_UNASSOCIATED.)
*
* \retval IS_ASSOCIATED if the interface is associated
* \retval IS_UNASSOCIATED if the interface is not associated
**/
int cardif_check_associated(context *ctx)
{
UCHAR bssid_dest[6];
if (cardif_windows_wireless_get_bssid(ctx, bssid_dest) == XENONE)
return IS_ASSOCIATED;
return IS_UNASSOCIATED;
}
/**
* \brief We have a frame received event. So handle it.
*
* @param[in] ctx The context that contains the interface that received a frame.
* @param[in] devHandle The device handle for the interface that received a frame.
*
* \retval XENONE on success
**/
int cardif_handle_frame(context *ctx, HANDLE devHandle)
{
if (cardif_getframe(ctx) != XENOFRAMES)
{
if (ctx->intType != ETH_802_11_INT)
eapol_execute(ctx);
}
return XENONE;
}
/**
* \brief If there is a mismatch between the Windows description and the
* one in our configuration file, we need to go through and rename stuff
* in memory.
*
* \note All of the changes that happen in this function *ONLY* happen in memory.
* However, if a request to write the configuration file is issued the changed
* connection and interface configuration data will be committed to disk!!
*
* @param[in] confdesc The description of the interface in the configuration.
* @param[in] windesc The description that Windows is providing us.
**/
void cardif_windows_fixup_config(char *confdesc, char *windesc)
{
struct config_connection *confcon = NULL;
struct xsup_interfaces *confints = NULL;
char *myconfdesc = NULL;
confints = config_get_config_ints();
if (confints == NULL)
{
// This should be virtually impossible! (Unless the caller is being *REALLY* stupid! ;)
debug_printf(DEBUG_NORMAL, "There was a request to fix some interface/connection issues, but there are no interfaces defined!?\n");
return;
}
while ((confints != NULL) && (strcmp(confints->description, confdesc) != 0))
confints = confints->next; // This is okay because we don't want to free the pointer as it points to the master structure. ;)
if (confints == NULL)
{
// This should also be virtually impossible!
debug_printf(DEBUG_NORMAL, "There was a request to fix some interface/connection issues, but the interface that triggered it isn't in configuration memory!?\n");
return;
}
// Make a copy of the "wrong" description, since we will probably overwrite it in the next set of commands. ;)
myconfdesc = _strdup(confdesc);
FREE(confints->description);
confints->description = _strdup(windesc); // Set the new interface name. If a write configuration request is made, this *WILL* get written to the config!!
confcon = config_get_connections();
if (confcon == NULL)
{
debug_printf(DEBUG_NORMAL, "There are no connections defined to update.\n");
FREE(myconfdesc);
return;
}
while (confcon != NULL)
{
if (strcmp(confcon->device, myconfdesc) == 0)
{
// We need to rewrite this.
FREE(confcon->device);
confcon->device = _strdup(windesc);
}
confcon = confcon->next;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?