首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WriteFile函数使用EtherType 0x88A4 (EtherCat)时的错误87

WriteFile函数使用EtherType 0x88A4 (EtherCat)时的错误87
EN

Stack Overflow用户
提问于 2021-06-01 08:32:42
回答 1查看 93关注 0票数 0

我试图通过第二层发送一个原始以太网帧,在C中使用用于NDIS驱动程序的prottest.c示例代码。该示例工作正常,但是当我修改以太类型(0x88A4 EtherCat)并使用必要的结构和信息调整帧时,Writefile函数总是返回错误87 (不正确的参数)。

如果没有TCP/IP协议栈,就不能在第二层编写这个函数吗?

谢谢你的帮助。诚挚的问候。

代码语言:javascript
复制
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,
        0,
        NULL,
        0,
        &BytesReturned,
        NULL))
    {
        DEBUGP(("IOCTL_NDISIO_BIND_WAIT failed, error %x\n", GetLastError()));
        CloseHandle(Handle);
        Handle = INVALID_HANDLE_VALUE;
    }

    return (Handle);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-01 23:15:12

为了安全,驱动程序默认拒绝发送这些类型的数据包。

当然,因为您有驱动程序的源代码,所以您可以随意修改这个限制--这是您的驱动程序。您可以添加一行,专门允许0x88A4 EtherType,或者删除整个if-语句以允许所有EtherTypes。如果用户模式进程想发送“可疑”网络帧,可以要求它以管理员身份运行。

关于安全角度的一些细节。如果允许不受信任的用户/程序将任意数据放置到网络上,则可能会危及或削弱网络安全。这就是为什么示例驱动程序(通常是Windows )不允许任意程序在网络上放置任意数据的原因。

例如,不受限制地访问以太网层的恶意程序可以为恶意DHCP服务器做广告,该服务器将客户端指向恶意DNS服务器,对您的交换机进行ARP中毒攻击,对交换机进行DoS (例如,使用802.3x暂停帧,或使用破坏QoS策略的LLDPDU),或者规避您可能拥有的任何防火墙策略。

这些潜在的攻击不一定会破坏交易:考虑到这大致相当于允许某人将任意的非托管设备插入到您网络上的以太网插孔中。如果您的网络已经有了防范敌对以太网端点的措施,那么从示例驱动程序中删除限制不会使情况变得更糟。或者,如果您对所有用户都有一定程度的信任&将运行您的驱动程序的PC上的代码,那么修改驱动程序就无关紧要了。或者,如果您的威胁模型已经假定网络是敌对的和不可靠的,那么取消这些限制只会有助于满足您的威胁模型的期望。;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67785400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档