CyberShadow / dhcptest

Cross-platform DHCP test client
https://blog.cy.md/2013/01/10/dhcp-test-client
363 stars 57 forks source link

I can't get it to work in Linux (Manjaro ... almost Arch) #21

Closed D33M0N closed 4 years ago

D33M0N commented 4 years ago

if I run it without sudo I get error:

Error while attempting to bind socket:
Unable to set socket option: Operation not permitted
Replies will not be visible. Use a packet capture tool to see replies,
or try re-running the program with more permissions.

which is obvious, but when I run it as sudo I still don't get any reply ever.

$ sudo dhcptest --iface enp0s31f6 [sudo] password for deemon: dhcptest v0.7 - Created by Vladimir Panteleev https://github.com/CyberShadow/dhcptest Run with --help for a list of command-line options.

Listening for DHCP replies on port 68. Type "d" to broadcast a DHCP discover packet, or "help" for details. d Sending packet: op=BOOTREQUEST chaddr=36:60:A7:14:11:2C hops=0 xid=A878818A secs=0 flags=8000 ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file= 1 options: 53 (DHCP Message Type): discover d Sending packet: op=BOOTREQUEST chaddr=36:60:A7:14:11:2C hops=0 xid=4B02BE58 secs=0 flags=8000 ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file= 1 options: 53 (DHCP Message Type): discover d Sending packet: op=BOOTREQUEST chaddr=36:60:A7:14:11:2C hops=0 xid=78E2B844 secs=0 flags=8000 ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file= 1 options: 53 (DHCP Message Type): discover

same thing with --iface enp0s31f6 --raw

Does work fine in windows computer.

CyberShadow commented 4 years ago

Most likely that's because your DHCP server is not replying.

You can confirm this with tcpdump or Wireshark.

CyberShadow commented 4 years ago

I think it's possible that if you have another program listening for DHCP replies running, such as dhclient or some network management software such as NetworkManager or systemd-networkd, you won't see a reply in dhcptest either.

D33M0N commented 4 years ago

can't be it, because DHCP works. I do get address from DHCP server. Need this tool to discover possible rogue DHCP servers (duplicate replies from different sources)

CyberShadow commented 4 years ago

can't be it, because DHCP works. I do get address from DHCP server.

The DHCP server may decide to reply to your PC's actual DHCP client, but not dhcptest (e.g. due to the random MAC address in the request).

D33M0N commented 4 years ago

it should make no difference, because it works this way in windows. And even when I use the actual MAC I get no reply:

$ sudo dhcptest --iface enp0s31f6 --mac 98:FA:9B:1A:41:33
dhcptest v0.7 - Created by Vladimir Panteleev
https://github.com/CyberShadow/dhcptest
Run with --help for a list of command-line options.

Listening for DHCP replies on port 68.
Type "d" to broadcast a DHCP discover packet, or "help" for details.
d
Sending packet:
  op=BOOTREQUEST chaddr=98:FA:9B:1A:41:33 hops=0 xid=FC5E558F secs=0 flags=8000
  ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file=
  1 options:
     53 (DHCP Message Type): discover
d
Sending packet:
  op=BOOTREQUEST chaddr=98:FA:9B:1A:41:33 hops=0 xid=45B52D21 secs=0 flags=8000
  ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file=
  1 options:
     53 (DHCP Message Type): discover
q

not sure I can just kill network manager or anything similar and the network keeps functioning?

D33M0N commented 4 years ago

dhcpd.service is not running by default when it doesn't need to get new address:

$ systemctl status dhcpcd.service 
● dhcpcd.service - dhcpcd on all interfaces
     Loaded: loaded (/usr/lib/systemd/system/dhcpcd.service; disabled; vendor preset: disabled)
     Active: inactive (dead)
CyberShadow commented 4 years ago

You can confirm this with tcpdump or Wireshark.

D33M0N commented 4 years ago

wireshark confirms I get reply. dhcptest does not show anything about it though.

