mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-02 15:25:48 +00:00
Incremental changes to support DHCP protocol
This commit is contained in:
@@ -105,12 +105,15 @@ int main (argc, argv, envp)
|
|||||||
FD_ZERO (&w);
|
FD_ZERO (&w);
|
||||||
FD_ZERO (&x);
|
FD_ZERO (&x);
|
||||||
FD_SET (sock, &r);
|
FD_SET (sock, &r);
|
||||||
|
FD_SET (sock, &w);
|
||||||
|
FD_SET (sock, &x);
|
||||||
FD_SET (0, &r); /* stdin */
|
FD_SET (0, &r); /* stdin */
|
||||||
|
|
||||||
if (select (sock + 1, &r, &w, &x, (struct timeval *)0) < 0) {
|
if (select (sock + 1, &r, &w, &x, (struct timeval *)0) < 0) {
|
||||||
error ("select: %m");
|
error ("select: %m");
|
||||||
}
|
}
|
||||||
if (FD_ISSET (sock, &r)) {
|
if (FD_ISSET (sock, &r) || FD_ISSET (sock, &w)
|
||||||
|
|| FD_ISSET (sock, &x)) {
|
||||||
if ((result =
|
if ((result =
|
||||||
recvfrom (sock, packbuf, sizeof packbuf, 0,
|
recvfrom (sock, packbuf, sizeof packbuf, 0,
|
||||||
(struct sockaddr *)&from, &fromlen))
|
(struct sockaddr *)&from, &fromlen))
|
||||||
@@ -188,7 +191,7 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cons_options ((struct packet *)0,
|
cons_options ((struct packet *)0,
|
||||||
&outgoing, &decl, bufs);
|
&outgoing, decl.options, bufs);
|
||||||
|
|
||||||
if (decl.ciaddr) {
|
if (decl.ciaddr) {
|
||||||
tree_evaluate (decl.ciaddr);
|
tree_evaluate (decl.ciaddr);
|
||||||
|
@@ -277,6 +277,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "iaddr"))
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
return CIADDR;
|
return CIADDR;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (!strcasecmp (atom + 1, "efault-lease-time"))
|
||||||
|
return DEFAULT_LEASE_TIME;
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (!strcasecmp (atom + 1, "thernet"))
|
if (!strcasecmp (atom + 1, "thernet"))
|
||||||
return ETHERNET;
|
return ETHERNET;
|
||||||
@@ -303,6 +307,14 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "ease"))
|
if (!strcasecmp (atom + 1, "ease"))
|
||||||
return LEASE;
|
return LEASE;
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
if (!strcasecmp (atom + 1, "ax-lease-time"))
|
||||||
|
return MAX_LEASE_TIME;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (!strcasecmp (atom + 1, "etmask"))
|
||||||
|
return NETMASK;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!strcasecmp (atom + 1, "acket"))
|
if (!strcasecmp (atom + 1, "acket"))
|
||||||
return PACKET;
|
return PACKET;
|
||||||
@@ -320,6 +332,8 @@ static int intern (atom, dfv)
|
|||||||
return STARTS;
|
return STARTS;
|
||||||
if (!strcasecmp (atom + 1, "iaddr"))
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
return SIADDR;
|
return SIADDR;
|
||||||
|
if (!strcasecmp (atom + 1, "ubnet"))
|
||||||
|
return SUBNET;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (!strcasecmp (atom + 1, "timestamp"))
|
if (!strcasecmp (atom + 1, "timestamp"))
|
||||||
|
@@ -92,11 +92,11 @@ struct host_decl *find_host_by_addr (htype, haddr, hlen)
|
|||||||
return (struct host_decl *)0;
|
return (struct host_decl *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_address_range (low, high, netmask)
|
void new_address_range (low, high, subnet)
|
||||||
struct iaddr low, high, netmask;
|
struct iaddr low, high;
|
||||||
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
struct lease *address_range, *lp, *plp;
|
struct lease *address_range, *lp, *plp;
|
||||||
struct subnet *subnet;
|
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
int min, max, i;
|
int min, max, i;
|
||||||
char lowbuf [16], highbuf [16], netbuf [16];
|
char lowbuf [16], highbuf [16], netbuf [16];
|
||||||
@@ -110,39 +110,23 @@ void new_address_range (low, high, netmask)
|
|||||||
lease_hw_addr_hash = new_hash ();
|
lease_hw_addr_hash = new_hash ();
|
||||||
|
|
||||||
/* Make sure that high and low addresses are in same subnet. */
|
/* Make sure that high and low addresses are in same subnet. */
|
||||||
net = subnet_number (low, netmask);
|
net = subnet_number (low, subnet -> netmask);
|
||||||
if (!addr_eq (net, subnet_number (high, netmask))) {
|
if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
|
||||||
strcpy (lowbuf, piaddr (low));
|
strcpy (lowbuf, piaddr (low));
|
||||||
strcpy (highbuf, piaddr (high));
|
strcpy (highbuf, piaddr (high));
|
||||||
strcpy (netbuf, piaddr (netmask));
|
strcpy (netbuf, piaddr (subnet -> netmask));
|
||||||
error ("Address range %s to %s, netmask %s spans %s!",
|
error ("Address range %s to %s, netmask %s spans %s!",
|
||||||
lowbuf, highbuf, netbuf, "multiple subnets");
|
lowbuf, highbuf, netbuf, "multiple subnets");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if this subnet is already known - if not, make a new one. */
|
|
||||||
subnet = find_subnet (net);
|
|
||||||
if (!subnet) {
|
|
||||||
subnet = new_subnet ("new_address_range");
|
|
||||||
if (!subnet)
|
|
||||||
error ("No memory for new subnet");
|
|
||||||
subnet -> net = net;
|
|
||||||
subnet -> netmask = netmask;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the high and low host addresses... */
|
/* Get the high and low host addresses... */
|
||||||
max = host_addr (high, netmask);
|
max = host_addr (high, subnet -> netmask);
|
||||||
min = host_addr (low, netmask);
|
min = host_addr (low, subnet -> 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 (min > max) {
|
if (min > max) {
|
||||||
max = min;
|
max = min;
|
||||||
min = host_addr (high, netmask);
|
min = host_addr (high, subnet -> netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a lease structure for each address in the range. */
|
/* Get a lease structure for each address in the range. */
|
||||||
@@ -155,8 +139,9 @@ void new_address_range (low, high, netmask)
|
|||||||
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
||||||
|
|
||||||
/* Fill in the last lease if it hasn't been already... */
|
/* Fill in the last lease if it hasn't been already... */
|
||||||
if (!subnet -> last_lease)
|
if (!subnet -> last_lease) {
|
||||||
subnet -> last_lease = &address_range [0];
|
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 = 0; i < max - min + 1; i++) {
|
for (i = 0; i < max - min + 1; i++) {
|
||||||
@@ -269,11 +254,6 @@ 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
|
||||||
@@ -325,7 +305,6 @@ printf ("\n");
|
|||||||
|
|
||||||
/* Copy the data files, but not the linkages. */
|
/* Copy the data files, but not the linkages. */
|
||||||
comp -> starts = lease -> starts;
|
comp -> starts = lease -> starts;
|
||||||
comp -> ends = lease -> ends;
|
|
||||||
comp -> timestamp = lease -> timestamp;
|
comp -> timestamp = lease -> timestamp;
|
||||||
comp -> uid = lease -> uid;
|
comp -> uid = lease -> uid;
|
||||||
comp -> uid_len = lease -> uid_len;
|
comp -> uid_len = lease -> uid_len;
|
||||||
@@ -373,13 +352,13 @@ printf ("\n");
|
|||||||
head of the list. */
|
head of the list. */
|
||||||
comp -> contain -> leases = comp;
|
comp -> contain -> leases = comp;
|
||||||
comp -> contain -> last_lease = comp;
|
comp -> contain -> last_lease = comp;
|
||||||
} else if (lp -> ends > comp -> ends) {
|
} else if (lp -> ends > lease -> 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 > lease -> ends) {
|
||||||
lp = lp -> next;
|
lp = lp -> next;
|
||||||
}
|
}
|
||||||
if (lp -> ends > comp -> ends) {
|
if (lp -> ends > lease -> 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;
|
||||||
@@ -389,7 +368,7 @@ printf ("\n");
|
|||||||
} 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. */
|
||||||
comp -> prev = lp -> prev;
|
if ((comp -> prev = lp -> prev))
|
||||||
comp -> prev -> next = comp;
|
comp -> prev -> next = comp;
|
||||||
comp -> next = lp;
|
comp -> next = lp;
|
||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
@@ -397,10 +376,10 @@ printf ("\n");
|
|||||||
} else {
|
} else {
|
||||||
/* Skip up 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 < lease -> ends) {
|
||||||
lp = lp -> prev;
|
lp = lp -> prev;
|
||||||
}
|
}
|
||||||
if (lp -> ends < comp -> ends) {
|
if (lp -> ends < lease -> 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;
|
||||||
@@ -410,13 +389,14 @@ printf ("\n");
|
|||||||
} else {
|
} else {
|
||||||
/* If we didn't, put it between lp and
|
/* If we didn't, put it between lp and
|
||||||
the next item on the list. */
|
the next item on the list. */
|
||||||
comp -> next = lp -> next;
|
if ((comp -> next = lp -> next))
|
||||||
comp -> next -> prev = comp;
|
comp -> next -> prev = comp;
|
||||||
comp -> prev = lp;
|
comp -> prev = lp;
|
||||||
lp -> next = comp;
|
lp -> next = comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comp -> contain -> insertion_point = comp;
|
comp -> contain -> insertion_point = comp;
|
||||||
|
comp -> ends = lease -> ends;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +407,8 @@ void release_lease (lease)
|
|||||||
{
|
{
|
||||||
struct lease lt;
|
struct lease lt;
|
||||||
|
|
||||||
lease -> ends = 0;
|
|
||||||
lt = *lease;
|
lt = *lease;
|
||||||
|
lt.ends = cur_time;
|
||||||
supersede_lease (lease, <);
|
supersede_lease (lease, <);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -150,10 +150,10 @@ void parse_option_buffer (packet, buffer, length)
|
|||||||
/* Cons up options based on client-supplied desired option list (if any)
|
/* Cons up options based on client-supplied desired option list (if any)
|
||||||
and selected server option list. */
|
and selected server option list. */
|
||||||
|
|
||||||
void cons_options (inpacket, outpacket, hp, overload)
|
void cons_options (inpacket, outpacket, options, overload)
|
||||||
struct packet *inpacket;
|
struct packet *inpacket;
|
||||||
struct packet *outpacket;
|
struct packet *outpacket;
|
||||||
struct host_decl *hp;
|
struct tree_cache **options;
|
||||||
int overload; /* Overload flags that may be set. */
|
int overload; /* Overload flags that may be set. */
|
||||||
{
|
{
|
||||||
option_mask options_have; /* Options we can send. */
|
option_mask options_have; /* Options we can send. */
|
||||||
@@ -217,7 +217,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
/* Make a bitmask of all the options we have available. */
|
/* Make a bitmask of all the options we have available. */
|
||||||
OPTION_ZERO (options_have);
|
OPTION_ZERO (options_have);
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
if (hp -> options [i])
|
if (options [i])
|
||||||
OPTION_SET (options_have, i);
|
OPTION_SET (options_have, i);
|
||||||
|
|
||||||
/* Put the cookie up front... */
|
/* Put the cookie up front... */
|
||||||
@@ -235,7 +235,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
int length;
|
int length;
|
||||||
|
|
||||||
/* If no data is available for this option, skip it. */
|
/* If no data is available for this option, skip it. */
|
||||||
if (!hp -> options [code])
|
if (!options [code])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Don't look at options that have already been stored. */
|
/* Don't look at options that have already been stored. */
|
||||||
@@ -243,11 +243,11 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Find the value of the option... */
|
/* Find the value of the option... */
|
||||||
if (!tree_evaluate (hp -> options [code]))
|
if (!tree_evaluate (options [code]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We should now have a constant length for the option. */
|
/* We should now have a constant length for the option. */
|
||||||
length = (hp -> options [code] -> len - stored_length [code]);
|
length = (options [code] -> len - stored_length [code]);
|
||||||
|
|
||||||
/* If there's no space for this option, skip it. */
|
/* If there's no space for this option, skip it. */
|
||||||
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
|
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
|
||||||
@@ -260,7 +260,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, store the option. */
|
/* Otherwise, store the option. */
|
||||||
result = store_option (hp, code,
|
result = store_option (options, code,
|
||||||
buffer + bufix,
|
buffer + bufix,
|
||||||
buflen - bufix - reserved,
|
buflen - bufix - reserved,
|
||||||
stored_length);
|
stored_length);
|
||||||
@@ -268,16 +268,16 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
|
|
||||||
/* The following test should always succeed because of
|
/* The following test should always succeed because of
|
||||||
preconditioning above. */
|
preconditioning above. */
|
||||||
if (stored_length [code] == hp -> options [code] -> len)
|
if (stored_length [code] == options [code] -> len)
|
||||||
OPTION_SET (options_done, code);
|
OPTION_SET (options_done, code);
|
||||||
else {
|
else {
|
||||||
warn ("%s: Only stored %d out of %d bytes.",
|
warn ("%s: Only stored %d out of %d bytes.",
|
||||||
dhcp_options [code].name,
|
dhcp_options [code].name,
|
||||||
stored_length [code],
|
stored_length [code],
|
||||||
hp -> options [code] -> len);
|
options [code] -> len);
|
||||||
if (++missed == 1) {
|
if (++missed == 1) {
|
||||||
missed_code = code;
|
missed_code = code;
|
||||||
missed_length = hp -> options [code] -> len
|
missed_length = options [code] -> len
|
||||||
- stored_length [code];
|
- stored_length [code];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,20 +300,20 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
overloading. */
|
overloading. */
|
||||||
if (reserved && missed == 1
|
if (reserved && missed == 1
|
||||||
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
|
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
|
||||||
result = store_option (hp, missed_code,
|
result = store_option (options, missed_code,
|
||||||
buffer + bufix, buflen - bufix,
|
buffer + bufix, buflen - bufix,
|
||||||
stored_length);
|
stored_length);
|
||||||
bufix += result;
|
bufix += result;
|
||||||
/* This test should always fail -- we'll send bad
|
/* This test should always fail -- we'll send bad
|
||||||
data if it doesn't. */
|
data if it doesn't. */
|
||||||
if (stored_length [missed_code]
|
if (stored_length [missed_code]
|
||||||
== hp -> options [missed_code] -> len) {
|
== options [missed_code] -> len) {
|
||||||
OPTION_SET (options_done, missed_code);
|
OPTION_SET (options_done, missed_code);
|
||||||
} else {
|
} else {
|
||||||
warn ("%s (last): Only stored %d out of %d bytes.",
|
warn ("%s (last): Only stored %d out of %d bytes.",
|
||||||
dhcp_options [missed_code].name,
|
dhcp_options [missed_code].name,
|
||||||
stored_length [missed_code],
|
stored_length [missed_code],
|
||||||
hp -> options [missed_code] -> len);
|
options [missed_code] -> len);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -323,7 +323,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
option into the current buffer and part into the next. */
|
option into the current buffer and part into the next. */
|
||||||
if (bufix + OPTION_SPACE (missed_length) + reserved
|
if (bufix + OPTION_SPACE (missed_length) + reserved
|
||||||
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
|
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
|
||||||
result = store_option (hp, missed_code,
|
result = store_option (options, missed_code,
|
||||||
buffer + bufix,
|
buffer + bufix,
|
||||||
buflen - bufix - reserved,
|
buflen - bufix - reserved,
|
||||||
stored_length);
|
stored_length);
|
||||||
@@ -331,7 +331,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
|
|
||||||
/* This test should never fail. */
|
/* This test should never fail. */
|
||||||
if (stored_length [missed_code]
|
if (stored_length [missed_code]
|
||||||
== hp -> options [missed_code] -> len) {
|
== options [missed_code] -> len) {
|
||||||
OPTION_SET (options_done, missed_code);
|
OPTION_SET (options_done, missed_code);
|
||||||
warn ("%s: Unexpected completed store.",
|
warn ("%s: Unexpected completed store.",
|
||||||
dhcp_options [missed_code].name);
|
dhcp_options [missed_code].name);
|
||||||
@@ -391,17 +391,17 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
data that has been stored so far. Return 1 if all the option data
|
data that has been stored so far. Return 1 if all the option data
|
||||||
has been stored. */
|
has been stored. */
|
||||||
|
|
||||||
int store_option (hp, code, buffer, buflen, stored_length)
|
int store_option (options, code, buffer, buflen, stored_length)
|
||||||
struct host_decl *hp;
|
struct tree_cache **options;
|
||||||
unsigned char code;
|
unsigned char code;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int buflen;
|
int buflen;
|
||||||
int *stored_length;
|
int *stored_length;
|
||||||
{
|
{
|
||||||
int length = hp -> options [code] -> len - stored_length [code];
|
int length = options [code] -> len - stored_length [code];
|
||||||
int bufix = 0;
|
int bufix = 0;
|
||||||
printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
||||||
length, buflen, hp -> options [code] -> len, stored_length [code]);
|
length, buflen, options [code] -> len, stored_length [code]);
|
||||||
if (length > buflen) {
|
if (length > buflen) {
|
||||||
length = buflen;
|
length = buflen;
|
||||||
}
|
}
|
||||||
@@ -415,7 +415,7 @@ printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
|||||||
unsigned char incr = length > 255 ? 255 : length;
|
unsigned char incr = length > 255 ? 255 : length;
|
||||||
buffer [bufix] = code;
|
buffer [bufix] = code;
|
||||||
buffer [bufix + 1] = incr;
|
buffer [bufix + 1] = incr;
|
||||||
memcpy (buffer + bufix + 2, (hp -> options [code] -> value
|
memcpy (buffer + bufix + 2, (options [code] -> value
|
||||||
+ stored_length [code]), incr);
|
+ stored_length [code]), incr);
|
||||||
length -= incr;
|
length -= incr;
|
||||||
stored_length [code] += incr;
|
stored_length [code] += incr;
|
||||||
|
@@ -326,6 +326,17 @@ struct option dhcp_options [256] = {
|
|||||||
/* Default dhcp option priority list (this is ad hoc and should not be
|
/* Default dhcp option priority list (this is ad hoc and should not be
|
||||||
mistaken for a carefully crafted and optimized list). */
|
mistaken for a carefully crafted and optimized list). */
|
||||||
unsigned char dhcp_option_default_priority_list [] = {
|
unsigned char dhcp_option_default_priority_list [] = {
|
||||||
|
DHO_DHCP_REQUESTED_ADDRESS,
|
||||||
|
DHO_DHCP_LEASE_TIME,
|
||||||
|
DHO_DHCP_MESSAGE_TYPE,
|
||||||
|
DHO_DHCP_OPTION_OVERLOAD,
|
||||||
|
DHO_DHCP_SERVER_IDENTIFIER,
|
||||||
|
DHO_DHCP_MESSAGE,
|
||||||
|
DHO_DHCP_MAX_MESSAGE_SIZE,
|
||||||
|
DHO_DHCP_RENEWAL_TIME,
|
||||||
|
DHO_DHCP_REBINDING_TIME,
|
||||||
|
DHO_DHCP_CLASS_IDENTIFIER,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER,
|
||||||
DHO_SUBNET_MASK,
|
DHO_SUBNET_MASK,
|
||||||
DHO_TIME_OFFSET,
|
DHO_TIME_OFFSET,
|
||||||
DHO_ROUTERS,
|
DHO_ROUTERS,
|
||||||
@@ -375,18 +386,7 @@ unsigned char dhcp_option_default_priority_list [] = {
|
|||||||
DHO_NETBIOS_SCOPE,
|
DHO_NETBIOS_SCOPE,
|
||||||
DHO_FONT_SERVERS,
|
DHO_FONT_SERVERS,
|
||||||
DHO_X_DISPLAY_MANAGER,
|
DHO_X_DISPLAY_MANAGER,
|
||||||
DHO_DHCP_REQUESTED_ADDRESS,
|
|
||||||
DHO_DHCP_LEASE_TIME,
|
|
||||||
DHO_DHCP_OPTION_OVERLOAD,
|
|
||||||
DHO_DHCP_MESSAGE_TYPE,
|
|
||||||
DHO_DHCP_SERVER_IDENTIFIER,
|
|
||||||
DHO_DHCP_PARAMETER_REQUEST_LIST,
|
DHO_DHCP_PARAMETER_REQUEST_LIST,
|
||||||
DHO_DHCP_MESSAGE,
|
|
||||||
DHO_DHCP_MAX_MESSAGE_SIZE,
|
|
||||||
DHO_DHCP_RENEWAL_TIME,
|
|
||||||
DHO_DHCP_REBINDING_TIME,
|
|
||||||
DHO_DHCP_CLASS_IDENTIFIER,
|
|
||||||
DHO_DHCP_CLIENT_IDENTIFIER,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int sizeof_dhcp_option_default_priority_list =
|
int sizeof_dhcp_option_default_priority_list =
|
||||||
|
14
conflex.c
14
conflex.c
@@ -277,6 +277,10 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "iaddr"))
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
return CIADDR;
|
return CIADDR;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (!strcasecmp (atom + 1, "efault-lease-time"))
|
||||||
|
return DEFAULT_LEASE_TIME;
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (!strcasecmp (atom + 1, "thernet"))
|
if (!strcasecmp (atom + 1, "thernet"))
|
||||||
return ETHERNET;
|
return ETHERNET;
|
||||||
@@ -303,6 +307,14 @@ static int intern (atom, dfv)
|
|||||||
if (!strcasecmp (atom + 1, "ease"))
|
if (!strcasecmp (atom + 1, "ease"))
|
||||||
return LEASE;
|
return LEASE;
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
if (!strcasecmp (atom + 1, "ax-lease-time"))
|
||||||
|
return MAX_LEASE_TIME;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (!strcasecmp (atom + 1, "etmask"))
|
||||||
|
return NETMASK;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!strcasecmp (atom + 1, "acket"))
|
if (!strcasecmp (atom + 1, "acket"))
|
||||||
return PACKET;
|
return PACKET;
|
||||||
@@ -320,6 +332,8 @@ static int intern (atom, dfv)
|
|||||||
return STARTS;
|
return STARTS;
|
||||||
if (!strcasecmp (atom + 1, "iaddr"))
|
if (!strcasecmp (atom + 1, "iaddr"))
|
||||||
return SIADDR;
|
return SIADDR;
|
||||||
|
if (!strcasecmp (atom + 1, "ubnet"))
|
||||||
|
return SUBNET;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (!strcasecmp (atom + 1, "timestamp"))
|
if (!strcasecmp (atom + 1, "timestamp"))
|
||||||
|
143
confpars.c
143
confpars.c
@@ -102,9 +102,9 @@ void parse_statement (cfile)
|
|||||||
parsed_time = parse_timestamp (cfile, &bc);
|
parsed_time = parse_timestamp (cfile, &bc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RANGE:
|
case SUBNET:
|
||||||
if (!setjmp (bc)) {
|
if (!setjmp (bc)) {
|
||||||
parse_address_range (cfile, &bc);
|
parse_subnet_statement (cfile, &bc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -209,6 +209,113 @@ char *parse_host_name (cfile, bc)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* subnet_statement :== SUBNET net NETMASK netmask declarations SEMI
|
||||||
|
host_declarations :== <nil> | host_declaration
|
||||||
|
| host_declarations host_declaration SEMI */
|
||||||
|
|
||||||
|
struct subnet *parse_subnet_statement (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jmp_buf *bc;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
struct subnet *subnet;
|
||||||
|
struct iaddr net, netmask;
|
||||||
|
unsigned char addr [4];
|
||||||
|
int len = sizeof addr;
|
||||||
|
|
||||||
|
subnet = new_subnet ("parse_subnet_statement");
|
||||||
|
if (!subnet)
|
||||||
|
error ("No memory for new subnet");
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Get the network number... */
|
||||||
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
|
memcpy (net.iabuf, addr, len);
|
||||||
|
net.len = len;
|
||||||
|
subnet -> net = net;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NETMASK) {
|
||||||
|
parse_warn ("Expecting netmask");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the netmask... */
|
||||||
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
|
memcpy (netmask.iabuf, addr, len);
|
||||||
|
netmask.len = len;
|
||||||
|
subnet -> netmask = netmask;
|
||||||
|
|
||||||
|
enter_subnet (subnet);
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = peek_token (&val, cfile);
|
||||||
|
if (token == SEMI) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parse_subnet_decl (cfile, bc, subnet);
|
||||||
|
} while (1);
|
||||||
|
return subnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subnet_declaration :== hardware_declaration | filename_declaration
|
||||||
|
| fixed_addr_declaration | option_declaration */
|
||||||
|
|
||||||
|
void parse_subnet_decl (cfile, bc, decl)
|
||||||
|
FILE *cfile;
|
||||||
|
jmp_buf *bc;
|
||||||
|
struct subnet *decl;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
switch (token) {
|
||||||
|
case RANGE:
|
||||||
|
parse_address_range (cfile, bc, decl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric default lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)&decl -> default_lease_time,
|
||||||
|
val, 10, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric max lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)&decl -> max_lease_time,
|
||||||
|
val, 10, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parse_warn ("expecting a subnet declaration.");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* host_declaration :== hardware_declaration | filename_declaration
|
/* host_declaration :== hardware_declaration | filename_declaration
|
||||||
| fixed_addr_declaration | option_declaration */
|
| fixed_addr_declaration | option_declaration */
|
||||||
|
|
||||||
@@ -232,7 +339,7 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
parse_fixed_addr_decl (cfile, bc, decl);
|
parse_fixed_addr_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl);
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
break;
|
break;
|
||||||
case CIADDR:
|
case CIADDR:
|
||||||
decl -> ciaddr =
|
decl -> ciaddr =
|
||||||
@@ -400,10 +507,10 @@ void parse_fixed_addr_decl (cfile, bc, decl)
|
|||||||
would be painful to come up with BNF for it. However, it always
|
would be painful to come up with BNF for it. However, it always
|
||||||
starts as above. */
|
starts as above. */
|
||||||
|
|
||||||
void parse_option_decl (cfile, bc, decl)
|
void parse_option_decl (cfile, bc, options)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jmp_buf *bc;
|
jmp_buf *bc;
|
||||||
struct host_decl *decl;
|
struct tree_cache **options;
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int token;
|
int token;
|
||||||
@@ -570,11 +677,11 @@ void parse_option_decl (cfile, bc, decl)
|
|||||||
}
|
}
|
||||||
} while (*fmt == 'A');
|
} while (*fmt == 'A');
|
||||||
|
|
||||||
if (decl -> options [option -> code]) {
|
if (options [option -> code]) {
|
||||||
parse_warn ("duplicate option code %d (%s).",
|
parse_warn ("duplicate option code %d (%s).",
|
||||||
option -> code, option -> name);
|
option -> code, option -> name);
|
||||||
}
|
}
|
||||||
decl -> options [option -> code] = tree_cache (tree);
|
options [option -> code] = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timestamp :== TIMESTAMP date SEMI
|
/* timestamp :== TIMESTAMP date SEMI
|
||||||
@@ -724,13 +831,14 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
return &lease;
|
return &lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* address_range :== RANGE ip_address ip_address ip_address SEMI */
|
/* address_range :== RANGE ip_address ip_address */
|
||||||
|
|
||||||
void parse_address_range (cfile, bc)
|
void parse_address_range (cfile, bc, subnet)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jmp_buf *bc;
|
jmp_buf *bc;
|
||||||
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
struct iaddr low, high, mask;
|
struct iaddr low, high;
|
||||||
unsigned char addr [4];
|
unsigned char addr [4];
|
||||||
int len = sizeof addr;
|
int len = sizeof addr;
|
||||||
int token;
|
int token;
|
||||||
@@ -746,21 +854,8 @@ void parse_address_range (cfile, bc)
|
|||||||
memcpy (high.iabuf, addr, len);
|
memcpy (high.iabuf, addr, len);
|
||||||
high.len = len;
|
high.len = len;
|
||||||
|
|
||||||
/* Get the netmask of the subnet containing the range... */
|
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
|
||||||
memcpy (mask.iabuf, addr, len);
|
|
||||||
mask.len = len;
|
|
||||||
|
|
||||||
/* Snarf the semi... */
|
|
||||||
token = next_token (&val, cfile);
|
|
||||||
if (token != SEMI) {
|
|
||||||
parse_warn ("semicolon expected");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (*bc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the new address range... */
|
/* Create the new address range... */
|
||||||
new_address_range (low, high, mask);
|
new_address_range (low, high, subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
||||||
|
@@ -105,12 +105,15 @@ int main (argc, argv, envp)
|
|||||||
FD_ZERO (&w);
|
FD_ZERO (&w);
|
||||||
FD_ZERO (&x);
|
FD_ZERO (&x);
|
||||||
FD_SET (sock, &r);
|
FD_SET (sock, &r);
|
||||||
|
FD_SET (sock, &w);
|
||||||
|
FD_SET (sock, &x);
|
||||||
FD_SET (0, &r); /* stdin */
|
FD_SET (0, &r); /* stdin */
|
||||||
|
|
||||||
if (select (sock + 1, &r, &w, &x, (struct timeval *)0) < 0) {
|
if (select (sock + 1, &r, &w, &x, (struct timeval *)0) < 0) {
|
||||||
error ("select: %m");
|
error ("select: %m");
|
||||||
}
|
}
|
||||||
if (FD_ISSET (sock, &r)) {
|
if (FD_ISSET (sock, &r) || FD_ISSET (sock, &w)
|
||||||
|
|| FD_ISSET (sock, &x)) {
|
||||||
if ((result =
|
if ((result =
|
||||||
recvfrom (sock, packbuf, sizeof packbuf, 0,
|
recvfrom (sock, packbuf, sizeof packbuf, 0,
|
||||||
(struct sockaddr *)&from, &fromlen))
|
(struct sockaddr *)&from, &fromlen))
|
||||||
@@ -188,7 +191,7 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cons_options ((struct packet *)0,
|
cons_options ((struct packet *)0,
|
||||||
&outgoing, &decl, bufs);
|
&outgoing, decl.options, bufs);
|
||||||
|
|
||||||
if (decl.ciaddr) {
|
if (decl.ciaddr) {
|
||||||
tree_evaluate (decl.ciaddr);
|
tree_evaluate (decl.ciaddr);
|
||||||
|
119
dhcp.c
119
dhcp.c
@@ -54,6 +54,18 @@ void dhcp (packet)
|
|||||||
struct lease lt;
|
struct lease lt;
|
||||||
TIME lease_time;
|
TIME lease_time;
|
||||||
|
|
||||||
|
int bufs = 0;
|
||||||
|
struct packet outgoing;
|
||||||
|
struct dhcp_packet raw;
|
||||||
|
struct tree_cache *options [256];
|
||||||
|
struct sockaddr_in to;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
unsigned char dhcpoffer = DHCPOFFER;
|
||||||
|
struct tree_cache dhcpoffer_tree;
|
||||||
|
unsigned char lease_time_buf [4];
|
||||||
|
struct tree_cache lease_time_tree;
|
||||||
|
|
||||||
dump_packet (packet);
|
dump_packet (packet);
|
||||||
|
|
||||||
/* Try to find a lease that's been assigned to the specified
|
/* Try to find a lease that's been assigned to the specified
|
||||||
@@ -86,20 +98,6 @@ void dhcp (packet)
|
|||||||
} else
|
} else
|
||||||
ip_lease = (struct lease *)0;
|
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... */
|
/* Toss extra pointers to the same lease... */
|
||||||
if (ip_lease == hw_lease)
|
if (ip_lease == hw_lease)
|
||||||
ip_lease = (struct lease *)0;
|
ip_lease = (struct lease *)0;
|
||||||
@@ -108,20 +106,6 @@ void dhcp (packet)
|
|||||||
if (ip_lease == uid_lease)
|
if (ip_lease == uid_lease)
|
||||||
ip_lease = (struct lease *)0;
|
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
|
/* 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
|
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
|
have zeroed it out above, so the only way we can take it at this
|
||||||
@@ -145,20 +129,6 @@ void dhcp (packet)
|
|||||||
hw_lease = (struct lease *)0;
|
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
|
/* At this point, if ip_lease is nonzero, we can assign it to
|
||||||
this client. */
|
this client. */
|
||||||
lease = ip_lease;
|
lease = ip_lease;
|
||||||
@@ -249,5 +219,68 @@ void dhcp (packet)
|
|||||||
supersede_lease (lease, <);
|
supersede_lease (lease, <);
|
||||||
|
|
||||||
/* Send a response to the client... */
|
/* Send a response to the client... */
|
||||||
dump_subnets ();
|
|
||||||
|
memset (&outgoing, 0, sizeof outgoing);
|
||||||
|
memset (&raw, 0, sizeof raw);
|
||||||
|
outgoing.raw = &raw;
|
||||||
|
|
||||||
|
/* Copy in the filename if given; otherwise, flag the filename
|
||||||
|
buffer as available for options. */
|
||||||
|
bufs |= 1; /* XXX */
|
||||||
|
|
||||||
|
/* Copy in the server name if given; otherwise, flag the
|
||||||
|
server_name buffer as available for options. */
|
||||||
|
bufs |= 2; /* XXX */
|
||||||
|
|
||||||
|
memcpy (raw.chaddr, packet -> raw -> chaddr, packet -> raw -> hlen);
|
||||||
|
raw.hlen = packet -> raw -> hlen;
|
||||||
|
raw.htype = packet -> raw -> htype;
|
||||||
|
|
||||||
|
/* Start out with the subnet options... */
|
||||||
|
memcpy (options, packet -> subnet -> options, sizeof options);
|
||||||
|
|
||||||
|
/* Now put in options that override those. */
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] = &dhcpoffer_tree;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> value = &dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> len = sizeof dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> buf_size = sizeof dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> timeout = 0xFFFFFFFF;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> tree = (struct tree *)0;
|
||||||
|
|
||||||
|
|
||||||
|
putULong (lease_time_buf, lease -> ends - cur_time);
|
||||||
|
options [DHO_DHCP_LEASE_TIME] = &lease_time_tree;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> value = lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> len = sizeof lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> buf_size = sizeof lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> timeout = 0xFFFFFFFF;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> tree = (struct tree *)0;
|
||||||
|
|
||||||
|
cons_options (packet, &outgoing, options, bufs);
|
||||||
|
|
||||||
|
raw.ciaddr = packet -> raw -> ciaddr;
|
||||||
|
memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
|
||||||
|
memcpy (&raw.siaddr, siaddr.iabuf, 4);
|
||||||
|
raw.giaddr = packet -> raw -> giaddr;
|
||||||
|
|
||||||
|
raw.xid = packet -> raw -> xid;
|
||||||
|
raw.secs = packet -> raw -> secs;
|
||||||
|
raw.flags = packet -> raw -> flags;
|
||||||
|
raw.hops = packet -> raw -> hops;
|
||||||
|
raw.op = BOOTREPLY;
|
||||||
|
|
||||||
|
to.sin_port = htons (2000);
|
||||||
|
to.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
|
to.sin_family = AF_INET;
|
||||||
|
to.sin_len = sizeof to;
|
||||||
|
memset (to.sin_zero, 0, sizeof to.sin_zero);
|
||||||
|
|
||||||
|
note ("Sending dhcp reply to %s, port %d",
|
||||||
|
inet_ntoa (to.sin_addr), htons (to.sin_port));
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
result = sendto (packet -> client_sock, &raw, outgoing.packet_length,
|
||||||
|
0, (struct sockaddr *)&to, sizeof to);
|
||||||
|
if (result < 0)
|
||||||
|
warn ("sendto: %m");
|
||||||
}
|
}
|
||||||
|
14
dhcpd.c
14
dhcpd.c
@@ -57,6 +57,7 @@ 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;
|
||||||
|
struct iaddr siaddr;
|
||||||
|
|
||||||
int main (argc, argv, envp)
|
int main (argc, argv, envp)
|
||||||
int argc;
|
int argc;
|
||||||
@@ -66,7 +67,6 @@ 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;
|
||||||
@@ -152,7 +152,7 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
taddr.len = 0;
|
siaddr.len = 0;
|
||||||
server_addrlist = get_interface_list (&server_addrcount);
|
server_addrlist = get_interface_list (&server_addrcount);
|
||||||
for (i = 0; i < server_addrcount; i++) {
|
for (i = 0; i < server_addrcount; i++) {
|
||||||
struct sockaddr_in foo;
|
struct sockaddr_in foo;
|
||||||
@@ -160,13 +160,13 @@ int main (argc, argv, envp)
|
|||||||
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
||||||
|
|
||||||
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
||||||
if (taddr.len) {
|
if (siaddr.len) {
|
||||||
error ("dhcpd currently does not support "
|
error ("dhcpd currently does not support "
|
||||||
"multiple interfaces");
|
"multiple interfaces");
|
||||||
}
|
}
|
||||||
taddr.len = 4;
|
siaddr.len = 4;
|
||||||
memcpy (taddr.iabuf, &server_addrlist [i], 4);
|
memcpy (siaddr.iabuf, &server_addrlist [i], 4);
|
||||||
local_subnet = find_subnet (taddr);
|
local_subnet = find_subnet (siaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,8 +184,6 @@ int main (argc, argv, envp)
|
|||||||
close (i);
|
close (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_subnets ();
|
|
||||||
|
|
||||||
/* Receive packets and dispatch them... */
|
/* Receive packets and dispatch them... */
|
||||||
dispatch ();
|
dispatch ();
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
range 204.254.239.11 204.254.239.17 255.255.255.0;
|
subnet 204.254.239.0 netmask 255.255.255.0
|
||||||
range 204.254.240.11 204.254.240.12 255.255.255.0;
|
range 204.254.239.11 204.254.239.17;
|
||||||
|
|
||||||
|
subnet 204.254.240.0 netmask 255.255.255.0
|
||||||
|
range 204.254.240.11 204.254.240.12;
|
||||||
|
|
||||||
host minuet
|
host minuet
|
||||||
hardware ethernet 08:00:2b:35:0c:18
|
hardware ethernet 08:00:2b:35:0c:18
|
||||||
|
16
dhcpd.h
16
dhcpd.h
@@ -121,6 +121,7 @@ struct subnet {
|
|||||||
struct iaddr netmask;
|
struct iaddr netmask;
|
||||||
TIME default_lease_time;
|
TIME default_lease_time;
|
||||||
TIME max_lease_time;
|
TIME max_lease_time;
|
||||||
|
struct tree_cache *options [256];
|
||||||
struct lease *leases;
|
struct lease *leases;
|
||||||
struct lease *insertion_point;
|
struct lease *insertion_point;
|
||||||
struct lease *last_lease;
|
struct lease *last_lease;
|
||||||
@@ -159,8 +160,8 @@ typedef unsigned char option_mask [16];
|
|||||||
void parse_options PROTO ((struct packet *));
|
void parse_options PROTO ((struct packet *));
|
||||||
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
|
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
|
||||||
void cons_options PROTO ((struct packet *, struct packet *,
|
void cons_options PROTO ((struct packet *, struct packet *,
|
||||||
struct host_decl *, int));
|
struct tree_cache **, int));
|
||||||
int store_option PROTO ((struct host_decl *, unsigned char,
|
int store_option PROTO ((struct tree_cache **, unsigned char,
|
||||||
unsigned char *, int, int *));
|
unsigned char *, int, int *));
|
||||||
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
|
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
|
||||||
|
|
||||||
@@ -175,9 +176,12 @@ int parse_warn PROTO ((char *, ...));
|
|||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
TIME default_lease_time;
|
TIME default_lease_time;
|
||||||
TIME max_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;
|
||||||
|
struct iaddr siaddr;
|
||||||
|
|
||||||
int main PROTO ((int, char **, char **));
|
int main PROTO ((int, char **, char **));
|
||||||
void cleanup PROTO ((void));
|
void cleanup PROTO ((void));
|
||||||
void do_packet PROTO ((unsigned char *, int,
|
void do_packet PROTO ((unsigned char *, int,
|
||||||
@@ -196,17 +200,19 @@ void parse_statement PROTO ((FILE *));
|
|||||||
void skip_to_semi PROTO ((FILE *));
|
void skip_to_semi PROTO ((FILE *));
|
||||||
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
|
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
|
||||||
char *parse_host_name PROTO ((FILE *, jmp_buf *));
|
char *parse_host_name PROTO ((FILE *, jmp_buf *));
|
||||||
|
struct subnet *parse_subnet_statement PROTO ((FILE *, jmp_buf *));
|
||||||
|
void parse_subnet_decl PROTO ((FILE *, jmp_buf *, struct subnet *));
|
||||||
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
|
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
|
||||||
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, jmp_buf *, int));
|
struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, jmp_buf *, int));
|
||||||
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct tree_cache **));
|
||||||
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
|
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
|
||||||
TIME parse_date PROTO ((FILE *, jmp_buf *));
|
TIME parse_date PROTO ((FILE *, jmp_buf *));
|
||||||
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
|
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
|
||||||
void parse_address_range PROTO ((FILE *, jmp_buf *));
|
void parse_address_range PROTO ((FILE *, jmp_buf *, struct subnet *));
|
||||||
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
|
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
|
||||||
unsigned char *, int *,
|
unsigned char *, int *,
|
||||||
int, int, int));
|
int, int, int));
|
||||||
@@ -233,7 +239,7 @@ void enter_host PROTO ((struct host_decl *));
|
|||||||
struct host_decl *find_host_by_name PROTO ((char *name));
|
struct host_decl *find_host_by_name PROTO ((char *name));
|
||||||
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
|
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
|
||||||
void new_address_range PROTO ((struct iaddr, struct iaddr,
|
void new_address_range PROTO ((struct iaddr, struct iaddr,
|
||||||
struct iaddr));
|
struct subnet *));
|
||||||
extern struct subnet *find_subnet (struct iaddr);
|
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 *));
|
||||||
|
@@ -68,7 +68,12 @@
|
|||||||
#define YIADDR 275
|
#define YIADDR 275
|
||||||
#define SIADDR 276
|
#define SIADDR 276
|
||||||
#define GIADDR 277
|
#define GIADDR 277
|
||||||
#define LAST_TOKEN GIADDR
|
#define SUBNET 278
|
||||||
|
#define NETMASK 279
|
||||||
|
#define DEFAULT_LEASE_TIME 280
|
||||||
|
#define MAX_LEASE_TIME 281
|
||||||
|
|
||||||
|
#define LAST_TOKEN MAX_LEASE_TIME
|
||||||
|
|
||||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||||
(x) <= LAST_TOKEN && \
|
(x) <= LAST_TOKEN && \
|
||||||
|
@@ -121,6 +121,7 @@ struct subnet {
|
|||||||
struct iaddr netmask;
|
struct iaddr netmask;
|
||||||
TIME default_lease_time;
|
TIME default_lease_time;
|
||||||
TIME max_lease_time;
|
TIME max_lease_time;
|
||||||
|
struct tree_cache *options [256];
|
||||||
struct lease *leases;
|
struct lease *leases;
|
||||||
struct lease *insertion_point;
|
struct lease *insertion_point;
|
||||||
struct lease *last_lease;
|
struct lease *last_lease;
|
||||||
@@ -159,8 +160,8 @@ typedef unsigned char option_mask [16];
|
|||||||
void parse_options PROTO ((struct packet *));
|
void parse_options PROTO ((struct packet *));
|
||||||
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
|
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
|
||||||
void cons_options PROTO ((struct packet *, struct packet *,
|
void cons_options PROTO ((struct packet *, struct packet *,
|
||||||
struct host_decl *, int));
|
struct tree_cache **, int));
|
||||||
int store_option PROTO ((struct host_decl *, unsigned char,
|
int store_option PROTO ((struct tree_cache **, unsigned char,
|
||||||
unsigned char *, int, int *));
|
unsigned char *, int, int *));
|
||||||
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
|
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
|
||||||
|
|
||||||
@@ -175,9 +176,12 @@ int parse_warn PROTO ((char *, ...));
|
|||||||
TIME cur_time;
|
TIME cur_time;
|
||||||
TIME default_lease_time;
|
TIME default_lease_time;
|
||||||
TIME max_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;
|
||||||
|
struct iaddr siaddr;
|
||||||
|
|
||||||
int main PROTO ((int, char **, char **));
|
int main PROTO ((int, char **, char **));
|
||||||
void cleanup PROTO ((void));
|
void cleanup PROTO ((void));
|
||||||
void do_packet PROTO ((unsigned char *, int,
|
void do_packet PROTO ((unsigned char *, int,
|
||||||
@@ -196,17 +200,19 @@ void parse_statement PROTO ((FILE *));
|
|||||||
void skip_to_semi PROTO ((FILE *));
|
void skip_to_semi PROTO ((FILE *));
|
||||||
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
|
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
|
||||||
char *parse_host_name PROTO ((FILE *, jmp_buf *));
|
char *parse_host_name PROTO ((FILE *, jmp_buf *));
|
||||||
|
struct subnet *parse_subnet_statement PROTO ((FILE *, jmp_buf *));
|
||||||
|
void parse_subnet_decl PROTO ((FILE *, jmp_buf *, struct subnet *));
|
||||||
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
|
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
|
||||||
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, jmp_buf *, int));
|
struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, jmp_buf *, int));
|
||||||
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
||||||
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
|
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct tree_cache **));
|
||||||
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
|
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
|
||||||
TIME parse_date PROTO ((FILE *, jmp_buf *));
|
TIME parse_date PROTO ((FILE *, jmp_buf *));
|
||||||
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
|
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
|
||||||
void parse_address_range PROTO ((FILE *, jmp_buf *));
|
void parse_address_range PROTO ((FILE *, jmp_buf *, struct subnet *));
|
||||||
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
|
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
|
||||||
unsigned char *, int *,
|
unsigned char *, int *,
|
||||||
int, int, int));
|
int, int, int));
|
||||||
@@ -233,7 +239,7 @@ void enter_host PROTO ((struct host_decl *));
|
|||||||
struct host_decl *find_host_by_name PROTO ((char *name));
|
struct host_decl *find_host_by_name PROTO ((char *name));
|
||||||
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
|
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
|
||||||
void new_address_range PROTO ((struct iaddr, struct iaddr,
|
void new_address_range PROTO ((struct iaddr, struct iaddr,
|
||||||
struct iaddr));
|
struct subnet *));
|
||||||
extern struct subnet *find_subnet (struct iaddr);
|
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 *));
|
||||||
|
@@ -68,7 +68,12 @@
|
|||||||
#define YIADDR 275
|
#define YIADDR 275
|
||||||
#define SIADDR 276
|
#define SIADDR 276
|
||||||
#define GIADDR 277
|
#define GIADDR 277
|
||||||
#define LAST_TOKEN GIADDR
|
#define SUBNET 278
|
||||||
|
#define NETMASK 279
|
||||||
|
#define DEFAULT_LEASE_TIME 280
|
||||||
|
#define MAX_LEASE_TIME 281
|
||||||
|
|
||||||
|
#define LAST_TOKEN MAX_LEASE_TIME
|
||||||
|
|
||||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||||
(x) <= LAST_TOKEN && \
|
(x) <= LAST_TOKEN && \
|
||||||
|
60
memory.c
60
memory.c
@@ -92,11 +92,11 @@ struct host_decl *find_host_by_addr (htype, haddr, hlen)
|
|||||||
return (struct host_decl *)0;
|
return (struct host_decl *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_address_range (low, high, netmask)
|
void new_address_range (low, high, subnet)
|
||||||
struct iaddr low, high, netmask;
|
struct iaddr low, high;
|
||||||
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
struct lease *address_range, *lp, *plp;
|
struct lease *address_range, *lp, *plp;
|
||||||
struct subnet *subnet;
|
|
||||||
struct iaddr net;
|
struct iaddr net;
|
||||||
int min, max, i;
|
int min, max, i;
|
||||||
char lowbuf [16], highbuf [16], netbuf [16];
|
char lowbuf [16], highbuf [16], netbuf [16];
|
||||||
@@ -110,39 +110,23 @@ void new_address_range (low, high, netmask)
|
|||||||
lease_hw_addr_hash = new_hash ();
|
lease_hw_addr_hash = new_hash ();
|
||||||
|
|
||||||
/* Make sure that high and low addresses are in same subnet. */
|
/* Make sure that high and low addresses are in same subnet. */
|
||||||
net = subnet_number (low, netmask);
|
net = subnet_number (low, subnet -> netmask);
|
||||||
if (!addr_eq (net, subnet_number (high, netmask))) {
|
if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
|
||||||
strcpy (lowbuf, piaddr (low));
|
strcpy (lowbuf, piaddr (low));
|
||||||
strcpy (highbuf, piaddr (high));
|
strcpy (highbuf, piaddr (high));
|
||||||
strcpy (netbuf, piaddr (netmask));
|
strcpy (netbuf, piaddr (subnet -> netmask));
|
||||||
error ("Address range %s to %s, netmask %s spans %s!",
|
error ("Address range %s to %s, netmask %s spans %s!",
|
||||||
lowbuf, highbuf, netbuf, "multiple subnets");
|
lowbuf, highbuf, netbuf, "multiple subnets");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if this subnet is already known - if not, make a new one. */
|
|
||||||
subnet = find_subnet (net);
|
|
||||||
if (!subnet) {
|
|
||||||
subnet = new_subnet ("new_address_range");
|
|
||||||
if (!subnet)
|
|
||||||
error ("No memory for new subnet");
|
|
||||||
subnet -> net = net;
|
|
||||||
subnet -> netmask = netmask;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the high and low host addresses... */
|
/* Get the high and low host addresses... */
|
||||||
max = host_addr (high, netmask);
|
max = host_addr (high, subnet -> netmask);
|
||||||
min = host_addr (low, netmask);
|
min = host_addr (low, subnet -> 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 (min > max) {
|
if (min > max) {
|
||||||
max = min;
|
max = min;
|
||||||
min = host_addr (high, netmask);
|
min = host_addr (high, subnet -> netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a lease structure for each address in the range. */
|
/* Get a lease structure for each address in the range. */
|
||||||
@@ -155,8 +139,9 @@ void new_address_range (low, high, netmask)
|
|||||||
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
|
||||||
|
|
||||||
/* Fill in the last lease if it hasn't been already... */
|
/* Fill in the last lease if it hasn't been already... */
|
||||||
if (!subnet -> last_lease)
|
if (!subnet -> last_lease) {
|
||||||
subnet -> last_lease = &address_range [0];
|
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 = 0; i < max - min + 1; i++) {
|
for (i = 0; i < max - min + 1; i++) {
|
||||||
@@ -269,11 +254,6 @@ 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
|
||||||
@@ -325,7 +305,6 @@ printf ("\n");
|
|||||||
|
|
||||||
/* Copy the data files, but not the linkages. */
|
/* Copy the data files, but not the linkages. */
|
||||||
comp -> starts = lease -> starts;
|
comp -> starts = lease -> starts;
|
||||||
comp -> ends = lease -> ends;
|
|
||||||
comp -> timestamp = lease -> timestamp;
|
comp -> timestamp = lease -> timestamp;
|
||||||
comp -> uid = lease -> uid;
|
comp -> uid = lease -> uid;
|
||||||
comp -> uid_len = lease -> uid_len;
|
comp -> uid_len = lease -> uid_len;
|
||||||
@@ -373,13 +352,13 @@ printf ("\n");
|
|||||||
head of the list. */
|
head of the list. */
|
||||||
comp -> contain -> leases = comp;
|
comp -> contain -> leases = comp;
|
||||||
comp -> contain -> last_lease = comp;
|
comp -> contain -> last_lease = comp;
|
||||||
} else if (lp -> ends > comp -> ends) {
|
} else if (lp -> ends > lease -> 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 > lease -> ends) {
|
||||||
lp = lp -> next;
|
lp = lp -> next;
|
||||||
}
|
}
|
||||||
if (lp -> ends > comp -> ends) {
|
if (lp -> ends > lease -> 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;
|
||||||
@@ -389,7 +368,7 @@ printf ("\n");
|
|||||||
} 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. */
|
||||||
comp -> prev = lp -> prev;
|
if ((comp -> prev = lp -> prev))
|
||||||
comp -> prev -> next = comp;
|
comp -> prev -> next = comp;
|
||||||
comp -> next = lp;
|
comp -> next = lp;
|
||||||
lp -> prev = comp;
|
lp -> prev = comp;
|
||||||
@@ -397,10 +376,10 @@ printf ("\n");
|
|||||||
} else {
|
} else {
|
||||||
/* Skip up 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 < lease -> ends) {
|
||||||
lp = lp -> prev;
|
lp = lp -> prev;
|
||||||
}
|
}
|
||||||
if (lp -> ends < comp -> ends) {
|
if (lp -> ends < lease -> 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;
|
||||||
@@ -410,13 +389,14 @@ printf ("\n");
|
|||||||
} else {
|
} else {
|
||||||
/* If we didn't, put it between lp and
|
/* If we didn't, put it between lp and
|
||||||
the next item on the list. */
|
the next item on the list. */
|
||||||
comp -> next = lp -> next;
|
if ((comp -> next = lp -> next))
|
||||||
comp -> next -> prev = comp;
|
comp -> next -> prev = comp;
|
||||||
comp -> prev = lp;
|
comp -> prev = lp;
|
||||||
lp -> next = comp;
|
lp -> next = comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comp -> contain -> insertion_point = comp;
|
comp -> contain -> insertion_point = comp;
|
||||||
|
comp -> ends = lease -> ends;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +407,8 @@ void release_lease (lease)
|
|||||||
{
|
{
|
||||||
struct lease lt;
|
struct lease lt;
|
||||||
|
|
||||||
lease -> ends = 0;
|
|
||||||
lt = *lease;
|
lt = *lease;
|
||||||
|
lt.ends = cur_time;
|
||||||
supersede_lease (lease, <);
|
supersede_lease (lease, <);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
options.c
40
options.c
@@ -150,10 +150,10 @@ void parse_option_buffer (packet, buffer, length)
|
|||||||
/* Cons up options based on client-supplied desired option list (if any)
|
/* Cons up options based on client-supplied desired option list (if any)
|
||||||
and selected server option list. */
|
and selected server option list. */
|
||||||
|
|
||||||
void cons_options (inpacket, outpacket, hp, overload)
|
void cons_options (inpacket, outpacket, options, overload)
|
||||||
struct packet *inpacket;
|
struct packet *inpacket;
|
||||||
struct packet *outpacket;
|
struct packet *outpacket;
|
||||||
struct host_decl *hp;
|
struct tree_cache **options;
|
||||||
int overload; /* Overload flags that may be set. */
|
int overload; /* Overload flags that may be set. */
|
||||||
{
|
{
|
||||||
option_mask options_have; /* Options we can send. */
|
option_mask options_have; /* Options we can send. */
|
||||||
@@ -217,7 +217,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
/* Make a bitmask of all the options we have available. */
|
/* Make a bitmask of all the options we have available. */
|
||||||
OPTION_ZERO (options_have);
|
OPTION_ZERO (options_have);
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
if (hp -> options [i])
|
if (options [i])
|
||||||
OPTION_SET (options_have, i);
|
OPTION_SET (options_have, i);
|
||||||
|
|
||||||
/* Put the cookie up front... */
|
/* Put the cookie up front... */
|
||||||
@@ -235,7 +235,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
int length;
|
int length;
|
||||||
|
|
||||||
/* If no data is available for this option, skip it. */
|
/* If no data is available for this option, skip it. */
|
||||||
if (!hp -> options [code])
|
if (!options [code])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Don't look at options that have already been stored. */
|
/* Don't look at options that have already been stored. */
|
||||||
@@ -243,11 +243,11 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Find the value of the option... */
|
/* Find the value of the option... */
|
||||||
if (!tree_evaluate (hp -> options [code]))
|
if (!tree_evaluate (options [code]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We should now have a constant length for the option. */
|
/* We should now have a constant length for the option. */
|
||||||
length = (hp -> options [code] -> len - stored_length [code]);
|
length = (options [code] -> len - stored_length [code]);
|
||||||
|
|
||||||
/* If there's no space for this option, skip it. */
|
/* If there's no space for this option, skip it. */
|
||||||
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
|
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
|
||||||
@@ -260,7 +260,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, store the option. */
|
/* Otherwise, store the option. */
|
||||||
result = store_option (hp, code,
|
result = store_option (options, code,
|
||||||
buffer + bufix,
|
buffer + bufix,
|
||||||
buflen - bufix - reserved,
|
buflen - bufix - reserved,
|
||||||
stored_length);
|
stored_length);
|
||||||
@@ -268,16 +268,16 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
|
|
||||||
/* The following test should always succeed because of
|
/* The following test should always succeed because of
|
||||||
preconditioning above. */
|
preconditioning above. */
|
||||||
if (stored_length [code] == hp -> options [code] -> len)
|
if (stored_length [code] == options [code] -> len)
|
||||||
OPTION_SET (options_done, code);
|
OPTION_SET (options_done, code);
|
||||||
else {
|
else {
|
||||||
warn ("%s: Only stored %d out of %d bytes.",
|
warn ("%s: Only stored %d out of %d bytes.",
|
||||||
dhcp_options [code].name,
|
dhcp_options [code].name,
|
||||||
stored_length [code],
|
stored_length [code],
|
||||||
hp -> options [code] -> len);
|
options [code] -> len);
|
||||||
if (++missed == 1) {
|
if (++missed == 1) {
|
||||||
missed_code = code;
|
missed_code = code;
|
||||||
missed_length = hp -> options [code] -> len
|
missed_length = options [code] -> len
|
||||||
- stored_length [code];
|
- stored_length [code];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,20 +300,20 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
overloading. */
|
overloading. */
|
||||||
if (reserved && missed == 1
|
if (reserved && missed == 1
|
||||||
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
|
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
|
||||||
result = store_option (hp, missed_code,
|
result = store_option (options, missed_code,
|
||||||
buffer + bufix, buflen - bufix,
|
buffer + bufix, buflen - bufix,
|
||||||
stored_length);
|
stored_length);
|
||||||
bufix += result;
|
bufix += result;
|
||||||
/* This test should always fail -- we'll send bad
|
/* This test should always fail -- we'll send bad
|
||||||
data if it doesn't. */
|
data if it doesn't. */
|
||||||
if (stored_length [missed_code]
|
if (stored_length [missed_code]
|
||||||
== hp -> options [missed_code] -> len) {
|
== options [missed_code] -> len) {
|
||||||
OPTION_SET (options_done, missed_code);
|
OPTION_SET (options_done, missed_code);
|
||||||
} else {
|
} else {
|
||||||
warn ("%s (last): Only stored %d out of %d bytes.",
|
warn ("%s (last): Only stored %d out of %d bytes.",
|
||||||
dhcp_options [missed_code].name,
|
dhcp_options [missed_code].name,
|
||||||
stored_length [missed_code],
|
stored_length [missed_code],
|
||||||
hp -> options [missed_code] -> len);
|
options [missed_code] -> len);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -323,7 +323,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
option into the current buffer and part into the next. */
|
option into the current buffer and part into the next. */
|
||||||
if (bufix + OPTION_SPACE (missed_length) + reserved
|
if (bufix + OPTION_SPACE (missed_length) + reserved
|
||||||
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
|
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
|
||||||
result = store_option (hp, missed_code,
|
result = store_option (options, missed_code,
|
||||||
buffer + bufix,
|
buffer + bufix,
|
||||||
buflen - bufix - reserved,
|
buflen - bufix - reserved,
|
||||||
stored_length);
|
stored_length);
|
||||||
@@ -331,7 +331,7 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
|
|
||||||
/* This test should never fail. */
|
/* This test should never fail. */
|
||||||
if (stored_length [missed_code]
|
if (stored_length [missed_code]
|
||||||
== hp -> options [missed_code] -> len) {
|
== options [missed_code] -> len) {
|
||||||
OPTION_SET (options_done, missed_code);
|
OPTION_SET (options_done, missed_code);
|
||||||
warn ("%s: Unexpected completed store.",
|
warn ("%s: Unexpected completed store.",
|
||||||
dhcp_options [missed_code].name);
|
dhcp_options [missed_code].name);
|
||||||
@@ -391,17 +391,17 @@ void cons_options (inpacket, outpacket, hp, overload)
|
|||||||
data that has been stored so far. Return 1 if all the option data
|
data that has been stored so far. Return 1 if all the option data
|
||||||
has been stored. */
|
has been stored. */
|
||||||
|
|
||||||
int store_option (hp, code, buffer, buflen, stored_length)
|
int store_option (options, code, buffer, buflen, stored_length)
|
||||||
struct host_decl *hp;
|
struct tree_cache **options;
|
||||||
unsigned char code;
|
unsigned char code;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int buflen;
|
int buflen;
|
||||||
int *stored_length;
|
int *stored_length;
|
||||||
{
|
{
|
||||||
int length = hp -> options [code] -> len - stored_length [code];
|
int length = options [code] -> len - stored_length [code];
|
||||||
int bufix = 0;
|
int bufix = 0;
|
||||||
printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
||||||
length, buflen, hp -> options [code] -> len, stored_length [code]);
|
length, buflen, options [code] -> len, stored_length [code]);
|
||||||
if (length > buflen) {
|
if (length > buflen) {
|
||||||
length = buflen;
|
length = buflen;
|
||||||
}
|
}
|
||||||
@@ -415,7 +415,7 @@ printf ("store_option: length = %d buflen = %d packet %d stored %d\n",
|
|||||||
unsigned char incr = length > 255 ? 255 : length;
|
unsigned char incr = length > 255 ? 255 : length;
|
||||||
buffer [bufix] = code;
|
buffer [bufix] = code;
|
||||||
buffer [bufix + 1] = incr;
|
buffer [bufix + 1] = incr;
|
||||||
memcpy (buffer + bufix + 2, (hp -> options [code] -> value
|
memcpy (buffer + bufix + 2, (options [code] -> value
|
||||||
+ stored_length [code]), incr);
|
+ stored_length [code]), incr);
|
||||||
length -= incr;
|
length -= incr;
|
||||||
stored_length [code] += incr;
|
stored_length [code] += incr;
|
||||||
|
@@ -102,9 +102,9 @@ void parse_statement (cfile)
|
|||||||
parsed_time = parse_timestamp (cfile, &bc);
|
parsed_time = parse_timestamp (cfile, &bc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RANGE:
|
case SUBNET:
|
||||||
if (!setjmp (bc)) {
|
if (!setjmp (bc)) {
|
||||||
parse_address_range (cfile, &bc);
|
parse_subnet_statement (cfile, &bc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -209,6 +209,113 @@ char *parse_host_name (cfile, bc)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* subnet_statement :== SUBNET net NETMASK netmask declarations SEMI
|
||||||
|
host_declarations :== <nil> | host_declaration
|
||||||
|
| host_declarations host_declaration SEMI */
|
||||||
|
|
||||||
|
struct subnet *parse_subnet_statement (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jmp_buf *bc;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
struct subnet *subnet;
|
||||||
|
struct iaddr net, netmask;
|
||||||
|
unsigned char addr [4];
|
||||||
|
int len = sizeof addr;
|
||||||
|
|
||||||
|
subnet = new_subnet ("parse_subnet_statement");
|
||||||
|
if (!subnet)
|
||||||
|
error ("No memory for new subnet");
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Get the network number... */
|
||||||
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
|
memcpy (net.iabuf, addr, len);
|
||||||
|
net.len = len;
|
||||||
|
subnet -> net = net;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NETMASK) {
|
||||||
|
parse_warn ("Expecting netmask");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the netmask... */
|
||||||
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
|
memcpy (netmask.iabuf, addr, len);
|
||||||
|
netmask.len = len;
|
||||||
|
subnet -> netmask = netmask;
|
||||||
|
|
||||||
|
enter_subnet (subnet);
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = peek_token (&val, cfile);
|
||||||
|
if (token == SEMI) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parse_subnet_decl (cfile, bc, subnet);
|
||||||
|
} while (1);
|
||||||
|
return subnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subnet_declaration :== hardware_declaration | filename_declaration
|
||||||
|
| fixed_addr_declaration | option_declaration */
|
||||||
|
|
||||||
|
void parse_subnet_decl (cfile, bc, decl)
|
||||||
|
FILE *cfile;
|
||||||
|
jmp_buf *bc;
|
||||||
|
struct subnet *decl;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
switch (token) {
|
||||||
|
case RANGE:
|
||||||
|
parse_address_range (cfile, bc, decl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric default lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)&decl -> default_lease_time,
|
||||||
|
val, 10, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric max lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)&decl -> max_lease_time,
|
||||||
|
val, 10, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parse_warn ("expecting a subnet declaration.");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (*bc, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* host_declaration :== hardware_declaration | filename_declaration
|
/* host_declaration :== hardware_declaration | filename_declaration
|
||||||
| fixed_addr_declaration | option_declaration */
|
| fixed_addr_declaration | option_declaration */
|
||||||
|
|
||||||
@@ -232,7 +339,7 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
parse_fixed_addr_decl (cfile, bc, decl);
|
parse_fixed_addr_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl);
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
break;
|
break;
|
||||||
case CIADDR:
|
case CIADDR:
|
||||||
decl -> ciaddr =
|
decl -> ciaddr =
|
||||||
@@ -400,10 +507,10 @@ void parse_fixed_addr_decl (cfile, bc, decl)
|
|||||||
would be painful to come up with BNF for it. However, it always
|
would be painful to come up with BNF for it. However, it always
|
||||||
starts as above. */
|
starts as above. */
|
||||||
|
|
||||||
void parse_option_decl (cfile, bc, decl)
|
void parse_option_decl (cfile, bc, options)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jmp_buf *bc;
|
jmp_buf *bc;
|
||||||
struct host_decl *decl;
|
struct tree_cache **options;
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int token;
|
int token;
|
||||||
@@ -570,11 +677,11 @@ void parse_option_decl (cfile, bc, decl)
|
|||||||
}
|
}
|
||||||
} while (*fmt == 'A');
|
} while (*fmt == 'A');
|
||||||
|
|
||||||
if (decl -> options [option -> code]) {
|
if (options [option -> code]) {
|
||||||
parse_warn ("duplicate option code %d (%s).",
|
parse_warn ("duplicate option code %d (%s).",
|
||||||
option -> code, option -> name);
|
option -> code, option -> name);
|
||||||
}
|
}
|
||||||
decl -> options [option -> code] = tree_cache (tree);
|
options [option -> code] = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timestamp :== TIMESTAMP date SEMI
|
/* timestamp :== TIMESTAMP date SEMI
|
||||||
@@ -724,13 +831,14 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
return &lease;
|
return &lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* address_range :== RANGE ip_address ip_address ip_address SEMI */
|
/* address_range :== RANGE ip_address ip_address */
|
||||||
|
|
||||||
void parse_address_range (cfile, bc)
|
void parse_address_range (cfile, bc, subnet)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jmp_buf *bc;
|
jmp_buf *bc;
|
||||||
|
struct subnet *subnet;
|
||||||
{
|
{
|
||||||
struct iaddr low, high, mask;
|
struct iaddr low, high;
|
||||||
unsigned char addr [4];
|
unsigned char addr [4];
|
||||||
int len = sizeof addr;
|
int len = sizeof addr;
|
||||||
int token;
|
int token;
|
||||||
@@ -746,21 +854,8 @@ void parse_address_range (cfile, bc)
|
|||||||
memcpy (high.iabuf, addr, len);
|
memcpy (high.iabuf, addr, len);
|
||||||
high.len = len;
|
high.len = len;
|
||||||
|
|
||||||
/* Get the netmask of the subnet containing the range... */
|
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
|
||||||
memcpy (mask.iabuf, addr, len);
|
|
||||||
mask.len = len;
|
|
||||||
|
|
||||||
/* Snarf the semi... */
|
|
||||||
token = next_token (&val, cfile);
|
|
||||||
if (token != SEMI) {
|
|
||||||
parse_warn ("semicolon expected");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (*bc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the new address range... */
|
/* Create the new address range... */
|
||||||
new_address_range (low, high, mask);
|
new_address_range (low, high, subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
||||||
|
119
server/dhcp.c
119
server/dhcp.c
@@ -54,6 +54,18 @@ void dhcp (packet)
|
|||||||
struct lease lt;
|
struct lease lt;
|
||||||
TIME lease_time;
|
TIME lease_time;
|
||||||
|
|
||||||
|
int bufs = 0;
|
||||||
|
struct packet outgoing;
|
||||||
|
struct dhcp_packet raw;
|
||||||
|
struct tree_cache *options [256];
|
||||||
|
struct sockaddr_in to;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
unsigned char dhcpoffer = DHCPOFFER;
|
||||||
|
struct tree_cache dhcpoffer_tree;
|
||||||
|
unsigned char lease_time_buf [4];
|
||||||
|
struct tree_cache lease_time_tree;
|
||||||
|
|
||||||
dump_packet (packet);
|
dump_packet (packet);
|
||||||
|
|
||||||
/* Try to find a lease that's been assigned to the specified
|
/* Try to find a lease that's been assigned to the specified
|
||||||
@@ -86,20 +98,6 @@ void dhcp (packet)
|
|||||||
} else
|
} else
|
||||||
ip_lease = (struct lease *)0;
|
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... */
|
/* Toss extra pointers to the same lease... */
|
||||||
if (ip_lease == hw_lease)
|
if (ip_lease == hw_lease)
|
||||||
ip_lease = (struct lease *)0;
|
ip_lease = (struct lease *)0;
|
||||||
@@ -108,20 +106,6 @@ void dhcp (packet)
|
|||||||
if (ip_lease == uid_lease)
|
if (ip_lease == uid_lease)
|
||||||
ip_lease = (struct lease *)0;
|
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
|
/* 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
|
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
|
have zeroed it out above, so the only way we can take it at this
|
||||||
@@ -145,20 +129,6 @@ void dhcp (packet)
|
|||||||
hw_lease = (struct lease *)0;
|
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
|
/* At this point, if ip_lease is nonzero, we can assign it to
|
||||||
this client. */
|
this client. */
|
||||||
lease = ip_lease;
|
lease = ip_lease;
|
||||||
@@ -249,5 +219,68 @@ void dhcp (packet)
|
|||||||
supersede_lease (lease, <);
|
supersede_lease (lease, <);
|
||||||
|
|
||||||
/* Send a response to the client... */
|
/* Send a response to the client... */
|
||||||
dump_subnets ();
|
|
||||||
|
memset (&outgoing, 0, sizeof outgoing);
|
||||||
|
memset (&raw, 0, sizeof raw);
|
||||||
|
outgoing.raw = &raw;
|
||||||
|
|
||||||
|
/* Copy in the filename if given; otherwise, flag the filename
|
||||||
|
buffer as available for options. */
|
||||||
|
bufs |= 1; /* XXX */
|
||||||
|
|
||||||
|
/* Copy in the server name if given; otherwise, flag the
|
||||||
|
server_name buffer as available for options. */
|
||||||
|
bufs |= 2; /* XXX */
|
||||||
|
|
||||||
|
memcpy (raw.chaddr, packet -> raw -> chaddr, packet -> raw -> hlen);
|
||||||
|
raw.hlen = packet -> raw -> hlen;
|
||||||
|
raw.htype = packet -> raw -> htype;
|
||||||
|
|
||||||
|
/* Start out with the subnet options... */
|
||||||
|
memcpy (options, packet -> subnet -> options, sizeof options);
|
||||||
|
|
||||||
|
/* Now put in options that override those. */
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] = &dhcpoffer_tree;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> value = &dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> len = sizeof dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> buf_size = sizeof dhcpoffer;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> timeout = 0xFFFFFFFF;
|
||||||
|
options [DHO_DHCP_MESSAGE_TYPE] -> tree = (struct tree *)0;
|
||||||
|
|
||||||
|
|
||||||
|
putULong (lease_time_buf, lease -> ends - cur_time);
|
||||||
|
options [DHO_DHCP_LEASE_TIME] = &lease_time_tree;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> value = lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> len = sizeof lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> buf_size = sizeof lease_time_buf;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> timeout = 0xFFFFFFFF;
|
||||||
|
options [DHO_DHCP_LEASE_TIME] -> tree = (struct tree *)0;
|
||||||
|
|
||||||
|
cons_options (packet, &outgoing, options, bufs);
|
||||||
|
|
||||||
|
raw.ciaddr = packet -> raw -> ciaddr;
|
||||||
|
memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
|
||||||
|
memcpy (&raw.siaddr, siaddr.iabuf, 4);
|
||||||
|
raw.giaddr = packet -> raw -> giaddr;
|
||||||
|
|
||||||
|
raw.xid = packet -> raw -> xid;
|
||||||
|
raw.secs = packet -> raw -> secs;
|
||||||
|
raw.flags = packet -> raw -> flags;
|
||||||
|
raw.hops = packet -> raw -> hops;
|
||||||
|
raw.op = BOOTREPLY;
|
||||||
|
|
||||||
|
to.sin_port = htons (2000);
|
||||||
|
to.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
|
to.sin_family = AF_INET;
|
||||||
|
to.sin_len = sizeof to;
|
||||||
|
memset (to.sin_zero, 0, sizeof to.sin_zero);
|
||||||
|
|
||||||
|
note ("Sending dhcp reply to %s, port %d",
|
||||||
|
inet_ntoa (to.sin_addr), htons (to.sin_port));
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
result = sendto (packet -> client_sock, &raw, outgoing.packet_length,
|
||||||
|
0, (struct sockaddr *)&to, sizeof to);
|
||||||
|
if (result < 0)
|
||||||
|
warn ("sendto: %m");
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,7 @@ 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;
|
||||||
|
struct iaddr siaddr;
|
||||||
|
|
||||||
int main (argc, argv, envp)
|
int main (argc, argv, envp)
|
||||||
int argc;
|
int argc;
|
||||||
@@ -66,7 +67,6 @@ 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;
|
||||||
@@ -152,7 +152,7 @@ int main (argc, argv, envp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
taddr.len = 0;
|
siaddr.len = 0;
|
||||||
server_addrlist = get_interface_list (&server_addrcount);
|
server_addrlist = get_interface_list (&server_addrcount);
|
||||||
for (i = 0; i < server_addrcount; i++) {
|
for (i = 0; i < server_addrcount; i++) {
|
||||||
struct sockaddr_in foo;
|
struct sockaddr_in foo;
|
||||||
@@ -160,13 +160,13 @@ int main (argc, argv, envp)
|
|||||||
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
printf ("Address %d: %s\n", i, inet_ntoa (foo.sin_addr));
|
||||||
|
|
||||||
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
if (server_addrlist [i] != htonl (INADDR_LOOPBACK)) {
|
||||||
if (taddr.len) {
|
if (siaddr.len) {
|
||||||
error ("dhcpd currently does not support "
|
error ("dhcpd currently does not support "
|
||||||
"multiple interfaces");
|
"multiple interfaces");
|
||||||
}
|
}
|
||||||
taddr.len = 4;
|
siaddr.len = 4;
|
||||||
memcpy (taddr.iabuf, &server_addrlist [i], 4);
|
memcpy (siaddr.iabuf, &server_addrlist [i], 4);
|
||||||
local_subnet = find_subnet (taddr);
|
local_subnet = find_subnet (siaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,8 +184,6 @@ int main (argc, argv, envp)
|
|||||||
close (i);
|
close (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_subnets ();
|
|
||||||
|
|
||||||
/* Receive packets and dispatch them... */
|
/* Receive packets and dispatch them... */
|
||||||
dispatch ();
|
dispatch ();
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
range 204.254.239.11 204.254.239.17 255.255.255.0;
|
subnet 204.254.239.0 netmask 255.255.255.0
|
||||||
range 204.254.240.11 204.254.240.12 255.255.255.0;
|
range 204.254.239.11 204.254.239.17;
|
||||||
|
|
||||||
|
subnet 204.254.240.0 netmask 255.255.255.0
|
||||||
|
range 204.254.240.11 204.254.240.12;
|
||||||
|
|
||||||
host minuet
|
host minuet
|
||||||
hardware ethernet 08:00:2b:35:0c:18
|
hardware ethernet 08:00:2b:35:0c:18
|
||||||
|
22
tables.c
22
tables.c
@@ -326,6 +326,17 @@ struct option dhcp_options [256] = {
|
|||||||
/* Default dhcp option priority list (this is ad hoc and should not be
|
/* Default dhcp option priority list (this is ad hoc and should not be
|
||||||
mistaken for a carefully crafted and optimized list). */
|
mistaken for a carefully crafted and optimized list). */
|
||||||
unsigned char dhcp_option_default_priority_list [] = {
|
unsigned char dhcp_option_default_priority_list [] = {
|
||||||
|
DHO_DHCP_REQUESTED_ADDRESS,
|
||||||
|
DHO_DHCP_LEASE_TIME,
|
||||||
|
DHO_DHCP_MESSAGE_TYPE,
|
||||||
|
DHO_DHCP_OPTION_OVERLOAD,
|
||||||
|
DHO_DHCP_SERVER_IDENTIFIER,
|
||||||
|
DHO_DHCP_MESSAGE,
|
||||||
|
DHO_DHCP_MAX_MESSAGE_SIZE,
|
||||||
|
DHO_DHCP_RENEWAL_TIME,
|
||||||
|
DHO_DHCP_REBINDING_TIME,
|
||||||
|
DHO_DHCP_CLASS_IDENTIFIER,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER,
|
||||||
DHO_SUBNET_MASK,
|
DHO_SUBNET_MASK,
|
||||||
DHO_TIME_OFFSET,
|
DHO_TIME_OFFSET,
|
||||||
DHO_ROUTERS,
|
DHO_ROUTERS,
|
||||||
@@ -375,18 +386,7 @@ unsigned char dhcp_option_default_priority_list [] = {
|
|||||||
DHO_NETBIOS_SCOPE,
|
DHO_NETBIOS_SCOPE,
|
||||||
DHO_FONT_SERVERS,
|
DHO_FONT_SERVERS,
|
||||||
DHO_X_DISPLAY_MANAGER,
|
DHO_X_DISPLAY_MANAGER,
|
||||||
DHO_DHCP_REQUESTED_ADDRESS,
|
|
||||||
DHO_DHCP_LEASE_TIME,
|
|
||||||
DHO_DHCP_OPTION_OVERLOAD,
|
|
||||||
DHO_DHCP_MESSAGE_TYPE,
|
|
||||||
DHO_DHCP_SERVER_IDENTIFIER,
|
|
||||||
DHO_DHCP_PARAMETER_REQUEST_LIST,
|
DHO_DHCP_PARAMETER_REQUEST_LIST,
|
||||||
DHO_DHCP_MESSAGE,
|
|
||||||
DHO_DHCP_MAX_MESSAGE_SIZE,
|
|
||||||
DHO_DHCP_RENEWAL_TIME,
|
|
||||||
DHO_DHCP_REBINDING_TIME,
|
|
||||||
DHO_DHCP_CLASS_IDENTIFIER,
|
|
||||||
DHO_DHCP_CLIENT_IDENTIFIER,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int sizeof_dhcp_option_default_priority_list =
|
int sizeof_dhcp_option_default_priority_list =
|
||||||
|
Reference in New Issue
Block a user