从C#获取DHCPINFORM消息响应的问题

时间:2010-10-27 10:24:05

标签: c# udp dhcp udpclient

我正在开发一个应用程序,我想通过DHCP服务器提取一些信息。所以我在端口67 UDP广播上发送DHCPINFORM数据包。我面临的问题是我没有得到响应,即DHCPACK或来自DHCP服务器的任何其他消息,这意味着它有时会一次性发回一个DHCPACK数据包而有些时候根本不回复,这可能是导致此问题的原因?

这是我的网络配置 我的IP:192.168.3.31 DHCP服务器位于:192.168.3.108

我正在使用的

和C#代码是

private void SendDHCPINFORM()
    {
        UdpClient udpClient = new UdpClient();
        IPEndPoint dhcpClientEndpoint = new IPEndPoint(IPAddress.Broadcast, 67);

        #region Making Data DHCPINFORM
        D_op = 1;
        D_htype = 1;
        D_hlen = 6;
        D_hops = 0;
        D_xid = new byte[4];
        Random objRandom = new Random(8000);
        objRandom.NextBytes(D_xid);

        D_secs = new byte[2];
        D_secs = BitConverter.GetBytes(Convert.ToInt16(0));

        D_flags = new byte[2];
        D_flags = BitConverter.GetBytes(Convert.ToInt16(0));

        D_ciaddr = new byte[4];
        D_ciaddr[0] = 192;
        D_ciaddr[1] = 168;
        D_ciaddr[2] = 3;
        D_ciaddr[3] = 31;

        D_yiaddr = new byte[4];
        D_yiaddr = BitConverter.GetBytes(0);

        D_siaddr = new byte[4];
        D_siaddr = BitConverter.GetBytes(0);

        D_giaddr = new byte[4];
        D_giaddr = BitConverter.GetBytes(0);

        //00-13-D3-D5-27-73
        D_chaddr = new byte[16];
        D_chaddr[0] = 0;
        D_chaddr[1] = 19;
        D_chaddr[2] = 211;
        D_chaddr[3] = 213;
        D_chaddr[4] = 39;
        D_chaddr[5] = 115;

        D_sname = new byte[64];


        D_file = new byte[128];

        M_Cookie = new byte[4];
        M_Cookie[0] = 99;
        M_Cookie[1] = 130;
        M_Cookie[2] = 83;
        M_Cookie[3] = 99;


        D_options = new byte[60];

        //Making DHCPINFORM message
        byte[] messageType = new byte[3];
        messageType[0] = 53;
        messageType[1] = 1;
        messageType[2] = 8; //Message Type from 1-8
        Array.Copy(messageType, D_options, messageType.Length);

        int options_offset = 3;

        byte[] serverIdentifier = new byte[6];
        serverIdentifier[0] = 54;
        serverIdentifier[1] = 4;
        serverIdentifier[2] = 192;
        serverIdentifier[3] = 168;
        serverIdentifier[4] = 3;
        serverIdentifier[5] = 108;
        Array.Copy(serverIdentifier, 0, D_options, options_offset, serverIdentifier.Length);

        options_offset += serverIdentifier.Length;
        byte[] dummyPacket = new byte[3];
        dummyPacket[0] = 116;
        dummyPacket[1] = 1;
        dummyPacket[2] = 1;
        Array.Copy(dummyPacket, 0, D_options, options_offset, dummyPacket.Length);

        options_offset += dummyPacket.Length;
        byte[] clientIdentifier = new byte[9];
        clientIdentifier[0] = 61;
        clientIdentifier[1] = 7;
        clientIdentifier[2] = 1;
        Array.Copy(D_chaddr, 0, clientIdentifier, 3, 6);
        Array.Copy(clientIdentifier, 0, D_options, options_offset, clientIdentifier.Length);

        options_offset += clientIdentifier.Length;
        byte[] hostName = new byte[7];
        hostName[0] = 12;
        hostName[1] = 5;
        Array.Copy(Encoding.ASCII.GetBytes("host1"), 0, hostName, 2, Encoding.ASCII.GetBytes("host1").Length);
        Array.Copy(hostName, 0, D_options, options_offset, hostName.Length);

        options_offset += hostName.Length;
        byte[] vendorClassID = new byte[10];
        vendorClassID[0] = 60;
        vendorClassID[1] = 8;
        //Array.Copy(Encoding.ASCII.GetBytes("Unspecified"), 0, vendorClassID, 2, Encoding.ASCII.GetBytes("Unspecified").Length);
        Array.Copy(Encoding.ASCII.GetBytes("MSFT 5.0"), 0, vendorClassID, 2, Encoding.ASCII.GetBytes("MSFT 5.0").Length);
        Array.Copy(vendorClassID, 0, D_options, options_offset, vendorClassID.Length);

        options_offset += vendorClassID.Length;
        byte[] paramRequestList = new byte[13];
        paramRequestList[0] = 55;
        paramRequestList[1] = 11;
        paramRequestList[2] = 1;
        paramRequestList[3] = 15;
        paramRequestList[4] = 3;
        paramRequestList[5] = 6;
        paramRequestList[6] = 44;
        paramRequestList[7] = 46;
        paramRequestList[8] = 47;
        paramRequestList[9] = 31;
        paramRequestList[10] = 33;
        paramRequestList[11] = 249;
        paramRequestList[12] = 43;
        //Array.Copy(paramRequestList, 0, D_options, 31, paramRequestList.Length);
        Array.Copy(paramRequestList, 0, D_options, options_offset, paramRequestList.Length);

        options_offset += paramRequestList.Length;
        byte[] vendorSpecificInfo = new byte[5];
        vendorSpecificInfo[0] = 43;
        vendorSpecificInfo[1] = 2;
        vendorSpecificInfo[2] = 220;
        vendorSpecificInfo[3] = 0;
        vendorSpecificInfo[4] = 255;
        Array.Copy(vendorSpecificInfo, 0, D_options, options_offset, vendorSpecificInfo.Length);

        byte[] dhcpMessage = new byte[300];
        dhcpMessage[0] = D_op;
        dhcpMessage[1] = D_htype;
        dhcpMessage[2] = D_hlen;
        dhcpMessage[3] = D_hops;

        int destinationIndex = 4;
        Array.Copy(D_xid, 0, dhcpMessage, destinationIndex, D_xid.Length);

        destinationIndex = destinationIndex + D_xid.Length;
        Array.Copy(D_secs, 0, dhcpMessage, destinationIndex, D_secs.Length);

        destinationIndex = destinationIndex + D_secs.Length;
        Array.Copy(D_flags, 0, dhcpMessage, destinationIndex, D_flags.Length);

        destinationIndex = destinationIndex + D_flags.Length;
        Array.Copy(D_ciaddr, 0, dhcpMessage, destinationIndex, D_ciaddr.Length);

        destinationIndex = destinationIndex + D_ciaddr.Length;
        Array.Copy(D_yiaddr, 0, dhcpMessage, destinationIndex, D_yiaddr.Length);

        destinationIndex = destinationIndex + D_yiaddr.Length;
        Array.Copy(D_siaddr, 0, dhcpMessage, destinationIndex, D_siaddr.Length);

        destinationIndex = destinationIndex + D_siaddr.Length;
        Array.Copy(D_giaddr, 0, dhcpMessage, destinationIndex, D_giaddr.Length);

        destinationIndex = destinationIndex + D_giaddr.Length;
        Array.Copy(D_chaddr, 0, dhcpMessage, destinationIndex, D_chaddr.Length);

        destinationIndex = destinationIndex + D_chaddr.Length;
        Array.Copy(D_sname, 0, dhcpMessage, destinationIndex, D_sname.Length);

        destinationIndex = destinationIndex + D_sname.Length;
        Array.Copy(D_file, 0, dhcpMessage, destinationIndex, D_file.Length);

        destinationIndex = destinationIndex + D_file.Length;
        Array.Copy(M_Cookie, 0, dhcpMessage, destinationIndex, M_Cookie.Length);

        destinationIndex = destinationIndex + M_Cookie.Length;
        Array.Copy(D_options, 0, dhcpMessage, destinationIndex, D_options.Length);
        #endregion

        udpClient.Send(dhcpMessage, 300, dhcpClientEndpoint);

        UdpClient udpServerResponse = new UdpClient(68);
        IPEndPoint dhcpServerEndPoint = new IPEndPoint(IPAddress.Any, 0);

        //The following line is receiving the response from DHCP server
        //works some time immediately and some time not even after couple 
        //of minutes and program goes to halt state? Am I making some mistake?
        byte[] dataReceived = udpServerResponse.Receive(ref dhcpServerEndPoint);

        Console.WriteLine("Message Received");
    }

请帮帮我吗?

2 个答案:

答案 0 :(得分:1)

我真的不知道问题是什么,但不会更容易使用API​​,

DHCP客户端API http://msdn.microsoft.com/en-us/library/aa363344(v=VS.85).aspx

DHCP服务器标注API http://msdn.microsoft.com/en-us/library/aa363372(v=VS.85).aspx

答案 1 :(得分:0)

这个问题看起来像是一个简单的操作顺序问题:因为在发送UdpClient之前你没有开始接收DHCPINFORM,服务器可能对你来说太快了<{1}}在绑定端口68之前进入(并被丢弃)。

您应该能够使用单个DHCPACK绑定端口68执行整个事务(发送和接收)。