Frame 2: 343 bytes on wire (2744 bits), 343 bytes captured (2744 bits) on interface enp0s31f6, id 0
    Interface id: 0 (enp0s31f6)
        Interface name: enp0s31f6
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 18, 2020 15:05:44.918571443 EEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1592481944.918571443 seconds
    [Time delta from previous captured frame: 0.000742063 seconds]
    [Time delta from previous displayed frame: 0.000742063 seconds]
    [Time since reference or first frame: 0.000742063 seconds]
    Frame Number: 2
    Frame Length: 343 bytes (2744 bits)
    Capture Length: 343 bytes (2744 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:udp:dhcp]
    [Coloring Rule Name: UDP]
    [Coloring Rule String: udp]
Ethernet II, Src: Cisco_80:4e:d9 (44:d3:ca:80:4e:d9), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Destination: Broadcast (ff:ff:ff:ff:ff:ff)
        Address: Broadcast (ff:ff:ff:ff:ff:ff)
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast)
    Source: Cisco_80:4e:d9 (44:d3:ca:80:4e:d9)
        Address: Cisco_80:4e:d9 (44:d3:ca:80:4e:d9)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.100.1, Dst: 255.255.255.255
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 329
    Identification: 0x00dc (220)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
    Fragment offset: 0
    Time to live: 255
    Protocol: UDP (17)
    Header checksum: 0x951e [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.100.1
    Destination: 255.255.255.255
User Datagram Protocol, Src Port: 67, Dst Port: 68
    Source Port: 67
    Destination Port: 68
    Length: 309
    Checksum: 0x5f74 [unverified]
    [Checksum Status: Unverified]
    [Stream index: 1]
    [Timestamps]
        [Time since first frame: 0.000000000 seconds]
        [Time since previous frame: 0.000000000 seconds]
Dynamic Host Configuration Protocol (Offer)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x80361a6c
    Seconds elapsed: 0
    Bootp flags: 0x8000, Broadcast flag (Broadcast)
        1... .... .... .... = Broadcast flag: Broadcast
        .000 0000 0000 0000 = Reserved flags: 0x0000
    Client IP address: 0.0.0.0
    Your (client) IP address: 192.168.100.23
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: LCFCHeFe_1a:41:33 (98:fa:9b:1a:41:33)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (Offer)
        Length: 1
        DHCP: Offer (2)
    Option: (54) DHCP Server Identifier (192.168.100.1)
        Length: 4
        DHCP Server Identifier: 192.168.100.1
    Option: (51) IP Address Lease Time
        Length: 4
        IP Address Lease Time: (86400s) 1 day
    Option: (58) Renewal Time Value
        Length: 4
        Renewal Time Value: (43200s) 12 hours
    Option: (59) Rebinding Time Value
        Length: 4
        Rebinding Time Value: (75600s) 21 hours
    Option: (1) Subnet Mask (255.255.255.0)
        Length: 4
        Subnet Mask: 255.255.255.0
    Option: (3) Router
        Length: 4
        Router: 192.168.100.1
    Option: (6) Domain Name Server
        Length: 8
        Domain Name Server: 1.1.1.1
        Domain Name Server: 1.0.0.1
    Option: (15) Domain Name
        Length: 9
        Domain Name: xxx
    Option: (255) End
        Option End: 255
CyberShadow commented 4 years ago

Then, you need to find the program listening on the DHCP client port (68).

D33M0N commented 4 years ago

Nothing seems to be:

$ sudo netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      858/pihole-FTL      
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1486/cupsd          
tcp        0      0 0.0.0.0:34375           0.0.0.0:*               LISTEN      1655/pcloud         
tcp        0      0 127.0.0.1:4711          0.0.0.0:*               LISTEN      858/pihole-FTL      
tcp6       0      0 :::53                   :::*                    LISTEN      858/pihole-FTL      
tcp6       0      0 ::1:631                 :::*                    LISTEN      1486/cupsd          
tcp6       0      0 ::1:4711                :::*                    LISTEN      858/pihole-FTL      
udp        0      0 0.0.0.0:53              0.0.0.0:*                           858/pihole-FTL      
udp        0      0 0.0.0.0:69              0.0.0.0:*                           851/in.tftpd        
udp        0      0 0.0.0.0:37978           0.0.0.0:*                           737/avahi-daemon: r 
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           737/avahi-daemon: r 
udp        0      0 0.0.0.0:42420           0.0.0.0:*                           1655/pcloud         
udp6       0      0 :::53                   :::*                                858/pihole-FTL      
udp6       0      0 :::69                   :::*                                851/in.tftpd        
udp6       0      0 :::49675                :::*                                737/avahi-daemon: r 
udp6       0      0 :::5353                 :::*                                737/avahi-daemon: r 
raw6       0      0 :::58                   :::*                    7           833/NetworkManager  
raw6       0      0 :::58                   :::*                    7           833/NetworkManager  
D33M0N commented 4 years ago

also while wireshark is able to capture the packet, then ... shouldn't dhcptest also? using same method or something?

CyberShadow commented 4 years ago

Packet capturing would make dhcptest be less like a DHCP client and more like a packet sniffer. It would also make it unportable. As such, it is outside of the scope of this project.

D33M0N commented 4 years ago

Wait what? Why did you close it? The problem is still here and dhcptest doesn't receive and show the the dhcp reply packet. Sorry for using "packet capture" to name the process, but name it whatever you want and is proper for you, but it doesn't do it.

D33M0N commented 4 years ago

Found a program from AUR to help with capture (yeah, this one actually uses capture with libpcap), yet it doesn't do the send request part. maybe take a look @ this capture thing. dhcpdump ( http://www.mavetju.org/unix/general.php ):

$ sudo dhcpdump -i enp24s0
  TIME: 2020-06-19 04:33:38.155
    IP: 192.168.1.11 (70:85:c2:b3:f2:6c) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
    OP: 1 (BOOTPREQUEST)
 HTYPE: 1 (Ethernet)
  HLEN: 6
  HOPS: 0
   XID: c0c86155
  SECS: 0
 FLAGS: 7f80
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: f6:ee:29:81:a6:a4:00:00:00:00:00:00:00:00:00:00
 SNAME: .
 FNAME: .
OPTION:  53 (  1) DHCP message type         1 (DHCPDISCOVER)
---------------------------------------------------------------------------

  TIME: 2020-06-19 04:33:38.775
    IP: 192.168.1.1 (74:4d:28:8c:70:6b) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
    OP: 2 (BOOTPREPLY)
 HTYPE: 1 (Ethernet)
  HLEN: 6
  HOPS: 0
   XID: c0c86155
  SECS: 0
 FLAGS: 7f80
CIADDR: 0.0.0.0
YIADDR: 192.168.1.108
SIADDR: 192.168.1.1
GIADDR: 0.0.0.0
CHADDR: f6:ee:29:81:a6:a4: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         192.168.1.1
OPTION:  51 (  4) IP address leasetime      600 (10m)
---------------------------------------------------------------------------

  TIME: 2020-06-19 04:36:09.349
    IP: 192.168.1.251 (f0:fe:6b:fe:de:8) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
    OP: 1 (BOOTPREQUEST)
 HTYPE: 1 (Ethernet)
  HLEN: 6
  HOPS: 0
   XID: 03000000
  SECS: 0
 FLAGS: 0
CIADDR: 192.168.1.251
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: f0:fe:6b:fe:de:08:00:00:00:00:00:00:00:00:00:00
 SNAME: .
 FNAME: .
OPTION:  53 (  1) DHCP message type         3 (DHCPREQUEST)
OPTION:  57 (  2) Maximum DHCP message size 1500
OPTION:  54 (  4) Server identifier         192.168.1.1
OPTION:  50 (  4) Request IP address        192.168.1.251
OPTION:  12 (  9) Host name                 HF-LPT220
---------------------------------------------------------------------------

First packet is then the one sent by the dhcptest below. The last packet is even some other device DHCP renewal packet!!! AWESOME! :)

