0

I am trying to create a simple DHCP client using Qt4.8.

I Have two host:

  1. Server with ip address inet addr:1.5.1.10 Bcast:1.5.1.255 Mask:255.255.255.0 and isc-dhcp-server that sends the following parameters to clients:

    IPs: 1.5.1.11-100 Bcast:1.5.255.255  Mask:255.255.0.0
    
  2. Client with parameters derived at boot - inet addr:1.5.1.14 Bcast:1.5.255.255 Mask:255.255.0.0

On the client I am trying to ask (in my program) the DHCP server for new options. Server has sent options, but my program can't receive any data from server, except data that is directly sent to client address (1.5.1.14:68).

For the client, I compile the Open DHCP Locate and it works fine. When I run tcpdump -i eth0 udp port 68 -e -n -vvvv -X on client side, it shows a packet from the server. I think that QUdpSocket need some parameters to receive these packets. What would these parameters be?

I have tried creating my socket like this:

udpSocket = new QUdpSocket(this);
//udpSocket->bind(QHostAddress(QString("1.5.1.14")), 68);
qDebug() << "bind" << udpSocket->bind(QHostAddress::Any, 68, QUdpSocket::ShareAddress);
//qDebug() << "bind" << udpSocket->bind(QHostAddress::Broadcast, 68);

//qDebug() << "joinMulticastGroup" << udpSocket->joinMulticastGroup(QHostAddress(QString("1.5.255.255")));
//udpSocket->setMulticastInterface(QNetworkInterface::interfaceFromName(QString("eth0")));


//  int optval = 1;
//  qDebug() << "SO_BROADCAST" << setsockopt(udpSocket->socketDescriptor(), SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
//  const char dev[] = "eth0";
//  qDebug() << "SO_BINDTODEVICE" << setsockopt(udpSocket->socketDescriptor(), SOL_SOCKET, SO_BINDTODEVICE, dev, sizeof(dev) );

In various combinations, but nothing is received.

Log from server side, cmds is:

#tcpdump -i eth1 udp port 67 or port 68 -e -n -X

and

#dhcpdump -i eth1

