From abf58d6ba5df9bbe04c4c7008cbbc8c7dc626392 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Fri, 8 Oct 2004 08:49:26 +0000 Subject: [PATCH] Wade Berrier writes: 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 | 7 ++ networking/udhcp/Makefile.in | 2 +- networking/udhcp/dhcpd.c | 25 ++++++- networking/udhcp/dhcpd.h | 7 ++ networking/udhcp/files.c | 53 ++++++++++++++ networking/udhcp/leases.c | 7 ++ networking/udhcp/serverpacket.c | 20 +++++- networking/udhcp/static_leases.c | 119 +++++++++++++++++++++++++++++++ networking/udhcp/static_leases.h | 25 +++++++ 9 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 networking/udhcp/static_leases.c create mode 100644 networking/udhcp/static_leases.h diff --git a/examples/udhcp/udhcpd.conf b/examples/udhcp/udhcpd.conf index 00105b3e5..f91fddebf 100644 --- a/examples/udhcp/udhcpd.conf +++ b/examples/udhcp/udhcpd.conf @@ -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 + + diff --git a/networking/udhcp/Makefile.in b/networking/udhcp/Makefile.in index 2d7a08816..94750f693 100644 --- a/networking/udhcp/Makefile.in +++ b/networking/udhcp/Makefile.in @@ -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)) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 6f38f07f7..ab3ddfe4f 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -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)); diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index 39658a8ff..c47f6aa3f 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -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; diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 89287ca2d..73a3bbc6e 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c @@ -11,6 +11,9 @@ #include #include +#include +#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, ""} }; diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index d478880a3..4da21a23b 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -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; } diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c index bc9d822a9..75d55bd92 100644 --- a/networking/udhcp/serverpacket.c +++ b/networking/udhcp/serverpacket.c @@ -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 index 000000000..1124d39de --- /dev/null +++ b/networking/udhcp/static_leases.c @@ -0,0 +1,119 @@ +/* + * static_leases.c -- Couple of functions to assist with storing and + * retrieving data for static leases + * + * Wade Berrier September 2004 + * + */ + + +#include +#include +#include + +#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 index 000000000..d06520b23 --- /dev/null +++ b/networking/udhcp/static_leases.h @@ -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 + + +