home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.uv.es
/
2014.11.ftp.uv.es.tar
/
ftp.uv.es
/
pub
/
unix
/
bootp.2.2+FdC.tar.Z
/
bootp.2.2+FdC.tar
/
gmods
< prev
next >
Wrap
Text File
|
1992-03-23
|
5KB
|
165 lines
Folks,
Here is a summary of the gateway mods needed for BOOTP (to allow
cross gateway booting), and some pseudo-code. First the
BOOTP packet (which is enclosed in an IP/UDP):
====
/*
* Bootstrap Protocol (BOOTP). RFC 951.
*/
struct bootp {
u_char bp_op; /* packet opcode type */
#define BOOTREQUEST 1
#define BOOTREPLY 2
u_char bp_htype; /* hardware addr type */
u_char bp_hlen; /* hardware addr length */
u_char bp_hops; /* gateway hops */
u_long bp_xid; /* transaction ID */
u_short bp_secs; /* seconds since boot began */
u_short bp_unused;
iaddr_t bp_ciaddr; /* client IP address */
iaddr_t bp_yiaddr; /* 'your' IP address */
iaddr_t bp_siaddr; /* server IP address */
iaddr_t bp_giaddr; /* gateway IP address */
u_char bp_chaddr[16]; /* client hardware address */
u_char bp_sname[64]; /* server host name */
u_char bp_file[128]; /* boot file name */
u_char bp_vend[64]; /* vendor-specific area */
};
#define IPPORT_BOOTPS 67
#define IPPORT_BOOTPC 68
====
Next, here is the section from [sri-nic]<rfc>rfc951.txt that has
most to do with gateway issues. However you will probably want to
hardcopy the entire document.
====
RFC 951 September 1985
Bootstrap Protocol [Page 9]
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
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.
====
And here is some pseudo-code:
/*
* Each gateway will probably have a locally configured table
* that lists the addresses of hosts (or gateways)
* (or net numbers) to which BOOTP's can be
* forwarded. Assume this table is called 'bootplist'. It
* can be initialized at compile time, or via a config file.
*
* The easiest case will be to use specific host (or gateway)
* addresses; if net addresses (e.g. 36.45.0.0)
* are used, that will probably require implementing IP directed
* broadcasts. It is probably best to start with the simple case
* of a host list.
*/
xxxxxxx bootplist[] = { , , , };
/*
* "ipreceive" is called with each incoming IP datagram.
*
* Packet headers for the respective layers are in: ether,ip,udp,bootp.
*/
ipreceive()
{
if (ether.dst == broadcast && ether.src == from_our_interfaces)
goto discard;
if (ipchecksum == bad || --ip.ttl <= 0)
goto discard;
if (ip.proto != UDP || udp.port != IPPORT_BOOTPS)
goto forward;
if (ip.dst != broadcast && ip.dst != one_of_my_interfaces)
goto forward;
/*
* We now have a UDP for the BOOTP Server port.
*/
switch (bootp.bp_op) {
case BOOTREQUEST:
if (bootp.bp_secs <= 5 || ++bootp.bp_hops > 5)
goto discard;
if (bootp.bp_giaddr == 0)
ip.src = bootp.bp_giaddr = my IP address;
/* of incoming interface, if possible */
for (each host in bootplist) {
copy_packet_into_new_buffer;
ip.dst = host address;
send_ip;
}
goto discard; /* discard original packet */
case BOOTREPLY:
if (bootp.bp_yiaddr != directly_accessable)
goto discard; /* if not 0 hops from me */
/*
* At this point, we need to use one of the methods
* described in RFC951, section 4, to send the reply
* to the client. Usually this will be: setup a
* temporary arp cache entry for bp_yiaddr at
* hardware address bp_chaddr.
*/
set_arp_cache(bootp.bp_yiaddr, bootp.bp_chaddr);
ip.dst = bootp.bp_yiaddr;
udp.port = IPPORT_BOOTPC; /* for client only now */
goto forward;
default:
goto discard; /* bad opcode */
}
forward:
if (ether.dst == broadcast || ip.dst == broadcast)
goto discard;
forward_ip; /* recomputes ip checksum if needed */
return;
discard:
discard_packet;
return;
}
====
Notes:
The "if (xxx == broadcast)" tests can use 4 or 6 bytes of all ones
(currently). However if directed broadcasts are eventually implemented,
the test would be a little different.