使用 ndisuio 接收 ip 帧
receive ip frames using ndisuio
我正在为 Windows ce 编写 DHCP 客户端。在用套接字完成这一切之后,我意识到我无法从 ip 0.0.0.0 发送数据包,所以我发现我需要使用 NDISUIO。
谷歌搜索 NDISUIO 后,我可以发送工作的 DHCP 发现数据包,但我无法收到服务器响应(程序卡住等待数据包)。请注意,我可以在 wireshark 中看到它们。
int cUDP::Start()
{
char MensajeLog[256];
char buff[1024];
TCHAR pDevName[1024];
TCHAR pDevBuf[1024];
PNDISUIO_QUERY_BINDING pQueryBinding;
ULONG ulData;
NDISUIO_SET_OID set_oid;
//NDISUIO_QUERY_OID query_oid;
//El ethernet type para el protocolo IP es 0x0800
USHORT uEther =0x0800;
//###########################################################
if(m_hAdapter == INVALID_HANDLE_VALUE)
m_hAdapter = CreateFile(
NDISUIO_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
if(m_hAdapter == INVALID_HANDLE_VALUE || m_hAdapter == NULL)
{
m_iLastError = CUDP_SOCKET_ERROR;
return 1;
}
pQueryBinding = (PNDISUIO_QUERY_BINDING) buff;
pQueryBinding->BindingIndex = 0;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_QUERY_BINDING,
pQueryBinding,
sizeof(NDISUIO_QUERY_BINDING),
NULL,
1024,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 2;
}
else
{
memset(pDevName,0,1024);
memcpy(pDevName,&buff[pQueryBinding->DeviceNameOffset], pQueryBinding->DeviceNameLength);
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_OPEN_DEVICE,
pDevName,
wcslen(pDevName)*sizeof(TCHAR),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 3;
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_ETHER_TYPE,
&uEther,
sizeof(uEther),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 5;
}
ulData = NDIS_PACKET_TYPE_ALL_LOCAL|NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_PROMISCUOUS;
set_oid.Oid = OID_GEN_CURRENT_PACKET_FILTER;
CopyMemory(&set_oid.Data[0], &ulData,sizeof(ulData));
set_oid.ptcDeviceName = pDevName;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
&set_oid,
sizeof(set_oid),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 6;
}
return 0;
};
int cUDP::ReceiveFrame ( BYTE* pBuffer,
DWORD Timeout_ms )
{
int timeout;
int timepoint;
DWORD pdwReadBytes;
socklen_t SendAddrlen = sizeof(m_SendAddr);
int BufferLen = sizeof(IPHeaderFormat) +
sizeof(UDPHeaderFormat) +
sizeof (DHCPMsgFormat);//sizeof (DHCPMsgFormat);
timepoint = GetTickCount();
do
{
timeout = GetTickCount();
{
if(!ReadFile( m_hAdapter,
pBuffer,
0,
NULL,
NULL))
{
m_iLastError = CUDP_RECEIVING_ERROR;
}
}
}while(((unsigned) (timeout - timepoint) < Timeout_ms));
return m_iLastError;
};
任何人都可以把我推向正确的方向吗?提前致谢
经过大量阅读和搜索,我发现问题出在使用 IOCTL_NDISUIO_SET_ETHER_TYPE 调用 DeviceIoControl 时。事实证明,uEther 必须采用网络字节顺序,因此将此变量更改为 uEther = 0x0008;
即可。
我正在为 Windows ce 编写 DHCP 客户端。在用套接字完成这一切之后,我意识到我无法从 ip 0.0.0.0 发送数据包,所以我发现我需要使用 NDISUIO。 谷歌搜索 NDISUIO 后,我可以发送工作的 DHCP 发现数据包,但我无法收到服务器响应(程序卡住等待数据包)。请注意,我可以在 wireshark 中看到它们。
int cUDP::Start()
{
char MensajeLog[256];
char buff[1024];
TCHAR pDevName[1024];
TCHAR pDevBuf[1024];
PNDISUIO_QUERY_BINDING pQueryBinding;
ULONG ulData;
NDISUIO_SET_OID set_oid;
//NDISUIO_QUERY_OID query_oid;
//El ethernet type para el protocolo IP es 0x0800
USHORT uEther =0x0800;
//###########################################################
if(m_hAdapter == INVALID_HANDLE_VALUE)
m_hAdapter = CreateFile(
NDISUIO_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
if(m_hAdapter == INVALID_HANDLE_VALUE || m_hAdapter == NULL)
{
m_iLastError = CUDP_SOCKET_ERROR;
return 1;
}
pQueryBinding = (PNDISUIO_QUERY_BINDING) buff;
pQueryBinding->BindingIndex = 0;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_QUERY_BINDING,
pQueryBinding,
sizeof(NDISUIO_QUERY_BINDING),
NULL,
1024,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 2;
}
else
{
memset(pDevName,0,1024);
memcpy(pDevName,&buff[pQueryBinding->DeviceNameOffset], pQueryBinding->DeviceNameLength);
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_OPEN_DEVICE,
pDevName,
wcslen(pDevName)*sizeof(TCHAR),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 3;
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_ETHER_TYPE,
&uEther,
sizeof(uEther),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 5;
}
ulData = NDIS_PACKET_TYPE_ALL_LOCAL|NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_PROMISCUOUS;
set_oid.Oid = OID_GEN_CURRENT_PACKET_FILTER;
CopyMemory(&set_oid.Data[0], &ulData,sizeof(ulData));
set_oid.ptcDeviceName = pDevName;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
&set_oid,
sizeof(set_oid),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 6;
}
return 0;
};
int cUDP::ReceiveFrame ( BYTE* pBuffer,
DWORD Timeout_ms )
{
int timeout;
int timepoint;
DWORD pdwReadBytes;
socklen_t SendAddrlen = sizeof(m_SendAddr);
int BufferLen = sizeof(IPHeaderFormat) +
sizeof(UDPHeaderFormat) +
sizeof (DHCPMsgFormat);//sizeof (DHCPMsgFormat);
timepoint = GetTickCount();
do
{
timeout = GetTickCount();
{
if(!ReadFile( m_hAdapter,
pBuffer,
0,
NULL,
NULL))
{
m_iLastError = CUDP_RECEIVING_ERROR;
}
}
}while(((unsigned) (timeout - timepoint) < Timeout_ms));
return m_iLastError;
};
任何人都可以把我推向正确的方向吗?提前致谢
经过大量阅读和搜索,我发现问题出在使用 IOCTL_NDISUIO_SET_ETHER_TYPE 调用 DeviceIoControl 时。事实证明,uEther 必须采用网络字节顺序,因此将此变量更改为 uEther = 0x0008;
即可。