1995-11-29 07:40:04 +00:00
|
|
|
/* bootp.c
|
|
|
|
|
|
|
|
BOOTP Protocol support. */
|
|
|
|
|
|
|
|
/*
|
1996-02-07 22:43:54 +00:00
|
|
|
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
|
|
|
* All rights reserved.
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
|
|
|
* 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[] =
|
|
|
|
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
#include "dhcpd.h"
|
|
|
|
|
|
|
|
void bootp (packet)
|
|
|
|
struct packet *packet;
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
struct host_decl *hp = find_host_by_addr (packet -> raw -> htype,
|
|
|
|
packet -> raw -> chaddr,
|
|
|
|
packet -> raw -> hlen);
|
1996-03-06 10:38:04 +00:00
|
|
|
struct packet outgoing;
|
|
|
|
struct dhcp_packet raw;
|
1995-11-29 07:40:04 +00:00
|
|
|
struct sockaddr_in to;
|
1996-03-06 10:38:04 +00:00
|
|
|
struct tree_cache *options [256];
|
|
|
|
int i;
|
1995-11-29 07:40:04 +00:00
|
|
|
|
|
|
|
/* If the packet is from a host we don't know, drop it on
|
|
|
|
the floor. XXX */
|
|
|
|
if (!hp) {
|
|
|
|
note ("Can't find record for BOOTP host %s",
|
|
|
|
print_hw_addr (packet -> raw -> htype,
|
|
|
|
packet -> raw -> hlen,
|
|
|
|
packet -> raw -> chaddr));
|
|
|
|
return;
|
|
|
|
}
|
1996-03-06 10:38:04 +00:00
|
|
|
|
|
|
|
/* If we don't have a fixed address for it, drop it. */
|
1995-11-29 07:40:04 +00:00
|
|
|
if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) {
|
|
|
|
note ("No fixed address for BOOTP host %s (%s)",
|
|
|
|
print_hw_addr (packet -> raw -> htype,
|
|
|
|
packet -> raw -> hlen,
|
|
|
|
packet -> raw -> chaddr),
|
|
|
|
hp -> name);
|
|
|
|
return;
|
|
|
|
}
|
1996-03-06 10:38:04 +00:00
|
|
|
|
|
|
|
/* Set up the outgoing packet... */
|
|
|
|
memset (&outgoing, 0, sizeof outgoing);
|
|
|
|
memset (&raw, 0, sizeof raw);
|
|
|
|
outgoing.raw = &raw;
|
|
|
|
|
|
|
|
/* Come up with a list of options that we want to send to this
|
|
|
|
client. Start with the per-subnet options, and then override
|
|
|
|
those with client-specific options. */
|
|
|
|
|
|
|
|
memcpy (options, packet -> subnet -> options, sizeof options);
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
if (hp -> options [i])
|
|
|
|
options [i] = hp -> options [i];
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
1996-03-06 10:38:04 +00:00
|
|
|
|
|
|
|
/* Pack the options into the buffer. Unlike DHCP, we can't
|
|
|
|
pack options into the filename and server name buffers. */
|
|
|
|
|
|
|
|
cons_options (packet, &outgoing, options, 0);
|
|
|
|
|
|
|
|
|
1995-11-29 07:40:04 +00:00
|
|
|
/* Take the fields that we care about... */
|
1996-03-06 10:38:04 +00:00
|
|
|
raw.op = BOOTREPLY;
|
|
|
|
raw.htype = packet -> raw -> htype;
|
|
|
|
raw.hlen = packet -> raw -> hlen;
|
|
|
|
memcpy (raw.chaddr, packet -> raw -> chaddr, raw.hlen);
|
|
|
|
memset (&raw.chaddr [raw.hlen], 0,
|
|
|
|
(sizeof raw.chaddr) - raw.hlen);
|
|
|
|
raw.hops = packet -> raw -> hops;
|
|
|
|
raw.xid = packet -> raw -> xid;
|
|
|
|
raw.secs = packet -> raw -> secs;
|
|
|
|
raw.flags = 0;
|
|
|
|
raw.ciaddr = packet -> raw -> ciaddr;
|
1995-11-29 07:40:04 +00:00
|
|
|
if (!tree_evaluate (hp -> fixed_addr))
|
|
|
|
warn ("tree_evaluate failed.");
|
|
|
|
debug ("fixed_addr: %x %d %d %d %d %x",
|
|
|
|
*(int *)(hp -> fixed_addr -> value), hp -> fixed_addr -> len,
|
|
|
|
hp -> fixed_addr -> buf_size, hp -> fixed_addr -> timeout,
|
|
|
|
hp -> fixed_addr -> tree);
|
1996-03-06 10:38:04 +00:00
|
|
|
memcpy (&raw.yiaddr, hp -> fixed_addr -> value,
|
|
|
|
sizeof raw.yiaddr);
|
|
|
|
raw.siaddr.s_addr = pick_interface (packet);
|
|
|
|
raw.giaddr = packet -> raw -> giaddr;
|
1995-11-29 07:40:04 +00:00
|
|
|
if (hp -> server_name) {
|
1996-03-06 10:38:04 +00:00
|
|
|
strncpy (raw.sname, hp -> server_name,
|
|
|
|
(sizeof raw.sname) - 1);
|
|
|
|
raw.sname [(sizeof raw.sname) - 1] = 0;
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
if (hp -> filename) {
|
1996-03-06 10:38:04 +00:00
|
|
|
strncpy (raw.file, hp -> filename,
|
|
|
|
(sizeof raw.file) - 1);
|
|
|
|
raw.file [(sizeof raw.file) - 1] = 0;
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
|
1996-03-06 10:38:04 +00:00
|
|
|
/* If this was gatewayed, send it back to the gateway... */
|
|
|
|
if (raw.giaddr.s_addr) {
|
|
|
|
to.sin_addr = raw.giaddr;
|
|
|
|
to.sin_port = server_port;
|
|
|
|
/* Otherwise, broadcast it on the local network. */
|
|
|
|
} else {
|
1995-11-29 07:40:04 +00:00
|
|
|
to.sin_addr.s_addr = INADDR_BROADCAST;
|
1996-03-06 10:38:04 +00:00
|
|
|
to.sin_port = htons (ntohs (server_port) + 1); /* XXX */
|
|
|
|
}
|
1995-11-29 07:40:04 +00:00
|
|
|
|
|
|
|
to.sin_family = AF_INET;
|
1996-03-06 10:38:04 +00:00
|
|
|
#ifdef HAVE_SIN_LEN
|
1995-11-29 07:40:04 +00:00
|
|
|
to.sin_len = sizeof to;
|
1996-03-06 10:38:04 +00:00
|
|
|
#endif
|
1995-11-29 07:40:04 +00:00
|
|
|
memset (to.sin_zero, 0, sizeof to.sin_zero);
|
|
|
|
|
|
|
|
note ("Sending bootp reply to %s, port %d",
|
1996-03-06 10:38:04 +00:00
|
|
|
inet_ntoa (to.sin_addr), to.sin_port);
|
1995-11-29 07:40:04 +00:00
|
|
|
|
|
|
|
errno = 0;
|
1996-03-06 10:38:04 +00:00
|
|
|
result = sendto (packet -> client_sock, &raw, outgoing.packet_length,
|
1995-11-29 07:40:04 +00:00
|
|
|
0, (struct sockaddr *)&to, sizeof to);
|
|
|
|
if (result < 0)
|
|
|
|
warn ("sendto: %m");
|
|
|
|
}
|