]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Add billing support and pool support. carrel-2
authorTed Lemon <source@isc.org>
Wed, 11 Nov 1998 08:01:49 +0000 (08:01 +0000)
committerTed Lemon <source@isc.org>
Wed, 11 Nov 1998 08:01:49 +0000 (08:01 +0000)
server/dhcp.c

index be9dc30f00e33c19002f9aa2e9967ddbb7c4db74..dc84ce7c2d561f67002ccc0ae68d10c8d760f525 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: dhcp.c,v 1.71 1998/11/09 02:46:58 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: dhcp.c,v 1.72 1998/11/11 08:01:49 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -90,14 +90,15 @@ void dhcpdiscover (packet)
        struct packet *packet;
 {
        struct lease *lease;
+       char msgbuf [1024];
 
-       note ("DHCPDISCOVER from %s via %s",
-             print_hw_addr (packet -> raw -> htype,
-                            packet -> raw -> hlen,
-                            packet -> raw -> chaddr),
-             packet -> raw -> giaddr.s_addr
-                     ? inet_ntoa (packet -> raw -> giaddr)
-             : packet -> interface -> name);
+       sprintf (msgbuf, "DHCPDISCOVER from %s via %s",
+                print_hw_addr (packet -> raw -> htype,
+                               packet -> raw -> hlen,
+                               packet -> raw -> chaddr),
+                (packet -> raw -> giaddr.s_addr
+                 ? inet_ntoa (packet -> raw -> giaddr)
+                 : packet -> interface -> name));
 
        lease = find_lease (packet, packet -> shared_network, 0);
 
@@ -122,7 +123,7 @@ void dhcpdiscover (packet)
                }
        }
 
-       ack_lease (packet, lease, DHCPOFFER, cur_time + 120);
+       ack_lease (packet, lease, DHCPOFFER, cur_time + 120, msgbuf);
 }
 
 void dhcprequest (packet)
@@ -135,6 +136,7 @@ void dhcprequest (packet)
        struct option_cache *oc;
        struct data_string data;
        int status;
+       char msgbuf [1024];
 
        oc = lookup_option (packet -> options.dhcp_hash,
                            DHO_DHCP_REQUESTED_ADDRESS);
@@ -159,14 +161,14 @@ void dhcprequest (packet)
        else
                lease = (struct lease *)0;
 
-       note ("DHCPREQUEST for %s from %s via %s",
-             piaddr (cip),
-             print_hw_addr (packet -> raw -> htype,
-                            packet -> raw -> hlen,
-                            packet -> raw -> chaddr),
-             packet -> raw -> giaddr.s_addr
-             ? inet_ntoa (packet -> raw -> giaddr)
-             : packet -> interface -> name);
+       sprintf (msgbuf, "DHCPREQUEST for %s from %s via %s",
+                piaddr (cip),
+                print_hw_addr (packet -> raw -> htype,
+                               packet -> raw -> hlen,
+                               packet -> raw -> chaddr),
+                (packet -> raw -> giaddr.s_addr
+                 ? inet_ntoa (packet -> raw -> giaddr)
+                 : packet -> interface -> name));
 
        /* If a client on a given network REQUESTs a lease on an
           address on a different network, NAK it.  If the Requested
@@ -220,6 +222,7 @@ void dhcprequest (packet)
                   from there.   Fry it. */
                if (!packet -> shared_network) {
                        if (subnet) {
+                               note ("%s: wrong network.", msgbuf);
                                nak_lease (packet, &cip);
                                return;
                        }
@@ -231,6 +234,7 @@ void dhcprequest (packet)
                   address that is not on that shared network, nak it. */
                subnet = find_grouped_subnet (packet -> shared_network, cip);
                if (!subnet) {
+                       note ("%s: wrong network.", msgbuf);
                        nak_lease (packet, &cip);
                        return;
                }
@@ -243,14 +247,18 @@ void dhcprequest (packet)
                /* If we found the address the client asked for, but
                    it wasn't what got picked, the lease belongs to us,
                    so we can tenuously justify NAKing it. */
-               if (ours)
+               if (ours) {
+                       note ("%s: wrong lease %s.", msgbuf, piaddr (cip));
                        nak_lease (packet, &cip);
+               } else
+                       note ("%s: unknown lease %s", msgbuf, piaddr (cip));
                return;
        }
 
        /* If the address the client asked for is ours, but it wasn't
            available for the client, NAK it. */
        if (!lease && ours) {
+               note ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
                nak_lease (packet, &cip);
                return;
        }
