pombreda / staticdhcpd

Automatically exported from code.google.com/p/staticdhcpd
GNU General Public License v3.0
0 stars 0 forks source link

Dell iDRAC ignores dhcp offer #15

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Configure iDRAC as DHCP client
2. staticDHCP offer ip address but iDRAC ignores it
3.

What is the expected output? What do you see instead?
ISC-dhcp server and dhcpserver in Force10 switch works - dhcpdump shows:

  TIME: 2013-06-18 15:01:53.016
    IP: 10.20.0.23 (0:1:e8:d7:85:8e) > 10.20.0.253 (e0:db:55:20:8c:72)
    OP: 2 (BOOTPREPLY)
 HTYPE: 1 (Ethernet)
  HLEN: 6
  HOPS: 1
   XID: 4b872265
  SECS: 0
 FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 10.20.0.253
SIADDR: 10.20.0.23
GIADDR: 10.20.0.23
CHADDR: e0:db:55:20:8c:72: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         10.20.0.23
OPTION:  51 (  4) IP address leasetime      775923134 (1282w6d14h12m14s)
OPTION:   1 (  4) Subnet mask               255.255.255.0

The staticDHCP DHCPOFFER looks like this:

  TIME: 2013-06-18 15:01:29.311
    IP: 10.20.0.25 (90:b1:1c:49:dd:bc) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
    OP: 2 (BOOTPREPLY)
 HTYPE: 1 (Ethernet)
  HLEN: 6
  HOPS: 0
   XID: 83e0d837
  SECS: 0
 FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 10.20.0.43
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: e0:db:55:20:8c:72:00:00:00:00:00:00:00:00:00:00
 SNAME: .
 FNAME: .
OPTION:   1 (  4) Subnet mask               255.255.255.0
OPTION:  51 (  4) IP address leasetime      31536000 (52w24h)
OPTION:  53 (  1) DHCP message type         2 (DHCPOFFER)
OPTION:  54 (  4) Server identifier         10.20.0.25

What version of the product are you using? On what operating system?
Debian wheezy, tried with staticDHCPD-1.6.4 and 2.0.0-beta-2

Please provide any additional information below.
The only difference I see is that staticDHCPd responds to ff:ff:ff:ff:ff:ff 
instead of the client mac address ?

Original issue reported on code.google.com by kegef...@gmail.com on 18 Jun 2013 at 2:30

GoogleCodeExporter commented 9 years ago
I'd need to see the DHCP request that is being received.

From the looks of it, in the first case, the iDRAC server already has an IP 
address (possibly because this is a RENEW), which means that it is correct to 
use a unicast response. In the second, it could be a DISCOVER, in which case a 
broadcast response is the correct action in the absence of a relay, because the 
client cannot receive a unicast response at the time.

At present, I believe that dhcpdump is performing an ARP from your machine's 
interface after receiving the OFFER packet and no MAC can actually be 
associated with the global broadcast address. From CHADDR, it looks like the 
correct MAC is being set in the response packet, but I'll play with dhcpdump 
here while I try to finally finish work on 2.0.0 tonight and let you know if I 
prove my assumptions incorrect.

Original comment by red.hamsterx on 19 Jun 2013 at 11:09

GoogleCodeExporter commented 9 years ago
Something like this? :

# tcpdump -i eth1 -vvv -s 0 port bootps
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 65535 
bytes
12:04:26.667709 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP 
(17), length 317)
    0.0.0.0.bootpc > 255.255.255.255.bootps: [udp sum ok] BOOTP/DHCP, Request from e0:db:55:20:8c:72 (oui Unknown), length 289, xid 0x315a7434, Flags [none] (0x0000)
      Client-Ethernet-Address e0:db:55:20:8c:72 (oui Unknown)
      Vendor-rfc1048 Extensions
        Magic Cookie 0x63825363
        DHCP-Message Option 53, length 1: Discover
        Client-ID Option 61, length 7: ether e0:db:55:20:8c:72
        MSZ Option 57, length 2: 576
        Parameter-Request Option 55, length 8: 
          Subnet-Mask, Default-Gateway, Domain-Name-Server, Hostname
          Domain-Name, BR, NTP, Vendor-Option
        Vendor-Class Option 60, length 5: "iDRAC"
        Hostname Option 12, length 13: "idrac-JWCJWX1"
        END Option 255, length 0

