程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87?

开发过程中遇到使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87的问题如何解决?下面主要结合日常开发的经验,给出你关于使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87的解决方法建议,希望对你解决使用 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 上的所有用户和代码有一定程度的信任,那么修改驱动程序将无关紧要。或者,如果您的威胁模型已经假设网络是恶意且不可靠的,那么取消这些限制只会有助于满足您的威胁模型的期望。 ;)

大佬总结

以上是大佬教程为你收集整理的使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87全部内容,希望文章能够帮你解决使用 EtherType 0x88A4 (EtherCat) 时 WriteFile 函数 (NDIS) 中出现错误 87所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。