Wade Berrier writes:
authorEric Andersen <andersen@codepoet.org>
Fri, 8 Oct 2004 08:49:26 +0000 (08:49 -0000)
committerEric Andersen <andersen@codepoet.org>
Fri, 8 Oct 2004 08:49:26 +0000 (08:49 -0000)
Hello,

Here's a patch for a first attempt at static leases for udhcpd.
Included in the tarball are 2 files (static_leases.c, static_leases.h)
and a patch against the latest cvs.

In the config file you can configure static leases with the following
format:

static_lease 00:60:08:11:CE:4E 192.168.0.54
static_lease 00:60:08:11:CE:3E 192.168.0.44

Comments/suggestions/improvements are welcome.

Wade

examples/udhcp/udhcpd.conf
networking/udhcp/Makefile.in
networking/udhcp/dhcpd.c
networking/udhcp/dhcpd.h
networking/udhcp/files.c
networking/udhcp/leases.c
networking/udhcp/serverpacket.c
networking/udhcp/static_leases.c [new file with mode: 0644]
networking/udhcp/static_leases.h [new file with mode: 0644]

index 00105b3..f91fdde 100644 (file)
@@ -114,3 +114,10 @@ option     lease   864000          # 10 days of seconds
 #opt ntpsrv
 #opt tftp
 #opt bootfile
+
+
+# Static leases map
+#static_lease 00:60:08:11:CE:4E 192.168.0.54
+#static_lease 00:60:08:11:CE:3E 192.168.0.44
+
+
index 2d7a088..94750f6 100644 (file)
@@ -40,7 +40,7 @@ UDHCP-$(CONFIG_UDHCP_SHARED)    += common.c options.c packet.c pidfile.c \
 UDHCP-$(CONFIG_UDHCPC)         += dhcpc.c clientpacket.c clientsocket.c \
                                   script.c
 UDHCP-$(CONFIG_UDHCPD)         += dhcpd.c arpping.c files.c leases.c \
-                                  serverpacket.c
+                                  serverpacket.c static_leases.c
 UDHCP-$(CONFIG_DUMPLEASES)     += dumpleases.c
 UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y))
 
index 6f38f07..ab3ddfe 100644 (file)
@@ -44,6 +44,7 @@
 #include "serverpacket.h"
 #include "common.h"
 #include "signalpipe.h"
+#include "static_leases.h"
 
 
 /* globals */
@@ -68,9 +69,12 @@ int main(int argc, char *argv[])
        unsigned long timeout_end;
        struct option_set *option;
        struct dhcpOfferedAddr *lease;
+       struct dhcpOfferedAddr static_lease;
        int max_sock;
        unsigned long num_ips;
 
+       uint32_t static_lease_ip;
+
        memset(&server_config, 0, sizeof(struct server_config_t));
        read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
 
@@ -162,8 +166,25 @@ int main(int argc, char *argv[])
                        continue;
                }
 