Original comment by kegef...@gmail.com on 20 Jun 2013 at 10:07

GoogleCodeExporter commented 9 years ago
I'm seeing the same symptoms on the IPMI interface of a SuperMicro SuperServer 
using an X9DRD-iF motherboard. 

# tcpdump -i eth1 -vvv -s 0 port bootps

10:44:50.964295 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP 
(17), length 576) 0.0.0.0.bootpc > 255.255.255.255.bootps: [udp sum ok] 
BOOTP/DHCP, Request from 00:25:90:85:00:e1 (oui Unknown), length 548, xid 
0xe3c3426, Flags [none] (0x0000)
          Client-Ethernet-Address 00:25:90:85:00:e1 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Discover
            Client-ID Option 61, length 7: ether 00:25:90:85:00:e1
            Vendor-Class Option 60, length 12: "udhcp 1.12.0"
            MSZ Option 57, length 2: 576
            Parameter-Request Option 55, length 7:
              Subnet-Mask, Default-Gateway, Domain-Name-Server, Hostname
              Domain-Name, BR, NTP
            END Option 255, length 0
            PAD Option 0, length 0, occurs 268

Original comment by bhms.rob...@gmail.com on 3 Sep 2013 at 5:51

GoogleCodeExporter commented 9 years ago
First, sorry for missing your follow-up, kegefelt. It was in my inbox, but I 
somehow completely skipped past it back in June. :(

Now that we have data, though, I don't see a pattern... There's nothing 
specified with option 50 (and, even if there were, a unicast response isn't 
part of the spec during an initial DISCOVER sequence and a static lease should 
ignore a requested value), so I'm not sure where the IP in the first response 
are coming from.

The behaviour described as the problem seems to be correct, even though it's 
not what either of you need. I don't see any documentation about dhcpdump's 
formatting or parsing rules that helps to clarify matters, either.

If you can provide me with a tcpdump pcap, just so we (you, me, all of us) can 
dissect it to try to figure out what's inconsistent, that would help.

I want to push a fix for this into the codebase as soon as we know the cause, 
but I'm at a loss for even figuring out where to start right now, and don't 
have the means to reproduce your environments.

Original comment by red.hamsterx on 3 Sep 2013 at 6:32

GoogleCodeExporter commented 9 years ago
Attached is a WireShark capture as well as the text export from the SuperMicro. 

Original comment by bhms.rob...@gmail.com on 4 Sep 2013 at 2:27

Attachments:

GoogleCodeExporter commented 9 years ago
I chatted with one of our firmware engineers today today and he had a few good 
suggestions for me to try: 

1. Does it fail with the ISC dhcpd server? 

2. If no, get a WireShark capture and work backwards. 

3. If yes, keep going. He told me that he's seen several client implementations 
that simply ignore the offer because they don't have something defined that 
they want to see like a default gateway or a nameserver. 

I'll work on setting up the ISC dhcpd in the morning and post some captures as 
soon as I can. 

Ken

Original comment by bhms.rob...@gmail.com on 5 Sep 2013 at 11:55

GoogleCodeExporter commented 9 years ago
Thanks, Ken.

I should have time to look at this tomorrow. Unfortunately, I've been getting 
home late this week, due to work.

Original comment by red.hamsterx on 5 Sep 2013 at 11:58

GoogleCodeExporter commented 9 years ago
Hi Neil, 

Attached is two tcpdump capture files.  As you can see the DHCP sequence works 
correctly with the ISC dhcpd server but not with staticDHCPd.  The most 
interesting thing I've discovered is that the staticDHCPd OFFER never makes it 
onto the wire even though statusDHCPd reports that it sent it.  This explains a 
lot about why it isn't working.  Just to double check I also listened on eth0 
to make sure the OFFER wasn't accidentally being sent to the wrong interface. 
There's two additional network ports on the server (dhcp client) so I'm going 
to listen to those as well and see if I can find anything different between the 
ipmi DISCOVER and the lan1/lan2 DISCOVER. 

Stay tuned, 
Ken

Original comment by bhms.rob...@gmail.com on 6 Sep 2013 at 7:55

Attachments:

GoogleCodeExporter commented 9 years ago
Huh. Well, I can certainly test multiple interfaces very extensively this 
weekend, so send me all the suspicions and details that you can.

Thanks again for all the input; it's super-helpful.

Original comment by red.hamsterx on 6 Sep 2013 at 8:21

GoogleCodeExporter commented 9 years ago
Attached is a capture from LAN1 that works but I also see that I have a capture 
problem.  Even on a successful sequence I'm not seeing the OFFER nor ACK, only 
the DISCOVER and REQUEST packets so I suspect my previous email about the OFFER 
not getting on the wire is probably wrong.  I'm off to figure out why I can't 
capture correctly and to continue to bang on this. 

Thanks,
Ken

Original comment by bhms.rob...@gmail.com on 6 Sep 2013 at 10:15

GoogleCodeExporter commented 9 years ago
Oops. The attachment. ;(

Original comment by bhms.rob...@gmail.com on 6 Sep 2013 at 10:16

Attachments:

GoogleCodeExporter commented 9 years ago
Gotcha! (I think?)

Now that I figured out why I was only seeing half the conversation I now see an 
error in the OFFER packet. 

bad cksum 0 (->de7c)!)

[bad udp cksum 35a8!]

This could certainly cause the IPMI client to ignore the OFFER. 

What do you think?

Ken

Original comment by bhms.rob...@gmail.com on 7 Sep 2013 at 7:31

Attachments:

GoogleCodeExporter commented 9 years ago
No, that won't cause it.

If you're looking at the PCAP, it's capturing things from the IP stack in the 
kernel, but outgoing checksums are almost always computed on the cards 
themselves. So it's normal to have an invalid checksum before things actually 
leave the NIC.

Original comment by red.hamsterx on 7 Sep 2013 at 9:07

GoogleCodeExporter commented 9 years ago
Bummer.  I was hoping I had found something good. It sounds like I need to be 
sniffing with WireShark on a mirrored port to really get valid data? 

Original comment by bhms.rob...@gmail.com on 8 Sep 2013 at 5:18

GoogleCodeExporter commented 9 years ago
No, we can trust the data you're seeing from the source (if you had 
checksumming errors, the host would seem totally unreliable).

