DHCP Server Option 82 denial

David W. Hankins David_Hankins at isc.org
Fri May 26 20:49:46 UTC 2006


On Fri, May 26, 2006 at 10:11:07AM -0700, Scott Baker wrote:
> May 26 09:53:39 dhcp-server dhcpd: DHCPDISCOVER from
> 00:02:a5:cf:49:75 via 65.182.241.1
> May 26 09:53:40 dhcp-server dhcpd: DHCPOFFER on 65.182.239.219 to
> 00:02:a5:cf:49:75 via 65.182.241.1
> May 26 09:53:40 dhcp-server dhcpd: DHCPDISCOVER from
> 00:02:a5:cf:49:75 via 65.182.241.1: no available billing

Hm.  The obvious problem being that it appears the server is allocating
the client a separate address on the second offer.  That's curious, it
shouldn't.

Let's assume that the client is somehow identifying itself differently...
by say providing a client identifier instead of not...there's no reason
it shouldn't just offer the same address (and then that wouldn't run into
billing problems).

But it doesn't make a lot of sense to bill a class for an OFFER.  The
client isn't using the address (or at least shouldn't be).  There's no
good reason to mark them for it until we send an ACK.

At the same time, we need to know if there's available billing before
sending an OFFER, certainly, and we also need to link in the class for
billing-class-scoped config parameters.

Immediately what makes the most sense to me is to unbill billed classes
for offers immediately after ACKing.

If you're willing to experiment...

Find the function named 'dhcpdiscover' in server/dhcp.c, towards
the end of the function (line 375 in my sources), find:

        ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp,
                   (struct host_decl *)0);
      out:
        if (lease)
                lease_dereference (&lease, MDL);

Which is literally the last lines of that function.


Switch that last two lines so it reads instead:

	if (lease) {
		/* XXX - Super Ultra Unwise Experimental Code - Do Not Run
		 * (unless you enjoy pain).
		 *
		 * There's no good reason to bill a class on an OFFER,
		 * but there's also no good reason to OFFER if we would
		 * fail due to billing on the ACK.  Unbill the class for
		 * now, and we will rebill it on receiving a REQUEST.
		 */
		if ((lease->flags & STATIC_LEASE) &&
		    (lease->billing_class != NULL) &&
		    (lease->state == FTS_FREE || lease->state == FTS_BACKUP))
			unbill_class(lease, lease->billing_class);

		lease_dereference (&lease, MDL);
	}

Untested, random thoughts.


> I'm assuming it will timeout eventually because the customer didn't
> accept the lease. Is that timeout period controllable? If I stop and

2 minutes, should be, unless the lease is active when they got this
far.  And no isn't controllable (unless you edit sources).

I'm also pretty fuzzy on how non-active leases get 'expired'.  That's a
fair quagmire of code I've never managed to read from one end to the other
in one sitting.

It may be that you've illuminated where billing classes go to die.

-- 
David W. Hankins		"If you don't do it right the first time,
Software Engineer			you'll just have to do it again."
Internet Systems Consortium, Inc.		-- Jack T. Hankins


More information about the dhcp-users mailing list