970602 snapshot

This commit is contained in:
mellon 1997-06-03 02:49:04 +00:00
parent eed746a9eb
commit 185e701358
39 changed files with 1826 additions and 293 deletions

69
usr.sbin/dhcp/CHANGES Normal file
View File

@ -0,0 +1,69 @@
970602
- Added DHCP Client scripts for FreeBSD, Solaris, and Linux, but
they're not guaranteed to work.
- Added some Cygwin32 (Windows NT/Windows 95) support, but this is not
sufficiently complete to be useful yet.
- Updated README
- Put something useful in TODO - formerly it mostly listed projects
that were way out on the back burner.
In DHCP Client:
- Add default, supersede, prepend and append option support, so that a
client can override or modify server-supplied options, and provide
default values if the server provides no values.
- Add reject keyword, so that packets from rogue DHCP or BOOTP servers
can be rejected out of hand.
- Added support for booting from BOOTP servers.
- Added BOOTP flag to client lease declaration, to indicated that a
particular lease was acquired through a BOOTP server.
- Don't try to do INIT-REBOOT on leases acquired from BOOTP servers.
- Print server's IP address instead of its IP address when logging
DHCP/BOOTP messages received by client.
- Fix some bugs in saved lease activation.
- Fix some scripting bugs.
- New sample dhclient.conf script demonstrates new features.
In common code:
- Partially implemented asynchronous DNS lookups.
- Fixed some bugs in dispatch routine.
- Fix date parsing bug that was setting dates forward one day every
time dhcpd was restarted (this has been fixed for a while in the 1.0
branch).
- Change name-server option name to ien116-name-server so as to reduce
the potential for confusion.
DHCP Relay daemon:
- Fixed an operator precedence bug having to do with the broadcast
flag.
DHCP Server:
- Add support to record the client-supplied hostname in the lease file,
for better readability.
- Fixed a bug in the renewal code that resulted in the server ignoring
unicast renewals from non-local subnets. This bug caused some
heartburn for Win95 machines.
- Copy ciaddr from saved ciaddr, not from giaddr.
- New -t flag tests /etc/dhcpd.conf for syntax errors.

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: clparse.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
"$Id: clparse.c,v 1.1.1.2 1997/06/03 02:49:12 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -183,6 +183,9 @@ void read_client_leases ()
/* client-declaration :==
SEND option-decl |
DEFAULT option-decl |
SUPERCEDE option-decl |
PREPEND option-decl |
APPEND option-decl |
hardware-declaration |
REQUEST option-list |
REQUIRE option-list |
@ -202,6 +205,7 @@ void parse_client_statement (cfile, ip, config)
{
int token;
char *val;
struct option *option;
switch (next_token (&val, cfile)) {
case SEND:
@ -209,7 +213,31 @@ void parse_client_statement (cfile, ip, config)
return;
case DEFAULT:
parse_option_decl (cfile, &config -> defaults [0]);
option = parse_option_decl (cfile, &config -> defaults [0]);
if (option)
config -> default_actions [option -> code] =
ACTION_DEFAULT;
return;
case SUPERSEDE:
option = parse_option_decl (cfile, &config -> defaults [0]);
if (option)
config -> default_actions [option -> code] =
ACTION_SUPERSEDE;
return;
case APPEND:
option = parse_option_decl (cfile, &config -> defaults [0]);
if (option)
config -> default_actions [option -> code] =
ACTION_APPEND;
return;
case PREPEND:
option = parse_option_decl (cfile, &config -> defaults [0]);
if (option)
config -> default_actions [option -> code] =
ACTION_PREPEND;
return;
case MEDIA:
@ -279,6 +307,10 @@ void parse_client_statement (cfile, ip, config)
parse_client_lease_statement (cfile, 2);
return;
case REJECT:
parse_reject_statement (cfile, config);
return;
default:
parse_warn ("expecting a statement.");
skip_to_semi (cfile);
@ -610,6 +642,7 @@ void parse_client_lease_statement (cfile, is_static)
}
/* client-lease-declaration :==
BOOTP |
INTERFACE string |
FIXED_ADDR ip_address |
FILENAME string |
@ -630,6 +663,10 @@ void parse_client_lease_declaration (cfile, lease, ipp)
struct interface_info *ip;
switch (next_token (&val, cfile)) {
case BOOTP:
lease -> is_bootp = 1;
break;
case INTERFACE:
token = next_token (&val, cfile);
if (token != STRING) {
@ -642,7 +679,8 @@ void parse_client_lease_declaration (cfile, lease, ipp)
break;
case FIXED_ADDR:
parse_ip_addr (cfile, &lease -> address);
if (!parse_ip_addr (cfile, &lease -> address))
return;
break;
case MEDIUM:
@ -685,19 +723,7 @@ void parse_client_lease_declaration (cfile, lease, ipp)
}
}
void parse_ip_addr (cfile, addr)
FILE *cfile;
struct iaddr *addr;
{
char *val;
int token;
addr -> len = 4;
parse_numeric_aggregate (cfile, addr -> iabuf,
&addr -> len, DOT, 10, 8);
}
void parse_option_decl (cfile, options)
struct option *parse_option_decl (cfile, options)
FILE *cfile;
struct option_data *options;
{
@ -720,7 +746,7 @@ void parse_option_decl (cfile, options)
parse_warn ("expecting identifier after option keyword.");
if (token != SEMI)
skip_to_semi (cfile);
return;
return (struct option *)0;
}
vendor = malloc (strlen (val) + 1);
if (!vendor)
@ -737,7 +763,7 @@ void parse_option_decl (cfile, options)
parse_warn ("expecting identifier after '.'");
if (token != SEMI)
skip_to_semi (cfile);
return;
return (struct option *)0;
}
/* Look up the option name hash table for the specified
@ -749,7 +775,7 @@ void parse_option_decl (cfile, options)
if (!universe) {
parse_warn ("no vendor named %s.", vendor);
skip_to_semi (cfile);
return;
return (struct option *)0;
}
} else {
/* Use the default hash table, which contains all the
@ -769,7 +795,7 @@ void parse_option_decl (cfile, options)
parse_warn ("no option named %s for vendor %s",
val, vendor);
skip_to_semi (cfile);
return;
return (struct option *)0;
}
/* Free the initial identifier token. */
@ -797,14 +823,14 @@ void parse_option_decl (cfile, options)
if (token != STRING) {
parse_warn ("expecting string.");
skip_to_semi (cfile);
return;
return (struct option *)0;
}
len = strlen (val);
if (hunkix + len + 1 > sizeof hunkbuf) {
parse_warn ("option data buffer %s",
"overflow");
skip_to_semi (cfile);
return;
return (struct option *)0;
}
memcpy (&hunkbuf [hunkix], val, len + 1);
nul_term = 1;
@ -812,7 +838,8 @@ void parse_option_decl (cfile, options)
break;
case 'I': /* IP address. */
parse_ip_addr (cfile, &ip_addr);
if (!parse_ip_addr (cfile, &ip_addr))
return (struct option *)0;
len = ip_addr.len;
dp = ip_addr.iabuf;
@ -821,7 +848,7 @@ void parse_option_decl (cfile, options)
parse_warn ("option data buffer %s",
"overflow");
skip_to_semi (cfile);
return;
return (struct option *)0;
}
memcpy (&hunkbuf [hunkix], dp, len);
hunkix += len;
@ -835,7 +862,7 @@ void parse_option_decl (cfile, options)
parse_warn ("expecting number.");
if (token != SEMI)
skip_to_semi (cfile);
return;
return (struct option *)0;
}
convert_num (buf, val, 0, 32);
len = 4;
@ -869,7 +896,7 @@ void parse_option_decl (cfile, options)
bad_flag:
if (token != SEMI)
skip_to_semi (cfile);
return;
return (struct option *)0;
}
if (!strcasecmp (val, "true")
|| !strcasecmp (val, "on"))
@ -889,7 +916,7 @@ void parse_option_decl (cfile, options)
warn ("Bad format %c in parse_option_param.",
*fmt);
skip_to_semi (cfile);
return;
return (struct option *)0;
}
}
token = next_token (&val, cfile);
@ -898,7 +925,7 @@ void parse_option_decl (cfile, options)
if (token != SEMI) {
parse_warn ("semicolon expected.");
skip_to_semi (cfile);
return;
return (struct option *)0;
}
options [option -> code].data =
@ -907,6 +934,7 @@ void parse_option_decl (cfile, options)
error ("out of memory allocating option data.");
memcpy (options [option -> code].data, hunkbuf, hunkix + nul_term);
options [option -> code].len = hunkix;
return option;
}
void parse_string_list (cfile, lp, multiple)
@ -958,3 +986,36 @@ void parse_string_list (cfile, lp, multiple)
skip_to_semi (cfile);
}
}
void parse_reject_statement (cfile, config)
FILE *cfile;
struct client_config *config;
{
int token;
char *val;
struct iaddr addr;
struct iaddrlist *list;
do {
if (!parse_ip_addr (cfile, &addr)) {
parse_warn ("expecting IP address.");
skip_to_semi (cfile);
return;
}
list = (struct iaddrlist *)malloc (sizeof (struct iaddrlist));
if (!list)
error ("no memory for reject list!");
list -> addr = addr;
list -> next = config -> reject_list;
config -> reject_list = list;
token = next_token (&val, cfile);
} while (token == COMMA);
if (token != SEMI) {
parse_warn ("expecting semicolon.");
skip_to_semi (cfile);
}
}

View File