I've got tomorrow morning blocked off for this, so I'll try to find something. 

Original comment by red.hamsterx on 8 Sep 2013 at 5:26

GoogleCodeExporter commented 9 years ago
The only really significant difference that I can see is the order of options.

Right now, I'm just sorting them numerically (which is spec-compliant, but 
which may not be friendly to fast hardware processing), so I'll update the code 
to allow for fixed ordering of specific options before sorting occurs. 
Specifically, 53 will be placed first, followed by 51, and the ordering may 
evolve over time.

If you want to eliminate the other fields, pasted below, to rule out the 
possibility that the client doesn't like being told what its hostname is or 
something, just set the corresponding definitions in your database to null or 
omit them:
            Domain-Name-Server Option 6, length 4: 192.168.11.1
            Hostname Option 12, length 10: "uut01-ipmi"
            Domain-Name Option 15, length 4: "site"
            BR Option 28, length 4: 192.168.11.255
            NTP Option 42, length 4: 192.168.11.1

Please update your code and let me know if this fixes the problem. If you can't 
update from SVN, the changes will appear at 
http://code.google.com/p/staticdhcpd/source/detail?r=570 as soon as I've 
committed them, which should be in the next few minutes, once I've tested to 
make sure nothing's broken in my lab environment.

Original comment by red.hamsterx on 8 Sep 2013 at 4:58