@@ -270,9 +278,10 @@ void dhcprequest (packet)
                       packet -> raw -> chaddr,
                       packet -> raw -> hlen)))) {
                data_string_forget (&data, "dhcprequest");
-               ack_lease (packet, lease, DHCPACK, 0);
+               ack_lease (packet, lease, DHCPACK, 0, msgbuf);
                return;
        }
+       note ("%s: unknown lease %s.", msgbuf, piaddr (cip));
        data_string_forget (&data, "dhcprequest");
 }
 
@@ -510,11 +519,12 @@ void nak_lease (packet, cip)
                warn ("send_packet: %m");
 }
 
-void ack_lease (packet, lease, offer, when)
+void ack_lease (packet, lease, offer, when, msg)
        struct packet *packet;
        struct lease *lease;
        unsigned int offer;
        TIME when;
+       char *msg;
 {
        struct lease lt;
        struct lease_state *state;
@@ -531,10 +541,8 @@ void ack_lease (packet, lease, offer, when)
        int val;
 
        /* If we're already acking this lease, don't do it again. */
-       if (lease -> state) {
-               note ("already acking lease %s", piaddr (lease -> ip_addr));
+       if (lease -> state)
                return;
-       }
 
        /* Allocate a lease state structure... */
        state = new_lease_state ("ack_lease");
@@ -584,6 +592,7 @@ void ack_lease (packet, lease, offer, when)
 
        /* Execute the subnet statements. */
        execute_statements_in_scope (packet, &state -> options,
+                                    &state -> options,
                                     lease -> subnet -> group,
                                     (struct group *)0);
 
@@ -592,6 +601,7 @@ void ack_lease (packet, lease, offer, when)
                for (i = packet -> class_count; i > 0; i--) {
                         execute_statements_in_scope
                                (packet, &state -> options,
+                                &state -> options,
                                 packet -> classes [i - 1] -> group,
                                 (struct group *)0);
                }
@@ -601,6 +611,7 @@ void ack_lease (packet, lease, offer, when)
           with its group. */
        if (lease -> host)
                execute_statements_in_scope (packet, &state -> options,
+                                            &state -> options,
                                             lease -> host -> group,
                                             lease -> subnet -> group);
 
@@ -612,6 +623,8 @@ void ack_lease (packet, lease, offer, when)
                                           &packet -> options, oc)) {
                        if (d1.len && packet -> raw -> secs < d1.data [0]) {
                                data_string_forget (&d1, "ack_lease");
+                               note ("%s: %d secs < %d",
+                                     packet -> raw -> secs, d1.data [0]);
                                return;
                        }
                        data_string_forget (&d1, "ack_lease");
@@ -655,10 +668,7 @@ void ack_lease (packet, lease, offer, when)
                if (evaluate_option_cache (&d1, packet,
                                           &packet -> options, oc)) {
                        if (d1.len && !d1.data [0]) {
-                               note ("Ignoring unknown client %s",
-                                     print_hw_addr (packet -> raw -> htype,
-                                                    packet -> raw -> hlen,
-                                                    packet -> raw -> chaddr));
+                               note ("%s: unknown", msg);
                                data_string_forget (&d1, "ack_lease");
                                return;
                        }
@@ -673,11 +683,8 @@ void ack_lease (packet, lease, offer, when)
                if (evaluate_option_cache (&d1, packet,
                                           &packet -> options, oc)) {
                        if (d1.len && !d1.data [0]) {
-                               note ("Ignoring BOOTP client %s",
-                                     print_hw_addr (packet -> raw -> htype,
-                                                    packet -> raw -> hlen,
-                                                    packet -> raw -> chaddr));
                                data_string_forget (&d1, "ack_lease");
+                               note ("%s: bootp disallowed", msg);
                                return;
                        }
                        data_string_forget (&d1, "ack_lease");
@@ -689,18 +696,48 @@ void ack_lease (packet, lease, offer, when)
        if (oc &&
            evaluate_option_cache (&d1, packet, &packet -> options, oc)) {
                if (d1.len && !d1.data [0]) {
-                       note ("Declining to boot client %s",
-                             lease -> host -> name
-                             ? lease -> host -> name
-                             : print_hw_addr (packet -> raw -> htype,
-                                              packet -> raw -> hlen,
-                                              packet -> raw -> chaddr));
+                       note ("%s: booting disallowed", msg);
                        data_string_forget (&d1, "ack_lease");
                        return;
                }
                data_string_forget (&d1, "ack_lease");
        }
 
+       /* If we are configured to do per-class billing, do it. */
+       if (have_billing_classes) {
+
+               /* See if the lease is currently being billed to a
+                  class, and if so, whether or not it can continue to
+                  be billed to that class. */
+               if (lease -> billing_class) {
+                       for (i = 0; i < packet -> class_count; i++)
+                               if (packet -> classes [i] ==
+                                   lease -> billing_class)
+                                       break;
+                       if (i == packet -> class_count)
+                               unbill_class (lease, lease -> billing_class);
+               }
+               
+               /* If we don't have an active billing, see if we need
+                  one, and if we do, try to do so. */
+               if (!lease -> billing_class) {
+                       for (i = 0; i < packet -> class_count; i++) {
+                               if (!packet -> classes [i] -> lease_limit)
+                                       break;
+                       }
+                       if (i == packet -> class_count) {
+                               for (i = 0; i < packet -> class_count; i++)
+                                       if (bill_class (lease,
+                                                       packet -> classes [i]))
+                                               break;
+                               if (i == packet -> class_count) {
+                                       note ("%s: no available billing", msg);
+                                       return;
+                               }
+                       }
+               }
+       }
+
        /* Figure out the filename. */
        oc = lookup_option (state -> options.server_hash, SV_FILENAME);
        if (oc)
@@ -847,6 +884,7 @@ void ack_lease (packet, lease, offer, when)
        lt.host = lease -> host;
        lt.subnet = lease -> subnet;
        lt.shared_network = lease -> shared_network;
+       lt.billing_class = lease -> billing_class;
 
        /* Don't call supersede_lease on a mocked-up lease. */
        if (lease -> flags & STATIC_LEASE) {
@@ -869,8 +907,10 @@ void ack_lease (packet, lease, offer, when)
                   it) either. */
 
                if (!(supersede_lease (lease, &lt, !offer || offer == DHCPACK)
-                     || (offer && offer != DHCPACK)))
+                     || (offer && offer != DHCPACK))) {
+                       note ("%s: database update failed", msg);
                        return;
+               }
        }
 
        /* Remember the interface on which the packet arrived. */
@@ -1129,6 +1169,8 @@ void ack_lease (packet, lease, offer, when)
 
        lease -> state = state;
 
+       note ("%s", msg);
+
        /* If this is a DHCPOFFER, ping the lease address before actually
           sending the offer. */
        if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE)) {
@@ -1440,12 +1482,12 @@ struct lease *find_lease (packet, share, ours)
                        if (hw_lease -> flags & ABANDONED_LEASE)
                                continue;
                        /* If we're allowed to use this lease, do so. */
-                       if (!((lease -> pool -> prohibit_list &&
+                       if (!((hw_lease -> pool -> prohibit_list &&
                               permitted (packet,
-                                         lease -> pool -> prohibit_list)) ||
-                             (lease -> pool -> permit_list &&
+                                         hw_lease -> pool -> prohibit_list)) ||
+                             (hw_lease -> pool -> permit_list &&
                               !permitted (packet,
-                                          lease -> pool -> permit_list))))
+                                          hw_lease -> pool -> permit_list))))
                                break;
                }
        }