mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-28 12:57:42 +00:00
Fix handling of -A and -a flags in dhcrelay; it was failing to expand
packet size as needed to add relay agent options. [rt18296]
This commit is contained in:
parent
4408ba6133
commit
d352732ea7
3
RELNOTES
3
RELNOTES
@ -96,6 +96,9 @@ work on other platforms. Please report any problems and suggested fixes to
|
||||
- Merge DHCPv6-only "dhcrelay6" into general-purpose "dhcrelay" (use
|
||||
"-6" option to select DHCPv6 mode).
|
||||
|
||||
- Fix handling of -A and -a flags in dhcrelay; it was failing to expand
|
||||
packet size as needed to add relay agent options.
|
||||
|
||||
Changes since 4.0.0 (new features)
|
||||
|
||||
- Added DHCPv6 rapid commit support.
|
||||
|
@ -62,6 +62,9 @@ int server_packets_relayed = 0; /* Packets relayed from server to client. */
|
||||
int client_packet_errors = 0; /* Errors sending packets to clients. */
|
||||
|
||||
int add_agent_options = 0; /* If nonzero, add relay agent options. */
|
||||
|
||||
int agent_option_errors = 0; /* Number of packets forwarded without
|
||||
agent options because there was no room. */
|
||||
int drop_agent_mismatches = 0; /* If nonzero, drop server replies that
|
||||
don't have matching circuit-id's. */
|
||||
int corrupt_agent_options = 0; /* Number of packets dropped because
|
||||
@ -80,7 +83,7 @@ isc_boolean_t use_if_id = ISC_FALSE;
|
||||
#endif
|
||||
|
||||
/* Maximum size of a packet with agent options added. */
|
||||
int dhcp_max_agent_option_packet_length = 576;
|
||||
int dhcp_max_agent_option_packet_length = DHCP_MTU_MIN;
|
||||
|
||||
/* What to do about packets we're asked to relay that
|
||||
already have a relay option: */
|
||||
@ -269,7 +272,13 @@ main(int argc, char **argv) {
|
||||
#endif
|
||||
if (++i == argc)
|
||||
usage();
|
||||
|
||||
dhcp_max_agent_option_packet_length = atoi(argv[i]);
|
||||
|
||||
if (dhcp_max_agent_option_packet_length > DHCP_MTU_MAX)
|
||||
log_fatal("%s: packet length exceeds "
|
||||
"longest possible MTU\n",
|
||||
argv[i]);
|
||||
} else if (!strcmp(argv[i], "-m")) {
|
||||
#ifdef DHCPv6
|
||||
if (local_family_set && (local_family == AF_INET6)) {
|
||||
@ -873,7 +882,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
static int
|
||||
add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
unsigned length, struct in_addr giaddr) {
|
||||
int is_dhcp = 0;
|
||||
int is_dhcp = 0, mms;
|
||||
unsigned optlen;
|
||||
u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL;
|
||||
|
||||
@ -887,7 +896,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
if (memcmp(packet->options, DHCP_OPTIONS_COOKIE, 4))
|
||||
return (length);
|
||||
|
||||
max = ((u_int8_t *)packet) + length;
|
||||
max = ((u_int8_t *)packet) + dhcp_max_agent_option_packet_length;
|
||||
|
||||
/* Commence processing after the cookie. */
|
||||
sp = op = &packet->options[4];
|
||||
@ -919,7 +928,17 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
case DHO_DHCP_MESSAGE_TYPE:
|
||||
is_dhcp = 1;
|
||||
goto skip;
|
||||
break;
|
||||
|
||||
/*
|
||||
* If there's a maximum message size option, we
|
||||
* should pay attention to it
|
||||
*/
|
||||
case DHO_DHCP_MAX_MESSAGE_SIZE:
|
||||
mms = ntohs(*(op + 2));
|
||||
if (mms < dhcp_max_agent_option_packet_length &&
|
||||
mms >= DHCP_MTU_MIN)
|
||||
max = ((u_int8_t *)packet) + mms;
|
||||
goto skip;
|
||||
|
||||
/* Quit immediately if we hit an End option. */
|
||||
case DHO_END:
|
||||
@ -1013,9 +1032,12 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
log_fatal("Total agent option length(%u) out of range "
|
||||
"[3 - 255] on %s\n", optlen, ip->name);
|
||||
|
||||
/* Is there room for the option, its code+len, and DHO_END? */
|
||||
if ((sp > max) ||(max - sp < optlen + 3))
|
||||
return (0);
|
||||
/*
|
||||
* Is there room for the option, its code+len, and DHO_END?
|
||||
* If not, forward without adding the option.
|
||||
*/
|
||||
if (max - sp >= optlen + 3) {
|
||||
log_debug("Adding %d-byte relay agent option", optlen + 3);
|
||||
|
||||
/* Okay, cons up *our* Relay Agent Information option. */
|
||||
*sp++ = DHO_DHCP_AGENT_OPTIONS;
|
||||
@ -1034,8 +1056,20 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
memcpy(sp, ip->remote_id, ip->remote_id_len);
|
||||
sp += ip->remote_id_len;
|
||||
}
|
||||
} else {
|
||||
++agent_option_errors;
|
||||
log_error("No room in packet (used %d of %d) "
|
||||
"for %d-byte relay agent option: omitted",
|
||||
(int) (sp - ((u_int8_t *) packet)),
|
||||
(int) (max - ((u_int8_t *) packet)),
|
||||
optlen + 3);
|
||||
}
|
||||
|
||||
/* Deposit an END option. */
|
||||
/*
|
||||
* Deposit an END option unless the packet is full (shouldn't
|
||||
* be possible).
|
||||
*/
|
||||
if (sp < max)
|
||||
*sp++ = DHO_END;
|
||||
|
||||
/* Recalculate total packet length. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user