GoogleCodeExporter commented 9 years ago
All right, the changes have been tested and committed.

Attached is what an OFFER packet now looks like between my dev system and a VM.

Original comment by red.hamsterx on 8 Sep 2013 at 5:31

Attachments:

GoogleCodeExporter commented 9 years ago
r271 now also adds a pad-option to the end of the packet if the sender provided 
one.

I don't know if this is relevant or why it's done, but that should make the 
packet-formats between staticDHCPd's OFFER and the ISC's effectively identical. 
(The UDP checksum should fail if the packet gets truncated, and if a network is 
truncating packets and one endpoint isn't performing any validation (whether 
checksumming, validating length, or handling frame boundaries), padding won't 
help very much; one possibility is that certain implementations were just 
glitchy and ate one more character than needed, though)

Original comment by red.hamsterx on 8 Sep 2013 at 6:54

GoogleCodeExporter commented 9 years ago
Er, that should have said r571.

I'll stop spamming you via e-mail now. (I'm going to add an off-by-default 
word_align public attribute to the Packet class that will word-align everything 
in case that ever becomes an issue in the future, but that has nothing to do 
with your needs)

Original comment by red.hamsterx on 8 Sep 2013 at 6:57

GoogleCodeExporter commented 9 years ago
Thanks Neil for all your work on this.  I just drove into work to test this out 
but I get the following error when I try to checkout the code: 

Description : Failed to add file 
'/Users/ken.mitchell/Projects/VISTA/Systems/dev/network/test/trunk/staticDHCPd/s
taticDHCPd': a non-file object of the same name already exists
 Suggestion : The operation could not be completed.

Technical Information
=====================

      Error : V4Error
  Exception : ZSVNException

Causal Information
==================

Description : Failed to add file 
'/Users/ken.mitchell/Projects/VISTA/Systems/dev/network/test/trunk/staticDHCPd/s
taticDHCPd': a non-file object of the same name already exists
     Status : 155000
       File : subversion/libsvn_wc/update_editor.c, 3497

I just the same thing with Xcode SVN and Cornerstone. 

Any ideas? 

Thanks,
Ken

Original comment by bhms.rob...@gmail.com on 8 Sep 2013 at 7:03

