2
0
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:
Evan Hunt 2008-07-16 16:18:22 +00:00
parent 4408ba6133
commit d352732ea7
2 changed files with 167 additions and 130 deletions

View File

@ -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 - Merge DHCPv6-only "dhcrelay6" into general-purpose "dhcrelay" (use
"-6" option to select DHCPv6 mode). "-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) Changes since 4.0.0 (new features)
- Added DHCPv6 rapid commit support. - Added DHCPv6 rapid commit support.

View File

@ -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 client_packet_errors = 0; /* Errors sending packets to clients. */
int add_agent_options = 0; /* If nonzero, add relay agent options. */ 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 int drop_agent_mismatches = 0; /* If nonzero, drop server replies that
don't have matching circuit-id's. */ don't have matching circuit-id's. */
int corrupt_agent_options = 0; /* Number of packets dropped because int corrupt_agent_options = 0; /* Number of packets dropped because
@ -80,7 +83,7 @@ isc_boolean_t use_if_id = ISC_FALSE;
#endif #endif
/* Maximum size of a packet with agent options added. */ /* 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 /* What to do about packets we're asked to relay that
already have a relay option: */ already have a relay option: */
@ -269,7 +272,13 @@ main(int argc, char **argv) {
#endif #endif
if (++i == argc) if (++i == argc)
usage(); usage();
dhcp_max_agent_option_packet_length = atoi(argv[i]); 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")) { } else if (!strcmp(argv[i], "-m")) {
#ifdef DHCPv6 #ifdef DHCPv6
if (local_family_set && (local_family == AF_INET6)) { if (local_family_set && (local_family == AF_INET6)) {
@ -873,7 +882,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
static int static int
add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
unsigned length, struct in_addr giaddr) { unsigned length, struct in_addr giaddr) {
int is_dhcp = 0; int is_dhcp = 0, mms;
unsigned optlen; unsigned optlen;
u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; 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)) if (memcmp(packet->options, DHCP_OPTIONS_COOKIE, 4))
return (length); return (length);
max = ((u_int8_t *)packet) + length; max = ((u_int8_t *)packet) + dhcp_max_agent_option_packet_length;
/* Commence processing after the cookie. */ /* Commence processing after the cookie. */
sp = op = &packet->options[4]; 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: case DHO_DHCP_MESSAGE_TYPE:
is_dhcp = 1; is_dhcp = 1;
goto skip; 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. */ /* Quit immediately if we hit an End option. */
case DHO_END: 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 " log_fatal("Total agent option length(%u) out of range "
"[3 - 255] on %s\n", optlen, ip->name); "[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)) * Is there room for the option, its code+len, and DHO_END?
return (0); * 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. */ /* Okay, cons up *our* Relay Agent Information option. */
*sp++ = DHO_DHCP_AGENT_OPTIONS; *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); memcpy(sp, ip->remote_id, ip->remote_id_len);
sp += 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; *sp++ = DHO_END;
/* Recalculate total packet length. */ /* Recalculate total packet length. */