mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-03 15:56:00 +00:00
Intermediate changes to support actual DHCP protocol engine
This commit is contained in:
6
Makefile
6
Makefile
@@ -11,6 +11,8 @@ CFLAGS += -DDEBUG -g -Wall -Wstrict-prototypes -Wno-unused \
|
|||||||
-Wno-uninitialized -Werror
|
-Wno-uninitialized -Werror
|
||||||
|
|
||||||
dhclient: dhclient.o confpars.o alloc.o memory.o options.o \
|
dhclient: dhclient.o confpars.o alloc.o memory.o options.o \
|
||||||
hash.o tables.o inet.o convert.o conflex.o errwarn.o tree.o
|
hash.o tables.o inet.o convert.o conflex.o errwarn.o \
|
||||||
|
tree.o print.o
|
||||||
cc -o dhclient dhclient.o confpars.o alloc.o memory.o options.o \
|
cc -o dhclient dhclient.o confpars.o alloc.o memory.o options.o \
|
||||||
hash.o tables.o inet.o convert.o conflex.o errwarn.o tree.o
|
hash.o tables.o inet.o convert.o conflex.o errwarn.o \
|
||||||
|
print.o tree.o
|
@@ -189,10 +189,50 @@ int main (argc, argv, envp)
|
|||||||
|
|
||||||
cons_options ((struct packet *)0,
|
cons_options ((struct packet *)0,
|
||||||
&outgoing, &decl, bufs);
|
&outgoing, &decl, bufs);
|
||||||
memset (&raw.ciaddr, 0, sizeof raw.ciaddr);
|
|
||||||
memset (&raw.yiaddr, 0, sizeof raw.ciaddr);
|
if (decl.ciaddr) {
|
||||||
memset (&raw.siaddr, 0, sizeof raw.ciaddr);
|
if (tree_evaluate (decl.ciaddr) != 4)
|
||||||
memset (&raw.giaddr, 0, sizeof raw.ciaddr);
|
warn ("ciaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.ciaddr,
|
||||||
|
decl.ciaddr -> value,
|
||||||
|
decl.ciaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.ciaddr, 0, sizeof raw.ciaddr);
|
||||||
|
|
||||||
|
if (decl.yiaddr) {
|
||||||
|
if (tree_evaluate (decl.yiaddr) != 4)
|
||||||
|
warn ("yiaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.yiaddr,
|
||||||
|
decl.yiaddr -> value,
|
||||||
|
decl.yiaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.yiaddr, 0, sizeof raw.yiaddr);
|
||||||
|
|
||||||
|
if (decl.siaddr) {
|
||||||
|
if (tree_evaluate (decl.siaddr) != 4)
|
||||||
|
warn ("siaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.siaddr,
|
||||||
|
decl.siaddr -> value,
|
||||||
|
decl.siaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.siaddr, 0, sizeof raw.siaddr);
|
||||||
|
|
||||||
|
if (decl.giaddr) {
|
||||||
|
if (tree_evaluate (decl.giaddr) != 4)
|
||||||
|
warn ("giaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.giaddr,
|
||||||
|
decl.giaddr -> value,
|
||||||
|
decl.giaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.giaddr, 0, sizeof raw.giaddr);
|
||||||
|
|
||||||
raw.xid = xid++;
|
raw.xid = xid++;
|
||||||
raw.xid = htons (raw.xid);
|
raw.xid = htons (raw.xid);
|
||||||
|
@@ -274,6 +274,8 @@ static int intern (atom, dfv)
|
|||||||
case 'c':
|
case 'c':
|
||||||
if (!strcasecmp (atom + 1, "lass"))
|
if (!strcasecmp (atom + 1, "lass"))
|
||||||
return CLASS;
|
return CLASS;
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return CIADDR;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (!strcasecmp (atom + 1, "thernet"))
|
if (!strcasecmp (atom + 1, "thernet"))
|
||||||
@@ -287,6 +289,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "ixed-address"))
|
if (!strcasecmp (atom + 1, "ixed-address"))
|
||||||
return FIXED_ADDR;
|
return FIXED_ADDR;
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return GIADDR;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
if (!strcasecmp (atom + 1, "ost"))
|
if (!strcasecmp (atom + 1, "ost"))
|
||||||
return HOST;
|
return HOST;
|
||||||
@@ -312,6 +318,8 @@ static int intern (atom, dfv)
|
|||||||
case 's':
|
case 's':
|
||||||
if (!strcasecmp (atom + 1, "tarts"))
|
if (!strcasecmp (atom + 1, "tarts"))
|
||||||
return STARTS;
|
return STARTS;
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return SIADDR;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (!strcasecmp (atom + 1, "timestamp"))
|
if (!strcasecmp (atom + 1, "timestamp"))
|
||||||
@@ -321,6 +329,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "id"))
|
if (!strcasecmp (atom + 1, "id"))
|
||||||
return UID;
|
return UID;
|
||||||
break;
|
break;
|
||||||
|
case 'y':
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return YIADDR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return dfv;
|
return dfv;
|
||||||
}
|
}
|
||||||
|
@@ -103,6 +103,7 @@ void add_hash (table, name, len, pointer)
|
|||||||
bp -> name = name;
|
bp -> name = name;
|
||||||
bp -> value = pointer;
|
bp -> value = pointer;
|
||||||
bp -> next = table -> buckets [hashno];
|
bp -> next = table -> buckets [hashno];
|
||||||
|
bp -> len = len;
|
||||||
table -> buckets [hashno] = bp;
|
table -> buckets [hashno] = bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,10 +141,11 @@ unsigned char *hash_lookup (table, name, len)
|
|||||||
struct hash_bucket *bp;
|
struct hash_bucket *bp;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
|
||||||
if (len == bp -> len
|
if (len == bp -> len
|
||||||
&& !memcmp (bp -> name, name, len))
|
&& !memcmp (bp -> name, name, len))
|
||||||
return bp -> value;
|
return bp -> value;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
||||||
if (!strcmp (bp -> name, name))
|
if (!strcmp (bp -> name, name))
|
||||||
|
@@ -87,7 +87,7 @@ struct iaddr ip_addr (subnet, mask, host_address)
|
|||||||
j = rv.len - sizeof habuf;
|
j = rv.len - sizeof habuf;
|
||||||
for (i = sizeof habuf - 1; i >= 0; i--) {
|
for (i = sizeof habuf - 1; i >= 0; i--) {
|
||||||
if (mask.iabuf [i + j]) {
|
if (mask.iabuf [i + j]) {
|
||||||
if (habuf [i] > ~mask.iabuf [i + j]) {
|
if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
|
||||||
rv.len = 0;
|
rv.len = 0;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -97,10 +97,10 @@ struct iaddr ip_addr (subnet, mask, host_address)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv.iabuf [i + j] &= habuf [i];
|
rv.iabuf [i + j] |= habuf [i];
|
||||||
break;
|
break;
|
||||||
}
|
} else
|
||||||
rv.iabuf [i + j] = habuf [i];
|
rv.iabuf [i + j] = habuf [i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
123
common/memory.c
123
common/memory.c
@@ -48,7 +48,7 @@ static char copyright[] =
|
|||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
static struct host_decl *hosts;
|
static struct host_decl *hosts;
|
||||||
static struct hash_table *subnet_hash;
|
static struct subnet *subnets;
|
||||||
static struct hash_table *lease_uid_hash;
|
static struct hash_table *lease_uid_hash;
|
||||||
static struct hash_table *lease_ip_addr_hash;
|
static struct hash_table *lease_ip_addr_hash;
|
||||||
static struct hash_table *lease_hw_addr_hash;
|
static struct hash_table *lease_hw_addr_hash;
|
||||||
@@ -98,12 +98,10 @@ void new_address_range (low, high, netmask)
|
|||||||
struct lease *address_range, *lp, *plp;
|
struct lease *address_range, *lp, *plp;
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
int i, max;
|
int min, max, i;
|
||||||
char lowbuf [16], highbuf [16], netbuf [16];
|
char lowbuf [16], highbuf [16], netbuf [16];
|
||||||
|
|
||||||
/* Initialize the hash table if it hasn't been done yet. */
|
/* Initialize the hash table if it hasn't been done yet. */
|
||||||
if (!subnet_hash)
|
|
||||||
subnet_hash = new_hash ();
|
|
||||||
if (!lease_uid_hash)
|
if (!lease_uid_hash)
|
||||||
lease_uid_hash = new_hash ();
|
lease_uid_hash = new_hash ();
|
||||||
if (!lease_ip_addr_hash)
|
if (!lease_ip_addr_hash)
|
||||||
@@ -130,32 +128,40 @@ void new_address_range (low, high, netmask)
|
|||||||
subnet -> net = net;
|
subnet -> net = net;
|
||||||
subnet -> netmask = netmask;
|
subnet -> netmask = netmask;
|
||||||
subnet -> leases = (struct lease *)0;
|
subnet -> leases = (struct lease *)0;
|
||||||
|
subnet -> last_lease = (struct lease *)0;
|
||||||
|
subnet -> next = (struct subnet *)0;
|
||||||
|
subnet -> default_lease_time = default_lease_time;
|
||||||
|
subnet -> max_lease_time = max_lease_time;
|
||||||
enter_subnet (subnet);
|
enter_subnet (subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the high and low host addresses... */
|
/* Get the high and low host addresses... */
|
||||||
max = host_addr (high, netmask);
|
max = host_addr (high, netmask);
|
||||||
i = host_addr (low, netmask);
|
min = host_addr (low, netmask);
|
||||||
|
|
||||||
/* Allow range to be specified high-to-low as well as low-to-high. */
|
/* Allow range to be specified high-to-low as well as low-to-high. */
|
||||||
if (i > max) {
|
if (min > max) {
|
||||||
max = i;
|
max = min;
|
||||||
i = host_addr (high, netmask);
|
min = host_addr (high, netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a lease structure for each address in the range. */
|
/* Get a lease structure for each address in the range. */
|
||||||
address_range = new_leases (max - i + 1, "new_address_range");
|
address_range = new_leases (max - min + 1, "new_address_range");
|
||||||
if (!address_range) {
|
if (!address_range) {
|
||||||
strcpy (lowbuf, piaddr (low));
|
strcpy (lowbuf, piaddr (low));
|
||||||
strcpy (highbuf, piaddr (high));
|
strcpy (highbuf, piaddr (high));
|
||||||
error ("No memory for address range %s-%s.", lowbuf, highbuf);
|
error ("No memory for address range %s-%s.", lowbuf, highbuf);
|
||||||
}
|
}
|
||||||
memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
|
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
||||||
|
|
||||||
|
/* Fill in the last lease if it hasn't been already... */
|
||||||
|
if (!subnet -> last_lease)
|
||||||
|
subnet -> last_lease = &address_range [0];
|
||||||
|
|
||||||
/* Fill out the lease structures with some minimal information. */
|
/* Fill out the lease structures with some minimal information. */
|
||||||
for (; i <= max; i++) {
|
for (i = 0; i < max - min + 1; i++) {
|
||||||
address_range [i].ip_addr =
|
address_range [i].ip_addr =
|
||||||
ip_addr (subnet -> net, subnet -> netmask, i);
|
ip_addr (subnet -> net, subnet -> netmask, i + min);
|
||||||
address_range [i].starts =
|
address_range [i].starts =
|
||||||
address_range [i].timestamp = MIN_TIME;
|
address_range [i].timestamp = MIN_TIME;
|
||||||
address_range [i].ends = MIN_TIME;
|
address_range [i].ends = MIN_TIME;
|
||||||
@@ -200,13 +206,16 @@ void new_address_range (low, high, netmask)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct subnet *find_subnet (subnet)
|
struct subnet *find_subnet (addr)
|
||||||
struct iaddr subnet;
|
struct iaddr addr;
|
||||||
{
|
{
|
||||||
struct subnet *rv;
|
struct subnet *rv;
|
||||||
|
|
||||||
return (struct subnet *)hash_lookup (subnet_hash,
|
for (rv = subnets; rv; rv = rv -> next) {
|
||||||
(char *)subnet.iabuf, subnet.len);
|
if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return (struct subnet *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a new subnet into the subnet hash. */
|
/* Enter a new subnet into the subnet hash. */
|
||||||
@@ -214,8 +223,9 @@ struct subnet *find_subnet (subnet)
|
|||||||
void enter_subnet (subnet)
|
void enter_subnet (subnet)
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
add_hash (subnet_hash, (char *)subnet -> net.iabuf,
|
/* XXX Sort the nets into a balanced tree to make searching quicker. */
|
||||||
subnet -> net.len, (unsigned char *)subnet);
|
subnet -> next = subnets;
|
||||||
|
subnets = subnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a lease into the system. This is called by the parser each
|
/* Enter a lease into the system. This is called by the parser each
|
||||||
@@ -259,6 +269,11 @@ void supersede_lease (comp, lease)
|
|||||||
struct subnet *parent;
|
struct subnet *parent;
|
||||||
struct lease *lp;
|
struct lease *lp;
|
||||||
|
|
||||||
|
printf ("Supersede_lease:\n");
|
||||||
|
print_lease (comp);
|
||||||
|
print_lease (lease);
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
/* If the existing lease hasn't expired and has a different
|
/* If the existing lease hasn't expired and has a different
|
||||||
unique identifier or, if it doesn't have a unique
|
unique identifier or, if it doesn't have a unique
|
||||||
identifier, a different hardware address, then the two
|
identifier, a different hardware address, then the two
|
||||||
@@ -290,7 +305,9 @@ void supersede_lease (comp, lease)
|
|||||||
enter_uid = 1;
|
enter_uid = 1;
|
||||||
}
|
}
|
||||||
free (comp -> uid);
|
free (comp -> uid);
|
||||||
}
|
} else
|
||||||
|
enter_uid = 1;
|
||||||
|
|
||||||
if (comp -> hardware_addr.htype &&
|
if (comp -> hardware_addr.htype &&
|
||||||
((comp -> hardware_addr.hlen !=
|
((comp -> hardware_addr.hlen !=
|
||||||
lease -> hardware_addr.hlen) ||
|
lease -> hardware_addr.hlen) ||
|
||||||
@@ -303,7 +320,8 @@ void supersede_lease (comp, lease)
|
|||||||
comp -> hardware_addr.haddr,
|
comp -> hardware_addr.haddr,
|
||||||
comp -> hardware_addr.hlen);
|
comp -> hardware_addr.hlen);
|
||||||
enter_hwaddr = 1;
|
enter_hwaddr = 1;
|
||||||
}
|
} else if (!comp -> hardware_addr.htype)
|
||||||
|
enter_hwaddr = 1;
|
||||||
|
|
||||||
/* Copy the data files, but not the linkages. */
|
/* Copy the data files, but not the linkages. */
|
||||||
comp -> starts = lease -> starts;
|
comp -> starts = lease -> starts;
|
||||||
@@ -317,16 +335,16 @@ void supersede_lease (comp, lease)
|
|||||||
|
|
||||||
/* Record the lease in the uid hash if necessary. */
|
/* Record the lease in the uid hash if necessary. */
|
||||||
if (enter_uid && lease -> uid) {
|
if (enter_uid && lease -> uid) {
|
||||||
add_hash (lease_uid_hash, lease -> uid,
|
add_hash (lease_uid_hash, comp -> uid,
|
||||||
lease -> uid_len, (unsigned char *)lease);
|
comp -> uid_len, (unsigned char *)comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record it in the hardware address hash if necessary. */
|
/* Record it in the hardware address hash if necessary. */
|
||||||
if (enter_hwaddr && lease -> hardware_addr.htype) {
|
if (enter_hwaddr && lease -> hardware_addr.htype) {
|
||||||
add_hash (lease_hw_addr_hash,
|
add_hash (lease_hw_addr_hash,
|
||||||
lease -> hardware_addr.haddr,
|
comp -> hardware_addr.haddr,
|
||||||
lease -> hardware_addr.hlen,
|
comp -> hardware_addr.hlen,
|
||||||
(unsigned char *)lease);
|
(unsigned char *)comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the lease from its current place in the list. */
|
/* Remove the lease from its current place in the list. */
|
||||||
@@ -338,6 +356,9 @@ void supersede_lease (comp, lease)
|
|||||||
if (comp -> next) {
|
if (comp -> next) {
|
||||||
comp -> next -> prev = comp -> prev;
|
comp -> next -> prev = comp -> prev;
|
||||||
}
|
}
|
||||||
|
if (comp -> contain -> last_lease == comp) {
|
||||||
|
comp -> contain -> last_lease = comp -> prev;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the last insertion point... */
|
/* Find the last insertion point... */
|
||||||
if (comp == comp -> contain -> insertion_point ||
|
if (comp == comp -> contain -> insertion_point ||
|
||||||
@@ -351,18 +372,20 @@ void supersede_lease (comp, lease)
|
|||||||
/* Nothing on the list yet? Just make comp the
|
/* Nothing on the list yet? Just make comp the
|
||||||
head of the list. */
|
head of the list. */
|
||||||
comp -> contain -> leases = comp;
|
comp -> contain -> leases = comp;
|
||||||
} else if (lp -> ends <= comp -> ends) {
|
comp -> contain -> last_lease = comp;
|
||||||
|
} else if (lp -> ends > comp -> ends) {
|
||||||
/* Skip down the list until we run out of list
|
/* Skip down the list until we run out of list
|
||||||
or find a place for comp. */
|
or find a place for comp. */
|
||||||
while (lp -> next && lp -> ends < comp -> ends) {
|
while (lp -> next && lp -> ends > comp -> ends) {
|
||||||
lp = lp -> next;
|
lp = lp -> next;
|
||||||
}
|
}
|
||||||
if (lp -> ends < comp -> ends) {
|
if (lp -> ends > comp -> ends) {
|
||||||
/* If we ran out of list, put comp
|
/* If we ran out of list, put comp
|
||||||
at the end. */
|
at the end. */
|
||||||
lp -> next = comp;
|
lp -> next = comp;
|
||||||
comp -> prev = lp;
|
comp -> prev = lp;
|
||||||
comp -> next = (struct lease *)0;
|
comp -> next = (struct lease *)0;
|
||||||
|
comp -> contain -> last_lease = comp;
|
||||||
} else {
|
} else {
|
||||||
/* If we didn't, put it between lp and
|
/* If we didn't, put it between lp and
|
||||||
the previous item on the list. */
|
the previous item on the list. */
|
||||||
@@ -372,12 +395,12 @@ void supersede_lease (comp, lease)
|
|||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Skip ip the list until we run out of list
|
/* Skip up the list until we run out of list
|
||||||
or find a place for comp. */
|
or find a place for comp. */
|
||||||
while (lp -> prev && lp -> ends > comp -> ends) {
|
while (lp -> prev && lp -> ends < comp -> ends) {
|
||||||
lp = lp -> prev;
|
lp = lp -> prev;
|
||||||
}
|
}
|
||||||
if (lp -> ends > comp -> ends) {
|
if (lp -> ends < comp -> ends) {
|
||||||
/* If we ran out of list, put comp
|
/* If we ran out of list, put comp
|
||||||
at the beginning. */
|
at the beginning. */
|
||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
@@ -397,6 +420,18 @@ void supersede_lease (comp, lease)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release the specified lease and re-hash it as appropriate. */
|
||||||
|
|
||||||
|
void release_lease (lease)
|
||||||
|
struct lease *lease;
|
||||||
|
{
|
||||||
|
struct lease lt;
|
||||||
|
|
||||||
|
lease -> ends = 0;
|
||||||
|
lt = *lease;
|
||||||
|
supersede_lease (lease, <);
|
||||||
|
}
|
||||||
|
|
||||||
/* Locate the lease associated with a given IP address... */
|
/* Locate the lease associated with a given IP address... */
|
||||||
|
|
||||||
struct lease *find_lease_by_ip_addr (addr)
|
struct lease *find_lease_by_ip_addr (addr)
|
||||||
@@ -417,3 +452,29 @@ struct lease *find_lease_by_uid (uid, len)
|
|||||||
return lease;
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lease *find_lease_by_hw_addr (hwaddr, hwlen)
|
||||||
|
unsigned char *hwaddr;
|
||||||
|
int hwlen;
|
||||||
|
{
|
||||||
|
struct lease *lease = (struct lease *)hash_lookup (lease_hw_addr_hash,
|
||||||
|
hwaddr, hwlen);
|
||||||
|
return lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_subnets ()
|
||||||
|
{
|
||||||
|
struct lease *l;
|
||||||
|
struct subnet *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (s = subnets; s; s = s -> next) {
|
||||||
|
printf ("Subnet %s", piaddr (s -> net));
|
||||||
|
printf (" netmask %s\n",
|
||||||
|
piaddr (s -> netmask));
|
||||||
|
for (l = s -> leases; l; l = l -> next) {
|
||||||
|
print_lease (l);
|
||||||
|
}
|
||||||
|
printf ("Last Lease:\n");
|
||||||
|
print_lease (s -> last_lease);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -94,8 +94,6 @@ void parse_option_buffer (packet, buffer, length)
|
|||||||
int len;
|
int len;
|
||||||
int code;
|
int code;
|
||||||
|
|
||||||
printf ("parse_option_buffer (%x, %x, %d)\n",
|
|
||||||
(unsigned long)packet, (unsigned long)buffer, length);
|
|
||||||
for (s = buffer; *s != DHO_END && s < end; ) {
|
for (s = buffer; *s != DHO_END && s < end; ) {
|
||||||
code = s [0];
|
code = s [0];
|
||||||
/* Pad options don't have a length - just skip them. */
|
/* Pad options don't have a length - just skip them. */
|
||||||
@@ -126,8 +124,6 @@ printf ("parse_option_buffer (%x, %x, %d)\n",
|
|||||||
t [len] = 0;
|
t [len] = 0;
|
||||||
packet -> options [code].len = len;
|
packet -> options [code].len = len;
|
||||||
packet -> options [code].data = t;
|
packet -> options [code].data = t;
|
||||||
printf ("%s=%s\n", dhcp_options [code].name,
|
|
||||||
pretty_print_option (code, t, len));
|
|
||||||
} else {
|
} else {
|
||||||
/* If it's a repeat, concatenate it to whatever
|
/* If it's a repeat, concatenate it to whatever
|
||||||
we last saw. This is really only required
|
we last saw. This is really only required
|
||||||
|
@@ -55,13 +55,46 @@ char *print_hw_addr (htype, hlen, data)
|
|||||||
char *s;
|
char *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s = habuf;
|
if (htype == 0 || hlen == 0) {
|
||||||
for (i = 0; i < hlen; i++) {
|
strcpy (habuf, "<null>");
|
||||||
sprintf (s, "%x", data [i]);
|
} else {
|
||||||
s += strlen (s);
|
s = habuf;
|
||||||
*s++ = ':';
|
for (i = 0; i < hlen; i++) {
|
||||||
|
sprintf (s, "%x", data [i]);
|
||||||
|
s += strlen (s);
|
||||||
|
*s++ = ':';
|
||||||
|
}
|
||||||
|
*--s = 0;
|
||||||
}
|
}
|
||||||
*--s = 0;
|
|
||||||
return habuf;
|
return habuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_lease (lease)
|
||||||
|
struct lease *lease;
|
||||||
|
{
|
||||||
|
struct tm *t;
|
||||||
|
char tbuf [32];
|
||||||
|
|
||||||
|
printf (" Lease %s",
|
||||||
|
piaddr (lease -> ip_addr));
|
||||||
|
|
||||||
|
t = gmtime (&lease -> starts);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" start %s", tbuf);
|
||||||
|
|
||||||
|
t = gmtime (&lease -> ends);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" end %s", tbuf);
|
||||||
|
|
||||||
|
t = gmtime (&lease -> timestamp);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" stamp %s\n", tbuf);
|
||||||
|
|
||||||
|
printf (" hardware addr = %s",
|
||||||
|
print_hw_addr (lease -> hardware_addr.htype,
|
||||||
|
lease -> hardware_addr.hlen,
|
||||||
|
lease -> hardware_addr.haddr));
|
||||||
|
printf (" host %s state %x\n",
|
||||||
|
lease -> host ? lease -> host -> name : "<none>",
|
||||||
|
lease -> state);
|
||||||
|
}
|
||||||
|
@@ -184,6 +184,9 @@ void dispatch ()
|
|||||||
/* Wait for a packet or a timeout... XXX */
|
/* Wait for a packet or a timeout... XXX */
|
||||||
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
|
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
|
||||||
|
|
||||||
|
/* Get the current time... */
|
||||||
|
GET_TIME (&cur_time);
|
||||||
|
|
||||||
/* Not likely to be transitory... */
|
/* Not likely to be transitory... */
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
error ("select: %m");
|
error ("select: %m");
|
||||||
|
12
conflex.c
12
conflex.c
@@ -274,6 +274,8 @@ static int intern (atom, dfv)
|
|||||||
case 'c':
|
case 'c':
|
||||||
if (!strcasecmp (atom + 1, "lass"))
|
if (!strcasecmp (atom + 1, "lass"))
|
||||||
return CLASS;
|
return CLASS;
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return CIADDR;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (!strcasecmp (atom + 1, "thernet"))
|
if (!strcasecmp (atom + 1, "thernet"))
|
||||||
@@ -287,6 +289,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "ixed-address"))
|
if (!strcasecmp (atom + 1, "ixed-address"))
|
||||||
return FIXED_ADDR;
|
return FIXED_ADDR;
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return GIADDR;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
if (!strcasecmp (atom + 1, "ost"))
|
if (!strcasecmp (atom + 1, "ost"))
|
||||||
return HOST;
|
return HOST;
|
||||||
@@ -312,6 +318,8 @@ static int intern (atom, dfv)
|
|||||||
case 's':
|
case 's':
|
||||||
if (!strcasecmp (atom + 1, "tarts"))
|
if (!strcasecmp (atom + 1, "tarts"))
|
||||||
return STARTS;
|
return STARTS;
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return SIADDR;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (!strcasecmp (atom + 1, "timestamp"))
|
if (!strcasecmp (atom + 1, "timestamp"))
|
||||||
@@ -321,6 +329,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "id"))
|
if (!strcasecmp (atom + 1, "id"))
|
||||||
return UID;
|
return UID;
|
||||||
break;
|
break;
|
||||||
|
case 'y':
|
||||||
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
|
return YIADDR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return dfv;
|
return dfv;
|
||||||
}
|
}
|
||||||
|
16
confpars.c
16
confpars.c
@@ -234,6 +234,22 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl);
|
parse_option_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
|
case CIADDR:
|
||||||
|
decl -> ciaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case YIADDR:
|
||||||
|
decl -> yiaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case SIADDR:
|
||||||
|
decl -> siaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case GIADDR:
|
||||||
|
decl -> giaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
parse_warn ("expecting a dhcp option declaration.");
|
parse_warn ("expecting a dhcp option declaration.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
|
48
dhclient.c
48
dhclient.c
@@ -189,10 +189,50 @@ int main (argc, argv, envp)
|
|||||||
|
|
||||||
cons_options ((struct packet *)0,
|
cons_options ((struct packet *)0,
|
||||||
&outgoing, &decl, bufs);
|
&outgoing, &decl, bufs);
|
||||||
memset (&raw.ciaddr, 0, sizeof raw.ciaddr);
|
|
||||||
memset (&raw.yiaddr, 0, sizeof raw.ciaddr);
|
if (decl.ciaddr) {
|
||||||
memset (&raw.siaddr, 0, sizeof raw.ciaddr);
|
if (tree_evaluate (decl.ciaddr) != 4)
|
||||||
memset (&raw.giaddr, 0, sizeof raw.ciaddr);
|
warn ("ciaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.ciaddr,
|
||||||
|
decl.ciaddr -> value,
|
||||||
|
decl.ciaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.ciaddr, 0, sizeof raw.ciaddr);
|
||||||
|
|
||||||
|
if (decl.yiaddr) {
|
||||||
|
if (tree_evaluate (decl.yiaddr) != 4)
|
||||||
|
warn ("yiaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.yiaddr,
|
||||||
|
decl.yiaddr -> value,
|
||||||
|
decl.yiaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.yiaddr, 0, sizeof raw.yiaddr);
|
||||||
|
|
||||||
|
if (decl.siaddr) {
|
||||||
|
if (tree_evaluate (decl.siaddr) != 4)
|
||||||
|
warn ("siaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.siaddr,
|
||||||
|
decl.siaddr -> value,
|
||||||
|
decl.siaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.siaddr, 0, sizeof raw.siaddr);
|
||||||
|
|
||||||
|
if (decl.giaddr) {
|
||||||
|
if (tree_evaluate (decl.giaddr) != 4)
|
||||||
|
warn ("giaddr is more"
|
||||||
|
" than one address");
|
||||||
|
else
|
||||||
|
memcpy (&raw.giaddr,
|
||||||
|
decl.giaddr -> value,
|
||||||
|
decl.giaddr -> len);
|
||||||
|
} else
|
||||||
|
memset (&raw.giaddr, 0, sizeof raw.giaddr);
|
||||||
|
|
||||||
raw.xid = xid++;
|
raw.xid = xid++;
|
||||||
raw.xid = htons (raw.xid);
|
raw.xid = htons (raw.xid);
|
||||||
|
200
dhcp.c
200
dhcp.c
@@ -49,5 +49,205 @@ static char copyright[] =
|
|||||||
void dhcp (packet)
|
void dhcp (packet)
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
{
|
{
|
||||||
|
struct lease *uid_lease, *ip_lease, *hw_lease, *lease;
|
||||||
|
struct iaddr cip;
|
||||||
|
struct lease lt;
|
||||||
|
TIME lease_time;
|
||||||
|
|
||||||
dump_packet (packet);
|
dump_packet (packet);
|
||||||
|
|
||||||
|
/* Try to find a lease that's been assigned to the specified
|
||||||
|
unique client identifier. */
|
||||||
|
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len)
|
||||||
|
uid_lease =
|
||||||
|
find_lease_by_uid (packet -> options
|
||||||
|
[DHO_DHCP_CLIENT_IDENTIFIER].data,
|
||||||
|
packet -> options
|
||||||
|
[DHO_DHCP_CLIENT_IDENTIFIER].len);
|
||||||
|
else
|
||||||
|
uid_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
/* Try to find a lease that's been attached to the client's
|
||||||
|
hardware address... */
|
||||||
|
hw_lease = find_lease_by_hw_addr (packet -> raw -> chaddr,
|
||||||
|
packet -> raw -> hlen);
|
||||||
|
|
||||||
|
/* Try to find a lease that's been allocated to the client's
|
||||||
|
IP address. */
|
||||||
|
if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len &&
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len
|
||||||
|
<= sizeof cip.iabuf) {
|
||||||
|
cip.len = packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len;
|
||||||
|
memcpy (cip.iabuf,
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data,
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len);
|
||||||
|
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
|
||||||
|
ip_lease = find_lease_by_ip_addr (cip);
|
||||||
|
} else
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
printf ("First blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toss extra pointers to the same lease... */
|
||||||
|
if (ip_lease == hw_lease)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
if (hw_lease == uid_lease)
|
||||||
|
hw_lease = (struct lease *)0;
|
||||||
|
if (ip_lease == uid_lease)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
printf ("Second blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got an ip address lease, make sure it isn't assigned to
|
||||||
|
some *other* client! If it was assigned to this client, we'd
|
||||||
|
have zeroed it out above, so the only way we can take it at this
|
||||||
|
point is if some other client had it but it's timed out, or if no
|
||||||
|
other client has ever had it. */
|
||||||
|
if (ip_lease &&
|
||||||
|
ip_lease -> ends >= cur_time)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
/* Now eliminate leases that are on the wrong subnet... */
|
||||||
|
if (ip_lease && packet -> subnet != ip_lease -> contain) {
|
||||||
|
release_lease (ip_lease);
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
if (uid_lease && packet -> subnet != uid_lease -> contain) {
|
||||||
|
release_lease (uid_lease);
|
||||||
|
uid_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
if (hw_lease && packet -> subnet != hw_lease -> contain) {
|
||||||
|
release_lease (hw_lease);
|
||||||
|
hw_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Third blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point, if ip_lease is nonzero, we can assign it to
|
||||||
|
this client. */
|
||||||
|
lease = ip_lease;
|
||||||
|
|
||||||
|
/* If we got a lease that matched the client identifier, we may want
|
||||||
|
to use it, but if we already have a lease we like, we must free
|
||||||
|
the lease that matched the client identifier. */
|
||||||
|
if (uid_lease) {
|
||||||
|
if (lease) {
|
||||||
|
release_lease (uid_lease);
|
||||||
|
} else
|
||||||
|
lease = uid_lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The lease that matched the hardware address is treated likewise. */
|
||||||
|
if (hw_lease) {
|
||||||
|
if (lease) {
|
||||||
|
release_lease (hw_lease);
|
||||||
|
} else
|
||||||
|
lease = hw_lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't find a lease, try to allocate one... */
|
||||||
|
if (!lease) {
|
||||||
|
lease = packet -> subnet -> last_lease;
|
||||||
|
|
||||||
|
/* If there are no leases in that subnet that have
|
||||||
|
expired, we have nothing to offer this client. */
|
||||||
|
if (lease -> ends >= cur_time) {
|
||||||
|
note ("no free leases on subnet %s",
|
||||||
|
piaddr (packet -> subnet -> net));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lease -> host = (struct host_decl *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point, we have a lease that we can offer the client.
|
||||||
|
Now we construct a lease structure that contains what we want,
|
||||||
|
and call supersede_lease to do the right thing with it. */
|
||||||
|
|
||||||
|
memset (<, 0, sizeof lt);
|
||||||
|
|
||||||
|
/* Use the ip address of the lease that we finally found in
|
||||||
|
the database. */
|
||||||
|
lt.ip_addr = lease -> ip_addr;
|
||||||
|
|
||||||
|
/* Start now. */
|
||||||
|
lt.starts = cur_time;
|
||||||
|
|
||||||
|
/* Figure out how long a lease to assign. */
|
||||||
|
if (packet -> options [DHO_DHCP_LEASE_TIME].len == 4) {
|
||||||
|
lease_time = getULong (packet ->
|
||||||
|
options [DHO_DHCP_LEASE_TIME].data);
|
||||||
|
|
||||||
|
/* Don't let the client ask for a longer lease than
|
||||||
|
is supported for this subnet. */
|
||||||
|
if (lease_time > packet -> subnet -> max_lease_time)
|
||||||
|
lease_time = packet -> subnet -> max_lease_time;
|
||||||
|
} else
|
||||||
|
lease_time = packet -> subnet -> default_lease_time;
|
||||||
|
lt.ends = cur_time + lease_time;
|
||||||
|
|
||||||
|
lt.timestamp = cur_time;
|
||||||
|
|
||||||
|
/* Record the uid, if given... */
|
||||||
|
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len) {
|
||||||
|
lt.uid_len =
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len;
|
||||||
|
lt.uid = packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data;
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data =
|
||||||
|
(unsigned char *)0;
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record the hardware address, if given... */
|
||||||
|
lt.hardware_addr.hlen = packet -> raw -> hlen;
|
||||||
|
lt.hardware_addr.htype = packet -> raw -> htype;
|
||||||
|
memcpy (lt.hardware_addr.haddr, packet -> raw -> chaddr,
|
||||||
|
packet -> raw -> hlen);
|
||||||
|
|
||||||
|
lt.host = lease -> host; /* XXX */
|
||||||
|
lt.contain = lease -> contain;
|
||||||
|
|
||||||
|
/* Record the transaction id... */
|
||||||
|
lt.xid = packet -> raw -> xid;
|
||||||
|
|
||||||
|
/* Install the new information about this lease in the database. */
|
||||||
|
supersede_lease (lease, <);
|
||||||
|
|
||||||
|
/* Send a response to the client... */
|
||||||
|
dump_subnets ();
|
||||||
}
|
}
|
||||||
|
52
dhcpd.c
52
dhcpd.c
@@ -50,7 +50,10 @@ static char copyright[] =
|
|||||||
static void usage PROTO ((void));
|
static void usage PROTO ((void));
|
||||||
|
|
||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
|
TIME default_lease_time = 43200; /* 12 hours... */
|
||||||
|
TIME max_lease_time = 86400; /* 24 hours... */
|
||||||
|
|
||||||
|
struct subnet *local_subnet;
|
||||||
u_int32_t *server_addrlist;
|
u_int32_t *server_addrlist;
|
||||||
int server_addrcount;
|
int server_addrcount;
|
||||||
u_int16_t server_port;
|
u_int16_t server_port;
|
||||||
@@ -63,6 +66,7 @@ int main (argc, argv, envp)
|
|||||||
int port = 0;
|
int port = 0;
|
||||||
int i;
|
int i;
|
||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
|
struct iaddr taddr;
|
||||||
u_int32_t *addrlist = (u_int32_t *)0;
|
u_int32_t *addrlist = (u_int32_t *)0;
|
||||||
int addrcount = 0;
|
int addrcount = 0;
|
||||||
struct tree *addrtree = (struct tree *)0;
|
struct tree *addrtree = (struct tree *)0;
|
||||||
@@ -148,7 +152,23 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
taddr.len = 0;
|
||||||
server_addrlist = get_interface_list (&server_addrcount);
|
server_addrlist = get_interface_list (&server_addrcount);
|
||||||
|
for (i = 0; i < server_addrcount; i++) {
|
||||||
|
struct sockaddr_in foo;
|
||||||
|
foo.sin_addr.s_addr = server_addrlist [i];
|
||||||
|
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
||||||
|
|
||||||
|
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
||||||
|
if (taddr.len) {
|
||||||
|
error ("dhcpd currently does not support "
|
||||||
|
"multiple interfaces");
|
||||||
|
}
|
||||||
|
taddr.len = 4;
|
||||||
|
memcpy (taddr.iabuf, &server_addrlist [i], 4);
|
||||||
|
local_subnet = find_subnet (taddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Listen on the specified (or default) port on each specified
|
/* Listen on the specified (or default) port on each specified
|
||||||
(or default) IP address. */
|
(or default) IP address. */
|
||||||
@@ -164,6 +184,8 @@ int main (argc, argv, envp)
|
|||||||
close (i);
|
close (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_subnets ();
|
||||||
|
|
||||||
/* Receive packets and dispatch them... */
|
/* Receive packets and dispatch them... */
|
||||||
dispatch ();
|
dispatch ();
|
||||||
|
|
||||||
@@ -191,6 +213,7 @@ void do_packet (packbuf, len, from_port, from, sock)
|
|||||||
{
|
{
|
||||||
struct packet *tp;
|
struct packet *tp;
|
||||||
struct dhcp_packet *tdp;
|
struct dhcp_packet *tdp;
|
||||||
|
struct iaddr ia;
|
||||||
|
|
||||||
if (!(tp = new_packet ("do_packet")))
|
if (!(tp = new_packet ("do_packet")))
|
||||||
return;
|
return;
|
||||||
@@ -205,12 +228,29 @@ void do_packet (packbuf, len, from_port, from, sock)
|
|||||||
tp -> client_port = from_port;
|
tp -> client_port = from_port;
|
||||||
tp -> client_addr = from;
|
tp -> client_addr = from;
|
||||||
tp -> client_sock = sock;
|
tp -> client_sock = sock;
|
||||||
parse_options (tp);
|
|
||||||
if (tp -> options_valid &&
|
/* If this came through a gateway, find the corresponding subnet... */
|
||||||
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
|
if (tp -> raw -> giaddr.s_addr) {
|
||||||
dhcp (tp);
|
ia.len = 4;
|
||||||
else
|
memcpy (ia.iabuf, &tp -> raw -> giaddr, 4);
|
||||||
bootp (tp);
|
tp -> subnet = find_subnet (ia);
|
||||||
|
} else {
|
||||||
|
tp -> subnet = local_subnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the subnet from whence this packet came is unknown to us,
|
||||||
|
drop it on the floor... */
|
||||||
|
if (!tp -> subnet)
|
||||||
|
note ("Packet from unknown subnet: %s",
|
||||||
|
inet_ntoa (tp -> raw -> giaddr));
|
||||||
|
else {
|
||||||
|
parse_options (tp);
|
||||||
|
if (tp -> options_valid &&
|
||||||
|
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
|
||||||
|
dhcp (tp);
|
||||||
|
else
|
||||||
|
bootp (tp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_packet (tp)
|
void dump_packet (tp)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
range 204.254.239.11 204.254.239.254 255.255.255.0;
|
range 204.254.239.11 204.254.239.17 255.255.255.0;
|
||||||
|
range 204.254.240.11 204.254.240.12 255.255.255.0;
|
||||||
|
|
||||||
host minuet
|
host minuet
|
||||||
hardware ethernet 08:00:2b:35:0c:18
|
hardware ethernet 08:00:2b:35:0c:18
|
||||||
|
17
dhcpd.h
17
dhcpd.h
@@ -53,6 +53,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cdefs.h"
|
#include "cdefs.h"
|
||||||
@@ -70,6 +71,7 @@ struct packet {
|
|||||||
int client_port;
|
int client_port;
|
||||||
struct iaddr client_addr;
|
struct iaddr client_addr;
|
||||||
int client_sock;
|
int client_sock;
|
||||||
|
struct subnet *subnet;
|
||||||
struct {
|
struct {
|
||||||
int len;
|
int len;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
@@ -91,6 +93,10 @@ struct host_decl {
|
|||||||
char *filename;
|
char *filename;
|
||||||
char *server_name;
|
char *server_name;
|
||||||
struct tree_cache *fixed_addr;
|
struct tree_cache *fixed_addr;
|
||||||
|
struct tree_cache *ciaddr;
|
||||||
|
struct tree_cache *yiaddr;
|
||||||
|
struct tree_cache *siaddr;
|
||||||
|
struct tree_cache *giaddr;
|
||||||
struct tree_cache *options [256];
|
struct tree_cache *options [256];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,13 +112,18 @@ struct lease {
|
|||||||
struct subnet *contain;
|
struct subnet *contain;
|
||||||
struct hardware hardware_addr;
|
struct hardware hardware_addr;
|
||||||
int state;
|
int state;
|
||||||
|
int xid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subnet {
|
struct subnet {
|
||||||
|
struct subnet *next;
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
struct iaddr netmask;
|
struct iaddr netmask;
|
||||||
|
TIME default_lease_time;
|
||||||
|
TIME max_lease_time;
|
||||||
struct lease *leases;
|
struct lease *leases;
|
||||||
struct lease *insertion_point;
|
struct lease *insertion_point;
|
||||||
|
struct lease *last_lease;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Bitmask of dhcp option codes. */
|
/* Bitmask of dhcp option codes. */
|
||||||
@@ -162,6 +173,8 @@ int parse_warn PROTO ((char *, ...));
|
|||||||
|
|
||||||
/* dhcpd.c */
|
/* dhcpd.c */
|
||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
|
TIME default_lease_time;
|
||||||
|
TIME max_lease_time;
|
||||||
extern u_int32_t *server_addrlist;
|
extern u_int32_t *server_addrlist;
|
||||||
extern int server_addrcount;
|
extern int server_addrcount;
|
||||||
extern u_int16_t server_port;
|
extern u_int16_t server_port;
|
||||||
@@ -225,8 +238,11 @@ extern struct subnet *find_subnet (struct iaddr);
|
|||||||
void enter_subnet (struct subnet *);
|
void enter_subnet (struct subnet *);
|
||||||
void enter_lease PROTO ((struct lease *));
|
void enter_lease PROTO ((struct lease *));
|
||||||
void supersede_lease PROTO ((struct lease *, struct lease *));
|
void supersede_lease PROTO ((struct lease *, struct lease *));
|
||||||
|
void release_lease PROTO ((struct lease *));
|
||||||
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
|
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
|
||||||
|
struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
|
||||||
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
|
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
|
||||||
|
void dump_subnets PROTO ((void));
|
||||||
|
|
||||||
/* alloc.c */
|
/* alloc.c */
|
||||||
VOIDPTR dmalloc PROTO ((int, char *));
|
VOIDPTR dmalloc PROTO ((int, char *));
|
||||||
@@ -251,6 +267,7 @@ void free_tree PROTO ((struct tree *, char *));
|
|||||||
|
|
||||||
/* print.c */
|
/* print.c */
|
||||||
char *print_hw_addr PROTO ((int, int, unsigned char *));
|
char *print_hw_addr PROTO ((int, int, unsigned char *));
|
||||||
|
void print_lease PROTO ((struct lease *));
|
||||||
|
|
||||||
/* socket.c */
|
/* socket.c */
|
||||||
u_int32_t *get_interface_list PROTO ((int *));
|
u_int32_t *get_interface_list PROTO ((int *));
|
||||||
|
@@ -64,7 +64,11 @@
|
|||||||
#define LEASE 271
|
#define LEASE 271
|
||||||
#define RANGE 272
|
#define RANGE 272
|
||||||
#define PACKET 273
|
#define PACKET 273
|
||||||
#define LAST_TOKEN PACKET
|
#define CIADDR 274
|
||||||
|
#define YIADDR 275
|
||||||
|
#define SIADDR 276
|
||||||
|
#define GIADDR 277
|
||||||
|
#define LAST_TOKEN GIADDR
|
||||||
|
|
||||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||||
(x) <= LAST_TOKEN && \
|
(x) <= LAST_TOKEN && \
|
||||||
|
4
hash.c
4
hash.c
@@ -103,6 +103,7 @@ void add_hash (table, name, len, pointer)
|
|||||||
bp -> name = name;
|
bp -> name = name;
|
||||||
bp -> value = pointer;
|
bp -> value = pointer;
|
||||||
bp -> next = table -> buckets [hashno];
|
bp -> next = table -> buckets [hashno];
|
||||||
|
bp -> len = len;
|
||||||
table -> buckets [hashno] = bp;
|
table -> buckets [hashno] = bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,10 +141,11 @@ unsigned char *hash_lookup (table, name, len)
|
|||||||
struct hash_bucket *bp;
|
struct hash_bucket *bp;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
|
||||||
if (len == bp -> len
|
if (len == bp -> len
|
||||||
&& !memcmp (bp -> name, name, len))
|
&& !memcmp (bp -> name, name, len))
|
||||||
return bp -> value;
|
return bp -> value;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
|
||||||
if (!strcmp (bp -> name, name))
|
if (!strcmp (bp -> name, name))
|
||||||
|
@@ -53,6 +53,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cdefs.h"
|
#include "cdefs.h"
|
||||||
@@ -70,6 +71,7 @@ struct packet {
|
|||||||
int client_port;
|
int client_port;
|
||||||
struct iaddr client_addr;
|
struct iaddr client_addr;
|
||||||
int client_sock;
|
int client_sock;
|
||||||
|
struct subnet *subnet;
|
||||||
struct {
|
struct {
|
||||||
int len;
|
int len;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
@@ -91,6 +93,10 @@ struct host_decl {
|
|||||||
char *filename;
|
char *filename;
|
||||||
char *server_name;
|
char *server_name;
|
||||||
struct tree_cache *fixed_addr;
|
struct tree_cache *fixed_addr;
|
||||||
|
struct tree_cache *ciaddr;
|
||||||
|
struct tree_cache *yiaddr;
|
||||||
|
struct tree_cache *siaddr;
|
||||||
|
struct tree_cache *giaddr;
|
||||||
struct tree_cache *options [256];
|
struct tree_cache *options [256];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,13 +112,18 @@ struct lease {
|
|||||||
struct subnet *contain;
|
struct subnet *contain;
|
||||||
struct hardware hardware_addr;
|
struct hardware hardware_addr;
|
||||||
int state;
|
int state;
|
||||||
|
int xid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subnet {
|
struct subnet {
|
||||||
|
struct subnet *next;
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
struct iaddr netmask;
|
struct iaddr netmask;
|
||||||
|
TIME default_lease_time;
|
||||||
|
TIME max_lease_time;
|
||||||
struct lease *leases;
|
struct lease *leases;
|
||||||
struct lease *insertion_point;
|
struct lease *insertion_point;
|
||||||
|
struct lease *last_lease;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Bitmask of dhcp option codes. */
|
/* Bitmask of dhcp option codes. */
|
||||||
@@ -162,6 +173,8 @@ int parse_warn PROTO ((char *, ...));
|
|||||||
|
|
||||||
/* dhcpd.c */
|
/* dhcpd.c */
|
||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
|
TIME default_lease_time;
|
||||||
|
TIME max_lease_time;
|
||||||
extern u_int32_t *server_addrlist;
|
extern u_int32_t *server_addrlist;
|
||||||
extern int server_addrcount;
|
extern int server_addrcount;
|
||||||
extern u_int16_t server_port;
|
extern u_int16_t server_port;
|
||||||
@@ -225,8 +238,11 @@ extern struct subnet *find_subnet (struct iaddr);
|
|||||||
void enter_subnet (struct subnet *);
|
void enter_subnet (struct subnet *);
|
||||||
void enter_lease PROTO ((struct lease *));
|
void enter_lease PROTO ((struct lease *));
|
||||||
void supersede_lease PROTO ((struct lease *, struct lease *));
|
void supersede_lease PROTO ((struct lease *, struct lease *));
|
||||||
|
void release_lease PROTO ((struct lease *));
|
||||||
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
|
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
|
||||||
|
struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
|
||||||
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
|
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
|
||||||
|
void dump_subnets PROTO ((void));
|
||||||
|
|
||||||
/* alloc.c */
|
/* alloc.c */
|
||||||
VOIDPTR dmalloc PROTO ((int, char *));
|
VOIDPTR dmalloc PROTO ((int, char *));
|
||||||
@@ -251,6 +267,7 @@ void free_tree PROTO ((struct tree *, char *));
|
|||||||
|
|
||||||
/* print.c */
|
/* print.c */
|
||||||
char *print_hw_addr PROTO ((int, int, unsigned char *));
|
char *print_hw_addr PROTO ((int, int, unsigned char *));
|
||||||
|
void print_lease PROTO ((struct lease *));
|
||||||
|
|
||||||
/* socket.c */
|
/* socket.c */
|
||||||
u_int32_t *get_interface_list PROTO ((int *));
|
u_int32_t *get_interface_list PROTO ((int *));
|
||||||
|
@@ -64,7 +64,11 @@
|
|||||||
#define LEASE 271
|
#define LEASE 271
|
||||||
#define RANGE 272
|
#define RANGE 272
|
||||||
#define PACKET 273
|
#define PACKET 273
|
||||||
#define LAST_TOKEN PACKET
|
#define CIADDR 274
|
||||||
|
#define YIADDR 275
|
||||||
|
#define SIADDR 276
|
||||||
|
#define GIADDR 277
|
||||||
|
#define LAST_TOKEN GIADDR
|
||||||
|
|
||||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||||
(x) <= LAST_TOKEN && \
|
(x) <= LAST_TOKEN && \
|
||||||
|
8
inet.c
8
inet.c
@@ -87,7 +87,7 @@ struct iaddr ip_addr (subnet, mask, host_address)
|
|||||||
j = rv.len - sizeof habuf;
|
j = rv.len - sizeof habuf;
|
||||||
for (i = sizeof habuf - 1; i >= 0; i--) {
|
for (i = sizeof habuf - 1; i >= 0; i--) {
|
||||||
if (mask.iabuf [i + j]) {
|
if (mask.iabuf [i + j]) {
|
||||||
if (habuf [i] > ~mask.iabuf [i + j]) {
|
if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
|
||||||
rv.len = 0;
|
rv.len = 0;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -97,10 +97,10 @@ struct iaddr ip_addr (subnet, mask, host_address)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv.iabuf [i + j] &= habuf [i];
|
rv.iabuf [i + j] |= habuf [i];
|
||||||
break;
|
break;
|
||||||
}
|
} else
|
||||||
rv.iabuf [i + j] = habuf [i];
|
rv.iabuf [i + j] = habuf [i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
123
memory.c
123
memory.c
@@ -48,7 +48,7 @@ static char copyright[] =
|
|||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
static struct host_decl *hosts;
|
static struct host_decl *hosts;
|
||||||
static struct hash_table *subnet_hash;
|
static struct subnet *subnets;
|
||||||
static struct hash_table *lease_uid_hash;
|
static struct hash_table *lease_uid_hash;
|
||||||
static struct hash_table *lease_ip_addr_hash;
|
static struct hash_table *lease_ip_addr_hash;
|
||||||
static struct hash_table *lease_hw_addr_hash;
|
static struct hash_table *lease_hw_addr_hash;
|
||||||
@@ -98,12 +98,10 @@ void new_address_range (low, high, netmask)
|
|||||||
struct lease *address_range, *lp, *plp;
|
struct lease *address_range, *lp, *plp;
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
int i, max;
|
int min, max, i;
|
||||||
char lowbuf [16], highbuf [16], netbuf [16];
|
char lowbuf [16], highbuf [16], netbuf [16];
|
||||||
|
|
||||||
/* Initialize the hash table if it hasn't been done yet. */
|
/* Initialize the hash table if it hasn't been done yet. */
|
||||||
if (!subnet_hash)
|
|
||||||
subnet_hash = new_hash ();
|
|
||||||
if (!lease_uid_hash)
|
if (!lease_uid_hash)
|
||||||
lease_uid_hash = new_hash ();
|
lease_uid_hash = new_hash ();
|
||||||
if (!lease_ip_addr_hash)
|
if (!lease_ip_addr_hash)
|
||||||
@@ -130,32 +128,40 @@ void new_address_range (low, high, netmask)
|
|||||||
subnet -> net = net;
|
subnet -> net = net;
|
||||||
subnet -> netmask = netmask;
|
subnet -> netmask = netmask;
|
||||||
subnet -> leases = (struct lease *)0;
|
subnet -> leases = (struct lease *)0;
|
||||||
|
subnet -> last_lease = (struct lease *)0;
|
||||||
|
subnet -> next = (struct subnet *)0;
|
||||||
|
subnet -> default_lease_time = default_lease_time;
|
||||||
|
subnet -> max_lease_time = max_lease_time;
|
||||||
enter_subnet (subnet);
|
enter_subnet (subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the high and low host addresses... */
|
/* Get the high and low host addresses... */
|
||||||
max = host_addr (high, netmask);
|
max = host_addr (high, netmask);
|
||||||
i = host_addr (low, netmask);
|
min = host_addr (low, netmask);
|
||||||
|
|
||||||
/* Allow range to be specified high-to-low as well as low-to-high. */
|
/* Allow range to be specified high-to-low as well as low-to-high. */
|
||||||
if (i > max) {
|
if (min > max) {
|
||||||
max = i;
|
max = min;
|
||||||
i = host_addr (high, netmask);
|
min = host_addr (high, netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a lease structure for each address in the range. */
|
/* Get a lease structure for each address in the range. */
|
||||||
address_range = new_leases (max - i + 1, "new_address_range");
|
address_range = new_leases (max - min + 1, "new_address_range");
|
||||||
if (!address_range) {
|
if (!address_range) {
|
||||||
strcpy (lowbuf, piaddr (low));
|
strcpy (lowbuf, piaddr (low));
|
||||||
strcpy (highbuf, piaddr (high));
|
strcpy (highbuf, piaddr (high));
|
||||||
error ("No memory for address range %s-%s.", lowbuf, highbuf);
|
error ("No memory for address range %s-%s.", lowbuf, highbuf);
|
||||||
}
|
}
|
||||||
memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
|
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
||||||
|
|
||||||
|
/* Fill in the last lease if it hasn't been already... */
|
||||||
|
if (!subnet -> last_lease)
|
||||||
|
subnet -> last_lease = &address_range [0];
|
||||||
|
|
||||||
/* Fill out the lease structures with some minimal information. */
|
/* Fill out the lease structures with some minimal information. */
|
||||||
for (; i <= max; i++) {
|
for (i = 0; i < max - min + 1; i++) {
|
||||||
address_range [i].ip_addr =
|
address_range [i].ip_addr =
|
||||||
ip_addr (subnet -> net, subnet -> netmask, i);
|
ip_addr (subnet -> net, subnet -> netmask, i + min);
|
||||||
address_range [i].starts =
|
address_range [i].starts =
|
||||||
address_range [i].timestamp = MIN_TIME;
|
address_range [i].timestamp = MIN_TIME;
|
||||||
address_range [i].ends = MIN_TIME;
|
address_range [i].ends = MIN_TIME;
|
||||||
@@ -200,13 +206,16 @@ void new_address_range (low, high, netmask)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct subnet *find_subnet (subnet)
|
struct subnet *find_subnet (addr)
|
||||||
struct iaddr subnet;
|
struct iaddr addr;
|
||||||
{
|
{
|
||||||
struct subnet *rv;
|
struct subnet *rv;
|
||||||
|
|
||||||
return (struct subnet *)hash_lookup (subnet_hash,
|
for (rv = subnets; rv; rv = rv -> next) {
|
||||||
(char *)subnet.iabuf, subnet.len);
|
if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return (struct subnet *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a new subnet into the subnet hash. */
|
/* Enter a new subnet into the subnet hash. */
|
||||||
@@ -214,8 +223,9 @@ struct subnet *find_subnet (subnet)
|
|||||||
void enter_subnet (subnet)
|
void enter_subnet (subnet)
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
add_hash (subnet_hash, (char *)subnet -> net.iabuf,
|
/* XXX Sort the nets into a balanced tree to make searching quicker. */
|
||||||
subnet -> net.len, (unsigned char *)subnet);
|
subnet -> next = subnets;
|
||||||
|
subnets = subnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a lease into the system. This is called by the parser each
|
/* Enter a lease into the system. This is called by the parser each
|
||||||
@@ -259,6 +269,11 @@ void supersede_lease (comp, lease)
|
|||||||
struct subnet *parent;
|
struct subnet *parent;
|
||||||
struct lease *lp;
|
struct lease *lp;
|
||||||
|
|
||||||
|
printf ("Supersede_lease:\n");
|
||||||
|
print_lease (comp);
|
||||||
|
print_lease (lease);
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
/* If the existing lease hasn't expired and has a different
|
/* If the existing lease hasn't expired and has a different
|
||||||
unique identifier or, if it doesn't have a unique
|
unique identifier or, if it doesn't have a unique
|
||||||
identifier, a different hardware address, then the two
|
identifier, a different hardware address, then the two
|
||||||
@@ -290,7 +305,9 @@ void supersede_lease (comp, lease)
|
|||||||
enter_uid = 1;
|
enter_uid = 1;
|
||||||
}
|
}
|
||||||
free (comp -> uid);
|
free (comp -> uid);
|
||||||
}
|
} else
|
||||||
|
enter_uid = 1;
|
||||||
|
|
||||||
if (comp -> hardware_addr.htype &&
|
if (comp -> hardware_addr.htype &&
|
||||||
((comp -> hardware_addr.hlen !=
|
((comp -> hardware_addr.hlen !=
|
||||||
lease -> hardware_addr.hlen) ||
|
lease -> hardware_addr.hlen) ||
|
||||||
@@ -303,7 +320,8 @@ void supersede_lease (comp, lease)
|
|||||||
comp -> hardware_addr.haddr,
|
comp -> hardware_addr.haddr,
|
||||||
comp -> hardware_addr.hlen);
|
comp -> hardware_addr.hlen);
|
||||||
enter_hwaddr = 1;
|
enter_hwaddr = 1;
|
||||||
}
|
} else if (!comp -> hardware_addr.htype)
|
||||||
|
enter_hwaddr = 1;
|
||||||
|
|
||||||
/* Copy the data files, but not the linkages. */
|
/* Copy the data files, but not the linkages. */
|
||||||
comp -> starts = lease -> starts;
|
comp -> starts = lease -> starts;
|
||||||
@@ -317,16 +335,16 @@ void supersede_lease (comp, lease)
|
|||||||
|
|
||||||
/* Record the lease in the uid hash if necessary. */
|
/* Record the lease in the uid hash if necessary. */
|
||||||
if (enter_uid && lease -> uid) {
|
if (enter_uid && lease -> uid) {
|
||||||
add_hash (lease_uid_hash, lease -> uid,
|
add_hash (lease_uid_hash, comp -> uid,
|
||||||
lease -> uid_len, (unsigned char *)lease);
|
comp -> uid_len, (unsigned char *)comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record it in the hardware address hash if necessary. */
|
/* Record it in the hardware address hash if necessary. */
|
||||||
if (enter_hwaddr && lease -> hardware_addr.htype) {
|
if (enter_hwaddr && lease -> hardware_addr.htype) {
|
||||||
add_hash (lease_hw_addr_hash,
|
add_hash (lease_hw_addr_hash,
|
||||||
lease -> hardware_addr.haddr,
|
comp -> hardware_addr.haddr,
|
||||||
lease -> hardware_addr.hlen,
|
comp -> hardware_addr.hlen,
|
||||||
(unsigned char *)lease);
|
(unsigned char *)comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the lease from its current place in the list. */
|
/* Remove the lease from its current place in the list. */
|
||||||
@@ -338,6 +356,9 @@ void supersede_lease (comp, lease)
|
|||||||
if (comp -> next) {
|
if (comp -> next) {
|
||||||
comp -> next -> prev = comp -> prev;
|
comp -> next -> prev = comp -> prev;
|
||||||
}
|
}
|
||||||
|
if (comp -> contain -> last_lease == comp) {
|
||||||
|
comp -> contain -> last_lease = comp -> prev;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the last insertion point... */
|
/* Find the last insertion point... */
|
||||||
if (comp == comp -> contain -> insertion_point ||
|
if (comp == comp -> contain -> insertion_point ||
|
||||||
@@ -351,18 +372,20 @@ void supersede_lease (comp, lease)
|
|||||||
/* Nothing on the list yet? Just make comp the
|
/* Nothing on the list yet? Just make comp the
|
||||||
head of the list. */
|
head of the list. */
|
||||||
comp -> contain -> leases = comp;
|
comp -> contain -> leases = comp;
|
||||||
} else if (lp -> ends <= comp -> ends) {
|
comp -> contain -> last_lease = comp;
|
||||||
|
} else if (lp -> ends > comp -> ends) {
|
||||||
/* Skip down the list until we run out of list
|
/* Skip down the list until we run out of list
|
||||||
or find a place for comp. */
|
or find a place for comp. */
|
||||||
while (lp -> next && lp -> ends < comp -> ends) {
|
while (lp -> next && lp -> ends > comp -> ends) {
|
||||||
lp = lp -> next;
|
lp = lp -> next;
|
||||||
}
|
}
|
||||||
if (lp -> ends < comp -> ends) {
|
if (lp -> ends > comp -> ends) {
|
||||||
/* If we ran out of list, put comp
|
/* If we ran out of list, put comp
|
||||||
at the end. */
|
at the end. */
|
||||||
lp -> next = comp;
|
lp -> next = comp;
|
||||||
comp -> prev = lp;
|
comp -> prev = lp;
|
||||||
comp -> next = (struct lease *)0;
|
comp -> next = (struct lease *)0;
|
||||||
|
comp -> contain -> last_lease = comp;
|
||||||
} else {
|
} else {
|
||||||
/* If we didn't, put it between lp and
|
/* If we didn't, put it between lp and
|
||||||
the previous item on the list. */
|
the previous item on the list. */
|
||||||
@@ -372,12 +395,12 @@ void supersede_lease (comp, lease)
|
|||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Skip ip the list until we run out of list
|
/* Skip up the list until we run out of list
|
||||||
or find a place for comp. */
|
or find a place for comp. */
|
||||||
while (lp -> prev && lp -> ends > comp -> ends) {
|
while (lp -> prev && lp -> ends < comp -> ends) {
|
||||||
lp = lp -> prev;
|
lp = lp -> prev;
|
||||||
}
|
}
|
||||||
if (lp -> ends > comp -> ends) {
|
if (lp -> ends < comp -> ends) {
|
||||||
/* If we ran out of list, put comp
|
/* If we ran out of list, put comp
|
||||||
at the beginning. */
|
at the beginning. */
|
||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
@@ -397,6 +420,18 @@ void supersede_lease (comp, lease)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release the specified lease and re-hash it as appropriate. */
|
||||||
|
|
||||||
|
void release_lease (lease)
|
||||||
|
struct lease *lease;
|
||||||
|
{
|
||||||
|
struct lease lt;
|
||||||
|
|
||||||
|
lease -> ends = 0;
|
||||||
|
lt = *lease;
|
||||||
|
supersede_lease (lease, <);
|
||||||
|
}
|
||||||
|
|
||||||
/* Locate the lease associated with a given IP address... */
|
/* Locate the lease associated with a given IP address... */
|
||||||
|
|
||||||
struct lease *find_lease_by_ip_addr (addr)
|
struct lease *find_lease_by_ip_addr (addr)
|
||||||
@@ -417,3 +452,29 @@ struct lease *find_lease_by_uid (uid, len)
|
|||||||
return lease;
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lease *find_lease_by_hw_addr (hwaddr, hwlen)
|
||||||
|
unsigned char *hwaddr;
|
||||||
|
int hwlen;
|
||||||
|
{
|
||||||
|
struct lease *lease = (struct lease *)hash_lookup (lease_hw_addr_hash,
|
||||||
|
hwaddr, hwlen);
|
||||||
|
return lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_subnets ()
|
||||||
|
{
|
||||||
|
struct lease *l;
|
||||||
|
struct subnet *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (s = subnets; s; s = s -> next) {
|
||||||
|
printf ("Subnet %s", piaddr (s -> net));
|
||||||
|
printf (" netmask %s\n",
|
||||||
|
piaddr (s -> netmask));
|
||||||
|
for (l = s -> leases; l; l = l -> next) {
|
||||||
|
print_lease (l);
|
||||||
|
}
|
||||||
|
printf ("Last Lease:\n");
|
||||||
|
print_lease (s -> last_lease);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -94,8 +94,6 @@ void parse_option_buffer (packet, buffer, length)
|
|||||||
int len;
|
int len;
|
||||||
int code;
|
int code;
|
||||||
|
|
||||||
printf ("parse_option_buffer (%x, %x, %d)\n",
|
|
||||||
(unsigned long)packet, (unsigned long)buffer, length);
|
|
||||||
for (s = buffer; *s != DHO_END && s < end; ) {
|
for (s = buffer; *s != DHO_END && s < end; ) {
|
||||||
code = s [0];
|
code = s [0];
|
||||||
/* Pad options don't have a length - just skip them. */
|
/* Pad options don't have a length - just skip them. */
|
||||||
@@ -126,8 +124,6 @@ printf ("parse_option_buffer (%x, %x, %d)\n",
|
|||||||
t [len] = 0;
|
t [len] = 0;
|
||||||
packet -> options [code].len = len;
|
packet -> options [code].len = len;
|
||||||
packet -> options [code].data = t;
|
packet -> options [code].data = t;
|
||||||
printf ("%s=%s\n", dhcp_options [code].name,
|
|
||||||
pretty_print_option (code, t, len));
|
|
||||||
} else {
|
} else {
|
||||||
/* If it's a repeat, concatenate it to whatever
|
/* If it's a repeat, concatenate it to whatever
|
||||||
we last saw. This is really only required
|
we last saw. This is really only required
|
||||||
|
45
print.c
45
print.c
@@ -55,13 +55,46 @@ char *print_hw_addr (htype, hlen, data)
|
|||||||
char *s;
|
char *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s = habuf;
|
if (htype == 0 || hlen == 0) {
|
||||||
for (i = 0; i < hlen; i++) {
|
strcpy (habuf, "<null>");
|
||||||
sprintf (s, "%x", data [i]);
|
} else {
|
||||||
s += strlen (s);
|
s = habuf;
|
||||||
*s++ = ':';
|
for (i = 0; i < hlen; i++) {
|
||||||
|
sprintf (s, "%x", data [i]);
|
||||||
|
s += strlen (s);
|
||||||
|
*s++ = ':';
|
||||||
|
}
|
||||||
|
*--s = 0;
|
||||||
}
|
}
|
||||||
*--s = 0;
|
|
||||||
return habuf;
|
return habuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_lease (lease)
|
||||||
|
struct lease *lease;
|
||||||
|
{
|
||||||
|
struct tm *t;
|
||||||
|
char tbuf [32];
|
||||||
|
|
||||||
|
printf (" Lease %s",
|
||||||
|
piaddr (lease -> ip_addr));
|
||||||
|
|
||||||
|
t = gmtime (&lease -> starts);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" start %s", tbuf);
|
||||||
|
|
||||||
|
t = gmtime (&lease -> ends);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" end %s", tbuf);
|
||||||
|
|
||||||
|
t = gmtime (&lease -> timestamp);
|
||||||
|
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
|
||||||
|
printf (" stamp %s\n", tbuf);
|
||||||
|
|
||||||
|
printf (" hardware addr = %s",
|
||||||
|
print_hw_addr (lease -> hardware_addr.htype,
|
||||||
|
lease -> hardware_addr.hlen,
|
||||||
|
lease -> hardware_addr.haddr));
|
||||||
|
printf (" host %s state %x\n",
|
||||||
|
lease -> host ? lease -> host -> name : "<none>",
|
||||||
|
lease -> state);
|
||||||
|
}
|
||||||
|
@@ -234,6 +234,22 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl);
|
parse_option_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
|
case CIADDR:
|
||||||
|
decl -> ciaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case YIADDR:
|
||||||
|
decl -> yiaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case SIADDR:
|
||||||
|
decl -> siaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
|
case GIADDR:
|
||||||
|
decl -> giaddr =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
parse_warn ("expecting a dhcp option declaration.");
|
parse_warn ("expecting a dhcp option declaration.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
|
200
server/dhcp.c
200
server/dhcp.c
@@ -49,5 +49,205 @@ static char copyright[] =
|
|||||||
void dhcp (packet)
|
void dhcp (packet)
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
{
|
{
|
||||||
|
struct lease *uid_lease, *ip_lease, *hw_lease, *lease;
|
||||||
|
struct iaddr cip;
|
||||||
|
struct lease lt;
|
||||||
|
TIME lease_time;
|
||||||
|
|
||||||
dump_packet (packet);
|
dump_packet (packet);
|
||||||
|
|
||||||
|
/* Try to find a lease that's been assigned to the specified
|
||||||
|
unique client identifier. */
|
||||||
|
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len)
|
||||||
|
uid_lease =
|
||||||
|
find_lease_by_uid (packet -> options
|
||||||
|
[DHO_DHCP_CLIENT_IDENTIFIER].data,
|
||||||
|
packet -> options
|
||||||
|
[DHO_DHCP_CLIENT_IDENTIFIER].len);
|
||||||
|
else
|
||||||
|
uid_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
/* Try to find a lease that's been attached to the client's
|
||||||
|
hardware address... */
|
||||||
|
hw_lease = find_lease_by_hw_addr (packet -> raw -> chaddr,
|
||||||
|
packet -> raw -> hlen);
|
||||||
|
|
||||||
|
/* Try to find a lease that's been allocated to the client's
|
||||||
|
IP address. */
|
||||||
|
if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len &&
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len
|
||||||
|
<= sizeof cip.iabuf) {
|
||||||
|
cip.len = packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len;
|
||||||
|
memcpy (cip.iabuf,
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data,
|
||||||
|
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len);
|
||||||
|
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
|
||||||
|
ip_lease = find_lease_by_ip_addr (cip);
|
||||||
|
} else
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
printf ("First blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toss extra pointers to the same lease... */
|
||||||
|
if (ip_lease == hw_lease)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
if (hw_lease == uid_lease)
|
||||||
|
hw_lease = (struct lease *)0;
|
||||||
|
if (ip_lease == uid_lease)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
printf ("Second blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got an ip address lease, make sure it isn't assigned to
|
||||||
|
some *other* client! If it was assigned to this client, we'd
|
||||||
|
have zeroed it out above, so the only way we can take it at this
|
||||||
|
point is if some other client had it but it's timed out, or if no
|
||||||
|
other client has ever had it. */
|
||||||
|
if (ip_lease &&
|
||||||
|
ip_lease -> ends >= cur_time)
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
|
||||||
|
/* Now eliminate leases that are on the wrong subnet... */
|
||||||
|
if (ip_lease && packet -> subnet != ip_lease -> contain) {
|
||||||
|
release_lease (ip_lease);
|
||||||
|
ip_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
if (uid_lease && packet -> subnet != uid_lease -> contain) {
|
||||||
|
release_lease (uid_lease);
|
||||||
|
uid_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
if (hw_lease && packet -> subnet != hw_lease -> contain) {
|
||||||
|
release_lease (hw_lease);
|
||||||
|
hw_lease = (struct lease *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Third blush:\n");
|
||||||
|
if (ip_lease) {
|
||||||
|
printf ("ip_lease: ");
|
||||||
|
print_lease (ip_lease);
|
||||||
|
}
|
||||||
|
if (hw_lease) {
|
||||||
|
printf ("hw_lease: ");
|
||||||
|
print_lease (hw_lease);
|
||||||
|
}
|
||||||
|
if (uid_lease) {
|
||||||
|
printf ("uid_lease: ");
|
||||||
|
print_lease (uid_lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point, if ip_lease is nonzero, we can assign it to
|
||||||
|
this client. */
|
||||||
|
lease = ip_lease;
|
||||||
|
|
||||||
|
/* If we got a lease that matched the client identifier, we may want
|
||||||
|
to use it, but if we already have a lease we like, we must free
|
||||||
|
the lease that matched the client identifier. */
|
||||||
|
if (uid_lease) {
|
||||||
|
if (lease) {
|
||||||
|
release_lease (uid_lease);
|
||||||
|
} else
|
||||||
|
lease = uid_lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The lease that matched the hardware address is treated likewise. */
|
||||||
|
if (hw_lease) {
|
||||||
|
if (lease) {
|
||||||
|
release_lease (hw_lease);
|
||||||
|
} else
|
||||||
|
lease = hw_lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't find a lease, try to allocate one... */
|
||||||
|
if (!lease) {
|
||||||
|
lease = packet -> subnet -> last_lease;
|
||||||
|
|
||||||
|
/* If there are no leases in that subnet that have
|
||||||
|
expired, we have nothing to offer this client. */
|
||||||
|
if (lease -> ends >= cur_time) {
|
||||||
|
note ("no free leases on subnet %s",
|
||||||
|
piaddr (packet -> subnet -> net));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lease -> host = (struct host_decl *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point, we have a lease that we can offer the client.
|
||||||
|
Now we construct a lease structure that contains what we want,
|
||||||
|
and call supersede_lease to do the right thing with it. */
|
||||||
|
|
||||||
|
memset (<, 0, sizeof lt);
|
||||||
|
|
||||||
|
/* Use the ip address of the lease that we finally found in
|
||||||
|
the database. */
|
||||||
|
lt.ip_addr = lease -> ip_addr;
|
||||||
|
|
||||||
|
/* Start now. */
|
||||||
|
lt.starts = cur_time;
|
||||||
|
|
||||||
|
/* Figure out how long a lease to assign. */
|
||||||
|
if (packet -> options [DHO_DHCP_LEASE_TIME].len == 4) {
|
||||||
|
lease_time = getULong (packet ->
|
||||||
|
options [DHO_DHCP_LEASE_TIME].data);
|
||||||
|
|
||||||
|
/* Don't let the client ask for a longer lease than
|
||||||
|
is supported for this subnet. */
|
||||||
|
if (lease_time > packet -> subnet -> max_lease_time)
|
||||||
|
lease_time = packet -> subnet -> max_lease_time;
|
||||||
|
} else
|
||||||
|
lease_time = packet -> subnet -> default_lease_time;
|
||||||
|
lt.ends = cur_time + lease_time;
|
||||||
|
|
||||||
|
lt.timestamp = cur_time;
|
||||||
|
|
||||||
|
/* Record the uid, if given... */
|
||||||
|
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len) {
|
||||||
|
lt.uid_len =
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len;
|
||||||
|
lt.uid = packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data;
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data =
|
||||||
|
(unsigned char *)0;
|
||||||
|
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record the hardware address, if given... */
|
||||||
|
lt.hardware_addr.hlen = packet -> raw -> hlen;
|
||||||
|
lt.hardware_addr.htype = packet -> raw -> htype;
|
||||||
|
memcpy (lt.hardware_addr.haddr, packet -> raw -> chaddr,
|
||||||
|
packet -> raw -> hlen);
|
||||||
|
|
||||||
|
lt.host = lease -> host; /* XXX */
|
||||||
|
lt.contain = lease -> contain;
|
||||||
|
|
||||||
|
/* Record the transaction id... */
|
||||||
|
lt.xid = packet -> raw -> xid;
|
||||||
|
|
||||||
|
/* Install the new information about this lease in the database. */
|
||||||
|
supersede_lease (lease, <);
|
||||||
|
|
||||||
|
/* Send a response to the client... */
|
||||||
|
dump_subnets ();
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,10 @@ static char copyright[] =
|
|||||||
static void usage PROTO ((void));
|
static void usage PROTO ((void));
|
||||||
|
|
||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
|
TIME default_lease_time = 43200; /* 12 hours... */
|
||||||
|
TIME max_lease_time = 86400; /* 24 hours... */
|
||||||
|
|
||||||
|
struct subnet *local_subnet;
|
||||||
u_int32_t *server_addrlist;
|
u_int32_t *server_addrlist;
|
||||||
int server_addrcount;
|
int server_addrcount;
|
||||||
u_int16_t server_port;
|
u_int16_t server_port;
|
||||||
@@ -63,6 +66,7 @@ int main (argc, argv, envp)
|
|||||||
int port = 0;
|
int port = 0;
|
||||||
int i;
|
int i;
|
||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
|
struct iaddr taddr;
|
||||||
u_int32_t *addrlist = (u_int32_t *)0;
|
u_int32_t *addrlist = (u_int32_t *)0;
|
||||||
int addrcount = 0;
|
int addrcount = 0;
|
||||||
struct tree *addrtree = (struct tree *)0;
|
struct tree *addrtree = (struct tree *)0;
|
||||||
@@ -148,7 +152,23 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
taddr.len = 0;
|
||||||
server_addrlist = get_interface_list (&server_addrcount);
|
server_addrlist = get_interface_list (&server_addrcount);
|
||||||
|
for (i = 0; i < server_addrcount; i++) {
|
||||||
|
struct sockaddr_in foo;
|
||||||
|
foo.sin_addr.s_addr = server_addrlist [i];
|
||||||
|
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
||||||
|
|
||||||
|
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
||||||
|
if (taddr.len) {
|
||||||
|
error ("dhcpd currently does not support "
|
||||||
|
"multiple interfaces");
|
||||||
|
}
|
||||||
|
taddr.len = 4;
|
||||||
|
memcpy (taddr.iabuf, &server_addrlist [i], 4);
|
||||||
|
local_subnet = find_subnet (taddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Listen on the specified (or default) port on each specified
|
/* Listen on the specified (or default) port on each specified
|
||||||
(or default) IP address. */
|
(or default) IP address. */
|
||||||
@@ -164,6 +184,8 @@ int main (argc, argv, envp)
|
|||||||
close (i);
|
close (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_subnets ();
|
||||||
|
|
||||||
/* Receive packets and dispatch them... */
|
/* Receive packets and dispatch them... */
|
||||||
dispatch ();
|
dispatch ();
|
||||||
|
|
||||||
@@ -191,6 +213,7 @@ void do_packet (packbuf, len, from_port, from, sock)
|
|||||||
{
|
{
|
||||||
struct packet *tp;
|
struct packet *tp;
|
||||||
struct dhcp_packet *tdp;
|
struct dhcp_packet *tdp;
|
||||||
|
struct iaddr ia;
|
||||||
|
|
||||||
if (!(tp = new_packet ("do_packet")))
|
if (!(tp = new_packet ("do_packet")))
|
||||||
return;
|
return;
|
||||||
@@ -205,12 +228,29 @@ void do_packet (packbuf, len, from_port, from, sock)
|
|||||||
tp -> client_port = from_port;
|
tp -> client_port = from_port;
|
||||||
tp -> client_addr = from;
|
tp -> client_addr = from;
|
||||||
tp -> client_sock = sock;
|
tp -> client_sock = sock;
|
||||||
parse_options (tp);
|
|
||||||
if (tp -> options_valid &&
|
/* If this came through a gateway, find the corresponding subnet... */
|
||||||
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
|
if (tp -> raw -> giaddr.s_addr) {
|
||||||
dhcp (tp);
|
ia.len = 4;
|
||||||
else
|
memcpy (ia.iabuf, &tp -> raw -> giaddr, 4);
|
||||||
bootp (tp);
|
tp -> subnet = find_subnet (ia);
|
||||||
|
} else {
|
||||||
|
tp -> subnet = local_subnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the subnet from whence this packet came is unknown to us,
|
||||||
|
drop it on the floor... */
|
||||||
|
if (!tp -> subnet)
|
||||||
|
note ("Packet from unknown subnet: %s",
|
||||||
|
inet_ntoa (tp -> raw -> giaddr));
|
||||||
|
else {
|
||||||
|
parse_options (tp);
|
||||||
|
if (tp -> options_valid &&
|
||||||
|
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
|
||||||
|
dhcp (tp);
|
||||||
|
else
|
||||||
|
bootp (tp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_packet (tp)
|
void dump_packet (tp)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
range 204.254.239.11 204.254.239.254 255.255.255.0;
|
range 204.254.239.11 204.254.239.17 255.255.255.0;
|
||||||
|
range 204.254.240.11 204.254.240.12 255.255.255.0;
|
||||||
|
|
||||||
host minuet
|
host minuet
|
||||||
hardware ethernet 08:00:2b:35:0c:18
|
hardware ethernet 08:00:2b:35:0c:18
|
||||||
|
3
socket.c
3
socket.c
@@ -184,6 +184,9 @@ void dispatch ()
|
|||||||
/* Wait for a packet or a timeout... XXX */
|
/* Wait for a packet or a timeout... XXX */
|
||||||
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
|
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
|
||||||
|
|
||||||
|
/* Get the current time... */
|
||||||
|
GET_TIME (&cur_time);
|
||||||
|
|
||||||
/* Not likely to be transitory... */
|
/* Not likely to be transitory... */
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
error ("select: %m");
|
error ("select: %m");
|
||||||
|
Reference in New Issue
Block a user