Virgin import of ISC-DHCP v2.0b1pl17

This commit is contained in:
obrien 1999-02-28 20:34:40 +00:00
parent a342fabba3
commit c4a13b4e0f
16 changed files with 5430 additions and 110 deletions

View File

@ -1,7 +1,7 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 11
February 8, 1998
Version 2, Beta 1, Patchlevel 17
February 27, 1998
This is the first Beta release of Version 2 of the Internet Software
Consortium DHCP Distribution. In version 2.0, this distribution
@ -47,9 +47,9 @@ information. On Digital Unix, type ``man pfilt''.
To build the DHCP Distribution, unpack the compressed tar file using
the tar utility and the gzip command - type something like:
zcat dhcp-2.0b1pl11.tar.gz |tar xvf -
zcat dhcp-2.0b1pl17.tar.gz |tar xvf -
Now, cd to the dhcp-2.0b1pl11 subdirectory that you've just created and
Now, cd to the dhcp-2.0b1pl17 subdirectory that you've just created and
configure the source tree by typing:
./configure
@ -232,14 +232,36 @@ must install this extension in order to get dhcpd or dhclient to work.
SOLARIS
One problem which has been observed and is not fixed in this patchlevel
has to do with using DLPI on Solaris 2.6 machines, probably only on Intel,
but possibly also on SPARC. The symptom of this problem is that you never
receive any DHCP packets. If you are running Solaris 2.6, and you
encounter this symptom, and you are running the DHCP server on a machine
with a single broadcast network interface, you may wish to edit the
includes/site.h file and uncomment the #define USE_SOCKETS line. Then
type ``make clean; make''.
One problem which has been observed and is not fixed in this
patchlevel has to do with using DLPI on Solaris machines. The symptom
of this problem is that the DHCP server never receives any requests.
If you are using Solaris 2.6, and you encounter this symptom, and
you are running the DHCP server on a machine with a single broadcast
network interface, you may wish to edit the includes/site.h file and
uncomment the #define USE_SOCKETS line. Then type ``make clean;
make''.
The DHCP client on Solaris will only work with DLPI. If you run it
and it just keeps saying it's sending DHCPREQUEST packets, but never
gets a response, you may be having DLPI trouble as described above.
If so, you are SOL. Also, because Solaris requires you to "plumb" an
interface before it can be detected by the DHCP client, you must
either specify the name(s) of the interface(s) you want to configure
on the command line, or must plumb the interfaces prior to invoking
the DHCP client. This can be done with ``ifconfig iface plumb'',
where iface is the name of the interface (e.g., ``ifconfig hme0
plumb'').
It should be noted that Solaris versions from 2.6 onward include a
DHCP client that you can run with ``/sbin/ifconfig iface dhcp start''
rather than using the ISC DHCP client. The feature set of the Solaris
client is different (not necessarily better or worse) than that of the
ISC client, but in most cases it will be a lot easier for you to just
use that. Please do not ask for help in using the Solaris DHCP client
on Internet Software Consortium mailing lists - that's why you're
paying Sun the big bucks. If you're having a problem with the
Solaris client interoperating with the ISC dhcp server, that's another
matter, but please check with Sun first.
SUPPORT

View File

@ -1,7 +1,7 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 10
February 8, 1998
Version 2, Beta 1, Patchlevel 18
February 27, 1998
Release Notes
@ -53,6 +53,110 @@ running in producion at the ISC, but is not expected to be stable in
the near future, and is intended for sites that are in a position to
experiment, or for sites that desperately need the new features.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 16
- Fix linux man page install location.
- Fix some confusion in the dhclient-script man page.
- Fix error in includes/cf/linux.h that would have made network API
selections in site.h work incorrectly.
- Fix some major stupidity in the code that figures out where or not a
client owns a particular lease.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 15
- Fix Makefile.conf on Linux to refer to /var/state/dhcp instead of
/var/state/dhcpd.
- Eliminate redundant #defines in includes/cf/linux.h (for neatness).
- Fix an obscure case where dhcpd is started by the /etc/rc system
with exactly the same pid each time, dhcpd.pid is not erased on
reboot, and therefore dhcpd would detect a server (itself) with the
pid in dhcpd.pid and decide that another server was running and
exit.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 14
- Install the dhcp databases in /var/state/dhcp instead of /etc or
/var/dhcpd, as suggested in the Linux Filesystem Hierarchy
Standard.
- Fix an endianness bug in dlpi.c. As a consequence, make the
Solaris/i386 use dlpi again.
- Fix a bunch of bugs in the Solaris client script.
- Add some more information about Solaris to the README file.
- Adjust startup message in interface probe so that the relay agent
and client's unattached status will not trigger questions.
- Update some error messages to provide more help to new users for
some common mistakes.
- Create an interface alias on Solaris when setting up IP aliases,
rather than trying to do things the *BSD way.
- Fix a null pointer dereference bug (this time I went through the
whole function and audited it for more null pointer dereferences,
and I didn't find any, for what that's worth).
- Don't ever release leases in response to a DHCPDISCOVER (I think
this was unlikely anyway, but why not be correct?).
- Remove the shared-network example from the sample dhcpd.conf file.
- Make ``make install'' make all first.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 13
- Support DESTDIR on installs.
- Fix a bug in dhcp.c where a store through a null pointer would
be made under some reasonably common circumstances.
- Add test for ARPHRD_TUNNEL so that client and server do not fail on
versions of Linux running IPsec implementations or the like.
- Move tests for constants defined in O.S. headers into osdep.h - test
for HAVE_whatever in .c files. Define relevant HAVE_whatevers in
linux.h, so that versions of linux that define these constants as
enums will still work.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 12
- Initialize the "quiet" variable in dhclient.c to zero (it was used
without first having been initialized).
- Fix the parser code for the authoritative keyword.
- Adjust lease discovery code to NAK more aggressively for addresses
the server knows it owns.
- Add several new messages for DHCPNAK.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 11
- Use DLPI only on sparcs running Solaris, since it seems not to work
on i386 boxes running Solaris for reasons yet to be determined.
- In the client, close standard I/O descriptors when forking a daemon.
- Don't let large lease lengths wrap lease expiry times - just use
what fits into a TIME value.
- Fix a bug in the SIOCGIFCONF interface scanning code.
- Fix a core dump in the interface scanner that crops up on Linux when
an interface is specified on the command line.
- Don't use %D in strftime because egcs complains about it.
- Print the error message if SO_BINDTODEVICE fails.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 10
- Update top-level Makefile so that it exits correctly on errors in
@ -249,7 +353,6 @@ experiment, or for sites that desperately need the new features.
- Fix up dhcp-options man page to make it more readable. Note that
netbios-name-server is the same thing as WINS.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 5

