如何解决使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87
我正在尝试使用 Ndis 驱动程序的 prottest.c example 代码在 C 中通过第 2 层发送原始以太网帧。 该示例没有问题,但是当我修改以太类型 (0x88A4 EtherCat) 并用必要的结构和信息调整帧,Writefile 函数总是返回错误 87(不正确的参数)。
在没有 TCP/IP 堆栈的情况下,是否无法在第 2 层上使用此函数在 Raw 中写入,这会出什么问题?
感谢您的帮助。 最好的问候。
VOID
DoWriteProc(
HANDLE Handle
)
{
PUCHAR pWriteBuf = NULL;
PUCHAR pData;
INT SendCount;
PETH_HEADER pEthHeader;
DWORD BytesWritten;
BOOLEAN bSuccess;
DEBUGP(("DoWriteProc\n"));
SendCount = 0;
do
{
pWriteBuf = malloc(PacketLength);
if (pWriteBuf == NULL)
{
DEBUGP(("DoWriteProc: Failed to malloc %d bytes\n",PacketLength));
break;
}
pEthHeader = (PETH_HEADER)pWriteBuf;
pEthHeader->EthType = EthType;
if (bUseFakeAddress)
{
memcpy(pEthHeader->SrcAddr,FakeSrcMacAddr,MAC_ADDR_LEN);
}
else
{
memcpy(pEthHeader->SrcAddr,SrcMacAddr,MAC_ADDR_LEN);
}
memcpy(pEthHeader->DstAddr,DstMacAddr,MAC_ADDR_LEN);
pData = (PUCHAR)(pEthHeader + 1);
*pData++ = (UCHAR)0x8C; //Lenght
*pData++ = (UCHAR)0x45; //Res & Type
*pData++ = (UCHAR)0xD0; //Publisher
*pData++ = (UCHAR)0x50;
*pData++ = (UCHAR)0x99;
*pData++ = (UCHAR)0x45;
*pData++ = (UCHAR)0x34;
*pData++ = (UCHAR)0x9D;
*pData++ = (UCHAR)0x01; //Count
*pData++ = (UCHAR)0x00;
*pData++ = (UCHAR)0x00; //Cycle
*pData++ = (UCHAR)0x00;
*pData++ = (UCHAR)0x00; //Res
*pData++ = (UCHAR)0x28; //EAP_SM
*pData++ = (UCHAR)0x04; //PD ID
*pData++ = (UCHAR)0x00;
*pData++ = (UCHAR)0x00; //Version
*pData++ = (UCHAR)0x00;
*pData++ = (UCHAR)0x78; //Lenght
*pData++ = (UCHAR)0x05;
*pData++ = (UCHAR)0x00; //Quality
*pData++ = (UCHAR)0x00;
unsigned char j = 0;
for (int k = 0; k < 1400; k++) //Data
{
*pData++ = (UCHAR)j;
j++;
if (j > 0xFF)
{
j = 0;
}
}
SendCount = 0;
while (TRUE)
{
bSuccess = (BOOLEAN)WriteFile(
Handle,pWriteBuf,PacketLength,&BytesWritten,NULL);
DWORD err = GetLastError();
printf("ERROR: %i",err);
if (!bSuccess)
{
PRINTF(("DoWriteProc: WriteFile Failed on Handle %p\n",Handle));
break;
}
SendCount++;
DEBUGP(("DoWriteProc: sent %d bytes\n",BytesWritten));
if ((NumberOfPackets != -1) && (SendCount == NumberOfPackets))
{
break;
}
}
} while (FALSE);
if (pWriteBuf)
{
free(pWriteBuf);
}
PRINTF(("DoWriteProc: finished sending %d packets of %d bytes each\n",SendCount,PacketLength));}
HANDLE
OpenHandle(_In_ PSTR pDeviceName){
DWORD DesiredAccess;
DWORD ShareMode;
LPSecurity_ATTRIBUTES lpSecurityAttributes = NULL;
DWORD Creationdistribution;
DWORD FlagsAndAttributes;
HANDLE Handle;
DWORD BytesReturned;
DesiredAccess = GENERIC_READ | GENERIC_WRITE;
ShareMode = 0;
Creationdistribution = OPEN_EXISTING;
FlagsAndAttributes = FILE_ATTRIBUTE_norMAL;
Handle = CreateFileA(
pDeviceName,DesiredAccess,ShareMode,lpSecurityAttributes,Creationdistribution,FlagsAndAttributes,NULL
);
if (Handle == INVALID_HANDLE_VALUE)
{
DEBUGP(("Creating file Failed,error %x\n",GetLastError()));
return Handle;
}
//
// Wait for the driver to finish binding.
//
if (!DeviceIoControl(
Handle,IOCTL_NdisPROT_BIND_WAIT,NULL,&BytesReturned,NULL))
{
DEBUGP(("IOCTL_NdisIO_BIND_WAIT Failed,GetLastError()));
CloseHandle(Handle);
Handle = INVALID_HANDLE_VALUE;
}
return (Handle);
}
解决方法
为了安全起见,the driver refuses to send these types of packets by default。
当然,由于您拥有驱动程序的源代码,您可以随意修改此限制 — 这是您的驱动程序。您可以添加一行来专门允许 0x88A4 EtherType,或者删除整个 if 语句以允许 all EtherType。如果要发送“可疑”网络帧,您可以要求用户模式进程以管理员身份运行。
关于安全角度的更多细节。如果您允许不受信任的用户/程序将任意数据放置到网络上,则可能会危及或削弱网络安全。这就是示例驱动程序(以及一般的 Windows)不允许任意程序在网络上放置任意数据的原因。
例如,可以不受限制地访问以太网层的恶意程序可以通告恶意 DHCP 服务器,该服务器将客户端指向恶意 DNS 服务器,对您的交换机进行 ARP 中毒攻击,对交换机进行 DoS(例如,使用 802.3 x PAUSE 帧,或带有破坏 QoS 策略的 LLDPDU),或绕过您可能拥有的任何防火墙策略。
这些潜在的攻击不一定会破坏交易:考虑到这大致相当于允许某人将任意不受管理的设备插入您网络上的以太网插孔。如果您的网络已经采取措施来防御恶意以太网端点,那么从示例驱动程序中删除限制不会让事情变得更糟。或者,如果您对将运行您的驱动程序的 PC 上的所有用户和代码有一定程度的信任,那么修改驱动程序将无关紧要。或者,如果您的威胁模型已经假设网络是恶意且不可靠的,那么取消这些限制只会有助于满足您的威胁模型的期望。 ;)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。