@ -56,7 +56,7 @@
#ifndef lint
static char copyright[] =
"$Id: dhclient.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.1.1.2 1997/06/03 02:49:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -99,6 +99,7 @@ int main (argc, argv, envp)
int i;
struct servent *ent;
struct interface_info *ip;
int seed;
#ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY);
@ -107,7 +108,7 @@ int main (argc, argv, envp)
openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
#endif
#if !(defined (DEBUG) || defined (SYSLOG_4_2))
#if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
setlogmask (LOG_UPTO (LOG_INFO));
#endif
@ -143,7 +144,9 @@ int main (argc, argv, envp)
local_port = htons (68);
else
local_port = ent -> s_port;
#ifndef __CYGWIN32__
endservent ();
#endif
}
remote_port = htons (ntohs (local_port) - 1); /* XXX */
@ -196,9 +199,23 @@ int main (argc, argv, envp)
up the interfaces. */
discover_interfaces (DISCOVER_RUNNING);
/* Make up a seed for the random number generator from current
time plus the sum of the last four bytes of each
interface's hardware address interpreted as an integer.
Not much entropy, but we're booting, so we're not likely to
find anything better. */
seed = 0; /* Unfortunately, what's on the stack isn't random. :') */
for (ip = interfaces; ip; ip = ip -> next) {
int junk;
memcpy (&junk,
&ip -> hw_address.haddr [ip -> hw_address.hlen -
sizeof seed], sizeof seed);
seed += junk;
}
srandom (seed + cur_time);
/* Start a configuration state machine for each interface. */
for (ip = interfaces; ip; ip = ip -> next) {
srandom (cur_time + *(int *)(&ip -> hw_address.haddr [0]));
ip -> client -> state = S_INIT;
state_reboot (ip);
}
@ -258,7 +275,7 @@ void state_reboot (ipp)
/* If we don't remember an active lease, go straight to INIT. */
if (!ip -> client -> active ||
ip -> client -> active -> rebind < cur_time) {
ip -> client -> active -> is_bootp) {
state_init (ip);
return;
}
@ -359,6 +376,23 @@ void state_selecting (ipp)
return;
}
/* If it was a BOOTREPLY, we can just take the address right now. */
if (!picked -> options [DHO_DHCP_MESSAGE_TYPE].len) {
ip -> client -> new = picked;
/* Make up some lease expiry times
XXX these should be configurable. */
ip -> client -> new -> expiry = cur_time + 12000;
ip -> client -> new -> renewal += cur_time + 8000;
ip -> client -> new -> rebind += cur_time + 10000;
ip -> client -> state = S_REQUESTING;
/* Bind to the address we received. */
bind_lease (ip);
return;
}
/* Go to the REQUESTING state. */
ip -> client -> destination = iaddr_broadcast;
ip -> client -> state = S_REQUESTING;
@ -401,10 +435,7 @@ void dhcpack (packet)
return;
}
note ("DHCPACK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
note ("DHCPACK from %s", piaddr (packet -> client_addr));
lease = packet_to_lease (packet);
if (!lease) {
@ -447,6 +478,12 @@ void dhcpack (packet)
ip -> client -> new -> renewal += cur_time;
ip -> client -> new -> rebind += cur_time;
bind_lease (ip);
}
void bind_lease (ip)
struct interface_info *ip;
{
/* Write out the new lease. */
write_client_lease (ip, ip -> client -> new);
@ -478,7 +515,8 @@ void dhcpack (packet)
add_timeout (ip -> client -> active -> renewal,
state_bound, ip);
note ("bound: renewal in %d seconds.",
note ("bound to %s -- renewal in %d seconds.",
piaddr (ip -> client -> active -> address),
ip -> client -> active -> renewal - cur_time);
ip -> client -> state = S_BOUND;
reinitialize_interfaces ();
@ -536,31 +574,64 @@ void db_startup ()
void bootp (packet)
struct packet *packet;
{
note ("BOOTREPLY from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
struct iaddrlist *ap;
if (packet -> raw -> op != BOOTREPLY)
return;
/* If there's a reject list, make sure this packet's sender isn't
on it. */
for (ap = packet -> interface -> client -> config -> reject_list;
ap; ap = ap -> next) {
if (addr_eq (packet -> client_addr, ap -> addr)) {
note ("BOOTREPLY from %s rejected.",
piaddr (ap -> addr));
return;
}
}
dhcpoffer (packet);
}
void dhcp (packet)
struct packet *packet;
{
struct iaddrlist *ap;
void (*handler) PROTO ((struct packet *));
char *type;
switch (packet -> packet_type) {
case DHCPOFFER:
dhcpoffer (packet);
handler = dhcpoffer;
type = "DHCPOFFER";
break;
case DHCPNAK:
dhcpnak (packet);
handler = dhcpnak;
type = "DHCPNACK";
break;
case DHCPACK:
dhcpack (packet);
handler = dhcpack;
type = "DHCPACK";
break;
default:
break;
return;
}
/* If there's a reject list, make sure this packet's sender isn't
on it. */
for (ap = packet -> interface -> client -> config -> reject_list;
ap; ap = ap -> next) {
if (addr_eq (packet -> client_addr, ap -> addr)) {
note ("%s from %s rejected.",
type, piaddr (ap -> addr));
return;
}
}
(*handler) (packet);
}
void dhcpoffer (packet)
@ -570,6 +641,9 @@ void dhcpoffer (packet)
struct client_lease *lease, *lp;
int i;
int arp_timeout_needed, stop_selecting;
char *name = (packet -> options [DHO_DHCP_MESSAGE_TYPE].len
? "DHCPOFFER" : "BOOTREPLY");
struct iaddrlist *ap;
#ifdef DEBUG_PACKET
dump_packet (packet);
@ -579,21 +653,18 @@ void dhcpoffer (packet)
has an unrecognizable transaction id, then just drop it. */
if (ip -> client -> state != S_SELECTING ||
packet -> interface -> client -> xid != packet -> raw -> xid) {
debug ("DHCPOFFER in wrong transaction.");
debug ("%s in wrong transaction.", name);
return;
}
note ("DHCPOFFER from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
note ("%s from %s", name, piaddr (packet -> client_addr));
/* If this lease doesn't supply the minimum required parameters,
blow it off. */
for (i = 0; ip -> client -> config -> required_options [i]; i++) {
if (!packet -> options [ip -> client -> config ->
required_options [i]].len) {
note ("DHCPOFFER isn't satisfactory.");
note ("%s isn't satisfactory.", name);
return;
}
}
@ -604,7 +675,7 @@ void dhcpoffer (packet)
if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
!memcmp (lease -> address.iabuf,
&packet -> raw -> yiaddr, lease -> address.len)) {
debug ("DHCPOFFER already seen.");
debug ("%s already seen.", name);
return;
}
}
@ -615,6 +686,11 @@ void dhcpoffer (packet)
return;
}
/* If this lease was acquired through a BOOTREPLY, record that
fact. */
if (!packet -> options [DHO_DHCP_MESSAGE_TYPE].len)
lease -> is_bootp = 1;
/* Record the medium under which this lease was offered. */
lease -> medium = ip -> client -> medium;
@ -785,10 +861,7 @@ void dhcpnak (packet)
return;
}
note ("DHCPNAK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
note ("DHCPNAK from %s", piaddr (packet -> client_addr));
if (!ip -> client -> active) {
note ("DHCPNAK with no active lease.\n");
@ -806,10 +879,8 @@ void dhcpnak (packet)
}
/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
one after the right interval has expired. If we are past the renewal
(T1) interval but not yet past the rebind (T2) interval, unicast
the message; otherwise broadcast it. If the lease expires, go back to
the INIT state. */
one after the right interval has expired. If we don't get an offer by
the time we reach the panic interval, call the panic function. */
void send_discover (ipp)
void *ipp;
@ -893,17 +964,17 @@ void send_discover (ipp)
(ip -> client -> first_sending +
ip -> client -> config -> timeout) - cur_time + 1;
note ("DHCPDISCOVER on %s to %s port %d interval %ld",
ip -> name,
inet_ntoa (sockaddr_broadcast.sin_addr),
ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
/* Record the number of seconds since we started sending. */
if (interval < 255)
ip -> client -> packet.secs = interval;
else
ip -> client -> packet.secs = 255;
note ("DHCPDISCOVER on %s to %s port %d interval %ld",
ip -> name,
inet_ntoa (sockaddr_broadcast.sin_addr),
ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
/* Send out a packet. */
result = send_packet (ip, (struct packet *)0,
&ip -> client -> packet,
@ -933,10 +1004,8 @@ void state_panic (ipp)
/* We may not have an active lease, but we may have some
predefined leases that we can try. */
if (!ip -> client -> active && ip -> client -> leases) {
loop = ip -> client -> leases;
if (!ip -> client -> active && ip -> client -> leases)
goto activate_next;
}
/* Run through the list of leases and see if one can be used. */
while (ip -> client -> active) {
@ -1001,6 +1070,8 @@ void state_panic (ipp)
now. */
if (ip -> client -> active == loop)
break;
else if (!loop)
loop = ip -> client -> active;
}
/* No leases were available, or what was available didn't work, so
@ -1014,6 +1085,7 @@ void state_panic (ipp)
ip -> client -> state = S_INIT;
add_timeout (cur_time + ip -> client -> config -> retry_interval,
state_init, ip);
go_daemon ();
}
void send_request (ipp)
@ -1626,6 +1698,8 @@ void write_client_lease (ip, lease)
}
fprintf (leaseFile, "lease {\n");
if (lease -> is_bootp)
fprintf (leaseFile, " bootp;\n");
fprintf (leaseFile, " interface \"%s\";\n", ip -> name);
fprintf (leaseFile, " fixed-address %s;\n",
piaddr (lease -> address));
@ -1645,7 +1719,7 @@ void write_client_lease (ip, lease)
dhcp_options [i].name,
pretty_print_option
(i, lease -> options [i].data,
lease -> options [i].len, 1));
lease -> options [i].len, 1, 1));
}
}
t = gmtime (&lease -> renewal);
@ -1706,6 +1780,8 @@ void script_write_params (ip, prefix, lease)
struct client_lease *lease;
{
int i;
u_int8_t dbuf [1500];
int len;
fprintf (scriptFile, "%sip_address=\"%s\"\n",
prefix, piaddr (lease -> address));
@ -1721,13 +1797,82 @@ void script_write_params (ip, prefix, lease)
fprintf (scriptFile, "export %sserver_name\n", prefix);
}
for (i = 0; i < 256; i++) {
if (lease -> options [i].len) {
u_int8_t *dp;
if (ip -> client -> config -> defaults [i].len) {
if (lease -> options [i].len) {
switch (ip -> client ->
config -> default_actions [i]) {
case ACTION_DEFAULT:
dp = lease -> options [i].data;
len = lease -> options [i].len;
break;
case ACTION_SUPERSEDE:
supersede:
dp = ip -> client ->
config -> defaults [i].data;
len = ip -> client ->
config -> defaults [i].len;
break;
case ACTION_PREPEND:
len = (ip -> client ->
config -> defaults [i].len +
lease -> options [i].len);
if (len > sizeof dbuf) {
warn ("no space to %s %s",
"prepend option",
dhcp_options [i].name);
goto supersede;
}
dp = dbuf;
memcpy (dp,
ip -> client ->
config -> defaults [i].data,
ip -> client ->
config -> defaults [i].len);
memcpy (dp + ip -> client ->
config -> defaults [i].len,
lease -> options [i].data,
lease -> options [i].len);
break;
case ACTION_APPEND:
len = (ip -> client ->
config -> defaults [i].len +
lease -> options [i].len);
if (len > sizeof dbuf) {
warn ("no space to %s %s",
"prepend option",
dhcp_options [i].name);
goto supersede;
}
dp = dbuf;
memcpy (dp,
ip -> client ->
config -> defaults [i].data,
ip -> client ->
config -> defaults [i].len);
memcpy (dp + ip -> client ->
config -> defaults [i].len,
lease -> options [i].data,
lease -> options [i].len);
}
} else {
dp = ip -> client ->
config -> defaults [i].data;
len = ip -> client ->
config -> defaults [i].len;
}
} else if (lease -> options [i].len) {
len = lease -> options [i].len;
dp = lease -> options [i].data;
} else {
len = 0;
}
if (len) {
char *s = dhcp_option_ev_name (&dhcp_options [i]);
fprintf (scriptFile,
"%s%s=\"%s\"\n", prefix, s,
pretty_print_option
(i, lease -> options [i].data,
lease -> options [i].len, 0));
fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s,
pretty_print_option (i, dp, len, 0, 0));
fprintf (scriptFile, "export %s%s\n", prefix, s);
}
}

View File

@ -1,30 +1,35 @@
send host-name "snark.fugue.com";
send dhcp-client-identifier "snark";
send host-name "andare.fugue.com";
send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
send dhcp-lease-time 3600;
supersede domain-name "fugue.com home.vix.com";
prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name;
require subnet-mask, routers, domain-name-servers;
timeout 30;
require subnet-mask, domain-name-servers;
timeout 60;
retry 60;
reboot 10;
select-timeout 5;
initial-interval 2;
script "/etc/dhclient-script";
media "-link0 -link1 -link2", "link0 link1";
reject 192.33.137.209;
#alias {
# interface "ep0";
# fixed-address 192.5.5.213;
# option subnet-mask 255.255.255.255;
#}
alias {
interface "ep0";
fixed-address 192.5.5.213;
option subnet-mask 255.255.255.255;
}
lease {
interface "ep0";
fixed-address 10.9.8.7;
fixed-address 192.33.137.200;
medium "link0 link1";
option host-name "snark.nowhere.com";
option host-name "andare.swiftmedia.com";
option subnet-mask 255.255.255.0;
option broadcast-address 10.9.8.255;
option routers 10.9.8.1;
option domain-name "nowhere.com";
option domain-name-servers 127.0.0.1, 10.9.8.7;
option broadcast-address 192.33.137.255;
option routers 192.33.137.250;
option domain-name-servers 127.0.0.1;
renew 2 2000/1/12 00:00:01;
rebind 2 2000/1/12 00:00:01;
expire 2 2000/1/12 00:00:01;

View File

@ -0,0 +1,136 @@
#!/bin/sh
if [ x$new_broadcast_address != x ]; then
new_broadcast_arg="broadcast $new_broadcast_address"
fi
if [ x$old_broadcast_address != x ]; then
old_broadcast_arg="broadcast $old_broadcast_address"
fi
if [ x$new_subnet_mask != x ]; then
new_netmask_arg="netmask $new_subnet_mask"
fi
if [ x$old_subnet_mask != x ]; then
old_netmask_arg="netmask $old_subnet_mask"
fi
if [ x$alias_subnet_mask != x ]; then
alias_subnet_arg="netmask $alias_subnet_mask"
fi
if [ x$reason = xMEDIUM ]; then
ifconfig $interface $medium
ifconfig $interface inet -alias 0.0.0.0 $medium >/dev/null 2>&1
ifconfig $interface
sleep 1
exit 0
fi
if [ x$reason = xPREINIT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
broadcast 255.255.255.255 up
exit 0
fi
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
exit 0;
fi
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
[ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
[ x$alias_ip_address != x$old_ip_address ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' |sh
fi
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
fi
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
echo search $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
done
exit 0
fi
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
fi
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
exit 0
fi
if [ x$reason = xTIMEOUT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
sleep 1
set $new_routers
if ping -q -c 1 -w 1 $1; then
if [ x$new_ip_address != x$alias_ip_address ] && \
[ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
echo search $new_domain_name >/etc/resolv.conf.std
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf.std
done
if [ -f /etc/resolv.conf ]; then
rm -f /etc/resolv.conf
ln /etc/resolv.conf.std /etc/resolv.conf
fi
exit 0
fi
ifconfig $interface inet -alias $new_ip_address $medium
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
exit 1
fi
exit 0

View File

@ -0,0 +1,156 @@
#!/bin/sh
# dhclient-script for Linux. Dan Halbert, March, 1997.
# No guarantees about this. I'm a novice at the details of Linux
# networking.
# Notes:
# 0. This script is based on the netbsd script supplied with dhcp-970306.
# 1. ifconfig down apparently deletes all relevant routes and flushes
# the arp cache, so this doesn't need to be done explicitly.
# 2. The alias address handling here has not been tested AT ALL.
# I'm just going by the doc of modern Linux ip aliasing, which uses
# notations like eth0:0, eth0:1, for each alias.
# 3. I have to calculate the network address, and calculate the broadcast
# address if it is not supplied. This might be much more easily done
# by the dhclient C code, and passed on.
# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious
# of the $1 in its args.
############################################################################
# This horror, which depends on bash, does a bitwise and of the ip
# address and the network mask to produce the network address.
eval `echo $new_ip_address $new_subnet_mask | sed -e 's/\([0-9]\+\).\([0-9]\+\).\([0-9]\+\).\([0-9]\+\) \([0-9]\+\).\([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/new_network_address="$[\1\&\5].$[\2\&\6].$[\3\&\7].$[4\&\8]"/'`
# A similar horror to calculate the broadcast address if it's not given.
if [ x$new_broadcast_address = x ]; then
eval `echo $new_ip_address $new_subnet_mask | sed -e 's/\([0-9]\+\).\([0-9]\+\).\([0-9]\+\).\([0-9]\+\) \([0-9]\+\).\([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/new_broadcast_address="$[(\1\|~\5)\&255].$[(\2\|~\6)\&255].$[(\3\|~\7)\&255].$[(4\|~\8)\&255]"/'`
fi
if [ x$new_broadcast_address != x ]; then
new_broadcast_arg="broadcast $new_broadcast_address"
fi
if [ x$old_broadcast_address != x ]; then
old_broadcast_arg="broadcast $old_broadcast_address"
fi
if [ x$new_subnet_mask != x ]; then
new_subnet_arg="netmask $new_subnet_mask"
fi
if [ x$old_subnet_mask != x ]; then
old_subnet_arg="netmask $old_subnet_mask"
fi
if [ x$alias_subnet_mask != x ]; then
alias_subnet_arg="netmask $alias_subnet_mask"
fi
if [ x$reason = xMEDIUM ]; then
# Linux doesn't do mediums (ok, ok, media).
exit 0
fi
if [ x$reason = xPREINIT ]; then
if [ x$alias_ip_address != x ]; then
# Bring down alias interface. Its routes will disappear too.
ifconfig $interface:0- inet 0
fi
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
broadcast 255.255.255.255 up
# Add route to make broadcast work. Do not omit netmask.
route add default dev $interface netmask 0.0.0.0
exit 0
fi
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
exit 0;
fi
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
[ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
[ x$alias_ip_address != x$old_ip_address ]; then
# Possible new alias. Remove old alias.
ifconfig $interface:0- inet 0
fi
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
# IP address changed. Bringing down the interface will delete all routes,
# and clear the ARP cache.
ifconfig $interface inet down
fi
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
ifconfig $interface inet $new_ip_address $new_subnet_arg \
$new_broadcast_arg
# Add a network route to the computed network address.
route add -net $new_network_address $new_subnet_arg dev $interface
for router in $new_routers; do
route add default gw $router
done
fi
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
then
ifconfig $interface:0- inet 0
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
route add -host $alias_ip_address $interface:0
fi
echo domain $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
done
exit 0
fi
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
if [ x$alias_ip_address != x ]; then
# Turn off alias interface.
ifconfig $interface:0- inet 0
fi
if [ x$old_ip_address != x ]; then
# Shut down interface, which will delete routes and clear arp cache.
ifconfig $interface inet down
fi
if [ x$alias_ip_address != x ]; then
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
route add -host $alias_ip_address $interface:0
fi
exit 0
fi
if [ x$reason = xTIMEOUT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface:0- inet 0
fi
ifconfig $interface inet $new_ip_address $new_subnet_arg \
$new_broadcast_arg
set $new_routers
############## what is -w in ping?
if ping -q -c 1 -w 1 $1; then
if [ x$new_ip_address != x$alias_ip_address ] && \
[ x$alias_ip_address != x ]; then
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
route add -host $alias_ip_address dev $interface:0
fi
route add -net $new_network_address
for router in $new_routers; do
route add default gw $router
done
echo domain $new_domain_name >/etc/resolv.conf.std
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf.std
done
if [ -f /etc/resolv.conf ]; then
rm -f /etc/resolv.conf
ln /etc/resolv.conf.std /etc/resolv.conf
fi
exit 0
fi
ifconfig $interface inet down
exit 1
fi
exit 0

View File

@ -85,7 +85,7 @@ if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p'i \
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
fi
if [ x$alias_ip_address != x ]; then

View File

@ -0,0 +1,148 @@
#!/bin/sh
if [ x$new_broadcast_address != x ]; then
new_broadcast_arg="broadcast $new_broadcast_address"
fi
if [ x$old_broadcast_address != x ]; then
old_broadcast_arg="broadcast $old_broadcast_address"
fi
if [ x$new_subnet_mask != x ]; then
new_netmask_arg="netmask $new_subnet_mask"
fi
if [ x$old_subnet_mask != x ]; then
old_netmask_arg="netmask $old_subnet_mask"
fi
if [ x$alias_subnet_mask != x ]; then
alias_subnet_arg="netmask $alias_subnet_mask"
fi
# For Solaris, ifconfig lives in /sbin
OS=`uname -r`
if [ $OS = "5.5.1" ]; then
PATH=/sbin:$PATH
fi
if [ x$reason = xMEDIUM ]; then
ifconfig $interface $medium
ifconfig $interface inet -alias 0.0.0.0 $medium >/dev/null 2>&1
ifconfig $interface
sleep 1
exit 0
fi
if [ x$reason = xPREINIT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ $OS = "5.5.1" ]; then
# Turn the interface on
ifconfig $interface plumb
ifconfig $interface inet 10.0.0.1 up
else
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
broadcast 255.255.255.255 up
fi
exit 0
fi
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
exit 0;
fi
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
[ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
[ x$alias_ip_address != x$old_ip_address ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' |sh
fi
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
fi
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
echo search $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
done
exit 0
fi
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p'i \
|sh >/dev/null 2>&1
fi
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
exit 0
fi
if [ x$reason = xTIMEOUT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
sleep 1
set $new_routers
if ping -c 1 -w 1 $1; then
if [ x$new_ip_address != x$alias_ip_address ] && \
[ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
echo search $new_domain_name >/etc/resolv.conf.std
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf.std
done
if [ -f /etc/resolv.conf ]; then
rm -f /etc/resolv.conf
ln /etc/resolv.conf.std /etc/resolv.conf
fi
exit 0
fi
ifconfig $interface inet -alias $new_ip_address $medium
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
exit 1
fi
exit 0

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: alloc.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: alloc.c,v 1.1.1.2 1997/06/03 02:49:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -184,7 +184,7 @@ struct group *new_group (name)
struct protocol *new_protocol (name)
char *name;
{
struct protocol *rval = dmalloc (sizeof (struct group), name);
struct protocol *rval = dmalloc (sizeof (struct protocol), name);
return rval;
}
@ -205,6 +205,36 @@ struct lease_state *new_lease_state (name)
return rval;
}
struct domain_search_list *new_domain_search_list (name)
char *name;
{
struct domain_search_list *rval =
dmalloc (sizeof (struct domain_search_list), name);
return rval;
}
struct name_server *new_name_server (name)
char *name;
{
struct name_server *rval =
dmalloc (sizeof (struct name_server), name);
return rval;
}
void free_name_server (ptr, name)
struct name_server *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_domain_search_list (ptr, name)
struct domain_search_list *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_lease_state (ptr, name)
struct lease_state *ptr;
char *name;

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: conflex.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
"$Id: conflex.c,v 1.1.1.2 1997/06/03 02:49:19 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -55,6 +55,7 @@ char *token_line;
char *prev_line;
char *cur_line;
char *tlname;
int eol_token;
static char line1 [81];
static char line2 [81];
@ -141,7 +142,7 @@ static int get_token (cfile)
comments [comment_index++] = '\n';
#endif
if (isascii (c) && isspace (c))
if (!(c == '\n' && eol_token) && isascii (c) && isspace (c))
continue;
if (c == '#') {
#ifdef OLD_LEXER
@ -353,6 +354,8 @@ static int intern (atom, dfv)
switch (tolower (atom [0])) {
case 'a':
if (!strcasecmp (atom + 1, "ppend"))
return APPEND;
if (!strcasecmp (atom + 1, "llow"))
return ALLOW;
if (!strcasecmp (atom + 1, "lias"))
@ -378,6 +381,8 @@ static int intern (atom, dfv)
return CLIENT_IDENTIFIER;
break;
case 'd':
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
if (!strcasecmp (atom + 1, "eny"))
return DENY;
if (!strncasecmp (atom + 1, "efault", 6)) {
@ -447,6 +452,8 @@ static int intern (atom, dfv)
}
break;
case 'n':
if (!strcasecmp (atom + 1, "ameserver"))
return NAMESERVER;
if (!strcasecmp (atom + 1, "etmask"))
return NETMASK;
if (!strcasecmp (atom + 1, "ext-server"))
@ -459,6 +466,8 @@ static int intern (atom, dfv)
return ONE_LEASE_PER_CLIENT;
break;
case 'p':
if (!strcasecmp (atom + 1, "repend"))
return PREPEND;
if (!strcasecmp (atom + 1, "acket"))
return PACKET;
break;
@ -477,8 +486,12 @@ static int intern (atom, dfv)
return REBIND;
if (!strcasecmp (atom + 1, "eboot"))
return REBOOT;
if (!strcasecmp (atom + 1, "eject"))
return REJECT;
break;
case 's':
if (!strcasecmp (atom + 1, "earch"))
return SEARCH;
if (!strcasecmp (atom + 1, "tarts"))
return STARTS;
if (!strcasecmp (atom + 1, "iaddr"))
@ -497,6 +510,8 @@ static int intern (atom, dfv)
return SEND;
if (!strcasecmp (atom + 1, "cript"))
return SCRIPT;
if (!strcasecmp (atom + 1, "upersede"))
return SUPERSEDE;
break;
case 't':
if (!strcasecmp (atom + 1, "imestamp"))

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: convert.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: convert.c,v 1.1.1.2 1997/06/03 02:49:21 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -104,7 +104,7 @@ void putUShort (obuf, val)
unsigned char *obuf;
u_int16_t val;
{
u_int16_t tmp = htonl (val);
u_int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
}
@ -112,7 +112,7 @@ void putShort (obuf, val)
unsigned char *obuf;
int16_t val;
{
int16_t tmp = htonl (val);
int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: dispatch.c,v 1.1.1.2 1997/03/29 23:57:54 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: dispatch.c,v 1.1.1.3 1997/06/03 02:49:23 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -140,7 +140,9 @@ void discover_interfaces (state)
except don't skip down interfaces if we're trying to
get a list of configurable interfaces. */
if ((ifr.ifr_flags & IFF_LOOPBACK) ||
#ifdef IFF_POINTOPOINT
(ifr.ifr_flags & IFF_POINTOPOINT) ||
#endif
(!(ifr.ifr_flags & IFF_UP) &&
state != DISCOVER_UNCONFIGURED))
continue;
@ -514,7 +516,6 @@ void dispatch ()
for (l = protocols; l; l = l -> next) {
FD_SET (l -> fd, &r);
FD_SET (l -> fd, &x);
if (l -> fd > max)
max = l -> fd;
}

View File

@ -48,7 +48,7 @@
#ifndef lint
static char copyright[] =
"$Id: dns.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
"$Id: dns.c,v 1.1.1.2 1997/06/03 02:49:25 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -60,13 +60,15 @@ int dns_protocol_fd;
static int addlabel PROTO ((u_int8_t *, char *));
static int skipname PROTO ((u_int8_t *));
static int copy_out_name PROTO ((u_int8_t *, u_int8_t *, char *));
static int nslookup PROTO ((u_int8_t, char *, int, u_int16_t, u_int16_t));
static int zonelookup PROTO ((u_int8_t, char *, int, u_int16_t));
u_int16_t dns_port;
/* Initialize the DNS protocol. */
void dns_startup ()
{
struct servent *srv;
u_int16_t dns_port = htons (53);
struct sockaddr_in from;
/* Only initialize icmp once. */
@ -75,15 +77,19 @@ void dns_startup ()
dns_protocol_initialized = 1;
/* Get the protocol number (should be 1). */
srv = getsrvbyname ("domain", "tcp");
srv = getservbyname ("domain", "tcp");
if (srv)
port = srv -> s_port;
dns_port = srv -> s_port;
else
dns_port = htons (53);
/* Get a raw socket for the ICMP protocol. */
/* Get a socket for the DNS protocol. */
dns_protocol_fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (!dns_protocol_fd)
error ("unable to create dns socket: %m");
pick_name_server ();
add_protocol ("dns", dns_protocol_fd, dns_packet, 0);
}
@ -145,8 +151,7 @@ static int copy_out_name (base, name, buf)
called with a null pointer. Otherwise, the callback is called with the
address of the string returned by the name server. */
int ns_inaddr_lookup (server, id, inaddr)
struct sockaddr_in *server;
int ns_inaddr_lookup (id, inaddr)
u_int16_t id;
struct iaddr inaddr;
{
@ -159,7 +164,7 @@ int ns_inaddr_lookup (server, id, inaddr)
for (i = 3; i >= 0; --i) {
label = s++;
*label = 1;
c = inaddr -> addr [i];
c = inaddr.iabuf [i];
if (c > 100) {
++*label;
*s++ = '0' + c / 100;
@ -173,13 +178,13 @@ int ns_inaddr_lookup (server, id, inaddr)
s += addlabel (s, "in-addr");
s += addlabel (s, "arpa");
*s++ = 0;
return nslookup (server, id, namebuf, s - namebuf, T_PTR, C_IN);
/* return nslookup (id, namebuf, s - namebuf, T_PTR, C_IN); */
return zonelookup (id, namebuf, s - namebuf, C_IN);
}
/* Construct and transmit a name server query. */
int nslookup (server, id, qname, namelen, qtype, qclass)
struct sockaddr_in *server;
static int nslookup (id, qname, namelen, qtype, qclass)
u_int8_t id;
char *qname;
int namelen;
@ -188,20 +193,21 @@ int nslookup (server, id, qname, namelen, qtype, qclass)
{
HEADER *hdr;
unsigned char query [512];
unsigned char *s;
u_int8_t *s;
int len;
int i;
int i, status;
struct sockaddr_in *server = pick_name_server ();
/* Construct a header... */
hdr = (HEADER *)query;
memset (&hdr, 0, sizeof hdr);
memset (hdr, 0, sizeof *hdr);
hdr -> id = htons (id);
hdr -> rd = 1;
hdr -> opcode = QUERY;
hdr -> qdcount = htons (1);
/* Copy in the name we're looking up. */
s = (u_int8_t)(hdr + 1);
s = (u_int8_t *)(hdr + 1);
memcpy (s, qname, namelen);
s += namelen;
@ -223,9 +229,88 @@ int nslookup (server, id, qname, namelen, qtype, qclass)
return 1;
}
/* Construct a query for the SOA for a specified name.
Try every possible SOA name starting from the name specified and going
to the root name - e.g., for
215.5.5.192.in-addr.arpa, look for SOAs matching:
215.5.5.5.192.in-addr.arpa
5.5.192.in-addr.arpa
5.192.in-addr.arpa
192.in-addr.arpa
in-addr.arpa
arpa */
static int zonelookup (id, qname, namelen, qclass)
u_int8_t id;
char *qname;
int namelen;
u_int16_t qclass;
{
HEADER *hdr;
unsigned char query [512];
u_int8_t *s, *nptr;
int len;
int i, status, count;
struct sockaddr_in *server = pick_name_server ();
/* Construct a header... */
hdr = (HEADER *)query;
memset (hdr, 0, sizeof *hdr);
hdr -> id = htons (id);
hdr -> rd = 1;
hdr -> opcode = QUERY;
/* Copy in the name we're looking up. */
s = (u_int8_t *)(hdr + 1);
memcpy (s, qname, namelen);
s += namelen;
/* Set the query type. */
putUShort (s, T_SOA);
s += sizeof (u_int16_t);
/* Set the query class. */
putUShort (s, qclass);
s += sizeof (u_int16_t);
count = 1;
/* Now query up the hierarchy. */
nptr = (u_int8_t *)(hdr + 1);
while (*(nptr += *nptr + 1)) {
/* Store a compressed reference from the full name. */
putUShort (s, ntohs (htons (0xC000) |
htons (nptr - &query [0])));
s += sizeof (u_int16_t);
/* Store the query type. */
putUShort (s, T_SOA);
s += sizeof (u_int16_t);
putUShort (s, qclass);
s += sizeof (u_int16_t);
/* Increment the query count... */
++count;
break;
}
hdr -> qdcount = htons (count);
dump_raw (query, s - query);
/* Send the query. */
status = sendto (dns_protocol_fd, query, s - query, 0,
(struct sockaddr *)server, sizeof *server);
/* If the send failed, report the failure. */
if (status < 0)
return 0;
return 1;
}
/* Process a reply from a name server. */
dns_packet (protocol)
void dns_packet (protocol)
struct protocol *protocol;
{
HEADER *ns_header;
@ -235,14 +320,15 @@ dns_packet (protocol)
unsigned char nbuf [512];
unsigned char *base;
unsigned char *dptr;
int type;
int class;
int ttl;
int rdlength;
char nbuf [MAXDNAME];
u_int16_t type;
u_int16_t class;
TIME ttl;
u_int16_t rdlength;
int len, status;
int i;
len = sizeof from;
status = recvfrom (protocol -> fd, icbuf, sizeof icbuf, 0,
status = recvfrom (protocol -> fd, buf, sizeof buf, 0,
(struct sockaddr *)&from, &len);
if (status < 0) {
warn ("icmp_echoreply: %m");
@ -252,46 +338,60 @@ dns_packet (protocol)
ns_header = (HEADER *)buf;
base = (unsigned char *)(ns_header + 1);
#if 0
/* Ignore invalid packets... */
if (ntohs (ns_header -> id) > ns_query_max) {
printf ("Out-of-range NS message; id = %d\n",
ntohs (ns_header -> id));
return;
}
#endif
/* Parse the response... */
dptr = base;
/* Skip over the query name... */
dptr += skipname (dptr);
/* Skip over the query type and the query class. */
dptr += 2 * sizeof (short);
/* Skip over the queries... */
for (i = 0; i < ntohs (ns_header -> qdcount); i++) {
dptr += skipname (dptr);
/* Skip over the query type and query class. */
dptr += 2 * sizeof (u_int16_t);
}
/* Skip over the reply name... */
dptr += skipname (dptr);
/* Extract the numeric fields: */
getUShort (dptr, (u_int8_t *)&type);
dptr += sizeof type;
getULong (dptr, (u_int8_t *)&class);
dptr += sizeof class;
getULong (dptr, (u_int8_t *)&ttl);
dptr += sizeof ttl;
getUShort (dptr, (u_int8_t *)&rdlength);
dptr += sizeof rdlength;
/* Process the answers... */
for (i = 0; i < ntohs (ns_header -> ancount); i++) {
/* Skip over the name we looked up. */
dptr += skipname (dptr);
switch (type) {
case T_A:
printf ("A record; value is %d.%d.%d.%d",
dptr [0], dptr [1], dptr [2], dptr [3]);
break;
/* Get the type. */
type = getUShort (dptr);
dptr += sizeof type;
case T_CNAME:
case T_PTR:
copy_out_name (base, dptr, nbuf);
printf ("Domain name; value is %s\n", nbuf);
return;
/* Get the class. */
class = getUShort (dptr);
dptr += sizeof class;
default:
printf ("unhandled type: %x\n", type);
/* Get the time-to-live. */
ttl = getULong (dptr);
dptr += sizeof ttl;
/* Get the length of the reply. */
rdlength = getUShort (dptr);
dptr += sizeof rdlength;
switch (type) {
case T_A:
note ("A record; value is %d.%d.%d.%d",
dptr [0], dptr [1], dptr [2], dptr [3]);
break;
case T_CNAME:
case T_PTR:
copy_out_name (base, dptr, nbuf);
note ("Domain name; value is %s\n", nbuf);
return;
default:
note ("unhandled type: %x", type);
}
}
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: errwarn.c,v 1.1.1.1 1997/03/29 21:52:16 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: errwarn.c,v 1.1.1.2 1997/06/03 02:49:26 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -173,32 +173,40 @@ static void do_percentm (obuf, ibuf)
char *obuf;
char *ibuf;
{
char *s = ibuf;
char *p = obuf;
int infmt = 0;
char *s = ibuf;
char *p = obuf;
int infmt = 0;
char *m;
while (*s)
{
if (infmt)
while (*s)
{
if (*s == 'm')
{
strcpy (p - 1, strerror (errno));
p += strlen (p);
++s;
}
else
*p++ = *s++;
infmt = 0;
if (infmt)
{
if (*s == 'm')
{
#ifndef __CYGWIN32__
m = strerror (errno);
#else
m = pWSAError ();
#endif
if (!m)
m = "<unknown error>";
strcpy (p - 1, m);
p += strlen (p);
++s;
}
else
*p++ = *s++;
infmt = 0;
}
else
{
if (*s == '%')
infmt = 1;
*p++ = *s++;
}
}
else
{
if (*s == '%')
infmt = 1;
*p++ = *s++;
}
}
*p = 0;
*p = 0;
}
@ -259,3 +267,125 @@ char *strerror (err)
return sys_errlist [err];
}
#endif /* NO_STRERROR */
#ifdef _WIN32
char *pWSAError ()
{
int err = WSAGetLastError ();
switch (err)
{
case WSAEACCES:
return "Permission denied";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEALREADY:
return "Operation already in progress";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNREFUSED:
return "Connection refused";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEFAULT:
return "Bad address";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEINTR:
return "Interrupted function call";
case WSAEINVAL:
return "Invalid argument";
case WSAEISCONN:
return "Socket is already connected";
case WSAEMFILE:
return "Too many open files";
case WSAEMSGSIZE:
return "Message too long";
case WSAENETDOWN:
return "Network is down";
case WSAENETRESET:
return "Network dropped connection on reset";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENOBUFS:
return "No buffer space available";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAENOTCONN:
return "Socket is not connected";
case WSAENOTSOCK:
return "Socket operation on non-socket";
case WSAEOPNOTSUPP:
return "Operation not supported";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEPROCLIM:
return "Too many processes";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAEWOULDBLOCK:
return "Resource temporarily unavailable";
case WSAHOST_NOT_FOUND:
return "Host not found";
#if 0
case WSA_INVALID_HANDLE:
return "Specified event object handle is invalid";
case WSA_INVALID_PARAMETER:
return "One or more parameters are invalid";
case WSAINVALIDPROCTABLE:
return "Invalid procedure table from service provider";
case WSAINVALIDPROVIDER:
return "Invalid service provider version number";
case WSA_IO_PENDING:
return "Overlapped operations will complete later";
case WSA_IO_INCOMPLETE:
return "Overlapped I/O event object not in signaled state";
case WSA_NOT_ENOUGH_MEMORY:
return "Insufficient memory available";
#endif
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performer";
case WSANO_DATA:
return "Valid name, no data record of requested type";
case WSANO_RECOVERY:
return "This is a non-recoverable error";
#if 0
case WSAPROVIDERFAILEDINIT:
return "Unable to initialize a service provider";
case WSASYSCALLFAILURE:
return "System call failure";
#endif
case WSASYSNOTREADY:
return "Network subsystem is unavailable";
case WSATRY_AGAIN:
return "Non-authoritative host not found";
case WSAVERNOTSUPPORTED:
return "WINSOCK.DLL version out of range";
case WSAEDISCON:
return "Graceful shutdown in progress";
#if 0
case WSA_OPERATION_ABORTED:
return "Overlapped operation aborted";
#endif
}
return "Unknown WinSock error";
}
#endif /* _WIN32 */

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: icmp.c,v 1.1.1.2 1997/03/31 23:45:45 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
"$Id: icmp.c,v 1.1.1.3 1997/06/03 02:49:27 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -63,6 +63,7 @@ void icmp_startup (routep, handler)
int protocol = 1;
struct sockaddr_in from;
int fd;
int state;
/* Only initialize icmp once. */
if (icmp_protocol_initialized)
@ -76,9 +77,15 @@ void icmp_startup (routep, handler)
/* Get a raw socket for the ICMP protocol. */
icmp_protocol_fd = socket (AF_INET, SOCK_RAW, protocol);
if (!icmp_protocol_fd)
if (icmp_protocol_fd < 0)
error ("unable to create icmp socket: %m");
/* Make sure it does routing... */
state = 0;
if (setsockopt (icmp_protocol_fd, SOL_SOCKET, SO_DONTROUTE,
(char *)&state, sizeof state) < 0)
error ("Unable to disable SO_DONTROUTE on ICMP socket: %m");
add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply, handler);
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: memory.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: memory.c,v 1.1.1.2 1997/06/03 02:49:28 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -276,6 +276,7 @@ void new_address_range (low, high, subnet, dynamic)
memcpy (&ia, address_range [i].ip_addr.iabuf, 4);
if (subnet -> group -> get_lease_hostnames) {
ns_inaddr_lookup (0, address_range [i].ip_addr);
h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
if (!h)
warn ("No hostname for %s", inet_ntoa (ia));

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: options.c,v 1.1.1.2 1997/06/03 02:49:30 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@ -398,11 +398,12 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
/* Format the specified option so that a human can easily read it. */
char *pretty_print_option (code, data, len, emit_commas)
unsigned char code;
char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
unsigned int code;
unsigned char *data;
int len;
int emit_commas;
int emit_quotes;
{
static char optbuf [32768]; /* XXX */
int hunksize = 0;
@ -415,6 +416,10 @@ char *pretty_print_option (code, data, len, emit_commas)
struct in_addr foo;
char comma;
/* Code should be between 0 and 255. */
if (code > 255)
error ("pretty_print_option: bad code %d\n", code);
if (emit_commas)
comma = ',';
else
@ -503,10 +508,12 @@ char *pretty_print_option (code, data, len, emit_commas)
for (j = 0; j < numelem; j++) {
switch (fmtbuf [j]) {
case 't':
*op++ = '"';
if (emit_quotes)
*op++ = '"';
strcpy (op, dp);
op += strlen (dp);
*op++ = '"';
if (emit_quotes)
*op++ = '"';
*op = 0;
break;
case 'I':
@ -585,7 +592,7 @@ void do_packet (interface, packbuf, len, from_port, from, hfrom)
tp.options [DHO_DHCP_MESSAGE_TYPE].data [0];
if (tp.packet_type)
dhcp (&tp);
else if (tdp.op == BOOTREQUEST)
else
bootp (&tp);
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: packet.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: packet.c,v 1.1.1.2 1997/06/03 02:49:30 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -71,7 +71,7 @@ u_int32_t checksum (buf, nbytes, sum)
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
sum += (u_int16_t) ntohs(*((u_int16_t *)buf)++);
sum += (u_int16_t) ntohs(*((u_int16_t *)(buf + i)));
}
/* If there's a single byte left over, checksum it, too. Network
@ -80,7 +80,7 @@ u_int32_t checksum (buf, nbytes, sum)
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
sum += (*buf) << 8;
sum += buf [i] << 8;
}
return sum;

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: parse.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: parse.c,v 1.1.1.2 1997/06/03 02:49:31 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -83,6 +83,12 @@ void skip_to_semi (cfile)
} else if (token == SEMI && !brace_count) {
token = next_token (&val, cfile);
return;
} else if (token == EOL) {
/* EOL only happens when parsing /etc/resolv.conf,
and we treat it like a semicolon because the
resolv.conf file is line-oriented. */
token = next_token (&val, cfile);
return;
}
token = next_token (&val, cfile);
} while (token != EOF);
@ -128,6 +134,74 @@ char *parse_string (cfile)
return s;
}
/* hostname :== identifier | hostname DOT identifier */
char *parse_host_name (cfile)
FILE *cfile;
{
char *val;
int token;
int len = 0;
char *s;
char *t;
pair c = (pair)0;
/* Read a dotted hostname... */
do {
/* Read a token, which should be an identifier. */
token = next_token (&val, cfile);
if (!is_identifier (token) && token != NUMBER) {
parse_warn ("expecting an identifier in hostname");
skip_to_semi (cfile);
return (char *)0;
}
/* Store this identifier... */
if (!(s = (char *)malloc (strlen (val) + 1)))
error ("can't allocate temp space for hostname.");
strcpy (s, val);
c = cons ((caddr_t)s, c);
len += strlen (s) + 1;
/* Look for a dot; if it's there, keep going, otherwise
we're done. */
token = peek_token (&val, cfile);
if (token == DOT)
token = next_token (&val, cfile);
} while (token == DOT);
/* Assemble the hostname together into a string. */
if (!(s = (char *)malloc (len)))
error ("can't allocate space for hostname.");
t = s + len;
*--t = 0;
while (c) {
pair cdr = c -> cdr;
int l = strlen ((char *)(c -> car));
t -= l;
memcpy (t, (char *)(c -> car), l);
/* Free up temp space. */
free (c -> car);
free (c);
c = cdr;
if (t != s)
*--t = '.';
}
return s;
}
int parse_ip_addr (cfile, addr)
FILE *cfile;
struct iaddr *addr;
{
char *val;
int token;
addr -> len = 4;
if (parse_numeric_aggregate (cfile, addr -> iabuf,
&addr -> len, DOT, 10, 8))
return 1;
return 0;
}
/* hardware-parameter :== HARDWARE ETHERNET csns SEMI
csns :== NUMBER | csns COLON NUMBER */
@ -545,13 +619,13 @@ TIME parse_date (cfile)
/* Guess the time value... */
guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
(tm.tm_year - 72) / 4 + /* Leap days since '70 */
(tm.tm_year - 69) / 4 + /* Leap days since '70 */
(tm.tm_mon /* Days in months this year */
? months [tm.tm_mon - 1]
: 0) +
(tm.tm_mon > 1 && /* Leap day this year */
((tm.tm_year - 72) & 3)) +
tm.tm_mday) * 24) + /* Day of month */
!((tm.tm_year - 72) & 3)) +
tm.tm_mday - 1) * 24) + /* Day of month */
tm.tm_hour) * 60) +
tm.tm_min) * 60) + tm.tm_sec;

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: print.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: print.c,v 1.1.1.2 1997/06/03 02:49:32 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -131,7 +131,7 @@ void dump_packet (tp)
dhcp_options [i].name,
pretty_print_option
(i, tp -> options [i].data,
tp -> options [i].len, 1));
tp -> options [i].len, 1, 1));
}
}
debug ("");

