mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 06:15:55 +00:00
- The IO system now tracks all local IP addresses, so that the DHCP
applications (particularly the dhcrelay) can discern between what frames were tranmsitted to it, and what frames are being carried through it which it should not intercept. [ISC-Bugs #15573]
This commit is contained in:
4
RELNOTES
4
RELNOTES
@@ -63,6 +63,10 @@ and for prodding me into improving it.
|
||||
- RFC3942 compliance, site-local option spaces start at 224 now, not 128.
|
||||
||| THIS NEEDS TO BE SPELLED OUT IN THE NEW FEATURES LIST |||
|
||||
|
||||
- The IO system now tracks all local IP addresses, so that the DHCP
|
||||
applications (particularly the dhcrelay) can discern between what frames
|
||||
were tranmsitted to it, and what frames are being carried through it which
|
||||
it should not intercept.
|
||||
|
||||
Changes since 3.0.4b2
|
||||
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char ocopyright[] =
|
||||
"$Id: dhclient.c,v 1.133 2006/02/24 23:16:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: dhclient.c,v 1.134 2006/02/27 23:56:12 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -227,6 +227,8 @@ int main (argc, argv, envp)
|
||||
}
|
||||
}
|
||||
|
||||
limited_broadcast.s_addr = INADDR_BROADCAST;
|
||||
|
||||
if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
|
||||
path_dhclient_conf = s;
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: ctrace.c,v 1.4 2005/03/17 20:14:57 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: ctrace.c,v 1.5 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -46,8 +46,10 @@ void trace_interface_register (trace_type_t *ttype, struct interface_info *ip)
|
||||
memset (&tipkt, 0, sizeof tipkt);
|
||||
memcpy (&tipkt.hw_address,
|
||||
&ip -> hw_address, sizeof ip -> hw_address);
|
||||
memcpy (&tipkt.primary_address,
|
||||
&ip -> primary_address, sizeof ip -> primary_address);
|
||||
if (ip -> address_count > 0)
|
||||
memcpy (&tipkt.primary_address,
|
||||
&ip -> addresses [0],
|
||||
sizeof ip -> addresses [0]);
|
||||
memcpy (tipkt.name, ip -> name, sizeof ip -> name);
|
||||
tipkt.index = htonl (ip -> index);
|
||||
|
||||
@@ -87,8 +89,12 @@ void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
|
||||
|
||||
memcpy (&ip -> hw_address, &tipkt -> hw_address,
|
||||
sizeof ip -> hw_address);
|
||||
memcpy (&ip -> primary_address, &tipkt -> primary_address,
|
||||
sizeof ip -> primary_address);
|
||||
ip -> address_count = ip -> address_max = 1;
|
||||
ip -> addresses = dmalloc (sizeof (struct in_addr), MDL);
|
||||
if (!ip -> addresses)
|
||||
log_fatal ("Can't allocate address buffer for trace interface");
|
||||
memcpy (&ip -> addresses [0], &tipkt -> primary_address,
|
||||
sizeof ip -> addresses [0]);
|
||||
memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
|
||||
ip -> index = ntohl (tipkt -> index);
|
||||
|
||||
@@ -102,7 +108,7 @@ void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
|
||||
ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
|
||||
#endif
|
||||
sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
|
||||
sin -> sin_addr = ip -> primary_address;
|
||||
sin -> sin_addr = ip -> addresses [0];
|
||||
|
||||
addr.len = 4;
|
||||
memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: discover.c,v 1.49 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: discover.c,v 1.50 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -307,8 +307,38 @@ void discover_interfaces (state)
|
||||
if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK) &&
|
||||
((tmp -> flags & INTERFACE_AUTOMATIC) &&
|
||||
state == DISCOVER_SERVER))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* If the only address we have is 0.0.0.0, we
|
||||
shouldn't consider the interface configured. */
|
||||
if (foo.sin_addr.s_addr != htonl(INADDR_ANY))
|
||||
tmp->configured = 1;
|
||||
|
||||
if (!tmp -> addresses) {
|
||||
tmp -> addresses =
|
||||
dmalloc (10 * sizeof (struct in_addr),
|
||||
MDL);
|
||||
if (!tmp -> addresses)
|
||||
log_fatal ("no memory for ifaddrlist");
|
||||
tmp -> address_count = 0;
|
||||
tmp -> address_max = 10;
|
||||
} else if (tmp -> address_count >= tmp -> address_max) {
|
||||
struct in_addr *ta;
|
||||
int newmax = tmp -> address_max * 2;
|
||||
ta = dmalloc (newmax *
|
||||
sizeof (struct in_addr), MDL);
|
||||
if (!ta)
|
||||
log_fatal ("no memory for new "
|
||||
"ifaddrlist");
|
||||
memcpy (ta, tmp -> addresses,
|
||||
tmp -> address_max *
|
||||
sizeof (struct in_addr));
|
||||
dfree (tmp -> addresses, MDL);
|
||||
tmp -> addresses = ta;
|
||||
tmp -> address_max = newmax;
|
||||
}
|
||||
tmp -> addresses [tmp -> address_count++] =
|
||||
foo.sin_addr;
|
||||
|
||||
/* If this is the first real IP address we've
|
||||
found, keep a pointer to ifreq structure in
|
||||
@@ -325,7 +355,6 @@ void discover_interfaces (state)
|
||||
log_fatal ("no space for ifp.");
|
||||
memcpy (tif, ifp, len);
|
||||
tmp -> ifp = tif;
|
||||
tmp -> primary_address = foo.sin_addr;
|
||||
}
|
||||
|
||||
/* Grab the address... */
|
||||
@@ -1138,6 +1167,12 @@ void interface_stash (struct interface_info *tptr)
|
||||
}
|
||||
interface_vector = vec;
|
||||
}
|
||||
if (interface_vector [tptr -> index]) {
|
||||
log_fatal("invalid tracefile - two interfaces with "
|
||||
"same index - %s and %s",
|
||||
interface_vector [tptr->index] -> name,
|
||||
tptr -> name);
|
||||
}
|
||||
interface_reference (&interface_vector [tptr -> index], tptr, MDL);
|
||||
if (tptr -> index >= interface_count)
|
||||
interface_count = tptr -> index + 1;
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: packet.c,v 1.42 2005/03/17 20:14:59 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: packet.c,v 1.43 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -231,6 +231,8 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, buflen)
|
||||
unsigned len;
|
||||
unsigned ulen;
|
||||
int ignore = 0;
|
||||
struct interface_info *ii;
|
||||
int i;
|
||||
|
||||
memcpy(&ip, buf + bufix, sizeof (struct ip));
|
||||
udp = (struct udphdr *)(buf + bufix + ip_len);
|
||||
@@ -245,6 +247,38 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, buflen)
|
||||
return -1;
|
||||
#endif /* USERLAND_FILTER */
|
||||
|
||||
/* Eliminate packets that we might have accidentally intercepted because
|
||||
we are doing routing. */
|
||||
|
||||
/* The DHCP client may not have an IP address; in that case, if we
|
||||
got the packet, we need to look at it. So if address_count is
|
||||
zero on the interface on which we received the packet, accept the
|
||||
packet. */
|
||||
if (!interface -> configured)
|
||||
goto good;
|
||||
|
||||
/* XXX we should handle subnet broadcast addresses here. */
|
||||
/* XXX we should compare against 255.255.255.255, not limited_broadcast,
|
||||
XXX because sometimes we tweak limited_broadcast for debugging.
|
||||
XXX This is only currently a problem on the server. */
|
||||
if (ip.ip_dst.s_addr == limited_broadcast.s_addr)
|
||||
goto good;
|
||||
|
||||
/* Check IP addresses of _all_ interfaces - it's perfectly okay to send
|
||||
a packet to an IP address on one interface that happens to arrive
|
||||
through another interface. */
|
||||
/* XXX if the user excluded some interfaces, we will not accept packets
|
||||
XXX for those interfaces. */
|
||||
for (ii = interfaces; ii; ii = ii -> next) {
|
||||
for (i = 0; i < ii -> address_count; i++) {
|
||||
if (ii -> addresses [i].s_addr == ip.ip_dst.s_addr)
|
||||
goto good;
|
||||
}
|
||||
}
|
||||
/* The IP destination address didn't match any of our addresses. */
|
||||
return -1;
|
||||
|
||||
good:
|
||||
ulen = ntohs (udp -> uh_ulen);
|
||||
if (ulen < sizeof *udp ||
|
||||
((unsigned char *)udp) + ulen > buf + bufix + buflen) {
|
||||
|
@@ -779,6 +779,12 @@ struct client_state {
|
||||
struct option_state *sent_options; /* Options we sent. */
|
||||
};
|
||||
|
||||
/* Relay agent server list. */
|
||||
struct server_list {
|
||||
struct server_list *next;
|
||||
struct sockaddr_in to;
|
||||
} *servers;
|
||||
|
||||
/* Information about each network interface. */
|
||||
|
||||
struct interface_info {
|
||||
@@ -787,7 +793,12 @@ struct interface_info {
|
||||
struct shared_network *shared_network;
|
||||
/* Networks connected to this interface. */
|
||||
struct hardware hw_address; /* Its physical address. */
|
||||
struct in_addr primary_address; /* Primary interface address. */
|
||||
struct in_addr *addresses; /* Addresses associated with
|
||||
interface. */
|
||||
int address_count; /* Number of addresses associated with
|
||||
interface. */
|
||||
int address_max; /* Max number of addresses we can
|
||||
store in current buffer. */
|
||||
|
||||
u_int8_t *circuit_id; /* Circuit ID associated with this
|
||||
interface. */
|
||||
@@ -796,6 +807,8 @@ struct interface_info {
|
||||
u_int8_t *remote_id; /* Remote ID associated with this
|
||||
interface (if any). */
|
||||
unsigned remote_id_len; /* Length of Remote ID. */
|
||||
struct server_list *servers; /* List of relay servers for this
|
||||
interface. */
|
||||
|
||||
char name [IFNAMSIZ]; /* Its name... */
|
||||
int index; /* Its index. */
|
||||
@@ -808,6 +821,9 @@ struct interface_info {
|
||||
size_t rbuf_len; /* Length of data in buffer. */
|
||||
|
||||
struct ifreq *ifp; /* Pointer to ifreq struct. */
|
||||
int configured; /* If set to 1, interface has at
|
||||
* least one valid IP address.
|
||||
*/
|
||||
u_int32_t flags; /* Control flags... */
|
||||
#define INTERFACE_REQUESTED 1
|
||||
#define INTERFACE_AUTOMATIC 2
|
||||
@@ -2037,6 +2053,7 @@ int parse_ip_addr PROTO ((struct parse *, struct iaddr *));
|
||||
void parse_reject_statement PROTO ((struct parse *, struct client_config *));
|
||||
|
||||
/* dhcrelay.c */
|
||||
void new_relay_server (char *, struct server_list **);
|
||||
void relay PROTO ((struct interface_info *, struct dhcp_packet *, unsigned,
|
||||
unsigned int, struct iaddr, struct hardware *));
|
||||
int strip_relay_agent_options PROTO ((struct interface_info *,
|
||||
|
@@ -27,7 +27,7 @@
|
||||
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||
.\" Enterprises, see ``http://www.vix.com''.
|
||||
.\"
|
||||
.\" $Id: dhcrelay.8,v 1.10 2005/03/17 20:15:24 dhankins Exp $
|
||||
.\" $Id: dhcrelay.8,v 1.11 2006/02/27 23:56:13 dhankins Exp $
|
||||
.\"
|
||||
.TH dhcrelay 8
|
||||
.SH NAME
|
||||
@@ -48,6 +48,11 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent
|
||||
.B -i
|
||||
.I if0
|
||||
[
|
||||
.B -is
|
||||
.I server
|
||||
...
|
||||
]
|
||||
[
|
||||
.B ...
|
||||
.B -i
|
||||
.I ifN
|
||||
@@ -114,6 +119,11 @@ server) is attached. However, in some cases it may be necessary to
|
||||
exclude some networks; in this case, you must list all those network
|
||||
interfaces that should \fInot\fR be excluded using the \fB-i\fR flag.
|
||||
.PP
|
||||
The
|
||||
.B -is
|
||||
flag can be used to indicate that for the previous interface specified with
|
||||
-i, packets should be forwarded to the specified server.
|
||||
.PP
|
||||
In some cases it
|
||||
.I is
|
||||
helpful for the relay agent to forward requests from networks on which
|
||||
|
139
relay/dhcrelay.c
139
relay/dhcrelay.c
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char ocopyright[] =
|
||||
"$Id: dhcrelay.c,v 1.54 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: dhcrelay.c,v 1.55 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -92,11 +92,6 @@ enum { forward_and_append, /* Forward and append our own relay option. */
|
||||
u_int16_t local_port;
|
||||
u_int16_t remote_port;
|
||||
|
||||
struct server_list {
|
||||
struct server_list *next;
|
||||
struct sockaddr_in to;
|
||||
} *servers;
|
||||
|
||||
static char copyright [] = "Copyright 2004-2005 Internet Systems Consortium.";
|
||||
static char arr [] = "All rights reserved.";
|
||||
static char message [] = "Internet Systems Consortium DHCP Relay Agent";
|
||||
@@ -113,6 +108,7 @@ int main (argc, argv, envp)
|
||||
int quiet = 0;
|
||||
isc_result_t status;
|
||||
char *s;
|
||||
struct interface_info *tmp = (struct interface_info *)0;
|
||||
|
||||
/* Make sure we have stdin, stdout and stderr. */
|
||||
i = open ("/dev/null", O_RDWR);
|
||||
@@ -154,8 +150,8 @@ int main (argc, argv, envp)
|
||||
} else if (!strcmp (argv [i], "-d")) {
|
||||
no_daemon = 1;
|
||||
} else if (!strcmp (argv [i], "-i")) {
|
||||
struct interface_info *tmp =
|
||||
(struct interface_info *)0;
|
||||
if (tmp)
|
||||
interface_dereference (&tmp, MDL);
|
||||
status = interface_allocate (&tmp, MDL);
|
||||
if (status != ISC_R_SUCCESS)
|
||||
log_fatal ("%s: interface_allocate: %s",
|
||||
@@ -166,7 +162,14 @@ int main (argc, argv, envp)
|
||||
}
|
||||
strcpy (tmp -> name, argv [i]);
|
||||
interface_snorf (tmp, INTERFACE_REQUESTED);
|
||||
interface_dereference (&tmp, MDL);
|
||||
} else if (!strcmp (argv [i], "-is")) {
|
||||
if (++i == argc)
|
||||
usage ();
|
||||
if (!tmp) {
|
||||
log_error ("-is must follow -i.");
|
||||
usage ();
|
||||
}
|
||||
new_relay_server (argv [i], &tmp -> servers);
|
||||
} else if (!strcmp (argv [i], "-q")) {
|
||||
quiet = 1;
|
||||
quiet_interface_discovery = 1;
|
||||
@@ -206,33 +209,15 @@ int main (argc, argv, envp)
|
||||
log_info ("isc-dhcrelay-%s", DHCP_VERSION);
|
||||
exit (0);
|
||||
} else {
|
||||
struct hostent *he;
|
||||
struct in_addr ia, *iap = (struct in_addr *)0;
|
||||
if (inet_aton (argv [i], &ia)) {
|
||||
iap = &ia;
|
||||
} else {
|
||||
he = gethostbyname (argv [i]);
|
||||
if (!he) {
|
||||
log_error ("%s: host unknown",
|
||||
argv [i]);
|
||||
} else {
|
||||
iap = ((struct in_addr *)
|
||||
he -> h_addr_list [0]);
|
||||
}
|
||||
}
|
||||
if (iap) {
|
||||
sp = ((struct server_list *)
|
||||
dmalloc (sizeof *sp, MDL));
|
||||
if (!sp)
|
||||
log_fatal ("no memory for server.\n");
|
||||
sp -> next = servers;
|
||||
servers = sp;
|
||||
memcpy (&sp -> to.sin_addr,
|
||||
iap, sizeof *iap);
|
||||
}
|
||||
new_relay_server (argv [i], &servers);
|
||||
}
|
||||
}
|
||||
|
||||
limited_broadcast.s_addr = INADDR_BROADCAST;
|
||||
|
||||
if (tmp)
|
||||
interface_dereference (&tmp, MDL);
|
||||
|
||||
if ((s = getenv ("PATH_DHCRELAY_PID"))) {
|
||||
path_dhcrelay_pid = s;
|
||||
}
|
||||
@@ -259,7 +244,7 @@ int main (argc, argv, envp)
|
||||
remote_port = htons (ntohs (local_port) + 1);
|
||||
|
||||
/* We need at least one server. */
|
||||
if (!sp) {
|
||||
if (!servers) {
|
||||
usage ();
|
||||
}
|
||||
|
||||
@@ -272,6 +257,29 @@ int main (argc, argv, envp)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (interfaces) {
|
||||
interface_reference (&tmp, interfaces, MDL);
|
||||
do {
|
||||
struct interface_info *next = NULL;
|
||||
if (tmp -> next)
|
||||
interface_reference (&next, tmp -> next, MDL);
|
||||
|
||||
for (sp = tmp -> servers; sp; sp = sp -> next) {
|
||||
sp -> to.sin_port = local_port;
|
||||
sp -> to.sin_family = AF_INET;
|
||||
#ifdef HAVE_SA_LEN
|
||||
sp -> to.sin_len = sizeof sp -> to;
|
||||
#endif
|
||||
}
|
||||
|
||||
interface_dereference (&tmp, MDL);
|
||||
if (next) {
|
||||
interface_reference (&tmp, next, MDL);
|
||||
interface_dereference (&next, MDL);
|
||||
}
|
||||
} while (tmp);
|
||||
}
|
||||
|
||||
/* Get the current time... */
|
||||
GET_TIME (&cur_time);
|
||||
|
||||
@@ -323,6 +331,36 @@ int main (argc, argv, envp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void new_relay_server (char *arg, struct server_list **servers)
|
||||
{
|
||||
struct hostent *he;
|
||||
struct in_addr ia, *iap = (struct in_addr *)0;
|
||||
struct server_list *sp;
|
||||
|
||||
if (inet_aton (arg, &ia)) {
|
||||
iap = &ia;
|
||||
} else {
|
||||
he = gethostbyname (arg);
|
||||
if (!he) {
|
||||
log_error ("%s: host unknown", arg);
|
||||
} else {
|
||||
iap = ((struct in_addr *)
|
||||
he -> h_addr_list [0]);
|
||||
}
|
||||
}
|
||||
if (iap) {
|
||||
sp = ((struct server_list *)
|
||||
dmalloc (sizeof *sp, MDL));
|
||||
if (!sp)
|
||||
log_fatal ("no memory for server.\n");
|
||||
memset(sp, 0, sizeof *sp);
|
||||
sp -> next = *servers;
|
||||
*servers = sp;
|
||||
memcpy (&sp -> to.sin_addr,
|
||||
iap, sizeof *iap);
|
||||
}
|
||||
}
|
||||
|
||||
void relay (ip, packet, length, from_port, from, hfrom)
|
||||
struct interface_info *ip;
|
||||
struct dhcp_packet *packet;
|
||||
@@ -335,6 +373,7 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
struct sockaddr_in to;
|
||||
struct interface_info *out;
|
||||
struct hardware hto, *htop;
|
||||
int i;
|
||||
|
||||
if (packet -> hlen > sizeof packet -> chaddr) {
|
||||
log_info ("Discarding packet with invalid hlen.");
|
||||
@@ -345,14 +384,16 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
in the packet. */
|
||||
if (packet -> giaddr.s_addr) {
|
||||
for (out = interfaces; out; out = out -> next) {
|
||||
if (!memcmp (&out -> primary_address,
|
||||
&packet -> giaddr,
|
||||
sizeof packet -> giaddr))
|
||||
break;
|
||||
for (i = 0; i < out -> address_count; i++) {
|
||||
if (out -> addresses [i].s_addr ==
|
||||
packet -> giaddr.s_addr)
|
||||
goto matched;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out = (struct interface_info *)0;
|
||||
}
|
||||
matched:
|
||||
|
||||
/* If it's a bootreply, forward it to the client. */
|
||||
if (packet -> op == BOOTREPLY) {
|
||||
@@ -388,15 +429,18 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
return;
|
||||
|
||||
if (!out) {
|
||||
log_error ("packet to bogus giaddr %s.\n",
|
||||
log_error ("packet to bogus giaddr %s.",
|
||||
inet_ntoa (packet -> giaddr));
|
||||
++bogus_giaddr_drops;
|
||||
return;
|
||||
}
|
||||
|
||||
if (out -> address_count < 1)
|
||||
log_fatal ("no IP address on interface %s!",
|
||||
out -> name);
|
||||
if (send_packet (out,
|
||||
(struct packet *)0,
|
||||
packet, length, out -> primary_address,
|
||||
packet, length, out -> addresses [0],
|
||||
&to, htop) < 0) {
|
||||
++server_packet_errors;
|
||||
} else {
|
||||
@@ -415,10 +459,13 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
if (out)
|
||||
return;
|
||||
|
||||
if (ip -> address_count < 1)
|
||||
log_fatal ("no IP address on interface %s", ip -> name);
|
||||
|
||||
/* Add relay agent options if indicated. If something goes wrong,
|
||||
drop the packet. */
|
||||
if (!(length = add_relay_agent_options (ip, packet, length,
|
||||
ip -> primary_address)))
|
||||
ip -> addresses [0])))
|
||||
return;
|
||||
|
||||
/* If giaddr is not already set, Set it so the server can
|
||||
@@ -427,7 +474,7 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
set, the response will be sent directly to the relay agent
|
||||
that set giaddr, so we won't see it. */
|
||||
if (!packet -> giaddr.s_addr)
|
||||
packet -> giaddr = ip -> primary_address;
|
||||
packet -> giaddr = ip -> addresses [0];
|
||||
if (packet -> hops < max_hop_count)
|
||||
packet -> hops = packet -> hops + 1;
|
||||
else
|
||||
@@ -435,11 +482,12 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
|
||||
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
|
||||
servers. */
|
||||
for (sp = servers; sp; sp = sp -> next) {
|
||||
for (sp = (ip -> servers
|
||||
? ip -> servers : servers); sp; sp = sp -> next) {
|
||||
if (send_packet ((fallback_interface
|
||||
? fallback_interface : interfaces),
|
||||
(struct packet *)0,
|
||||
packet, length, ip -> primary_address,
|
||||
packet, length, ip -> addresses [0],
|
||||
&sp -> to, (struct hardware *)0) < 0) {
|
||||
++client_packet_errors;
|
||||
} else {
|
||||
@@ -450,13 +498,12 @@ void relay (ip, packet, length, from_port, from, hfrom)
|
||||
++client_packets_relayed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void usage ()
|
||||
{
|
||||
log_fatal ("Usage: dhcrelay [-p <port>] [-d] [-D] [-i %s%s%s%s",
|
||||
"interface] [-q] [-a]\n ",
|
||||
"interface [-is server ... ]]\n ",
|
||||
"[-c count] [-A length] ",
|
||||
"[-m append|replace|forward|discard]\n",
|
||||
" [server1 [... serverN]]");
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: bootp.c,v 1.73 2005/07/07 16:39:07 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: bootp.c,v 1.74 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -271,11 +271,13 @@ void bootp (packet)
|
||||
memcpy (&raw.siaddr, d1.data, 4);
|
||||
data_string_forget (&d1, MDL);
|
||||
} else {
|
||||
if (lease -> subnet -> shared_network -> interface)
|
||||
if (lease -> subnet -> shared_network -> interface &&
|
||||
lease -> subnet ->
|
||||
shared_network -> interface -> address_count)
|
||||
raw.siaddr = (lease -> subnet -> shared_network ->
|
||||
interface -> primary_address);
|
||||
else
|
||||
raw.siaddr = packet -> interface -> primary_address;
|
||||
interface -> addresses [0]);
|
||||
else if (packet -> interface -> address_count)
|
||||
raw.siaddr = packet -> interface -> addresses [0];
|
||||
}
|
||||
|
||||
raw.giaddr = packet -> raw -> giaddr;
|
||||
@@ -325,7 +327,8 @@ void bootp (packet)
|
||||
hto.hlen = packet -> raw -> hlen + 1;
|
||||
memcpy (&hto.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
|
||||
|
||||
from = packet -> interface -> primary_address;
|
||||
if (packet -> interface -> address_count)
|
||||
from = packet -> interface -> addresses [0];
|
||||
|
||||
/* Report what we're doing... */
|
||||
log_info ("%s", msgbuf);
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: dhcp.c,v 1.200 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: dhcp.c,v 1.201 2006/02/27 23:56:13 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -1092,21 +1092,21 @@ void dhcpinform (packet, ms_nulltp)
|
||||
if (!(oc = lookup_option (&dhcp_universe, options, i))) {
|
||||
use_primary:
|
||||
oc = (struct option_cache *)0;
|
||||
if (packet -> interface -> address_count > 0) {
|
||||
if (option_cache_allocate (&oc, MDL)) {
|
||||
if (make_const_data
|
||||
(&oc -> expression,
|
||||
((unsigned char *)
|
||||
&packet -> interface -> primary_address),
|
||||
sizeof packet -> interface -> primary_address,
|
||||
&packet -> interface -> addresses [0]),
|
||||
sizeof packet -> interface -> addresses [0],
|
||||
0, 0, MDL)) {
|
||||
oc -> option =
|
||||
dhcp_universe.options [i];
|
||||
save_option (&dhcp_universe,
|
||||
options, oc);
|
||||
oc -> option = dhcp_universe.options [i];
|
||||
save_option (&dhcp_universe, options, oc);
|
||||
}
|
||||
option_cache_dereference (&oc, MDL);
|
||||
}
|
||||
from = packet -> interface -> primary_address;
|
||||
from = packet -> interface -> addresses [0];
|
||||
}
|
||||
} else {
|
||||
if (evaluate_option_cache (&d1, packet, (struct lease *)0,
|
||||
(struct client_state *)0,
|
||||
@@ -1358,15 +1358,16 @@ void nak_lease (packet, cip)
|
||||
option_cache_dereference (&oc, MDL);
|
||||
|
||||
i = DHO_DHCP_SERVER_IDENTIFIER;
|
||||
if (!(oc = lookup_option (&dhcp_universe, options, i))) {
|
||||
if (packet -> interface -> address_count > 0) {
|
||||
if (!(oc = lookup_option (&dhcp_universe, options, i))) {
|
||||
use_primary:
|
||||
oc = (struct option_cache *)0;
|
||||
if (option_cache_allocate (&oc, MDL)) {
|
||||
if (make_const_data
|
||||
(&oc -> expression,
|
||||
((unsigned char *)
|
||||
&packet -> interface -> primary_address),
|
||||
sizeof packet -> interface -> primary_address,
|
||||
&packet -> interface -> addresses [0]),
|
||||
sizeof packet -> interface -> addresses [0],
|
||||
0, 0, MDL)) {
|
||||
oc -> option =
|
||||
dhcp_universe.options [i];
|
||||
@@ -1374,9 +1375,10 @@ void nak_lease (packet, cip)
|
||||
}
|
||||
option_cache_dereference (&oc, MDL);
|
||||
}
|
||||
myfrom.len = sizeof packet -> interface -> primary_address;
|
||||
myfrom.len = sizeof packet -> interface -> addresses [0];
|
||||
memcpy (myfrom.iabuf,
|
||||
&packet -> interface -> primary_address, myfrom.len);
|
||||
&packet -> interface -> addresses [0], myfrom.len);
|
||||
}
|
||||
} else {
|
||||
memset (&data, 0, sizeof data);
|
||||
if (evaluate_option_cache (&data, packet, (struct lease *)0,
|
||||
@@ -1421,7 +1423,8 @@ void nak_lease (packet, cip)
|
||||
option_state_dereference (&options, MDL);
|
||||
|
||||
/* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
|
||||
raw.siaddr = packet -> interface -> primary_address;
|
||||
if (packet -> interface -> address_count)
|
||||
raw.siaddr = packet -> interface -> addresses [0];
|
||||
raw.giaddr = packet -> raw -> giaddr;
|
||||
memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
|
||||
raw.hlen = packet -> raw -> hlen;
|
||||
@@ -2401,13 +2404,14 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
if (!(oc = lookup_option (&dhcp_universe,
|
||||
state -> options, i))) {
|
||||
use_primary:
|
||||
if (state -> ip -> address_count > 0) {
|
||||
oc = (struct option_cache *)0;
|
||||
if (option_cache_allocate (&oc, MDL)) {
|
||||
if (make_const_data
|
||||
(&oc -> expression,
|
||||
((unsigned char *)
|
||||
&state -> ip -> primary_address),
|
||||
sizeof state -> ip -> primary_address,
|
||||
&state -> ip -> addresses [0]),
|
||||
sizeof state -> ip -> addresses [0],
|
||||
0, 0, MDL)) {
|
||||
oc -> option =
|
||||
dhcp_universe.options [i];
|
||||
@@ -2417,10 +2421,11 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
option_cache_dereference (&oc, MDL);
|
||||
}
|
||||
state -> from.len =
|
||||
sizeof state -> ip -> primary_address;
|
||||
sizeof state -> ip -> addresses [0];
|
||||
memcpy (state -> from.iabuf,
|
||||
&state -> ip -> primary_address,
|
||||
&state -> ip -> addresses [0],
|
||||
state -> from.len);
|
||||
}
|
||||
} else {
|
||||
if (evaluate_option_cache (&d1, packet, lease,
|
||||
(struct client_state *)0,
|
||||
@@ -2505,11 +2510,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
option_cache_dereference (&oc, MDL);
|
||||
}
|
||||
} else {
|
||||
state -> from.len =
|
||||
sizeof state -> ip -> primary_address;
|
||||
memcpy (state -> from.iabuf,
|
||||
&state -> ip -> primary_address,
|
||||
state -> from.len);
|
||||
if (state -> ip -> address_count) {
|
||||
state -> from.len =
|
||||
sizeof state -> ip -> addresses [0];
|
||||
memcpy (state -> from.iabuf,
|
||||
&state -> ip -> addresses [0],
|
||||
state -> from.len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Figure out the address of the boot file server. */
|
||||
|
Reference in New Issue
Block a user