2017-10-02 24 views
0

私はWindows CEのDHCPクライアントを作成しています。ソケットを使ってすべてをやった後、私はIP 0.0.0.0からパケットを送ることができないことに気がついたので、私はNDISUIOを使う必要があることがわかった。 NDISUIOについてのグーグルでは、動作中のDHCPディスカバリパケットを送信できますが、サーバの応答を受け取ることができません(プログラムがパケットを待っている)。私はwiresharkでそれらを見ることができることに注意してください。は、ndisuioを使用してIPフレームを受信します。

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; 
}; 

誰でも正しい方向に私を押し込むことができますか?事前に感謝します。

答えて

1

多くを読んで検索したところ、IOCTL_NDISUIO_SET_ETHER_TYPEを使用してDeviceIoControlの呼び出しで問題が発生していました。 uEtherがネットワークバイトオーダーでなければならないことが分かります。この変数をuEther = 0x0008;に変更すると、このトリックが実行されます。

関連する問題