.

    10:30:15.775100 84:eb:18:e8:59:b2 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 285: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 271)
        1.5.1.14.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 31:32:33:34:35:36, length 243, Flags [none] (0x0000)
              Client-Ethernet-Address 31:32:33:34:35:36
              Vendor-rfc1048 Extensions
                Magic Cookie 0x63825363
                DHCP-Message Option 53, length 1: Discover
            0x0000:  4500 010f 0000 4000 4011 37cc 0105 010e  E.....@.@.7.....
            0x0010:  ffff ffff 0044 0043 00fb 6dda 0101 0600  .....D.C..m.....
            0x0020:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0030:  0000 0000 0000 0000 3132 3334 3536 0000  ........123456..
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0070:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0080:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0090:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00a0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00b0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00c0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00d0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00e0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00f0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0100:  0000 0000 0000 0000 6382 5363 3501 01    ........c.Sc5..
    10:30:16.776570 10:fe:ed:05:f9:53 > 31:32:33:34:35:36, ethertype IPv4 (0x0800), length 342: (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
        1.5.1.10.67 > 1.5.1.33.68: [udp sum ok] BOOTP/DHCP, Reply, length 300, Flags [none] (0x0000)
              Your-IP 1.5.1.33
              Server-IP 1.5.1.10
              Client-Ethernet-Address 31:32:33:34:35:36
              Vendor-rfc1048 Extensions
                Magic Cookie 0x63825363
                DHCP-Message Option 53, length 1: Offer
                Server-ID Option 54, length 4: 1.5.1.10
                Lease-Time Option 51, length 4: 864000
                Subnet-Mask Option 1, length 4: 255.255.0.0
                Default-Gateway Option 3, length 4: 1.5.1.10
                BR Option 28, length 4: 1.5.255.255
                NTP Option 42, length 4: 1.5.1.10
                END Option 255, length 0
                PAD Option 0, length 0, occurs 20
            0x0000:  4510 0148 0000 0000 8011 3561 0105 010a  E..H......5a....
            0x0010:  0105 0121 0043 0044 0134 0c29 0201 0600  ...!.C.D.4.)....
            0x0020:  0000 0000 0000 0000 0000 0000 0105 0121  ...............!
            0x0030:  0105 010a 0000 0000 3132 3334 3536 0000  ........123456..
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0070:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0080:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0090:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00a0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00b0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00c0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00d0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00e0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00f0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0100:  0000 0000 0000 0000 6382 5363 3501 0236  ........c.Sc5..6
            0x0110:  0401 0501 0a33 0400 0d2f 0001 04ff ff00  .....3.../......
            0x0120:  0003 0401 0501 0a1c 0401 05ff ff2a 0401  .............*..
            0x0130:  0501 0aff 0000 0000 0000 0000 0000 0000  ................
            0x0140:  0000 0000 0000 0000


    ---------------------------------------------------------------------------


      TIME: 2016-09-19 10:30:15.853
        IP: 1.5.1.14 (84:eb:18:e8:59:b2) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
        OP: 1 (BOOTPREQUEST)
     HTYPE: 1 (Ethernet)
      HLEN: 6
      HOPS: 0
       XID: 00000000
      SECS: 0
     FLAGS: 0
    CIADDR: 0.0.0.0
    YIADDR: 0.0.0.0
    SIADDR: 0.0.0.0
    GIADDR: 0.0.0.0
    CHADDR: 31:32:33:34:35:36:00:00:00:00:00:00:00:00:00:00
     SNAME: .
     FNAME: .
    OPTION:  53 (  1) DHCP message type         1 (DHCPDISCOVER)
    OPTION:  54 (  4) Server identifier         1.5.1.10
    OPTION:  51 (  4) IP address leasetime      864000 (1w3d)
    ---------------------------------------------------------------------------

      TIME: 2016-09-19 10:30:16.855
        IP: 1.5.1.10 (10:fe:ed:5:f9:53) > 1.5.1.33 (31:32:33:34:35:36)
        OP: 2 (BOOTPREPLY)
     HTYPE: 1 (Ethernet)
      HLEN: 6
      HOPS: 0
       XID: 00000000
      SECS: 0
     FLAGS: 0
    CIADDR: 0.0.0.0
    YIADDR: 1.5.1.33
    SIADDR: 1.5.1.10
    GIADDR: 0.0.0.0
    CHADDR: 31:32:33:34:35:36:00:00:00:00:00:00:00:00:00:00
     SNAME: .
     FNAME: .
    OPTION:  53 (  1) DHCP message type         2 (DHCPOFFER)
    OPTION:  54 (  4) Server identifier         1.5.1.10
    OPTION:  51 (  4) IP address leasetime      864000 (1w3d)
    OPTION:   1 (  4) Subnet mask               255.255.0.0
    OPTION:   3 (  4) Routers                   1.5.1.10
    OPTION:  28 (  4) Broadcast address         1.5.255.255
    OPTION:  42 (  4) NTP servers               1.5.1.10
Andrey Reeshkov
  • 331
  • 5
  • 14

2 Answers2

1

You first bind the socket to the interface you want to broadcast through, on port 68. Set the broadcast option. Send the DHCP discovery packet to the broadcast address (port 67) using writeDatagram. And then you simply wait for replies to the socket, which you read with readDatagram.

That should be all that is needed.

You of course need to be able to handle timeouts if you don't get a reply in a reasonable time. Remember that UDP is unreliable.

You program also need to run with elevated privileges to be able to bind to a privileged port number.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • My program has bind socket, has broadcast option, was send dhcp discovery to broadcast port 67 using writeDatagram and not receive reply from server! To timeout used - wait forever, runing from root. – Andrey Reeshkov Sep 19 '16 at 12:26
  • @AndreyReeshkov You did try to resend the discovery request on timeout? I've almost never seen a system where there isn't at least a couple of retries. Also, maybe try to send the broadcast to `255.255.255.255`? And you have a correct [discovery packet](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#DHCP_discovery) you send? – Some programmer dude Sep 19 '16 at 12:41
  • Yes, sended packet is correct - tcpdump and dhcpdump show request from client and answer from server: see log above – Andrey Reeshkov Sep 19 '16 at 14:57
0

The solution is set "broadcast" flag (discussed in Sections 3.1.1 and 4.1.2 of RFC 1542)

Andrey Reeshkov
  • 331
  • 5
  • 14