GoogleCodeExporter commented 9 years ago
Yeah, it's a case-sensitive filesystem problem, which was introduced without 
thinking, then corrected later (but not in trunk): there's a file called 
staticDHCPd, which is the main script, and a directory called staticdhcpd, 
which contains the logic. This is now staticdhcpdlib to avoid the collision, 
but I can't update trunk right now because there's nothing "stable" to replace 
it (2.0.0, while definitely what will be released, represents a deviation, not 
an iterative evolution, so just swapping it in for trunk without warning may 
break build systems, if anyone's using them).

I'd recommend checking out just the branch directory for now: svn co 
https://staticdhcpd.googlecode.com/svn/branches/2.0.0/

When it merges back into trunk, svn switch will let you repoint it, but you 
could also do a full checkout or grab tarballs from that point. I don't know 
how to build OS X-friendly packages, but if they can be scripted as part of my 
release process, I'll look into it once the Debian ones have been accepted.

Original comment by red.hamsterx on 8 Sep 2013 at 7:20

GoogleCodeExporter commented 9 years ago
OK, I was able to get the branch but unfortunately, no joy.  I still don't see 
a REQUEST coming back from the client and I get DISCOVER every 3 seconds. 

Attached is the latest tcpdump. 

Ken

Original comment by bhms.rob...@gmail.com on 8 Sep 2013 at 8:56

GoogleCodeExporter commented 9 years ago
Again, this time with capture file.  How can we get rid of that stupid word 
verification that keeps deleting the attachment if you don't type it correctly 
the first time? 

Original comment by bhms.rob...@gmail.com on 8 Sep 2013 at 8:57

Attachments:

GoogleCodeExporter commented 9 years ago
I'm not sure. The interface provides a browse-dialogue for me in Chromium.

udhcp(c) appears to be part of busybox and, with 1.20.2, it's able to get a 
lease just fine from my test server. The problem may be with 1.12.2 not liking 
something, so I'm trying to recreate your config, but would like to ask you to 
null out the DNS, NTP, BR (broadcast), and other fields not provided by the 
ISC's server. Just set them to null in your database or delete them from the 
INI file, if you're using that method.

Original comment by red.hamsterx on 8 Sep 2013 at 9:15

GoogleCodeExporter commented 9 years ago
If you could provide a binary pcap (just use -v or, if using Wireshark, export 
as bytes), then that could be used to drill further into the differences 
between the ICS's OFFER and that of staticDHCPd.

Original comment by red.hamsterx on 8 Sep 2013 at 9:20

GoogleCodeExporter commented 9 years ago
er... -w, not -v

Original comment by red.hamsterx on 8 Sep 2013 at 9:20

GoogleCodeExporter commented 9 years ago
Okay, I'm getting weird behaviour now.

Not because of any changes to configuration, but because I'm seeing ACKs being 
reported in response to REBINDs (which udhcpc is logging as RENEWs), but 
nothing is showing up on the line. A REBIND needs a source address for 
unicasting, but it looks like udhcpc is incorrectly specifying its source 
address as 0.0.0.0 at the IP layer, even though its knows its IP (independently 
of the requested value) in the DHCP body.

I don't see how this directly affects you, but it may be related in some way.

Original comment by red.hamsterx on 8 Sep 2013 at 9:42

GoogleCodeExporter commented 9 years ago
To make this weirder, it looks like udpchc doesn't reliably bind address to 
interfaces (it accepts a lease for eth0, but doesn't set it), and it gets a 
lease of 192.168.56.151 for eth1, but binds .150.

I'm going to experiment with this some more, but I want to finish writing the 
new database caching stuff to get that out of the way. Let me know if you think 
or or see anything, please.

Original comment by red.hamsterx on 8 Sep 2013 at 9:56

GoogleCodeExporter commented 9 years ago
Attached is the byte capture file with the extra fields NULLed out. 

Thanks,
Ken

Original comment by bhms.rob...@gmail.com on 8 Sep 2013 at 11:33

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry to be demanding, but can I get one of the ISC's captures to compare 
against this one? I'm going to try to achieve binary equivalence between the 
two, or at least figure out what the magic, missing detail is.

Original comment by red.hamsterx on 8 Sep 2013 at 11:42

GoogleCodeExporter commented 9 years ago
Demanding, you?  I think I'm the one asking YOU to work on this on a Sunday. 

Here's the capture from ISC.  One thing I did forget to change was the OFFER 
was for 192.168.11.201 instead of 192.168.11.51 since I had the scope of the 
two offset just to keep the scopes from overlapping. 

Original comment by bhms.rob...@gmail.com on 9 Sep 2013 at 1:45

Attachments:

GoogleCodeExporter commented 9 years ago
It's fine. I work on this stuff because these sorts of problems are always 
interesting.

I'm comparing them now; I'll let you know as soon as I've found something.

Original comment by red.hamsterx on 9 Sep 2013 at 2:06

GoogleCodeExporter commented 9 years ago
Structurally, aside from lease-time, addresses, and a long pad at the end, 
staticDHCPd's packet is bit-for-bit identical to the ISC's at this point.

The only thing that's different is that the ISC's server sends the response 
back to the IP that was just issued, rather than on broadcast.

This seems illogical because it assumes that a host that's performing a DHCP 
request is performing promiscuous analysis of traffic on an interface, looking 
for a response, but it might explain weird behaviour with Windows XP's firewall 
in the past... However, it does reduce the likelihood of collisions on a 
network because, if an IP is already associated with another MAC, a switch will 
send it to a host that will not be expecting it and it'll be safely discarded, 
rather than risking a duplicate allocation if a DECLINE fails to be emitted for 
any reason.

I'm going to add an experimental, on-by-default "UNICAST_OFFERS" config-option 
that will force a response to the just-issued address. I'll test this locally, 
but my version differs from yours. If it fixes my problem, though, it might 
just fix both of them.

Original comment by red.hamsterx on 9 Sep 2013 at 2:22

GoogleCodeExporter commented 9 years ago
Nope... That doesn't seem to work.

Somehow, the response packet is beign sent to a specific MAC, but it has to be 
UDP, which is layer 4, and the lowest an application is supposed to be able to 
manage is layer 3, so... more research.

I have all the data I could possibly need from you to help with this now, so 
I'll just keep you informed while I look into it. Hopefully, I'll have 
something within the hour.

Original comment by red.hamsterx on 9 Sep 2013 at 3:05

GoogleCodeExporter commented 9 years ago
If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is
   set, then the server broadcasts DHCPOFFER and DHCPACK messages to
   0xffffffff. If the broadcast bit is not set and 'giaddr' is zero and
   'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK
   messages to the client's hardware address and 'yiaddr' address.

Well, that certainly clarifies things. Now to find out how to set the hardware 
address from socket.h's abstraction.

Original comment by red.hamsterx on 9 Sep 2013 at 3:08

GoogleCodeExporter commented 9 years ago
Looks like I'll need to reimplement the socket logic as raw sockets so I can 
write custom headers.

This is a significant change (in terms of impact, not quantity of code), so 
it's very unlikely that I'll finish it tonight, but I should have time to 
finish implementation during lunch tomorrow and to start testing as soon as I 
get home.

Until I update this issue, consider the code in the development branch to be 
broken, because it's very likely that it won't work.

Original comment by red.hamsterx on 9 Sep 2013 at 3:36

GoogleCodeExporter commented 9 years ago
Thanks Neil.  Just let me know when you have something you want me to test. 

Ken

Original comment by bhms.rob...@gmail.com on 9 Sep 2013 at 12:51

GoogleCodeExporter commented 9 years ago
Just letting you know that I'm still working on this. I'd hoped to have a 
solution an hour or so ago, but crafting a packet at layer 2 is a lot 
lower-level than I'd expected. socket.h stops at layer 3, and I didn't notice 
that last night.

Original comment by red.hamsterx on 10 Sep 2013 at 2:10

GoogleCodeExporter commented 9 years ago
I've found a solution that looks like it'll work, but it relies on a Linux-only 
address-family (AF_PACKET).

To implement this and have staticDHCPd work on OS X would require one of the 
following approaches:
 - Make pcap Python bindings a requirement (pcap ships with OS X, but the bindings do not)
 - Implement two response methods: one that always sets the broadcast bit and sends the old way and one that's adaptive (which might not solve the problem you're facing)
 - Hybridise the two ideas described above

I'll keep looking into ways to send a packet from layer 2 in OS X/BSD via 
Python, and I can do some testing on a Snow Leopard box, but if you can get 
back to me with your input on what to do, that should speed things up.

If you can run your environment around a Linux-based system, I can implement 
the hybrid-solution for now and try to deal with bringing other platforms up to 
speed later, without introducing core dependencies, but you're currently the 
driving force behind this change, so whether that's a viable solution or not 
hinges on what you'd be willing to accept.

Original comment by red.hamsterx on 10 Sep 2013 at 3:13

GoogleCodeExporter commented 9 years ago
My environment is SLES11sp3 so I'd be happy to test out the hybrid solution. 

Thanks,
Ken

Original comment by bhms.rob...@gmail.com on 10 Sep 2013 at 3:30

GoogleCodeExporter commented 9 years ago
The architectural planning is complete and the implementation's about 75% of 
the way to being done.

My testing has shown that this works fine on any semi-recent Linux kernel, so I 
should have a stable (and slightly more efficient) hybrid ready tomorrow.

I'd say tonight, but I had plans to continue work on a 3D-printer this evening 
with a friend. If we finish early, I might have enough time to finish, though.

The only things left to look into are the algorithms for the UDP and IP 
checksums, since those will need to be calculated independently of the kernel, 
because of the nature of raw sockets. I'll look into those tomorrow, but links 
to examples (in any language -- just anything to avoid transcribing math from 
RFC-prose) would help.

Original comment by red.hamsterx on 10 Sep 2013 at 10:51

GoogleCodeExporter commented 9 years ago
Thanks Neil.  I've been off working on a different part of the project for the 
last two days.  Let me know when you have something you want me to try out. 

Ken

Original comment by bhms.rob...@gmail.com on 12 Sep 2013 at 4:56

GoogleCodeExporter commented 9 years ago
I think I've got something now.

I just finished (like, within the past few minutes) preliminary testing on the 
hybrid solution. It seems to be working properly in my test environment, but it 
almost worked on the first try, so I'm kinda scared.

You can enable it by setting "DHCP_RESPONSE_INTERFACE = 'eth0'" (or whatever is 
appropriate for your server) in conf.py. If that option is unset, the old 
behaviour (reimplemented, and thus possibly unstable, but 
stable-enough-for-beta) will be used instead, and non-Linux platforms will fall 
back to that with a warning.

The new raw packet method is a bit less efficient (computing checksums and 
performing memory-manipulation in Python, rather than letting the kernel do 
it), clocking in at about an extra 400us per packet on my test system, which 
isn't going to make a huge difference to anyone, but which won't be getting any 
optimisation until I've had a chance to rewrite my automated testing tools.

Original comment by red.hamsterx on 12 Sep 2013 at 5:36

GoogleCodeExporter commented 9 years ago
I'll start looking into just wrapping libpcap with ctypes for other platforms 
the next time I get a free hour.

Testing tools, then doc for 2.0.0's RC will follow.

Please let me know if this change works for you. I'll release beta 8 if it does.

Original comment by red.hamsterx on 12 Sep 2013 at 2:20

GoogleCodeExporter commented 9 years ago
There might be an easier solution using IP_HDRINCL on an IPPROTO socket. If so, 
the syntax of the new option may change, because that might use the kernel's 
routing table, rather than a fixed interface. It might also mean that checksums 
can be moved back to the kernel/NIC.

More importantly, it would mean BSD and OS X support. I should have that tested 
tonight, but it won't change the importance of any testing you do now.

Original comment by red.hamsterx on 12 Sep 2013 at 2:53

GoogleCodeExporter commented 9 years ago
Actually, no, IP_HDRINCL doesn't help because the Ethernet headers need to be 
rewritten, so back to pcap/dnet and ctypes it is. Don't expect the 
DHCP_RESPONSE_INTERFACE rule to go away, and if it works, its implementation 
will probably be stable forever.

Original comment by neiltal...@3d-p.com on 12 Sep 2013 at 6:54

GoogleCodeExporter commented 9 years ago
Okay, there should be support for OS X, BSD (thanks to some feedback from 
#dragonflybsd@efnet), and a fallback for Linux, in the unlikely event that the 
kernel was built without AF_PACKET.

The changes I just committed *may* have broken things, but they'll be minor 
syntax errors. If you encounter any problems let me know; otherwise, I'll fix 
them when I test in a couple of hours.

Original comment by red.hamsterx on 12 Sep 2013 at 11:32

GoogleCodeExporter commented 9 years ago
Syntax and reference errors fixed and testing done with the pcap method on both 
Linux and OS X.

Have at it and let me know if it works!

Original comment by red.hamsterx on 13 Sep 2013 at 2:22

GoogleCodeExporter commented 9 years ago
OK, Here's what I get when the first DISCOVER comes in: 

2013-09-13 03:25:23,457 : INFO : DISCOVER from 00:25:90:85:00:e1
2013-09-13 03:25:23,466 : CRITICAL : Unable to handle DISCOVER from  
00:25:90:85:00:e1:
Traceback (most recent call last):
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 429, in wrappedHandler
    f(self, wrapper)
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 548, in _handleDHCPDiscover
    wrapper.mac, definition.ip
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 800, in _emitDHCPPacket
    (bytes, ip, port) = self._sendDHCPPacket(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 191, in _sendDHCPPacket
    return self._network_link.sendData(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 322, in sendData
    return responder.send(packet, mac, ip, port, source_port=source_port)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 348, in send
    bytes_sent = self._send(packet, mac, ip, port, *args, **kwargs)
TypeError: _send() takes exactly 2 arguments (6 given)

2013-09-13 03:25:26,959 : INFO : DISCOVER from 00:25:90:85:00:e1
2013-09-13 03:25:26,966 : CRITICAL : Unable to handle DISCOVER from  
00:25:90:85:00:e1:
Traceback (most recent call last):
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 429, in wrappedHandler
    f(self, wrapper)
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 548, in _handleDHCPDiscover
    wrapper.mac, definition.ip
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 800, in _emitDHCPPacket
    (bytes, ip, port) = self._sendDHCPPacket(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 191, in _sendDHCPPacket
    return self._network_link.sendData(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 322, in sendData
    return responder.send(packet, mac, ip, port, source_port=source_port)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 348, in send
    bytes_sent = self._send(packet, mac, ip, port, *args, **kwargs)
TypeError: _send() takes exactly 2 arguments (6 given)

2013-09-13 03:25:30,671 : INFO : DISCOVER from 00:25:90:85:00:e1
2013-09-13 03:25:30,677 : CRITICAL : Unable to handle DISCOVER from  
00:25:90:85:00:e1:
Traceback (most recent call last):
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 429, in wrappedHandler
    f(self, wrapper)
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 548, in _handleDHCPDiscover
    wrapper.mac, definition.ip
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 800, in _emitDHCPPacket
    (bytes, ip, port) = self._sendDHCPPacket(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 191, in _sendDHCPPacket
    return self._network_link.sendData(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 322, in sendData
    return responder.send(packet, mac, ip, port, source_port=source_port)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 348, in send
    bytes_sent = self._send(packet, mac, ip, port, *args, **kwargs)
TypeError: _send() takes exactly 2 arguments (6 given)

2013-09-13 03:25:33,507 : INFO : DISCOVER from 00:25:90:85:00:e1
2013-09-13 03:25:33,514 : CRITICAL : Unable to handle DISCOVER from  
00:25:90:85:00:e1:
Traceback (most recent call last):
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 429, in wrappedHandler
    f(self, wrapper)
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 548, in _handleDHCPDiscover
    wrapper.mac, definition.ip
  File "/VISTA/network3/staticDHCPd/staticdhcpdlib/dhcp.py", line 800, in _emitDHCPPacket
    (bytes, ip, port) = self._sendDHCPPacket(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 191, in _sendDHCPPacket
    return self._network_link.sendData(packet, address, pxe, mac, client_ip)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 322, in sendData
    return responder.send(packet, mac, ip, port, source_port=source_port)
  File "/VISTA/network3/staticDHCPd/libpydhcpserver/dhcp_network.py", line 348, in send
    bytes_sent = self._send(packet, mac, ip, port, *args, **kwargs)
TypeError: _send() takes exactly 2 arguments (6 given)

^CTraceback (most recent call last):
  File "./staticDHCPd", line 282, in <module>
    _logger.warn("System shutdown requested via keyboard interrupt")
  File "/usr/local/lib/python2.7/logging/__init__.py", line 1161, in warning
    self._log(WARNING, msg, args, **kwargs)
  File "/usr/local/lib/python2.7/logging/__init__.py", line 1267, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/local/lib/python2.7/logging/__init__.py", line 1241, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/local/lib/python2.7/logging/__init__.py", line 280, in __init__
    self.msecs = (ct - long(ct)) * 1000
KeyboardInterrupt
 /VISTA/network3/staticDHCPd > 

Original comment by bhms.rob...@gmail.com on 13 Sep 2013 at 3:27

GoogleCodeExporter commented 9 years ago
I missed an underscore while cleaning up the code. Sorry about that.

It should be fixed now.

Original comment by red.hamsterx on 13 Sep 2013 at 3:29