I am trying to send a Raw Ethernet frame over layer 2, using the prottest.c example code for the NDIS driver, in C. The example works without problem, but when I modify the Ether Type (0x88A4 EtherCat) and adapt the frame with the necessary structure and information, the Writefile function always returns Error 87 (Incorrect parameters).
Is it not possible to write with this function on Layer 2, in Raw, without the TCP/IP stack, what could be wrong?
Thanks for your help. Best regards.
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);
}