-               /* ADDME: look for a static lease */
+               /* Look for a static lease */
+               static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);
+
+               if(static_lease_ip)
+               {
+                       printf("Found static lease: %x\n", static_lease_ip);
+
+                       memcpy(&static_lease.chaddr, &packet.chaddr, 16);
+                       static_lease.yiaddr = static_lease_ip;
+                       static_lease.expires = 0;
+
+                       lease = &static_lease;
+
+               }
+               else
+               {
                lease = find_lease_by_chaddr(packet.chaddr);
+               }
+
                switch (state[0]) {
                case DHCPDISCOVER:
                        DEBUG(LOG_INFO,"received DISCOVER");
@@ -181,7 +202,7 @@ int main(int argc, char *argv[])
                        if (requested) memcpy(&requested_align, requested, 4);
                        if (server_id) memcpy(&server_id_align, server_id, 4);
 
-                       if (lease) { /*ADDME: or static lease */
+                       if (lease) {
                                if (server_id) {
                                        /* SELECTING State */
                                        DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
index 39658a8..c47f6aa 100644 (file)
@@ -99,6 +99,12 @@ struct option_set {
        struct option_set *next;
 };
 
+struct static_lease {
+       uint8_t *mac;
+       uint32_t *ip;
+       struct static_lease *next;
+};
+
 struct server_config_t {
        uint32_t server;                /* Our IP, in network order */
        uint32_t start;         /* Start address of leases, network order */
@@ -124,6 +130,7 @@ struct server_config_t {
        uint32_t siaddr;                /* next server bootp option */
        char *sname;                    /* bootp server name */
        char *boot_file;                /* bootp boot file option */
+       struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */
 };
 
 extern struct server_config_t server_config;
index 89287ca..73a3bbc 100644 (file)
@@ -11,6 +11,9 @@
 #include <ctype.h>
 #include <netdb.h>
 
+#include <netinet/ether.h>
+#include "static_leases.h"
+
 #include "dhcpd.h"
 #include "files.h"
 #include "options.h"
@@ -38,6 +41,22 @@ static int read_ip(const char *line, void *arg)
        return retval;
 }
 
+static int read_mac(const char *line, void *arg)
+{
+       uint8_t *mac_bytes = arg;
+       struct ether_addr *temp_ether_addr;
+       int retval = 1;
+
+       temp_ether_addr = ether_aton(line);
+
+       if(temp_ether_addr == NULL)
+               retval = 0;
+       else
+               memcpy(mac_bytes, temp_ether_addr, 6);
+
+       return retval;
+}
+
 
 static int read_str(const char *line, void *arg)
 {
@@ -150,6 +169,39 @@ static int read_opt(const char *const_line, void *arg)
        return retval;
 }
 
+static int read_staticlease(const char *const_line, void *arg)
+{
+
+       char *line;
+       char *mac_string;
+       char *ip_string;
+       uint8_t *mac_bytes;
+       uint32_t *ip;
+
+
+       /* Allocate memory for addresses */
+       mac_bytes = xmalloc(sizeof(unsigned char) * 8);
+       ip = xmalloc(sizeof(uint32_t));
+
+       /* Read mac */
+       line = (char *) const_line;
+       mac_string = strtok(line, " \t");
+       read_mac(mac_string, mac_bytes);
+
+       /* Read ip */
+       ip_string = strtok(NULL, " \t");
+       read_ip(ip_string, ip);
+
+       addStaticLease(arg, mac_bytes, ip);
+
+#ifdef UDHCP_DEBUG
+       printStaticLeases(arg);
+#endif
+
+       return 1;
+
+}
+
 
 static const struct config_keyword keywords[] = {
        /* keyword      handler   variable address              default */
@@ -171,6 +223,7 @@ static const struct config_keyword keywords[] = {
        {"siaddr",      read_ip,  &(server_config.siaddr),      "0.0.0.0"},
        {"sname",       read_str, &(server_config.sname),       ""},
        {"boot_file",   read_str, &(server_config.boot_file),   ""},
+       {"static_lease",read_staticlease, &(server_config.static_leases),       ""},
        /*ADDME: static lease */
        {"",            NULL,     NULL,                         ""}
 };
index d478880..4da21a2 100644 (file)
@@ -16,6 +16,8 @@
 #include "arpping.h"
 #include "common.h"
 
+#include "static_leases.h"
+
 
 uint8_t blank_chaddr[] = {[0 ... 15] = 0};
 
@@ -134,6 +136,10 @@ uint32_t find_address(int check_expired)
                /* ie, 192.168.55.255 */
                if ((addr & 0xFF) == 0xFF) continue;
 
+               /* Only do if it isn't an assigned as a static lease */
+               if(!reservedIp(server_config.static_leases, htonl(addr)))
+               {
+
                /* lease is not taken */
                ret = htonl(addr);
                if ((!(lease = find_lease_by_yiaddr(ret)) ||
@@ -147,5 +153,6 @@ uint32_t find_address(int check_expired)
                        break;
                }
        }
+       }
        return 0;
 }
index bc9d822..75d55bd 100644 (file)
@@ -29,6 +29,7 @@
 #include "dhcpd.h"
 #include "options.h"
 #include "common.h"
+#include "static_leases.h"
 
 /* send a packet to giaddr using the kernel ip stack */
 static int send_packet_to_relay(struct dhcpMessage *payload)
@@ -113,9 +114,15 @@ int sendOffer(struct dhcpMessage *oldpacket)
        struct option_set *curr;
        struct in_addr addr;
 
+       uint32_t static_lease_ip;
+
        init_packet(&packet, oldpacket, DHCPOFFER);
 
+       static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr);
+
        /* ADDME: if static, short circuit */
+       if(!static_lease_ip)
+       {
        /* the client is in our lease/offered table */
        if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) {
                if (!lease_expired(lease))
@@ -132,15 +139,17 @@ int sendOffer(struct dhcpMessage *oldpacket)
                   ntohl(req_align) >= ntohl(server_config.start) &&
                   ntohl(req_align) <= ntohl(server_config.end) &&
                
-                  /* and its not already taken/offered */ /* ADDME: check that its not a static lease */
+                       !static_lease_ip &&  /* Check that its not a static lease */
+                       /* and is not already taken/offered */
                   ((!(lease = find_lease_by_yiaddr(req_align)) ||
                
                   /* or its taken, but expired */ /* ADDME: or maybe in here */
                   lease_expired(lease)))) {
                                packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */
 
-       /* otherwise, find a free IP */ /*ADDME: is it a static lease? */
+                       /* otherwise, find a free IP */
        } else {
+                       /* Is it a static lease? (No, because find_address skips static lease) */
                packet.yiaddr = find_address(0);
 
                /* try for an expired lease */
@@ -167,7 +176,14 @@ int sendOffer(struct dhcpMessage *oldpacket)
        /* Make sure we aren't just using the lease time from the previous offer */
        if (lease_time_align < server_config.min_lease)
                lease_time_align = server_config.lease;
+       }
        /* ADDME: end of short circuit */
+       else
+       {
+               /* It is a static lease... use it */
+               packet.yiaddr = static_lease_ip;
+       }
+
        add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align));
 
        curr = server_config.options;
diff --git a/networking/udhcp/static_leases.c b/networking/udhcp/static_leases.c
new file mode 100644 (file)
index 0000000..1124d39
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * static_leases.c -- Couple of functions to assist with storing and
+ * retrieving data for static leases
+ *
+ * Wade Berrier <wberrier@myrealbox.com> September 2004
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "static_leases.h"
+#include "dhcpd.h"
+
+/* Takes the address of the pointer to the static_leases linked list,
+ *   Address to a 6 byte mac address
+ *   Address to a 4 byte ip address */
+int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip)
+{
+
+       struct static_lease *cur;
+       struct static_lease *new_static_lease;
+
+       /* Build new node */
+       new_static_lease = xmalloc(sizeof(struct static_lease));
+       new_static_lease->mac = mac;
+       new_static_lease->ip = ip;
+       new_static_lease->next = NULL;
+
+       /* If it's the first node to be added... */
+       if(*lease_struct == NULL)
+       {
+               *lease_struct = new_static_lease;
+       }
+       else
+       {
+               cur = *lease_struct;
+               while(cur->next != NULL)
+               {
+                       cur = cur->next;
+               }
+
+               cur->next = new_static_lease;
+       }
+
+       return 1;
+
+}
+
+/* Check to see if a mac has an associated static lease */
+uint32_t getIpByMac(struct static_lease *lease_struct, void *arg)
+{
+       uint32_t return_ip;
+       struct static_lease *cur = lease_struct;
+       uint8_t *mac = arg;
+
+       return_ip = 0;
+
+       while(cur != NULL)
+       {
+               /* If the client has the correct mac  */
+               if(memcmp(cur->mac, mac, 6) == 0)
+               {
+                       return_ip = *(cur->ip);
+               }
+
+               cur = cur->next;
+       }
+
+       return return_ip;
+
+}
+
+/* Check to see if an ip is reserved as a static ip */
+uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip)
+{
+       struct static_lease *cur = lease_struct;
+
+       uint32_t return_val = 0;
+
+       while(cur != NULL)
+       {
+               /* If the client has the correct ip  */
+               if(*cur->ip == ip)
+                       return_val = 1;
+
+               cur = cur->next;
+       }
+
+       return return_val;
+
+}
+
+#ifdef UDHCP_DEBUG
+/* Print out static leases just to check what's going on */
+/* Takes the address of the pointer to the static_leases linked list */
+void printStaticLeases(struct static_lease **arg)
+{
+       /* Get a pointer to the linked list */
+       struct static_lease *cur = *arg;
+
+       while(cur != NULL)
+       {
+               /* printf("PrintStaticLeases: Lease mac Address: %x\n", cur->mac); */
+               printf("PrintStaticLeases: Lease mac Value: %x\n", *(cur->mac));
+               /* printf("PrintStaticLeases: Lease ip Address: %x\n", cur->ip); */
+               printf("PrintStaticLeases: Lease ip Value: %x\n", *(cur->ip));
+
+               cur = cur->next;
+       }
+
+
+}
+#endif
+
+
+
diff --git a/networking/udhcp/static_leases.h b/networking/udhcp/static_leases.h
new file mode 100644 (file)
index 0000000..d06520b
--- /dev/null
@@ -0,0 +1,25 @@
+/* static_leases.h */
+#ifndef _STATIC_LEASES_H
+#define _STATIC_LEASES_H
+
+#include "dhcpd.h"
+
+/* Config file will pass static lease info to this function which will add it
+ * to a data structure that can be searched later */
+int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip);
+
+/* Check to see if a mac has an associated static lease */
+uint32_t getIpByMac(struct static_lease *lease_struct, void *arg);
+
+/* Check to see if an ip is reserved as a static ip */
+uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip);
+
+#ifdef UDHCP_DEBUG
+/* Print out static leases just to check what's going on */
+void printStaticLeases(struct static_lease **lease_struct);
+#endif
+
+#endif
+
+
+