mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-04 08:15:14 +00:00
Ignore messages generated by dhcp relay agents (including self); send replies to correct port; more debugging info
This commit is contained in:
45
dhcrelay.c
45
dhcrelay.c
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: dhcrelay.c,v 1.1 1997/02/22 09:47:09 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: dhcrelay.c,v 1.2 1997/02/22 12:28:26 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -117,28 +117,30 @@ int main (argc, argv, envp)
|
|||||||
usage ();
|
usage ();
|
||||||
} else {
|
} else {
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
|
he = gethostbyname (argv [i]);
|
||||||
|
if (!he) {
|
||||||
|
herror (argv [i]);
|
||||||
|
} else {
|
||||||
sp = (struct server_list *)malloc (sizeof *sp);
|
sp = (struct server_list *)malloc (sizeof *sp);
|
||||||
if (!sp)
|
if (!sp)
|
||||||
error ("no memory for server.\n");
|
error ("no memory for server.\n");
|
||||||
sp -> next = servers;
|
sp -> next = servers;
|
||||||
he = gethostbyname (argv [i]);
|
servers = sp;
|
||||||
if (!he) {
|
|
||||||
herror (argv [i]);
|
|
||||||
}
|
|
||||||
memcpy (&sp -> to.sin_addr,
|
memcpy (&sp -> to.sin_addr,
|
||||||
he -> h_addr_list [0], he -> h_length);
|
he -> h_addr_list [0], he -> h_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Default to the DHCP/BOOTP port. */
|
/* Default to the DHCP/BOOTP port. */
|
||||||
if (!local_port) {
|
if (!local_port) {
|
||||||
ent = getservbyname ("dhcpc", "udp");
|
ent = getservbyname ("dhcps", "udp");
|
||||||
if (!ent)
|
if (!ent)
|
||||||
local_port = htons (68);
|
local_port = htons (67);
|
||||||
else
|
else
|
||||||
local_port = ent -> s_port;
|
local_port = ent -> s_port;
|
||||||
endservent ();
|
endservent ();
|
||||||
}
|
}
|
||||||
remote_port = local_port;
|
remote_port = htons (ntohs (local_port) + 1);
|
||||||
|
|
||||||
/* We need at least one server. */
|
/* We need at least one server. */
|
||||||
if (!sp) {
|
if (!sp) {
|
||||||
@@ -158,7 +160,7 @@ int main (argc, argv, envp)
|
|||||||
GET_TIME (&cur_time);
|
GET_TIME (&cur_time);
|
||||||
|
|
||||||
/* Discover all the network interfaces. */
|
/* Discover all the network interfaces. */
|
||||||
discover_interfaces (DISCOVER_SERVER);
|
discover_interfaces (DISCOVER_RELAY);
|
||||||
|
|
||||||
/* Start dispatching packets and timeouts... */
|
/* Start dispatching packets and timeouts... */
|
||||||
dispatch (0);
|
dispatch (0);
|
||||||
@@ -176,19 +178,17 @@ void relay (ip, packet, length)
|
|||||||
struct interface_info *out;
|
struct interface_info *out;
|
||||||
struct hardware hto;
|
struct hardware hto;
|
||||||
|
|
||||||
packet -> giaddr = ip -> primary_address;
|
|
||||||
|
|
||||||
/* If it's a bootreply, forward it to the client. */
|
/* If it's a bootreply, forward it to the client. */
|
||||||
if (packet -> op == BOOTREPLY) {
|
if (packet -> op == BOOTREPLY) {
|
||||||
#ifndef USE_FALLBACK
|
#ifndef USE_FALLBACK
|
||||||
if (!packet -> flags & htons (BOOTP_BROADCAST)) {
|
if (!packet -> flags & htons (BOOTP_BROADCAST)) {
|
||||||
to.sin_addr = packet -> raw -> ciaddr;
|
to.sin_addr = packet -> raw -> ciaddr;
|
||||||
to.sin_port = remote_port; /* XXX */
|
to.sin_port = remote_port;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
|
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
|
||||||
to.sin_port = remote_port; /* XXX */
|
to.sin_port = remote_port;
|
||||||
}
|
}
|
||||||
to.sin_family = AF_INET;
|
to.sin_family = AF_INET;
|
||||||
#ifdef HAVE_SA_LEN
|
#ifdef HAVE_SA_LEN
|
||||||
@@ -220,9 +220,28 @@ void relay (ip, packet, length)
|
|||||||
packet, length, out -> primary_address,
|
packet, length, out -> primary_address,
|
||||||
&to, &hto) < 0)
|
&to, &hto) < 0)
|
||||||
debug ("sendpkt: %m");
|
debug ("sendpkt: %m");
|
||||||
|
else
|
||||||
|
debug ("forwarded BOOTREPLY for %s to %s",
|
||||||
|
print_hw_addr (packet -> htype, packet -> hlen,
|
||||||
|
packet -> chaddr),
|
||||||
|
inet_ntoa (to.sin_addr));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If giaddr is set on a BOOTREQUEST, ignore it - it's already
|
||||||
|
been gatewayed. */
|
||||||
|
if (packet -> giaddr.s_addr) {
|
||||||
|
note ("ignoring BOOTREQUEST with giaddr of %s\n",
|
||||||
|
inet_ntoa (packet -> giaddr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the giaddr so the server can figure out what net it's
|
||||||
|
from and so that we can later forward the response to the
|
||||||
|
correct net. */
|
||||||
|
packet -> giaddr = ip -> primary_address;
|
||||||
|
|
||||||
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
|
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
|
||||||
servers. */
|
servers. */
|
||||||
for (sp = servers; sp; sp = sp -> next) {
|
for (sp = servers; sp; sp = sp -> next) {
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: dhcrelay.c,v 1.1 1997/02/22 09:47:09 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: dhcrelay.c,v 1.2 1997/02/22 12:28:26 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -117,28 +117,30 @@ int main (argc, argv, envp)
|
|||||||
usage ();
|
usage ();
|
||||||
} else {
|
} else {
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
|
he = gethostbyname (argv [i]);
|
||||||
|
if (!he) {
|
||||||
|
herror (argv [i]);
|
||||||
|
} else {
|
||||||
sp = (struct server_list *)malloc (sizeof *sp);
|
sp = (struct server_list *)malloc (sizeof *sp);
|
||||||
if (!sp)
|
if (!sp)
|
||||||
error ("no memory for server.\n");
|
error ("no memory for server.\n");
|
||||||
sp -> next = servers;
|
sp -> next = servers;
|
||||||
he = gethostbyname (argv [i]);
|
servers = sp;
|
||||||
if (!he) {
|
|
||||||
herror (argv [i]);
|
|
||||||
}
|
|
||||||
memcpy (&sp -> to.sin_addr,
|
memcpy (&sp -> to.sin_addr,
|
||||||
he -> h_addr_list [0], he -> h_length);
|
he -> h_addr_list [0], he -> h_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Default to the DHCP/BOOTP port. */
|
/* Default to the DHCP/BOOTP port. */
|
||||||
if (!local_port) {
|
if (!local_port) {
|
||||||
ent = getservbyname ("dhcpc", "udp");
|
ent = getservbyname ("dhcps", "udp");
|
||||||
if (!ent)
|
if (!ent)
|
||||||
local_port = htons (68);
|
local_port = htons (67);
|
||||||
else
|
else
|
||||||
local_port = ent -> s_port;
|
local_port = ent -> s_port;
|
||||||
endservent ();
|
endservent ();
|
||||||
}
|
}
|
||||||
remote_port = local_port;
|
remote_port = htons (ntohs (local_port) + 1);
|
||||||
|
|
||||||
/* We need at least one server. */
|
/* We need at least one server. */
|
||||||
if (!sp) {
|
if (!sp) {
|
||||||
@@ -158,7 +160,7 @@ int main (argc, argv, envp)
|
|||||||
GET_TIME (&cur_time);
|
GET_TIME (&cur_time);
|
||||||
|
|
||||||
/* Discover all the network interfaces. */
|
/* Discover all the network interfaces. */
|
||||||
discover_interfaces (DISCOVER_SERVER);
|
discover_interfaces (DISCOVER_RELAY);
|
||||||
|
|
||||||
/* Start dispatching packets and timeouts... */
|
/* Start dispatching packets and timeouts... */
|
||||||
dispatch (0);
|
dispatch (0);
|
||||||
@@ -176,19 +178,17 @@ void relay (ip, packet, length)
|
|||||||
struct interface_info *out;
|
struct interface_info *out;
|
||||||
struct hardware hto;
|
struct hardware hto;
|
||||||
|
|
||||||
packet -> giaddr = ip -> primary_address;
|
|
||||||
|
|
||||||
/* If it's a bootreply, forward it to the client. */
|
/* If it's a bootreply, forward it to the client. */
|
||||||
if (packet -> op == BOOTREPLY) {
|
if (packet -> op == BOOTREPLY) {
|
||||||
#ifndef USE_FALLBACK
|
#ifndef USE_FALLBACK
|
||||||
if (!packet -> flags & htons (BOOTP_BROADCAST)) {
|
if (!packet -> flags & htons (BOOTP_BROADCAST)) {
|
||||||
to.sin_addr = packet -> raw -> ciaddr;
|
to.sin_addr = packet -> raw -> ciaddr;
|
||||||
to.sin_port = remote_port; /* XXX */
|
to.sin_port = remote_port;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
|
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
|
||||||
to.sin_port = remote_port; /* XXX */
|
to.sin_port = remote_port;
|
||||||
}
|
}
|
||||||
to.sin_family = AF_INET;
|
to.sin_family = AF_INET;
|
||||||
#ifdef HAVE_SA_LEN
|
#ifdef HAVE_SA_LEN
|
||||||
@@ -220,9 +220,28 @@ void relay (ip, packet, length)
|
|||||||
packet, length, out -> primary_address,
|
packet, length, out -> primary_address,
|
||||||
&to, &hto) < 0)
|
&to, &hto) < 0)
|
||||||
debug ("sendpkt: %m");
|
debug ("sendpkt: %m");
|
||||||
|
else
|
||||||
|
debug ("forwarded BOOTREPLY for %s to %s",
|
||||||
|
print_hw_addr (packet -> htype, packet -> hlen,
|
||||||
|
packet -> chaddr),
|
||||||
|
inet_ntoa (to.sin_addr));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If giaddr is set on a BOOTREQUEST, ignore it - it's already
|
||||||
|
been gatewayed. */
|
||||||
|
if (packet -> giaddr.s_addr) {
|
||||||
|
note ("ignoring BOOTREQUEST with giaddr of %s\n",
|
||||||
|
inet_ntoa (packet -> giaddr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the giaddr so the server can figure out what net it's
|
||||||
|
from and so that we can later forward the response to the
|
||||||
|
correct net. */
|
||||||
|
packet -> giaddr = ip -> primary_address;
|
||||||
|
|
||||||
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
|
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
|
||||||
servers. */
|
servers. */
|
||||||
for (sp = servers; sp; sp = sp -> next) {
|
for (sp = servers; sp; sp = sp -> next) {
|
||||||
|
Reference in New Issue
Block a user