View File

@ -55,7 +55,7 @@ modify an existing one. In general, customizations specific to a
particular computer should be done in the
.B ETCDIR/dhclient.conf
script. If you find that you can't make such a customization without
customizing dhclient.conf, please submit a bug report.
customizing dhclient-script, please submit a bug report.
.SH OPERATION
When dhclient needs to invoke the client configuration script, it
writes a shell script into /tmp which defines a variety of variables.
@ -89,7 +89,7 @@ no examples exist yet. The IP address to check is passed in
$new_ip_address, and the interface name is passed in $interface.
.SH ARPCHECK
The DHCP client wants to know if a response to the ARP request send
using ARPCHECK has been received. If one has, the script should exit
using ARPSEND has been received. If one has, the script should exit
with a nonzero status, indicating that the offered address has already
been requested and should be declined. $new_ip_address and
$interface are set as with ARPSEND.

View File

@ -56,7 +56,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhclient.c,v 1.44.2.14 1999/02/09 04:59:50 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.44.2.24 1999/02/27 21:51:35 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -92,7 +92,7 @@ int save_scripts;
static char copyright[] =
"Copyright 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.";
static char arr [] = "All rights reserved.";
static char message [] = "Internet Software Consortium DHCP Client V2.0b1pl11";
static char message [] = "Internet Software Consortium DHCP Client V2.0b1pl17";
static char contrib [] = "\nPlease contribute if you find this software useful.";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
@ -106,7 +106,7 @@ int main (argc, argv, envp)
struct servent *ent;
struct interface_info *ip;
int seed;
int quiet;
int quiet = 0;
#ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY);
@ -498,6 +498,10 @@ void dhcpack (packet)
ip -> client -> new -> expiry =
getULong (ip -> client ->
new -> options [DHO_DHCP_LEASE_TIME].data);
/* A number that looks negative here is really just very large,
because the lease expiry offset is unsigned. */
if (ip -> client -> new -> expiry < 0)
ip -> client -> new -> expiry = TIME_MAX;
/* Take the server-provided renewal time if there is one;
otherwise figure it out according to the spec. */
@ -521,8 +525,15 @@ void dhcpack (packet)
ip -> client -> new -> renewal / 4;
ip -> client -> new -> expiry += cur_time;
/* Lease lengths can never be negative. */
if (ip -> client -> new -> expiry < cur_time)
ip -> client -> new -> expiry = TIME_MAX;
ip -> client -> new -> renewal += cur_time;
if (ip -> client -> new -> renewal < cur_time)
ip -> client -> new -> renewal = TIME_MAX;
ip -> client -> new -> rebind += cur_time;
if (ip -> client -> new -> rebind < cur_time)
ip -> client -> new -> rebind = TIME_MAX;
bind_lease (ip);
}
@ -1038,8 +1049,6 @@ void send_discover (ipp)
ip -> client -> packet_length,
inaddr_any, &sockaddr_broadcast,
(struct hardware *)0);
if (result < 0)
warn ("send_packet: %m");
add_timeout (cur_time + ip -> client -> interval, send_discover, ip);
}
@ -1292,9 +1301,6 @@ void send_request (ipp)
from, &destination,
(struct hardware *)0);
if (result < 0)
warn ("send_packet: %m");
add_timeout (cur_time + ip -> client -> interval,
send_request, ip);
}
@ -1316,8 +1322,6 @@ void send_decline (ipp)
ip -> client -> packet_length,
inaddr_any, &sockaddr_broadcast,
(struct hardware *)0);
if (result < 0)
warn ("send_packet: %m");
}
void send_release (ipp)
@ -1337,8 +1341,6 @@ void send_release (ipp)
ip -> client -> packet_length,
inaddr_any, &sockaddr_broadcast,
(struct hardware *)0);
if (result < 0)
warn ("send_packet: %m");
}
void make_discover (ip, lease)
@ -1690,7 +1692,7 @@ void make_release (ip, lease)
ip -> client -> packet.htype = ip -> hw_address.htype;
ip -> client -> packet.hlen = ip -> hw_address.hlen;
ip -> client -> packet.hops = 0;
ip -> client -> packet.xid = ip -> client -> xid;
ip -> client -> packet.xid = random ();
ip -> client -> packet.secs = 0;
ip -> client -> packet.flags = 0;
memcpy (&ip -> client -> packet.ciaddr,
@ -2096,6 +2098,11 @@ void go_daemon ()
/* Become session leader and get pid... */
pid = setsid ();
/* Close standard I/O descriptors. */
close(0);
close(1);
close(2);
write_client_pid_file ();
}

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: bpf.c,v 1.19.2.6 1999/02/09 04:46:59 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: bpf.c,v 1.19.2.8 1999/02/23 22:09:56 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -142,13 +142,14 @@ void if_register_send (info)
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on BPF/%s/%s/%s",
note ("Sending on BPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_BPF_SEND */
@ -250,13 +251,14 @@ void if_register_receive (info)
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
error ("Can't install packet filter program: %m");
if (!quiet_interface_discovery)
note ("Listening on BPF/%s/%s/%s",
note ("Listening on BPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_BPF_RECEIVE */
@ -273,6 +275,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
int result;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
@ -290,7 +293,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
result = writev(interface -> wfdesc, iov, 2);
if (result < 0)
warn ("send_packet: %m");
return result;
}
#endif /* USE_BPF_SEND */

View File

@ -3,8 +3,8 @@
Network input dispatcher... */
/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
* Copyright (c) 1995, 1996, 1997, 1998, 1999
* 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
@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: dispatch.c,v 1.47.2.9 1999/02/05 20:23:50 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: dispatch.c,v 1.47.2.12 1999/02/23 17:37:00 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -79,6 +79,7 @@ void discover_interfaces (state)
struct shared_network *share;
struct sockaddr_in foo;
int ir;
struct ifreq *tif;
#ifdef ALIAS_NAMES_PERMUTED
char *s;
#endif
@ -110,7 +111,7 @@ void discover_interfaces (state)
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
#ifdef HAVE_SA_LEN
if (ifp -> ifr_addr.sa_len)
if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
else
#endif
@ -139,7 +140,7 @@ 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
#ifdef HAVE_IFF_POINTOPOINT
(ifr.ifr_flags & IFF_POINTOPOINT) ||
#endif
(!(ifr.ifr_flags & IFF_UP) &&
@ -167,7 +168,7 @@ void discover_interfaces (state)
/* If we have the capability, extract link information
and record it in a linked list. */
#ifdef AF_LINK
#ifdef HAVE_AF_LINK
if (ifp -> ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *foo = ((struct sockaddr_dl *)
(&ifp -> ifr_addr));
@ -194,7 +195,6 @@ void discover_interfaces (state)
found, keep a pointer to ifreq structure in
which we found it. */
if (!tmp -> ifp) {
struct ifreq *tif;
#ifdef HAVE_SA_LEN
int len = ((sizeof ifp -> ifr_name) +
ifp -> ifr_addr.sa_len);
@ -276,7 +276,6 @@ void discover_interfaces (state)
if (state == DISCOVER_UNCONFIGURED) {
FILE *proc_dev;
char buffer [256];
struct ifreq *tif;
int skip = 2;
proc_dev = fopen (PROCDEV_DEVICE, "r");
@ -306,25 +305,10 @@ void discover_interfaces (state)
if (!strcmp (tmp -> name, name))
break;
/* If we found one, and it already has an ifreq
structure, nothing more to do.. */
if (tmp && tmp -> ifp)
/* If we found one, nothing more to do.. */
if (tmp)
continue;
/* Make up an ifreq structure. */
tif = (struct ifreq *)malloc (sizeof (struct ifreq));
if (!tif)
error ("no space to remember ifp.");
memset (tif, 0, sizeof (struct ifreq));
strcpy (tif -> ifr_name, name);
/* Now, if we just needed the ifreq structure, hook
it in and move on. */
if (tmp) {
tmp -> ifp = tif;
continue;
}
/* Otherwise, allocate one. */
tmp = ((struct interface_info *)
dmalloc (sizeof *tmp, "discover_interfaces"));
@ -334,7 +318,6 @@ void discover_interfaces (state)
memset (tmp, 0, sizeof *tmp);
strcpy (tmp -> name, name);
tmp -> ifp = tif;
tmp -> flags = ir;
tmp -> next = interfaces;
interfaces = tmp;
@ -345,12 +328,22 @@ void discover_interfaces (state)
/* Now cycle through all the interfaces we found, looking for
hardware addresses. */
#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
#if defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK)
for (tmp = interfaces; tmp; tmp = tmp -> next) {
struct ifreq ifr;
struct sockaddr sa;
int b, sk;
if (!tmp -> ifp) {
/* Make up an ifreq structure. */
tif = (struct ifreq *)malloc (sizeof (struct ifreq));
if (!tif)
error ("no space to remember ifp.");
memset (tif, 0, sizeof (struct ifreq));
strcpy (tif -> ifr_name, tmp -> name);
tmp -> ifp = tif;
}
/* Read the hardware address from this interface. */
ifr = *tmp -> ifp;
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
@ -359,7 +352,11 @@ void discover_interfaces (state)
sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
switch (sa.sa_family) {
#ifdef ARPHRD_LOOPBACK
#ifdef HAVE_ARPHRD_TUNNEL
case ARPHRD_TUNNEL:
/* ignore tunnel interfaces. */
#endif
#ifdef HAVE_ARPHRD_LOOPBACK
case ARPHRD_LOOPBACK:
/* ignore loopback interface */
break;
@ -389,7 +386,7 @@ void discover_interfaces (state)
memcpy (tmp -> hw_address.haddr, sa.sa_data, 16);
break;
#ifdef ARPHRD_METRICOM
#ifdef HAVE_ARPHRD_METRICOM
case ARPHRD_METRICOM:
tmp -> hw_address.hlen = 6;
tmp -> hw_address.htype = ARPHRD_METRICOM;
@ -402,7 +399,7 @@ void discover_interfaces (state)
ifr.ifr_name, sa.sa_family);
}
}
#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
#endif /* defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK) */
/* If we're just trying to get a list of interfaces that we might
be able to configure, we can quit now. */
@ -437,9 +434,13 @@ void discover_interfaces (state)
sizeof tmp -> ifp -> ifr_addr);
/* We must have a subnet declaration for each interface. */
if (!tmp -> shared_network && (state == DISCOVER_SERVER))
error ("No subnet declaration for %s (%s).",
tmp -> name, inet_ntoa (foo.sin_addr));
if (!tmp -> shared_network && (state == DISCOVER_SERVER)) {
warn ("No subnet declaration for %s (%s).",
tmp -> name, inet_ntoa (foo.sin_addr));
warn ("Please write a subnet declaration for the %s",
"network segment to");
error ("which interface %s is attached.", tmp -> name);
}
/* Find subnets that don't have valid interface
addresses... */

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: lpf.c,v 1.1.2.4 1999/02/09 04:51:05 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: lpf.c,v 1.1.2.6 1999/02/23 22:09:55 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -129,13 +129,14 @@ void if_register_send (info)
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on LPF/%s/%s/%s",
note ("Sending on LPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_LPF_SEND */
@ -174,13 +175,14 @@ void if_register_receive (info)
error ("Can't install packet filter program: %m");
}
if (!quiet_interface_discovery)
note ("Listening on LPF/%s/%s/%s",
note ("Listening on LPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_LPF_RECEIVE */
@ -197,6 +199,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int bufp = 0;
unsigned char buf [1500];
struct sockaddr sa;
int result;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
@ -216,8 +219,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
strncpy (sa.sa_data,
(const char *)interface -> ifp, sizeof sa.sa_data);
return sendto (interface -> wfdesc, buf, bufp + len, 0,
&sa, sizeof sa);
result = sendto (interface -> wfdesc, buf, bufp + len, 0,
&sa, sizeof sa);
if (result < 0)
warn ("send_packet: %m");
return result;
}
#endif /* USE_LPF_SEND */

View File

@ -4,7 +4,7 @@
with one crucial tidbit of help from Stu Grossmen. */
/*
* Copyright (c) 1996 The Internet Software Consortium.
* Copyright (c) 1996, 1998, 1999 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: nit.c,v 1.15.2.1 1998/12/20 18:27:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: nit.c,v 1.15.2.3 1999/02/23 22:09:54 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -155,12 +155,13 @@ void if_register_send (info)
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on NIT/%s/%s",
note ("Sending on NIT/%s%s%s",
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_NIT_SEND */
@ -238,12 +239,13 @@ void if_register_receive (info)
error ("Can't set NIT filter on %s: %m", info -> name);
if (!quiet_interface_discovery)
note ("Listening on NIT/%s/%s",
note ("Listening on NIT/%s%s%s",
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_NIT_RECEIVE */
@ -263,6 +265,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct strbuf ctl, data;
int hw_end;
struct sockaddr_in foo;
int result;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
@ -298,7 +301,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
data.buf = (char *)&buf [hw_end];
data.maxlen = data.len = bufp + len - hw_end;
return putmsg (interface -> wfdesc, &ctl, &data, 0);
result = putmsg (interface -> wfdesc, &ctl, &data, 0);
if (result < 0)
warn ("send_packet: %m");
return result;
}
#endif /* USE_NIT_SEND */

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: print.c,v 1.16.2.2 1998/11/24 22:39:35 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
"$Id: print.c,v 1.16.2.3 1999/02/13 19:19:03 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -80,15 +80,15 @@ void print_lease (lease)
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" stamp %s", tbuf);
debug (" hardware addr = %s",

View File

@ -16,7 +16,7 @@
Sigh. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* Copyright (c) 1995, 1996, 1997, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -54,7 +54,7 @@
#ifndef lint
static char copyright[] =
"$Id: raw.c,v 1.11 1997/10/20 21:47:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: raw.c,v 1.11.2.2 1999/02/23 22:09:54 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -97,10 +97,11 @@ void if_register_send (info)
info -> wfdesc = sock;
if (!quiet_interface_discovery)
note ("Sending on Raw/%s/%s",
note ("Sending on Raw/%s%s%s",
info -> name,
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
size_t send_packet (interface, packet, raw, len, from, to, hto)
@ -115,6 +116,7 @@ size_t send_packet (interface, packet, raw, len, from, to, hto)
unsigned char buf [256];
int bufp = 0;
struct iovec iov [2];
int result;
/* Assemble the headers... */
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
@ -127,6 +129,9 @@ size_t send_packet (interface, packet, raw, len, from, to, hto)
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
result = writev(interface -> wfdesc, iov, 2);
if (result < 0)
warn ("send_packet: %m");
return result;
}
#endif /* USE_SOCKET_SEND */

View File

@ -50,7 +50,7 @@
#ifndef lint
static char copyright[] =
"$Id: socket.c,v 1.26.2.6 1999/02/03 19:46:04 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: socket.c,v 1.26.2.10 1999/02/23 22:09:55 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -102,7 +102,7 @@ int if_register_socket (info)
int sock;
int flag;
#if !defined (SO_BINDTODEVICE) && !defined (USE_FALLBACK)
#if !defined (HAVE_SO_BINDTODEVICE) && !defined (USE_FALLBACK)
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s",
@ -136,12 +136,12 @@ int if_register_socket (info)
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
#if defined (SO_BINDTODEVICE)
#if defined (HAVE_SO_BINDTODEVICE)
/* Bind this socket to this interface. */
if (info -> ifp &&
setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
(char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
error("setsockopt: SO_BINDTODEVICE: %m");
}
#endif
@ -159,11 +159,11 @@ void if_register_send (info)
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on Socket/%s/%s",
note ("Sending on Socket/%s%s%s",
info -> name,
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_SOCKET_SEND */
@ -175,10 +175,11 @@ void if_register_receive (info)
we don't need to register this interface twice. */
info -> rfdesc = if_register_socket (info);
if (!quiet_interface_discovery)
note ("Listening on Socket/%s/%s",
note ("Listening on Socket/%s%s%s",
info -> name,
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_SOCKET_RECEIVE */
@ -206,6 +207,12 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
errno == ECONNREFUSED) &&
retry++ < 10);
#endif
if (result < 0) {
warn ("send_packet: %m");
if (errno == ENETUNREACH)
warn ("send_packet: please consult README file %s",
"regarding broadcast address.");
}
return result;
}
#endif /* USE_SOCKET_SEND */

View File

@ -3,8 +3,8 @@
Ultrix PacketFilter interface code.
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
* Copyright (c) 1995, 1996, 1997, 1998, 1999
* 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
@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: upf.c,v 1.3.2.1 1998/12/20 18:29:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: upf.c,v 1.3.2.3 1999/02/23 22:09:56 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -143,13 +143,14 @@ void if_register_send (info)
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on UPF/%s/%s/%s",
note ("Sending on UPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_UPF_SEND */
@ -208,13 +209,14 @@ void if_register_receive (info)
if (ioctl (info -> rfdesc, EIOCSETF, &pf) < 0)
error ("Can't install packet filter program: %m");
if (!quiet_interface_discovery)
note ("Listening on UPF/%s/%s/%s",
note ("Listening on UPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
info -> shared_network -> name : ""));
}
#endif /* USE_UPF_RECEIVE */
@ -231,6 +233,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
int result;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
@ -248,7 +251,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
result = writev(interface -> wfdesc, iov, 2);
if (result < 0)
warn ("send_packet: %m");
return result;
}
#endif /* USE_UPF_SEND */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,684 @@
Network Working Group Bill Croft (Stanford University)
Request for Comments: 951 John Gilmore (Sun Microsystems)
September 1985
BOOTSTRAP PROTOCOL (BOOTP)
1. Status of this Memo
This RFC suggests a proposed protocol for the ARPA-Internet
community, and requests discussion and suggestions for improvements.
Distribution of this memo is unlimited.
2. Overview
This RFC describes an IP/UDP bootstrap protocol (BOOTP) which allows
a diskless client machine to discover its own IP address, the address
of a server host, and the name of a file to be loaded into memory and
executed. The bootstrap operation can be thought of as consisting of
TWO PHASES. This RFC describes the first phase, which could be
labeled 'address determination and bootfile selection'. After this
address and filename information is obtained, control passes to the
second phase of the bootstrap where a file transfer occurs. The file
transfer will typically use the TFTP protocol [9], since it is
intended that both phases reside in PROM on the client. However
BOOTP could also work with other protocols such as SFTP [3] or
FTP [6].
We suggest that the client's PROM software provide a way to do a
complete bootstrap without 'user' interaction. This is the type of
boot that would occur during an unattended power-up. A mechanism
should be provided for the user to manually supply the necessary
address and filename information to bypass the BOOTP protocol and
enter the file transfer phase directly. If non-volatile storage is
available, we suggest keeping default settings there and bypassing
the BOOTP protocol unless these settings cause the file transfer
phase to fail. If the cached information fails, the bootstrap should
fall back to phase 1 and use BOOTP.
Here is a brief outline of the protocol:
1. A single packet exchange is performed. Timeouts are used to
retransmit until a reply is received. The same packet field
layout is used in both directions. Fixed length fields of maximum
reasonable length are used to simplify structure definition and
parsing.
2. An 'opcode' field exists with two values. The client
broadcasts a 'bootrequest' packet. The server then answers with a
'bootreply' packet. The bootrequest contains the client's
hardware address and its IP address, if known.
Croft & Gilmore [Page 1]
RFC 951 September 1985
Bootstrap Protocol
3. The request can optionally contain the name of the server the
client wishes to respond. This is so the client can force the
boot to occur from a specific host (e.g. if multiple versions of
the same bootfile exist or if the server is in a far distant
net/domain). The client does not have to deal with name / domain
services; instead this function is pushed off to the BOOTP server.
4. The request can optionally contain the 'generic' filename to be
booted. For example 'unix' or 'ethertip'. When the server sends
the bootreply, it replaces this field with the fully qualified
path name of the appropriate boot file. In determining this name,
the server may consult his own database correlating the client's
address and filename request, with a particular boot file
customized for that client. If the bootrequest filename is a null
string, then the server returns a filename field indicating the
'default' file to be loaded for that client.
5. In the case of clients who do not know their IP addresses, the
server must also have a database relating hardware address to IP
address. This client IP address is then placed into a field in
the bootreply.
6. Certain network topologies (such as Stanford's) may be such
that a given physical cable does not have a TFTP server directly
attached to it (e.g. all the gateways and hosts on a certain cable
may be diskless). With the cooperation of neighboring gateways,
BOOTP can allow clients to boot off of servers several hops away,
through these gateways. See the section 'Booting Through
Gateways' below. This part of the protocol requires no special
action on the part of the client. Implementation is optional and
requires a small amount of additional code in gateways and
servers.
3. Packet Format
All numbers shown are decimal, unless indicated otherwise. The BOOTP
packet is enclosed in a standard IP [8] UDP [7] datagram. For
simplicity it is assumed that the BOOTP packet is never fragmented.
Any numeric fields shown are packed in 'standard network byte order',
i.e. high order bits are sent first.
In the IP header of a bootrequest, the client fills in its own IP
source address if known, otherwise zero. When the server address is
unknown, the IP destination address will be the 'broadcast address'
255.255.255.255. This address means 'broadcast on the local cable,
(I don't know my net number)' [4].
Croft & Gilmore [Page 2]
RFC 951 September 1985
Bootstrap Protocol
The UDP header contains source and destination port numbers. The
BOOTP protocol uses two reserved port numbers, 'BOOTP client' (68)
and 'BOOTP server' (67). The client sends requests using 'BOOTP
server' as the destination port; this is usually a broadcast. The
server sends replies using 'BOOTP client' as the destination port;
depending on the kernel or driver facilities in the server, this may
or may not be a broadcast (this is explained further in the section
titled 'Chicken/Egg issues' below). The reason TWO reserved ports
are used, is to avoid 'waking up' and scheduling the BOOTP server
daemons, when a bootreply must be broadcast to a client. Since the
server and other hosts won't be listening on the 'BOOTP client' port,
any such incoming broadcasts will be filtered out at the kernel
level. We could not simply allow the client to pick a 'random' port
number for the UDP source port field; since the server reply may be
broadcast, a randomly chosen port number could confuse other hosts
that happened to be listening on that port.
The UDP length field is set to the length of the UDP plus BOOTP
portions of the packet. The UDP checksum field can be set to zero by
the client (or server) if desired, to avoid this extra overhead in a
PROM implementation. In the 'Packet Processing' section below the
phrase '[UDP checksum.]' is used whenever the checksum might be
verified/computed.
FIELD BYTES DESCRIPTION
----- ----- -----------
op 1 packet op code / message type.
1 = BOOTREQUEST, 2 = BOOTREPLY
htype 1 hardware address type,
see ARP section in "Assigned Numbers" RFC.
'1' = 10mb ethernet
hlen 1 hardware address length
(eg '6' for 10mb ethernet).
hops 1 client sets to zero,
optionally used by gateways
in cross-gateway booting.
xid 4 transaction ID, a random number,
used to match this boot request with the
responses it generates.
secs 2 filled in by client, seconds elapsed since
client started trying to boot.
Croft & Gilmore [Page 3]
RFC 951 September 1985
Bootstrap Protocol
-- 2 unused
ciaddr 4 client IP address;
filled in by client in bootrequest if known.
yiaddr 4 'your' (client) IP address;
filled by server if client doesn't
know its own address (ciaddr was 0).
siaddr 4 server IP address;
returned in bootreply by server.
giaddr 4 gateway IP address,
used in optional cross-gateway booting.
chaddr 16 client hardware address,
filled in by client.
sname 64 optional server host name,
null terminated string.
file 128 boot file name, null terminated string;
'generic' name or null in bootrequest,
fully qualified directory-path
name in bootreply.
vend 64 optional vendor-specific area,
e.g. could be hardware type/serial on request,
or 'capability' / remote file system handle
on reply. This info may be set aside for use
by a third phase bootstrap or kernel.
4. Chicken / Egg Issues
How can the server send an IP datagram to the client, if the client
doesnt know its own IP address (yet)? Whenever a bootreply is being
sent, the transmitting machine performs the following operations:
1. If the client knows its own IP address ('ciaddr' field is
nonzero), then the IP can be sent 'as normal', since the client
will respond to ARPs [5].
2. If the client does not yet know its IP address (ciaddr zero),
then the client cannot respond to ARPs sent by the transmitter of
the bootreply. There are two options:
a. If the transmitter has the necessary kernel or driver hooks
Croft & Gilmore [Page 4]
RFC 951 September 1985
Bootstrap Protocol
to 'manually' construct an ARP address cache entry, then it can
fill in an entry using the 'chaddr' and 'yiaddr' fields. Of
course, this entry should have a timeout on it, just like any
other entry made by the normal ARP code itself. The
transmitter of the bootreply can then simply send the bootreply
to the client's IP address. UNIX (4.2 BSD) has this
capability.
b. If the transmitter lacks these kernel hooks, it can simply
send the bootreply to the IP broadcast address on the
appropriate interface. This is only one additional broadcast
over the previous case.
5. Client Use of ARP
The client PROM must contain a simple implementation of ARP, e.g. the
address cache could be just one entry in size. This will allow a
second-phase-only boot (TFTP) to be performed when the client knows
the IP addresses and bootfile name.
Any time the client is expecting to receive a TFTP or BOOTP reply, it
should be prepared to answer an ARP request for its own IP to
hardware address mapping (if known).
Since the bootreply will contain (in the hardware encapsulation) the
hardware source address of the server/gateway, the client MAY be able
to avoid sending an ARP request for the server/gateway IP address to
be used in the following TFTP phase. However this should be treated
only as a special case, since it is desirable to still allow a
second-phase-only boot as described above.
6. Comparison to RARP
An earlier protocol, Reverse Address Resolution Protocol (RARP) [1]
was proposed to allow a client to determine its IP address, given
that it knew its hardware address. However RARP had the disadvantage
that it was a hardware link level protocol (not IP/UDP based). This
means that RARP could only be implemented on hosts containing special
kernel or driver modifications to access these 'raw' packets. Since
there are many network kernels existent now, with each source
maintained by different organizations, a boot protocol that does not
require kernel modifications is a decided advantage.
BOOTP provides this hardware to IP address lookup function, in
addition to the other useful features described in the sections
above.
Croft & Gilmore [Page 5]
RFC 951 September 1985
Bootstrap Protocol
7. Packet Processing
7.1. Client Transmission
Before setting up the packet for the first time, it is a good idea
to clear the entire packet buffer to all zeros; this will place
all fields in their default state. The client then creates a
packet with the following fields.
The IP destination address is set to 255.255.255.255. (the
broadcast address) or to the server's IP address (if known). The
IP source address and 'ciaddr' are set to the client's IP address
if known, else 0. The UDP header is set with the proper length;
source port = 'BOOTP client' port destination port = 'BOOTP
server' port.
'op' is set to '1', BOOTREQUEST. 'htype' is set to the hardware
address type as assigned in the ARP section of the "Assigned
Numbers" RFC. 'hlen' is set to the length of the hardware address,
e.g. '6' for 10mb ethernet.
'xid' is set to a 'random' transaction id. 'secs' is set to the
number of seconds that have elapsed since the client has started
booting. This will let the servers know how long a client has
been trying. As the number gets larger, certain servers may feel
more 'sympathetic' towards a client they don't normally service.
If a client lacks a suitable clock, it could construct a rough
estimate using a loop timer. Or it could choose to simply send
this field as always a fixed value, say 100 seconds.
If the client knows its IP address, 'ciaddr' (and the IP source
address) are set to this value. 'chaddr' is filled in with the
client's hardware address.
If the client wishes to restrict booting to a particular server
name, it may place a null-terminated string in 'sname'. The name
used should be any of the allowable names or nicknames of the
desired host.
The client has several options for filling the 'file' name field.
If left null, the meaning is 'I want to boot the default file for
my machine'. A null file name can also mean 'I am only interested
in finding out client/server/gateway IP addresses, I dont care
about file names'.
The field can also be a 'generic' name such as 'unix' or
Croft & Gilmore [Page 6]
RFC 951 September 1985
Bootstrap Protocol
'gateway'; this means 'boot the named program configured for my
machine'. Finally the field can be a fully directory qualified
path name.
The 'vend' field can be filled in by the client with
vendor-specific strings or structures. For example the machine
hardware type or serial number may be placed here. However the
operation of the BOOTP server should not DEPEND on this
information existing.
If the 'vend' field is used, it is recommended that a 4 byte
'magic number' be the first item within 'vend'. This lets a
server determine what kind of information it is seeing in this
field. Numbers can be assigned by the usual 'magic number'
process --you pick one and it's magic. A different magic number
could be used for bootreply's than bootrequest's to allow the
client to take special action with the reply information.
[UDP checksum.]
7.2. Client Retransmission Strategy
If no reply is received for a certain length of time, the client
should retransmit the request. The time interval must be chosen
carefully so as not to flood the network. Consider the case of a
cable containing 100 machines that are just coming up after a
power failure. Simply retransmitting the request every four
seconds will inundate the net.
As a possible strategy, you might consider backing off
exponentially, similar to the way ethernet backs off on a
collision. So for example if the first packet is at time 0:00,
the second would be at :04, then :08, then :16, then :32, then
:64. You should also randomize each time; this would be done
similar to the ethernet specification by starting with a mask and
'and'ing that with with a random number to get the first backoff.
On each succeeding backoff, the mask is increased in length by one
bit. This doubles the average delay on each backoff.
After the 'average' backoff reaches about 60 seconds, it should be
increased no further, but still randomized.
Before each retransmission, the client should update the 'secs'
field. [UDP checksum.]
Croft & Gilmore [Page 7]
RFC 951 September 1985
Bootstrap Protocol
7.3. Server Receives BOOTREQUEST
[UDP checksum.] If the UDP destination port does not match the
'BOOTP server' port, discard the packet.
If the server name field (sname) is null (no particular server
specified), or sname is specified and matches our name or
nickname, then continue with packet processing.
If the sname field is specified, but does not match 'us', then
there are several options:
1. You may choose to simply discard this packet.
2. If a name lookup on sname shows it to be on this same cable,
discard the packet.
3. If sname is on a different net, you may choose to forward
the packet to that address. If so, check the 'giaddr' (gateway
address) field. If 'giaddr' is zero, fill it in with my
address or the address of a gateway that can be used to get to
that net. Then forward the packet.
If the client IP address (ciaddr) is zero, then the client does
not know its own IP address. Attempt to lookup the client
hardware address (chaddr, hlen, htype) in our database. If no
match is found, discard the packet. Otherwise we now have an IP
address for this client; fill it into the 'yiaddr' (your IP
address) field.
We now check the boot file name field (file). The field will be
null if the client is not interested in filenames, or wants the
default bootfile. If the field is non-null, it is used as a
lookup key in a database, along with the client's IP address. If
there is a default file or generic file (possibly indexed by the
client address) or a fully-specified path name that matches, then
replace the 'file' field with the fully-specified path name of the
selected boot file. If the field is non-null and no match was
found, then the client is asking for a file we dont have; discard
the packet, perhaps some other BOOTP server will have it.
The 'vend' vendor-specific data field should now be checked and if
a recognized type of data is provided, client-specific actions
should be taken, and a response placed in the 'vend' data field of
the reply packet. For example, a workstation client could provide
Croft & Gilmore [Page 8]
RFC 951 September 1985
Bootstrap Protocol
an authentication key and receive from the server a capability for
remote file access, or a set of configuration options, which can
be passed to the operating system that will shortly be booted in.
Place my (server) IP address in the 'siaddr' field. Set the 'op'
field to BOOTREPLY. The UDP destination port is set to 'BOOTP
client'. If the client address 'ciaddr' is nonzero, send the
packet there; else if the gateway address 'giaddr' is nonzero, set
the UDP destination port to 'BOOTP server' and send the packet to
'giaddr'; else the client is on one of our cables but it doesnt
know its own IP address yet --use a method described in the 'Egg'
section above to send it to the client. If 'Egg' is used and we
have multiple interfaces on this host, use the 'yiaddr' (your IP
address) field to figure out which net (cable/interface) to send
the packet to. [UDP checksum.]
7.4. Server/Gateway Receives BOOTREPLY
[UDP checksum.] If 'yiaddr' (your [the client's] IP address)
refers to one of our cables, use one of the 'Egg' methods above to
forward it to the client. Be sure to send it to the 'BOOTP
client' UDP destination port.
7.5. Client Reception
Don't forget to process ARP requests for my own IP address (if I
know it). [UDP checksum.] The client should discard incoming
packets that: are not IP/UDPs addressed to the boot port; are not
BOOTREPLYs; do not match my IP address (if I know it) or my
hardware address; do not match my transaction id. Otherwise we
have received a successful reply. 'yiaddr' will contain my IP
address, if I didnt know it before. 'file' is the name of the
file name to TFTP 'read request'. The server address is in
'siaddr'. If 'giaddr' (gateway address) is nonzero, then the
packets should be forwarded there first, in order to get to the
server.
8. Booting Through Gateways
This part of the protocol is optional and requires some additional
code in cooperating gateways and servers, but it allows cross-gateway
booting. This is mainly useful when gateways are diskless machines.
Gateways containing disks (e.g. a UNIX machine acting as a gateway),
might as well run their own BOOTP/TFTP servers.
Gateways listening to broadcast BOOTREQUESTs may decide to forward or
rebroadcast these requests 'when appropriate'. For example, the
Croft & Gilmore [Page 9]
RFC 951 September 1985
Bootstrap Protocol
gateway could have, as part of his configuration tables, a list of
other networks or hosts to receive a copy of any broadcast
BOOTREQUESTs. Even though a 'hops' field exists, it is a poor idea
to simply globally rebroadcast the requests, since broadcast loops
will almost certainly occur.
The forwarding could begin immediately, or wait until the 'secs'
(seconds client has been trying) field passes a certain threshold.
If a gateway does decide to forward the request, it should look at
the 'giaddr' (gateway IP address) field. If zero, it should plug its
own IP address (on the receiving cable) into this field. It may also
use the 'hops' field to optionally control how far the packet is
reforwarded. Hops should be incremented on each forwarding. For
example, if hops passes '3', the packet should probably be discarded.
[UDP checksum.]
Here we have recommended placing this special forwarding function in
the gateways. But that does not have to be the case. As long as
some 'BOOTP forwarding agent' exists on the net with the booting
client, the agent can do the forwarding when appropriate. Thus this
service may or may not be co-located with the gateway.
In the case of a forwarding agent not located in the gateway, the
agent could save himself some work by plugging the broadcast address
of the interface receiving the bootrequest into the 'giaddr' field.
Thus the reply would get forwarded using normal gateways, not
involving the forwarding agent. Of course the disadvantage here is
that you lose the ability to use the 'Egg' non-broadcast method of
sending the reply, causing extra overhead for every host on the
client cable.
9. Sample BOOTP Server Database
As a suggestion, we show a sample text file database that the BOOTP
server program might use. The database has two sections, delimited
by a line containing an percent in column 1. The first section
contains a 'default directory' and mappings from generic names to
directory/pathnames. The first generic name in this section is the
'default file' you get when the bootrequest contains a null 'file'
string.
The second section maps hardware addresstype/address into an
ipaddress. Optionally you can also overide the default generic name
by supplying a ipaddress specific genericname. A 'suffix' item is
also an option; if supplied, any generic names specified by the
client will be accessed by first appending 'suffix' to the 'pathname'
Croft & Gilmore [Page 10]
RFC 951 September 1985
Bootstrap Protocol
appropriate to that generic name. If that file is not found, then
the plain 'pathname' will be tried. This 'suffix' option allows a
whole set of custom generics to be setup without a lot of effort.
Below is shown the general format; fields are delimited by one or
more spaces or tabs; trailing empty fields may be omitted; blank
lines and lines beginning with '#' are ignored.
# comment line
homedirectory
genericname1 pathname1
genericname2 pathname2
...
% end of generic names, start of address mappings
hostname1 hardwaretype hardwareaddr1 ipaddr1 genericname suffix
hostname2 hardwaretype hardwareaddr2 ipaddr2 genericname suffix
...
Here is a specific example. Note the 'hardwaretype' number is the
same as that shown in the ARP section of the 'Assigned Numbers' RFC.
The 'hardwaretype' and 'ipaddr' numbers are in decimal;
'hardwareaddr' is in hex.
# last updated by smith
/usr/boot
vmunix vmunix
tip ethertip
watch /usr/diag/etherwatch
gate gate.
% end of generic names, start of address mappings
hamilton 1 02.60.8c.06.34.98 36.19.0.5
burr 1 02.60.8c.34.11.78 36.44.0.12
101-gateway 1 02.60.8c.23.ab.35 36.44.0.32 gate 101
mjh-gateway 1 02.60.8c.12.32.bc 36.42.0.64 gate mjh
welch-tipa 1 02.60.8c.22.65.32 36.47.0.14 tip
welch-tipb 1 02.60.8c.12.15.c8 36.46.0.12 tip
In the example above, if 'mjh-gateway' does a default boot, it will
get the file '/usr/boot/gate.mjh'.
Croft & Gilmore [Page 11]
RFC 951 September 1985
Bootstrap Protocol
10. Acknowledgements
Ross Finlayson (et. al.) produced two earlier RFC's discussing TFTP
bootstraping [2] using RARP [1].
We would also like to acknowledge the previous work and comments of
Noel Chiappa, Bob Lyon, Jeff Mogul, Mark Lewis, and David Plummer.
REFERENCES
1. Ross Finlayson, Timothy Mann, Jeffrey Mogul, Marvin Theimer. A
Reverse Address Resolution Protocol. RFC 903, NIC, June, 1984.
2. Ross Finlayson. Bootstrap Loading using TFTP. RFC 906, NIC,
June, 1984.
3. Mark Lottor. Simple File Transfer Protocol. RFC 913, NIC,
September, 1984.
4. Jeffrey Mogul. Broadcasting Internet Packets. RFC 919, NIC,
October, 1984.
5. David Plummer. An Ethernet Address Resolution Protocol. RFC
826, NIC, September, 1982.
6. Jon Postel. File Transfer Protocol. RFC 765, NIC, June, 1980.
7. Jon Postel. User Datagram Protocol. RFC 768, NIC, August, 1980.
8. Jon Postel. Internet Protocol. RFC 791, NIC, September, 1981.
9. K. R. Sollins, Noel Chiappa. The TFTP Protocol. RFC 783, NIC,
June, 1981.
Croft & Gilmore [Page 12]

View File

@ -3,7 +3,7 @@
Operating system dependencies... */
/*
* Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
* Copyright (c) 1996, 1997, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -123,6 +123,10 @@
# endif
#endif
#if !defined (TIME_MAX)
# define TIME_MAX 2147483647
#endif
/* Porting::
If you add a new network API, and have it set up so that it can be
@ -226,3 +230,36 @@
#ifndef BPF_FORMAT
# define BPF_FORMAT "/dev/bpf%d"
#endif
#if defined (IFF_POINTOPOINT) && !defined (HAVE_IFF_POINTOPOINT)
# define HAVE_IFF_POINTOPOINT
#endif
#if defined (AF_LINK) && !defined (HAVE_AF_LINK)
# define HAVE_AF_LINK
#endif
#if defined (ARPHRD_TUNNEL) && !defined (HAVE_ARPHRD_TUNNEL)
# define HAVE_ARPHRD_TUNNEL
#endif
#if defined (ARPHRD_LOOPBACK) && !defined (HAVE_ARPHRD_LOOPBACK)
# define HAVE_ARPHRD_LOOPBACK
#endif
#if defined (ARPHRD_METRICOM) && !defined (HAVE_ARPHRD_METRICOM)
# define HAVE_ARPHRD_METRICOM
#endif
#if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
# define HAVE_SO_BINDTODEVICE
#endif
#if defined (SIOCGIFHWADDR) && !defined (HAVE_SIOCGIFHWADDR)
# define HAVE_SIOCGIFHWADDR
#endif
#if defined (AF_LINK) && !defined (HAVE_AF_LINK)
# define HAVE_AF_LINK
#endif