meanwhile in the dhcptest land:

$ sudo dhcptest --iface enp24s0
[sudo] password for deemon: 
dhcptest v0.7 - Created by Vladimir Panteleev
https://github.com/CyberShadow/dhcptest
Run with --help for a list of command-line options.

Listening for DHCP replies on port 68.
Type "d" to broadcast a DHCP discover packet, or "help" for details.
d
Sending packet:
  op=BOOTREQUEST chaddr=F6:EE:29:81:A6:A4 hops=0 xid=C0C86155 secs=0 flags=8000
  ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file=
  1 options:
     53 (DHCP Message Type): discover
q

In combination of those 2 I finally achieved what I wanted, even though the dhcptest in this case is used for sending out the requests on demand only.

CyberShadow commented 4 years ago

Wait what? Why did you close it?

I can't see a problem in dhcptest. It is acting as it should, by waiting for UDP packets on the specified port. You could confirm this by using a generic UDP client, such as socat.

I don't know why it doesn't see the replies on your machine. I listed some of the common causes known to me, but there may be other reasons.

This page is a mechanism for reporting issues in the software itself. It is not appropriate for requesting technical support for using the software, and definitely not the proper place to request technical support with administrating or configuring your system. I suggest you use your distribution's support channels for assistance on why UDP clients running on your machine do not receive DHCP packets when they should.