View File

@ -0,0 +1,201 @@
/* resolv.c
Parser for /etc/resolv.conf file. */
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: resolv.c,v 1.1.1.1 1997/06/03 02:49:33 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
struct name_server *name_servers;
struct domain_search_list *domains;
char path_resolv_conf [] = _PATH_RESOLV_CONF;
void read_resolv_conf (parse_time)
TIME parse_time;
{
FILE *cfile;
char *val;
int token;
int declaration = 0;
struct name_server *sp, *sl, *ns;
struct domain_search_list *dp, *dl, *nd;
struct iaddr *iaddr;
new_parse (path_resolv_conf);
eol_token = 1;
if ((cfile = fopen (path_resolv_conf, "r")) == NULL)
error ("Can't open %s: %m", path_resolv_conf);
do {
token = next_token (&val, cfile);
if (token == EOF)
break;
else if (token == EOL)
continue;
else if (token == DOMAIN || token == SEARCH) {
do {
struct domain_search_list *nd, **dp;
char *dn;
dn = parse_host_name (cfile);
if (!dn)
break;
dp = &domains;
for (nd = domains; nd; nd = nd -> next) {
dp = &nd -> next;
if (!strcmp (nd -> domain, dn))
break;
}
if (!nd) {
nd = new_domain_search_list
("read_resolv_conf");
if (!nd)
error ("No memory for %s", dn);
nd -> next =
(struct domain_search_list *)0;
*dp = nd;
nd -> domain = dn;
dn = (char *)0;
}
nd -> rcdate = parse_time;
token = peek_token (&val, cfile);
} while (token != EOL);
if (token != EOL) {
parse_warn ("junk after domain declaration");
skip_to_semi (cfile);
}
token = next_token (&val, cfile);
} else if (token == NAMESERVER) {
struct name_server *ns, **sp;
struct iaddr iaddr;
parse_ip_addr (cfile, &iaddr);
sp = &name_servers;
for (ns = name_servers; ns; ns = ns -> next) {
sp = &ns -> next;
if (!memcmp (&ns -> addr.sin_addr,
iaddr.iabuf, iaddr.len))
break;
}
if (!ns) {
ns = new_name_server ("read_resolv_conf");
if (!ns)
error ("No memory for nameserver %s",
piaddr (iaddr));
ns -> next = (struct name_server *)0;
*sp = ns;
memcpy (&ns -> addr.sin_addr,
iaddr.iabuf, iaddr.len);
#ifdef HAVE_SA_LEN
ns -> addr.sin_len = sizeof ns -> addr;
#endif
ns -> addr.sin_family = AF_INET;
ns -> addr.sin_port = htons (53);
memset (ns -> addr.sin_zero, 0,
sizeof ns -> addr.sin_zero);
}
ns -> rcdate = parse_time;
skip_to_semi (cfile);
}
} while (1);
token = next_token (&val, cfile); /* Clear the peek buffer */
/* Lose servers that are no longer in /etc/resolv.conf. */
sl = (struct name_server *)0;
for (sp = name_servers; sp; sp = ns) {
ns = sp -> next;
if (sp -> rcdate != parse_time) {
if (sl)
sl -> next = sp -> next;
else
name_servers = sp -> next;
free_name_server (sp, "pick_name_server");
} else
sl = sp;
}
/* Lose domains that are no longer in /etc/resolv.conf. */
dl = (struct domain_search_list *)0;
for (dp = domains; dp; dp = nd) {
nd = dp -> next;
if (dp -> rcdate != parse_time) {
if (dl)
dl -> next = dp -> next;
else
domains = dp -> next;
free_domain_search_list (dp, "pick_name_server");
} else
dl = dp;
}
eol_token = 0;
}
/* Pick a name server from the /etc/resolv.conf file. */
struct sockaddr_in *pick_name_server ()
{
FILE *rc;
static TIME rcdate;
struct stat st;
/* Check /etc/resolv.conf and reload it if it's changed. */
if (cur_time > rcdate) {
if (stat (path_resolv_conf, &st) < 0)
error ("Can't stat %s", path_resolv_conf);
if (st.st_mtime > rcdate) {
char rcbuf [512];
char *s, *t, *u;
rcdate = cur_time + 1;
read_resolv_conf (rcdate);
}
}
if (name_servers)
return &name_servers -> addr;
return (struct sockaddr_in *)0;
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: tables.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: tables.c,v 1.1.1.2 1997/06/03 02:49:34 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -71,7 +71,7 @@ struct option dhcp_options [256] = {
{ "time-offset", "l", &dhcp_universe, 2 },
{ "routers", "IA", &dhcp_universe, 3 },
{ "time-servers", "IA", &dhcp_universe, 4 },
{ "name-servers", "IA", &dhcp_universe, 5 },
{ "ien116-name-servers", "IA", &dhcp_universe, 5 },
{ "domain-name-servers", "IA", &dhcp_universe, 6 },
{ "log-servers", "IA", &dhcp_universe, 7 },
{ "cookie-servers", "IA", &dhcp_universe, 8 },
@ -151,9 +151,9 @@ struct option dhcp_options [256] = {
{ "option-82", "X", &dhcp_universe, 82 },
{ "option-83", "X", &dhcp_universe, 83 },
{ "option-84", "X", &dhcp_universe, 84 },
{ "option-85", "X", &dhcp_universe, 85 },
{ "option-86", "X", &dhcp_universe, 86 },
{ "option-87", "X", &dhcp_universe, 87 },
{ "nds-servers", "IA", &dhcp_universe, 85 },
{ "nds-tree-name", "X", &dhcp_universe, 86 },
{ "nds-context", "X", &dhcp_universe, 87 },
{ "option-88", "X", &dhcp_universe, 88 },
{ "option-89", "X", &dhcp_universe, 89 },
{ "option-90", "X", &dhcp_universe, 90 },

View File

@ -3,7 +3,7 @@
Routines for manipulating parse trees... */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: tree.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: tree.c,v 1.1.1.2 1997/06/03 02:49:34 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -314,9 +314,12 @@ static TIME do_host_lookup (bufix, bufp, bufcount, dns)
/* Otherwise, look it up... */
h = gethostbyname (dns -> hostname);
if (!h) {
#ifndef NO_H_ERRNO
switch (h_errno) {
case HOST_NOT_FOUND:
#endif
warn ("%s: host unknown.", dns -> hostname);
#ifndef NO_H_ERRNO
break;
case TRY_AGAIN:
warn ("%s: temporary name server failure",
@ -329,6 +332,7 @@ static TIME do_host_lookup (bufix, bufp, bufcount, dns)
warn ("%s: no A record associated with address",
dns -> hostname);
}
#endif /* !NO_H_ERRNO */
/* Okay to try again after a minute. */
return cur_time + 60;

View File

@ -43,6 +43,7 @@ typedef int int32_t;
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
typedef unsigned long u_int64_t;
#include <syslog.h>
#include <sys/types.h>

View File

@ -0,0 +1,120 @@
/* cygwin32.h
System dependencies for Win32, compiled with Cygwin32... */
/*
* Copyright (c) 1997 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software was written for the Internet Software Consortium by Ted Lemon
* under a contract with Vixie Laboratories.
*/
#include <sys/time.h>
#define IN
#define OUT
#undef fd_set
#undef FD_SET
#undef FD_CLR
#undef FD_ZERO
#undef FD_ISSET
#undef FD_ISCLR
#undef FD_SETSIZE
#define IFNAMSIZ 16
#include <winsock.h>
#include <syslog.h>
#include <string.h>
#include <paths.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <setjmp.h>
#include <limits.h>
#include <sys/wait.h>
#include <signal.h>
#define NO_H_ERRNO
#include <sys/param.h>
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
#define NO_SNPRINTF
#ifndef _PATH_DHCPD_PID
#define _PATH_DHCPD_PID "//e/etc/dhcpd.pid"
#endif
#ifndef _PATH_DHCPD_DB
#define _PATH_DHCPD_DB "//e/etc/dhcpd.leases"
#endif
#ifndef _PATH_DHCPD_CONF
#define _PATH_DHCPD_CONF "//e/etc/dhcpd.conf"
#endif
#ifndef _PATH_DHCLIENT_PID
#define _PATH_DHCLIENT_PID "//e/etc/dhclient.pid"
#endif
#ifndef _PATH_DHCLIENT_DB
#define _PATH_DHCLIENT_DB "//e/etc/dhclient.leases"
#endif
#ifndef _PATH_DHCLIENT_CONF
#define _PATH_DHCLIENT_CONF "//e/etc/dhclient.conf"
#endif
#ifndef _PATH_RESOLV_CONF
#define _PATH_RESOLV_CONF "//e/etc/resolv.conf"
#endif
#define int8_t char
#define int16_t short
#define int32_t long
#define u_int8_t unsigned char /* Not quite POSIX... */
#define u_int16_t unsigned short
#define u_int32_t unsigned long
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#define TIME time_t
#define GET_TIME(x) time ((x))
#if defined (USE_DEFAULT_NETWORK)
# define USE_SOCKETS
#endif
#ifdef __alpha__
#define PTRSIZE_64BIT
#endif

View File

@ -86,5 +86,4 @@ extern int h_errno;
#if defined (USE_DEFAULT_NETWORK)
# define USE_BPF
# define BROKEN_FREEBSD_BPF /* Fixed in 2.2 */
#endif

View File

@ -121,10 +121,6 @@ char *strerror PROTO ((int));
#define NEED_INET_ATON
/* SunOS select() doesn't work on streams, so we have to use poll -
as usual, SysV can't do networking to save its life. */
#define USE_POLL
/* By default, use NIT API for receiving and sending packets... */
#if defined (USE_DEFAULT_NETWORK)
# define USE_NIT
@ -134,6 +130,7 @@ char *strerror PROTO ((int));
#define VOIDPTR void *
#include <time.h>
#include <sys/time.h>
#define TIME time_t
#define GET_TIME(x) time ((x))

View File

@ -141,3 +141,5 @@ extern int h_errno;
@@@ ERROR @@@ Unable to determine byte order!
# endif
#endif
#define ALIAS_NAMES_PERMUTED

View File

@ -40,11 +40,16 @@
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef __CYGWIN32__
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#else
#define fd_set cygwin_fd_set
#include <sys/types.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
@ -71,6 +76,20 @@ struct string_list {
char string [1];
};
/* A name server, from /etc/resolv.conf. */
struct name_server {
struct name_server *next;
struct sockaddr_in addr;
TIME rcdate;
};
/* A domain search list element. */
struct domain_search_list {
struct domain_search_list *next;
char *domain;
TIME rcdate;
};
/* A dhcp packet and the pointers to its option values. */
struct packet {
struct dhcp_packet *raw;
@ -107,6 +126,7 @@ struct lease {
int uid_max;
unsigned char uid_buf [32];
char *hostname;
char *client_hostname;
struct host_decl *host;
struct subnet *subnet;
struct shared_network *shared_network;
@ -233,7 +253,8 @@ struct client_lease {
char *filename; /* Name of file we're supposed to boot. */
struct string_list *medium; /* Network medium. */
int is_static; /* If nonzero, lease came from config file. */
unsigned int is_static : 1; /* If set, lease is from config file. */
unsigned int is_bootp: 1; /* If set, lease was aquired with BOOTP. */
struct option_data options [256]; /* Options supplied with lease. */
};
@ -252,6 +273,14 @@ enum dhcp_state {
/* Configuration information from the config file... */
struct client_config {
struct option_data defaults [256]; /* Default values for options. */
enum {
ACTION_DEFAULT, /* Use server value if present,
otherwise default. */
ACTION_SUPERSEDE, /* Always use default. */
ACTION_PREPEND, /* Prepend default to server. */
ACTION_APPEND, /* Append default to server. */
} default_actions [256];
struct option_data send_options [256]; /* Send these to server. */
u_int8_t required_options [256]; /* Options server must supply. */
u_int8_t requested_options [256]; /* Options to request from server. */
@ -280,6 +309,8 @@ struct client_config {
/* Ignore, accept or prefer BOOTP
responses. */
struct string_list *medium; /* Current network medium. */
struct iaddrlist *reject_list; /* Servers to reject. */
};
/* Per-interface state used in the dhcp client... */
@ -396,6 +427,9 @@ typedef unsigned char option_mask [16];
#define _PATH_DHCLIENT_DB "/etc/dhclient.leases"
#endif
#ifndef _PATH_RESOLV_CONF
#define _PATH_RESOLV_CONF "/etc/resolv.conf"
#endif
#ifndef DHCPD_LOG_FACILITY
#define DHCPD_LOG_FACILITY LOG_DAEMON
@ -414,7 +448,8 @@ int cons_options PROTO ((struct packet *, struct dhcp_packet *,
struct tree_cache **, int, int));
int store_options PROTO ((unsigned char *, int, struct tree_cache **,
unsigned char *, int, int, int, int));
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int, int));
char *pretty_print_option PROTO ((unsigned int,
unsigned char *, int, int, int));
void do_packet PROTO ((struct interface_info *,
unsigned char *, int,
unsigned short, struct iaddr, struct hardware *));
@ -454,6 +489,7 @@ extern int lexline, lexchar;
extern char *token_line, *tlname;
extern char comments [4096];
extern int comment_index;
extern int eol_token;
void new_parse PROTO ((char *));
int next_token PROTO ((char **, FILE *));
int peek_token PROTO ((char **, FILE *));
@ -567,6 +603,10 @@ struct shared_network *new_shared_network PROTO ((char *));
struct group *new_group PROTO ((char *));
struct protocol *new_protocol PROTO ((char *));
struct lease_state *new_lease_state PROTO ((char *));
struct domain_search_list *new_domain_search_list PROTO ((char *));
struct name_server *new_name_server PROTO ((char *));
void free_name_server PROTO ((struct name_server *, char *));
void free_domain_search_list PROTO ((struct domain_search_list *, char *));
void free_lease_state PROTO ((struct lease_state *, char *));
void free_protocol PROTO ((struct protocol *, char *));
void free_group PROTO ((struct group *, char *));
@ -754,6 +794,8 @@ void state_requesting PROTO ((void *));
void state_bound PROTO ((void *));
void state_panic PROTO ((void *));
void bind_lease PROTO ((struct interface_info *));
void make_discover PROTO ((struct interface_info *, struct client_lease *));
void make_request PROTO ((struct interface_info *, struct client_lease *));
void make_decline PROTO ((struct interface_info *, struct client_lease *));
@ -847,9 +889,10 @@ void make_client_config PROTO ((struct interface_info *,
void parse_client_lease_statement PROTO ((FILE *, int));
void parse_client_lease_declaration PROTO ((FILE *, struct client_lease *,
struct interface_info **));
void parse_ip_addr PROTO ((FILE *, struct iaddr *));
void parse_option_decl PROTO ((FILE *, struct option_data *));
struct option *parse_option_decl PROTO ((FILE *, struct option_data *));
void parse_string_list PROTO ((FILE *, struct string_list **, int));
int parse_ip_addr PROTO ((FILE *, struct iaddr *));
void parse_reject_statement PROTO ((FILE *, struct client_config *));
/* dhcrelay.c */
void relay PROTO ((struct interface_info *, u_int8_t *, int,
@ -863,7 +906,16 @@ void icmp_echoreply PROTO ((struct protocol *));
/* dns.c */
void dns_startup PROTO ((void));
int ns_inaddr_lookup PROTO ((struct sockaddr_in *, u_int16_t, struct iaddr));
int ns_inaddr_lookup PROTO ((u_int16_t, struct iaddr));
void dns_packet PROTO ((struct protocol *));
/* resolv.c */
extern char path_resolv_conf [];
struct name_server *name_servers;
struct domain_search_list *domains;
void read_resolv_conf PROTO ((TIME));
struct sockaddr_in *pick_name_server PROTO ((void));
/* inet_addr.c */
#ifdef NEED_INET_ATON

View File

@ -115,6 +115,15 @@
#define ABANDONED 319
#define BACKOFF_CUTOFF 320
#define INITIAL_INTERVAL 321
#define NAMESERVER 322
#define DOMAIN 323
#define SEARCH 324
#define SUPERSEDE 325
#define APPEND 326
#define PREPEND 327
#define HOSTNAME 328
#define CLIENT_HOSTNAME 329
#define REJECT 330
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
(x) != STRING && \

View File

@ -45,3 +45,8 @@ struct iaddr {
int len;
unsigned char iabuf [16];
};
struct iaddrlist {
struct iaddrlist *next;
struct iaddr addr;
};

View File

@ -105,6 +105,10 @@
# include "cf/qnx.h"
#endif
#ifdef __CYGWIN32__
# include "cf/cygwin32.h"
#endif
/* Porting::
If you add a new network API, and have it set up so that it can be

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: dhcrelay.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhcrelay.c,v 1.1.1.2 1997/06/03 02:49:50 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -198,7 +198,7 @@ void relay (ip, packbuf, length, from_port, from, hfrom)
/* If it's a bootreply, forward it to the client. */
if (packet -> op == BOOTREPLY) {
#ifndef USE_FALLBACK
if (!packet -> flags & htons (BOOTP_BROADCAST)) {
if (!(packet -> flags & htons (BOOTP_BROADCAST))) {
to.sin_addr = packet -> ciaddr;
to.sin_port = remote_port;
} else

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: bootp.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: bootp.c,v 1.1.1.2 1997/06/03 02:49:53 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -64,6 +64,9 @@ void bootp (packet)
struct iaddr ip_address;
int i;
if (packet -> raw -> op != BOOTREQUEST)
return;
note ("BOOTREQUEST from %s via %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: confpars.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: confpars.c,v 1.1.1.2 1997/06/03 02:49:54 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -539,60 +539,6 @@ void parse_host_declaration (cfile, group)
enter_host (host);
}
/* hostname :== identifier | hostname DOT identifier */
char *parse_host_name (cfile)
FILE *cfile;
{
char *val;
int token;
int len = 0;
char *s;
char *t;
pair c = (pair)0;
/* Read a dotted hostname... */
do {
/* Read a token, which should be an identifier. */
token = next_token (&val, cfile);
if (!is_identifier (token) && token != NUMBER) {
parse_warn ("expecting an identifier in hostname");
skip_to_semi (cfile);
return (char *)0;
}
/* Store this identifier... */
if (!(s = (char *)malloc (strlen (val) + 1)))
error ("can't allocate temp space for hostname.");
strcpy (s, val);
c = cons ((caddr_t)s, c);
len += strlen (s) + 1;
/* Look for a dot; if it's there, keep going, otherwise
we're done. */
token = peek_token (&val, cfile);
if (token == DOT)
token = next_token (&val, cfile);
} while (token == DOT);
/* Assemble the hostname together into a string. */
if (!(s = (char *)malloc (len)))
error ("can't allocate space for hostname.");
t = s + len;
*--t = 0;
while (c) {
pair cdr = c -> cdr;
int l = strlen ((char *)(c -> car));
t -= l;
memcpy (t, (char *)(c -> car), l);
/* Free up temp space. */
free (c -> car);
free (c);
c = cdr;
if (t != s)
*--t = '.';
}
return s;
}
/* class-declaration :== STRING LBRACE parameters declarations RBRACE
*/
@ -1145,7 +1091,8 @@ TIME parse_timestamp (cfile)
| TIMESTAMP date
| HARDWARE hardware-parameter
| UID hex_numbers SEMI
| HOST hostname SEMI
| HOSTNAME hostname SEMI
| CLIENT_HOSTNAME hostname SEMI
| CLASS identifier SEMI
| DYNAMIC_BOOTP SEMI */
@ -1273,6 +1220,25 @@ struct lease *parse_lease_declaration (cfile)
lease.flags |= ABANDONED_LEASE;
break;
case HOSTNAME:
seenbit = 512;
lease.hostname = parse_host_name (cfile);
if (!lease.hostname) {
seenbit = 0;
return (struct lease *)0;
}
break;
case CLIENT_HOSTNAME:
seenbit = 1024;
lease.client_hostname =
parse_host_name (cfile);
if (!lease.client_hostname) {
seenbit = 0;
return (struct lease *)0;
}
break;
default:
skip_to_semi (cfile);
seenbit = 0;

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: db.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: db.c,v 1.1.1.2 1997/06/03 02:49:55 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -133,6 +133,22 @@ int write_lease (lease)
++errors;
}
}
if (lease -> client_hostname) {
errno = 0;
fprintf (db_file, "\n\tclient-hostname %s;",
lease -> client_hostname);
if (errno) {
++errors;
}
}
if (lease -> hostname) {
errno = 0;
fprintf (db_file, "\n\thostname %s;",
lease -> client_hostname);
if (errno) {
++errors;
}
}
errno = 0;
fputs ("\n}\n", db_file);
if (errno) {

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: dhcp.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhcp.c,v 1.1.1.2 1997/06/03 02:49:56 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -178,8 +178,9 @@ void dhcprequest (packet)
/* Find the lease that matches the address requested by the
client. */
if (packet -> shared_network)
lease = find_lease (packet, packet -> shared_network);
if (subnet)
lease = find_lease (packet, subnet -> shared_network);
else
lease = (struct lease *)0;
@ -192,25 +193,50 @@ void dhcprequest (packet)
? inet_ntoa (packet -> raw -> giaddr)
: packet -> interface -> name);
/* If a client on a given network wants to request a lease on
an address on a different network, NAK it. If the Requested
Address option was used, the protocol says that it must have
been broadcast, so we can trust the source network information.
/* If a client on a given network REQUESTs a lease on an
address on a different network, NAK it. If the Requested
Address option was used, the protocol says that it must
have been broadcast, so we can trust the source network
information.
If ciaddr was specified and Requested Address was not, then
we really only know for sure what network a packet came from
if it came through a BOOTP gateway - if it came through an
IP router, we'll just have to assume that it's cool.
This violates the protocol spec in the case that the client
is in the INIT-REBOOT state and broadcasts a DHCPREQUEST on
the local wire. We're supposed to check ciaddr for
validity in that case, but if the packet was unicast
through a router from a client in the RENEWING state, it
would look exactly the same to us and it would be very
bad to send a DHCPNAK. I think we just have to live with
this. */
if ((packet -> raw -> ciaddr.s_addr &&
If we don't think we know where the packet came from, it
came through a gateway from an unknown network, so it's not
from a RENEWING client. If we recognize the network it
*thinks* it's on, we can NAK it even though we don't
recognize the network it's *actually* on; otherwise we just
have to ignore it.
We don't currently try to take advantage of access to the
raw packet, because it's not available on all platforms.
So a packet that was unicast to us through a router from a
RENEWING client is going to look exactly like a packet that
was broadcast to us from an INIT-REBOOT client.
Since we can't tell the difference between these two kinds
of packets, if the packet appears to have come in off the
local wire, we have to treat it as if it's a RENEWING
client. This means that we can't NAK a RENEWING client on
the local wire that has a bogus address. The good news is
that we won't ACK it either, so it should revert to INIT
state and send us a DHCPDISCOVER, which we *can* work with.
Because we can't detect that a RENEWING client is on the
wrong wire, it's going to sit there trying to renew until
it gets to the REBIND state, when we *can* NAK it because
the packet will get to us through a BOOTP gateway. We
shouldn't actually see DHCPREQUEST packets from RENEWING
clients on the wrong wire anyway, since their idea of their
local router will be wrong. In any case, the protocol
doesn't really allow us to NAK a DHCPREQUEST from a
RENEWING client, so we can punt on this issue. */
if (!packet -> shared_network ||
(packet -> raw -> ciaddr.s_addr &&
packet -> raw -> giaddr.s_addr) ||
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
@ -226,9 +252,8 @@ void dhcprequest (packet)
return;
}
/* If we do know where it came from and either we don't
know where it came from at all or it came from a different
shared network than the packet came from, send a nak. */
/* If we do know where it came from and it asked for an
address that is not on that shared network, nak it. */
subnet = find_grouped_subnet (packet -> shared_network, cip);
if (!subnet) {
nak_lease (packet, &cip);
@ -430,7 +455,7 @@ void nak_lease (packet, cip)
#endif
} else {
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = packet->client_port;
to.sin_port = remote_port;
}
errno = 0;
@ -489,6 +514,31 @@ void ack_lease (packet, lease, offer, when)
user_class = (struct class *)0;
}
/* Replace the old lease hostname with the new one, if it's changed. */
if (packet -> options [DHO_HOST_NAME].len &&
lease -> client_hostname &&
(strlen (lease -> client_hostname) ==
packet -> options [DHO_HOST_NAME].len) &&
!memcmp (lease -> client_hostname,
packet -> options [DHO_HOST_NAME].data,
packet -> options [DHO_HOST_NAME].len)) {
} else if (packet -> options [DHO_HOST_NAME].len) {
if (lease -> client_hostname)
free (lease -> client_hostname);
lease -> client_hostname =
malloc (packet -> options [DHO_HOST_NAME].len + 1);
if (!lease -> client_hostname)
error ("no memory for client hostname.\n");
memcpy (lease -> client_hostname,
packet -> options [DHO_HOST_NAME].data,
packet -> options [DHO_HOST_NAME].len);
lease -> client_hostname
[packet -> options [DHO_HOST_NAME].len] = 0;
} else if (lease -> client_hostname) {
free (lease -> client_hostname);
lease -> client_hostname = 0;
}
/* Choose a filename; first from the host_decl, if any, then from
the user class, then from the vendor class. */
if (lease -> host && lease -> host -> group -> filename)
@ -633,7 +683,7 @@ void ack_lease (packet, lease, offer, when)
/* Remember the giaddr, xid, secs, flags and hops. */
state -> giaddr = packet -> raw -> giaddr;
state -> ciaddr = packet -> raw -> giaddr;
state -> ciaddr = packet -> raw -> ciaddr;
state -> xid = packet -> raw -> xid;
state -> secs = packet -> raw -> secs;
state -> bootp_flags = packet -> raw -> flags;

View File

@ -42,7 +42,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhcpd.c,v 1.1.1.1 1997/03/29 21:52:18 mellon Exp $ Copyright 1995, 1996 The Internet Software Consortium.";
"$Id: dhcpd.c,v 1.1.1.2 1997/06/03 02:49:57 mellon Exp $ Copyright 1995, 1996 The Internet Software Consortium.";
#endif
static char copyright[] =
@ -85,6 +85,7 @@ int main (argc, argv, envp)
int i, status;
struct servent *ent;
char *s;
int cftest = 0;
#ifndef DEBUG
int pidfilewritten = 0;
int pid;
@ -102,8 +103,10 @@ int main (argc, argv, envp)
#ifndef DEBUG
#ifndef SYSLOG_4_2
#ifndef __CYGWIN32__ /* XXX */
setlogmask (LOG_UPTO (LOG_INFO));
#endif
#endif
#endif
note (message);
note (copyright);
@ -141,6 +144,13 @@ int main (argc, argv, envp)
if (++i == argc)
usage ();
path_dhcpd_db = argv [i];
} else if (!strcmp (argv [i], "-t")) {
/* test configurations only */
#ifndef DEBUG
daemon = 0;
#endif
cftest = 1;
log_perror = -1;
} else if (argv [i][0] == '-') {
usage ();
} else {
@ -197,7 +207,9 @@ int main (argc, argv, envp)
local_port = htons (67);
else
local_port = ent -> s_port;
#ifndef __CYGWIN32__ /* XXX */
endservent ();
#endif
}
remote_port = htons (ntohs (local_port) + 1);
@ -205,10 +217,17 @@ int main (argc, argv, envp)
/* Get the current time... */
GET_TIME (&cur_time);
/* Initialize DNS support... */
dns_startup ();
/* Read the dhcpd.conf file... */
if (!readconf ())
error ("Configuration file errors encountered -- exiting");
/* test option should cause an early exit */
if (cftest)
exit(0);
/* Start up the database... */
db_startup ();

View File

@ -171,7 +171,7 @@ the entire organization), and so on. So, for example:
.nf
option domain-name "isc.org";
option name-servers ns1.isc.org, ns2.isc.org;
option domain-name-servers ns1.isc.org, ns2.isc.org;
.ce 1
Figure 2
@ -783,9 +783,9 @@ The time-server option specifies a list of RFC 868 time servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBname-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ];
\fBoption\fR \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ];
.PP
The name-servers option specifies a list of IEN 116 name servers
The ien116-name-servers option specifies a list of IEN 116 name servers
available to the client. Servers should be listed in order of
preference.
.PP