CyberShadow commented 4 years ago

it's listening on port 60053?

That looks like a randomly assigned port. (You could confirm by re-running dhcptest and checking if the port changes.) Could the bind call have failed in a silent manner somehow?

D33M0N commented 4 years ago

it's listening on port 60053?

That looks like a randomly assigned port. (You could confirm by re-running dhcptest and checking if the port changes.) Could the bind call have failed in a silent manner somehow?

Nvm, this port 60053 -- was my error. Didn't do it with sudo. When I ran it as sudo, it did listen correctly to UDP port 68. But it didn't fix the problem. The program still did not receive or recognize or parse the packet correctly. Is there any way to debug if the dhcptest actually receives anything from the port (but due to being "wrong" doesn't do anything (eg. print out anything)?) Like can I somehow make dhcptest output raw output what it receives from network -- everything, without trying to parse it first?

CyberShadow commented 4 years ago

Yes, you can try socat, as I suggested above.

sudo socat UDP4-RECVFROM:68 -

Then run dhcptest in another window and type d.

D33M0N commented 4 years ago

Can't do that. If I run first socat, then running sudo dhcptest gives error: Error while attempting to bind socket: Unable to bind socket: Address already in use Replies will not be visible. Use a packet capture tool to see replies, or try re-running the program with more permissions.

$ sudo netstat -tulnp | grep :68
udp        0      0 0.0.0.0:68              0.0.0.0:*                           230248/socat        

and when I run first sudo dhcptest, then sudo socat gives error: $ sudo socat UDP4-RECVFROM:68 - 2020/06/19 18:00:04 socat[230384] E bind(5, {AF=2 0.0.0.0:68}, 16): Address already in use

CyberShadow commented 4 years ago

Yes, that's expected. Use dhcptest only for sending, socat will do the receiving.

D33M0N commented 4 years ago

Nope. Nothing comes through... so wtf could be blocking it... but now I have tool to test with. Thanks, will let you know when I manage to figure something out :/

D33M0N commented 4 years ago

Jebus ... SORRY for wasting your time. Finally figured it out. It was the effing firewalld which for whatever reason didn't allow UDP 68 through even when the DHCP service was allowed (apparently was only allowing server UDP port 67 through) ... and somehow this never prevented the computer network manager ever getting ip address from DHCP server ever before... like network manager somehow ignored firewall? Very weird. SORRY AGAIN :blush: