[dhcp_relay] Base DHCP Relay Docker container on Debian Stretch (#2832)
* Base DHCP relay Docker image on Strech base Docker * Change URL for isc-dhcp source repository * Upgrade isc-dhcp source branch to 4.3.5-3.1 * Update patch #0001 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0002 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0003 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0004 to apply to isc-dhcp 4.3.5-3.1 * Remove security patches, as they are now applied as part of 4.3.5-3.1 source * Reorder patches to apply bug fix first, then features * Extend makefile to build debug Docker image * Update commit that series file applies against
This commit is contained in:
parent
ad2c1b26dd
commit
b186bb2c4c
@ -1,4 +1,4 @@
|
||||
FROM docker-config-engine
|
||||
FROM docker-config-engine-stretch
|
||||
|
||||
ARG docker_container_name
|
||||
RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf
|
||||
|
@ -1,12 +1,24 @@
|
||||
# Docker image for DHCP relay
|
||||
|
||||
DOCKER_DHCP_RELAY = docker-dhcp-relay.gz
|
||||
$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/docker-dhcp-relay
|
||||
DOCKER_DHCP_RELAY_STEM = docker-dhcp-relay
|
||||
DOCKER_DHCP_RELAY = $(DOCKER_DHCP_RELAY_STEM).gz
|
||||
DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz
|
||||
|
||||
$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM)
|
||||
|
||||
$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY)
|
||||
$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE)
|
||||
$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS)
|
||||
$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES)
|
||||
|
||||
$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH)
|
||||
|
||||
SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
|
||||
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
|
||||
SONIC_STRETCH_DOCKERS += $(DOCKER_DHCP_RELAY)
|
||||
|
||||
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
|
||||
SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
|
||||
SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG)
|
||||
|
||||
$(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay
|
||||
$(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t
|
||||
|
@ -1,6 +1,6 @@
|
||||
# isc-dhcp packages
|
||||
|
||||
ISC_DHCP_VERSION = 4.3.3-6
|
||||
ISC_DHCP_VERSION = 4.3.5-3.1
|
||||
|
||||
export ISC_DHCP_VERSION
|
||||
|
||||
@ -10,3 +10,5 @@ SONIC_MAKE_DEBS += $(ISC_DHCP_COMMON)
|
||||
|
||||
ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb
|
||||
$(eval $(call add_derived_package,$(ISC_DHCP_COMMON),$(ISC_DHCP_RELAY)))
|
||||
|
||||
SONIC_STRETCH_DEBS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY)
|
||||
|
@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
rm -rf ./isc-dhcp
|
||||
|
||||
# Clone isc-dhcp repo
|
||||
git clone https://salsa.debian.org/berni/isc-dhcp.git
|
||||
git clone https://salsa.debian.org/dhcp-team/isc-dhcp.git
|
||||
pushd ./isc-dhcp
|
||||
|
||||
# Reset HEAD to the commit of the proper tag
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 2bb21fcf4a9ad7535867809c50d2cf0ba1088e17 Mon Sep 17 00:00:00 2001
|
||||
From 7c1cfd636be589317710a8556a7ec667debee53a Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Fri, 9 Mar 2018 01:43:35 +0000
|
||||
Date: Fri, 26 Apr 2019 01:37:54 +0000
|
||||
Subject: [PATCH] [Bugfix] Don't print log messages to stderr in release builds
|
||||
|
||||
---
|
||||
@ -24,5 +24,5 @@ index 7c91d9d..aa74fd8 100644
|
||||
void (*log_cleanup) (void);
|
||||
|
||||
--
|
||||
2.1.4
|
||||
2.17.1
|
||||
|
@ -1,273 +0,0 @@
|
||||
From 284c87ff4b3873d0215904273fe3c86b07b4ba94 Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Mon, 11 Dec 2017 23:21:08 +0000
|
||||
Subject: [PATCH 1/3] Customizable Option 82 circuit ID and remote ID fields
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 152 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 15b4997..b9f8326 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -73,6 +73,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option
|
||||
did not match any known circuit ID. */
|
||||
int missing_circuit_id = 0; /* Circuit ID option in matching RAI option
|
||||
was missing. */
|
||||
+const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */
|
||||
+const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */
|
||||
int max_hop_count = 10; /* Maximum hop count */
|
||||
|
||||
#ifdef DHCPv6
|
||||
@@ -140,9 +142,19 @@ static const char message[] =
|
||||
static const char url[] =
|
||||
"For info, please visit https://www.isc.org/software/dhcp/";
|
||||
|
||||
+#define DHCRELAY_OPTION82_USAGE \
|
||||
+"circuit_id/remote_id interpreted sequences are:\n" \
|
||||
+"\n" \
|
||||
+" %%%% A single %%\n" \
|
||||
+" %%h Hostname of device\n" \
|
||||
+" %%p Name of interface that generated the request\n" \
|
||||
+" %%P Hardware address of interface that generated the request\n" \
|
||||
+" %%C Client hardware address\n" \
|
||||
+" %%I DHCP relay agent IP Address\n" \
|
||||
+
|
||||
#ifdef DHCPv6
|
||||
#define DHCRELAY_USAGE \
|
||||
-"Usage: dhcrelay [-4] [-d] [-q] [-a] [-D]\n"\
|
||||
+"Usage: dhcrelay [-4] [-d] [-q] [-a <circuit_id> <remote_id>] [-D]\n"\
|
||||
" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n"\
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
@@ -154,14 +166,15 @@ static const char url[] =
|
||||
" -l lower0 [ ... -l lowerN]\n" \
|
||||
" -u upper0 [ ... -u upperN]\n" \
|
||||
" lower (client link): [address%%]interface[#index]\n" \
|
||||
-" upper (server link): [address%%]interface"
|
||||
+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE
|
||||
#else
|
||||
#define DHCRELAY_USAGE \
|
||||
-"Usage: dhcrelay [-d] [-q] [-a] [-D] [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
-" [-pf <pid-file>] [--no-pid]\n" \
|
||||
+"Usage: dhcrelay [-d] [-q] [-a <circuit_id> <remote_id>] [-D]\n" \
|
||||
+" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
+" [-pf <pid-file>] [--no-pid]\n"\
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||
-" server0 [ ... serverN]\n\n"
|
||||
+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE
|
||||
#endif
|
||||
|
||||
static void usage() {
|
||||
@@ -287,6 +300,15 @@ main(int argc, char **argv) {
|
||||
local_family_set = 1;
|
||||
local_family = AF_INET;
|
||||
#endif
|
||||
+ if (++i == argc)
|
||||
+ usage();
|
||||
+
|
||||
+ if (argv[i] != NULL && argv[i][0] != '-')
|
||||
+ agent_circuit_id_fmt = argv[i++];
|
||||
+
|
||||
+ if (argv[i] != NULL && argv[i][0] != '-')
|
||||
+ agent_remote_id_fmt = argv[i];
|
||||
+
|
||||
add_agent_options = 1;
|
||||
} else if (!strcmp(argv[i], "-A")) {
|
||||
#ifdef DHCPv6
|
||||
@@ -938,6 +960,80 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Format the message that will be used by circuit_id and remote_id
|
||||
+ */
|
||||
+static int
|
||||
+format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet,
|
||||
+ const char *format, char *msg, size_t msgn) {
|
||||
+ size_t len = 0;
|
||||
+ char hostname[HOST_NAME_MAX] = { 0 };
|
||||
+ char ifname[IFNAMSIZ] = { 0 };
|
||||
+ char *buf = msg;
|
||||
+
|
||||
+ for ( ; format && *format && len < msgn; ++format) {
|
||||
+ size_t strn = 0;
|
||||
+ const char *str = NULL;
|
||||
+
|
||||
+ if (*format == '%') {
|
||||
+ switch (*++format) {
|
||||
+ case '\0':
|
||||
+ --format;
|
||||
+ break;
|
||||
+
|
||||
+ case '%': /* A literal '%' */
|
||||
+ str = "%";
|
||||
+ break;
|
||||
+
|
||||
+ case 'h': /* Hostname */
|
||||
+ gethostname(hostname, HOST_NAME_MAX);
|
||||
+ hostname[HOST_NAME_MAX - 1] = '\0';
|
||||
+ str = hostname;
|
||||
+ break;
|
||||
+
|
||||
+ case 'p': /* Name of interface that we received the request from */
|
||||
+ strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
+ str = ifname;
|
||||
+ break;
|
||||
+
|
||||
+ case 'P': /* Physical address of interface that we received the request from */
|
||||
+ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]);
|
||||
+ break;
|
||||
+
|
||||
+ case 'C': /* 24: Client hardware address */
|
||||
+ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr);
|
||||
+ break;
|
||||
+
|
||||
+ case 'I': /* 20: DHCP relay agent IP address */
|
||||
+ str = inet_ntoa(packet->giaddr);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ log_error("Option %%%c is unrecognized and will not be formatted!", *format);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (str)
|
||||
+ strn = strlen(str);
|
||||
+ } else {
|
||||
+ str = format;
|
||||
+ strn = 1;
|
||||
+ }
|
||||
+
|
||||
+ // Do we have room?
|
||||
+ if ((strn+len) >= msgn) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (str && strn > 0) {
|
||||
+ memcpy(buf+len, str, strn);
|
||||
+ len += strn;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Examine a packet to see if it's a candidate to have a Relay
|
||||
* Agent Information option tacked onto its tail. If it is, tack
|
||||
* the option on.
|
||||
@@ -946,8 +1042,11 @@ static int
|
||||
add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
unsigned length, struct in_addr giaddr) {
|
||||
int is_dhcp = 0, mms;
|
||||
- unsigned optlen;
|
||||
+ unsigned optlen = 0;
|
||||
u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL;
|
||||
+ char circuit_id_buf[256] = { '\0' };
|
||||
+ char remote_id_buf[256] = { '\0' };
|
||||
+ size_t circuit_id_len = 0, remote_id_len = 0;
|
||||
|
||||
/* If we're not adding agent options to packets, we can skip
|
||||
this. */
|
||||
@@ -1077,24 +1176,47 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
op = sp;
|
||||
#endif
|
||||
|
||||
- /* Sanity check. Had better not ever happen. */
|
||||
- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1))
|
||||
- log_fatal("Circuit ID length %d out of range [1-255] on "
|
||||
- "%s\n", ip->circuit_id_len, ip->name);
|
||||
- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */
|
||||
-
|
||||
- if (ip->remote_id) {
|
||||
- if (ip->remote_id_len > 255 || ip->remote_id_len < 1)
|
||||
- log_fatal("Remote ID length %d out of range [1-255] "
|
||||
- "on %s\n", ip->circuit_id_len, ip->name);
|
||||
- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */
|
||||
- }
|
||||
+ /* option82: custom string for circuit_id */
|
||||
+ if (agent_circuit_id_fmt) {
|
||||
+ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt,
|
||||
+ circuit_id_buf, sizeof(circuit_id_buf));
|
||||
+
|
||||
+ if (circuit_id_len == 0) {
|
||||
+ strncpy(circuit_id_buf, ip->name, sizeof(ip->name));
|
||||
+ circuit_id_len = strlen(circuit_id_buf);
|
||||
+ }
|
||||
+
|
||||
+ /* Sanity check. Had better not ever happen. */
|
||||
+ if (circuit_id_len > 255 || circuit_id_len < 1)
|
||||
+ log_fatal("Circuit ID length %d out of range [1-255] on %s\n",
|
||||
+ (int)circuit_id_len, ip->name);
|
||||
+
|
||||
+ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len
|
||||
+
|
||||
+ //log_debug("Sending on %s option82:circuit_id='%s' (%d)",
|
||||
+ // ip->name, circuit_id_buf, (int)circuit_id_len);
|
||||
+ }
|
||||
+
|
||||
+ /* option82: custom string for remote_id */
|
||||
+ if (agent_remote_id_fmt) {
|
||||
+ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt,
|
||||
+ remote_id_buf, sizeof(remote_id_buf));
|
||||
+
|
||||
+ if (remote_id_len > 255 || remote_id_len < 1)
|
||||
+ log_fatal("Remote ID length %d out of range [1-255] on %s\n",
|
||||
+ (int)remote_id_len, ip->name);
|
||||
+
|
||||
+ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len
|
||||
+
|
||||
+ //log_debug("Sending on %s option82:remote_id='%s' (%d)",
|
||||
+ // ip->name, remote_id_buf, (int)remote_id_len);
|
||||
+ }
|
||||
|
||||
- /* We do not support relay option fragmenting(multiple options to
|
||||
- * support an option data exceeding 255 bytes).
|
||||
+ /* We do not support relay option fragmenting (multiple options to
|
||||
+ * support an option data exceeding 255 bytes)
|
||||
*/
|
||||
- if ((optlen < 3) ||(optlen > 255))
|
||||
- log_fatal("Total agent option length(%u) out of range "
|
||||
+ if (optlen < 3 || optlen > 255)
|
||||
+ log_fatal("Total agent option length (%u) out of range "
|
||||
"[3 - 255] on %s\n", optlen, ip->name);
|
||||
|
||||
/*
|
||||
@@ -1102,7 +1224,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
* If not, forward without adding the option.
|
||||
*/
|
||||
if (max - sp >= optlen + 3) {
|
||||
- log_debug("Adding %d-byte relay agent option", 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;
|
||||
@@ -1110,16 +1232,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
|
||||
/* Copy in the circuit id... */
|
||||
*sp++ = RAI_CIRCUIT_ID;
|
||||
- *sp++ = ip->circuit_id_len;
|
||||
- memcpy(sp, ip->circuit_id, ip->circuit_id_len);
|
||||
- sp += ip->circuit_id_len;
|
||||
+ *sp++ = circuit_id_len;
|
||||
+ memcpy(sp, circuit_id_buf, circuit_id_len);
|
||||
+ sp += circuit_id_len;
|
||||
|
||||
/* Copy in remote ID... */
|
||||
- if (ip->remote_id) {
|
||||
+ if (remote_id_len > 0) {
|
||||
*sp++ = RAI_REMOTE_ID;
|
||||
- *sp++ = ip->remote_id_len;
|
||||
- memcpy(sp, ip->remote_id, ip->remote_id_len);
|
||||
- sp += ip->remote_id_len;
|
||||
+ *sp++ = remote_id_len;
|
||||
+ memcpy(sp, remote_id_buf, remote_id_len);
|
||||
+ sp += remote_id_len;
|
||||
}
|
||||
} else {
|
||||
++agent_option_errors;
|
||||
--
|
||||
2.1.4
|
||||
|
@ -0,0 +1,265 @@
|
||||
From 6b4c2e815118fb7312b8e8a07ac61a772b57e91a Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Thu, 25 Apr 2019 22:07:20 +0000
|
||||
Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 171 ++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 147 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 344cee7..7b4c1ef 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option
|
||||
did not match any known circuit ID. */
|
||||
int missing_circuit_id = 0; /* Circuit ID option in matching RAI option
|
||||
was missing. */
|
||||
+const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */
|
||||
+const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */
|
||||
int max_hop_count = 10; /* Maximum hop count */
|
||||
|
||||
#ifdef DHCPv6
|
||||
@@ -148,9 +150,19 @@ static const char url[] =
|
||||
|
||||
char *progname;
|
||||
|
||||
+#define DHCRELAY_OPTION82_USAGE \
|
||||
+"circuit_id/remote_id interpreted sequences are:\n" \
|
||||
+"\n" \
|
||||
+" %%%% A single %%\n" \
|
||||
+" %%h Hostname of device\n" \
|
||||
+" %%p Name of interface that generated the request\n" \
|
||||
+" %%P Hardware address of interface that generated the request\n" \
|
||||
+" %%C Client hardware address\n" \
|
||||
+" %%I DHCP relay agent IP Address\n" \
|
||||
+
|
||||
#ifdef DHCPv6
|
||||
#define DHCRELAY_USAGE \
|
||||
-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n"\
|
||||
+"Usage: %s [-4] [-d] [-q] [-a <circuit_id> <remote_id>] [-D]\n"\
|
||||
" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n"\
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
@@ -165,17 +177,18 @@ char *progname;
|
||||
" -l lower0 [ ... -l lowerN]\n" \
|
||||
" -u upper0 [ ... -u upperN]\n" \
|
||||
" lower (client link): [address%%]interface[#index]\n" \
|
||||
-" upper (server link): [address%%]interface"
|
||||
+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE
|
||||
#else
|
||||
#define DHCRELAY_USAGE \
|
||||
-"Usage: %s [-d] [-q] [-a] [-D] [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
+"Usage: %s [-d] [-q] [-a <circuit_id> <remote_id>] [-D]\n" \
|
||||
+" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n" \
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
" [-U interface]\n" \
|
||||
-" server0 [ ... serverN]\n\n"
|
||||
+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@@ -354,6 +367,15 @@ main(int argc, char **argv) {
|
||||
local_family_set = 1;
|
||||
local_family = AF_INET;
|
||||
#endif
|
||||
+ if (++i == argc)
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+
|
||||
+ if (argv[i] != NULL && argv[i][0] != '-')
|
||||
+ agent_circuit_id_fmt = argv[i++];
|
||||
+
|
||||
+ if (argv[i] != NULL && argv[i][0] != '-')
|
||||
+ agent_remote_id_fmt = argv[i];
|
||||
+
|
||||
add_agent_options = 1;
|
||||
} else if (!strcmp(argv[i], "-A")) {
|
||||
#ifdef DHCPv6
|
||||
@@ -1050,6 +1072,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Format the message that will be used by circuit_id and remote_id
|
||||
+ */
|
||||
+static int
|
||||
+format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet,
|
||||
+ const char *format, char *msg, size_t msgn) {
|
||||
+ size_t len = 0;
|
||||
+ char hostname[HOST_NAME_MAX] = { 0 };
|
||||
+ char ifname[IFNAMSIZ] = { 0 };
|
||||
+ char *buf = msg;
|
||||
+
|
||||
+ for ( ; format && *format && len < msgn; ++format) {
|
||||
+ size_t strn = 0;
|
||||
+ const char *str = NULL;
|
||||
+
|
||||
+ if (*format == '%') {
|
||||
+ switch (*++format) {
|
||||
+ case '\0':
|
||||
+ --format;
|
||||
+ break;
|
||||
+
|
||||
+ case '%': /* A literal '%' */
|
||||
+ str = "%";
|
||||
+ break;
|
||||
+
|
||||
+ case 'h': /* Hostname */
|
||||
+ gethostname(hostname, HOST_NAME_MAX);
|
||||
+ hostname[HOST_NAME_MAX - 1] = '\0';
|
||||
+ str = hostname;
|
||||
+ break;
|
||||
+
|
||||
+ case 'p': /* Name of interface that we received the request from */
|
||||
+ strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
+ str = ifname;
|
||||
+ break;
|
||||
+
|
||||
+ case 'P': /* Physical address of interface that we received the request from */
|
||||
+ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]);
|
||||
+ break;
|
||||
+
|
||||
+ case 'C': /* 24: Client hardware address */
|
||||
+ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr);
|
||||
+ break;
|
||||
+
|
||||
+ case 'I': /* 20: DHCP relay agent IP address */
|
||||
+ str = inet_ntoa(packet->giaddr);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ log_error("Option %%%c is unrecognized and will not be formatted!", *format);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (str) {
|
||||
+ strn = strlen(str);
|
||||
+ }
|
||||
+ } else {
|
||||
+ str = format;
|
||||
+ strn = 1;
|
||||
+ }
|
||||
+
|
||||
+ // Do we have room?
|
||||
+ if ((strn+len) >= msgn) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (str && strn > 0) {
|
||||
+ memcpy(buf+len, str, strn);
|
||||
+ len += strn;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Examine a packet to see if it's a candidate to have a Relay
|
||||
* Agent Information option tacked onto its tail. If it is, tack
|
||||
@@ -1059,9 +1156,12 @@ static int
|
||||
add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
unsigned length, struct in_addr giaddr) {
|
||||
int is_dhcp = 0, mms;
|
||||
- unsigned optlen;
|
||||
+ unsigned optlen = 0;
|
||||
u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL;
|
||||
int adding_link_select;
|
||||
+ char circuit_id_buf[256] = { '\0' };
|
||||
+ char remote_id_buf[256] = { '\0' };
|
||||
+ size_t circuit_id_len = 0, remote_id_len = 0;
|
||||
|
||||
/* If we're not adding agent options to packets, we can skip
|
||||
this. */
|
||||
@@ -1195,17 +1295,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
op = sp;
|
||||
#endif
|
||||
|
||||
- /* Sanity check. Had better not ever happen. */
|
||||
- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1))
|
||||
- log_fatal("Circuit ID length %d out of range [1-255] on "
|
||||
- "%s\n", ip->circuit_id_len, ip->name);
|
||||
- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */
|
||||
-
|
||||
- if (ip->remote_id) {
|
||||
- if (ip->remote_id_len > 255 || ip->remote_id_len < 1)
|
||||
- log_fatal("Remote ID length %d out of range [1-255] "
|
||||
- "on %s\n", ip->remote_id_len, ip->name);
|
||||
- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */
|
||||
+ /* option82: custom string for circuit_id */
|
||||
+ if (agent_circuit_id_fmt) {
|
||||
+ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt,
|
||||
+ circuit_id_buf, sizeof(circuit_id_buf));
|
||||
+
|
||||
+ if (circuit_id_len == 0) {
|
||||
+ strncpy(circuit_id_buf, ip->name, sizeof(ip->name));
|
||||
+ circuit_id_len = strlen(circuit_id_buf);
|
||||
+ }
|
||||
+
|
||||
+ /* Sanity check. Had better not ever happen. */
|
||||
+ if (circuit_id_len > 255 || circuit_id_len < 1)
|
||||
+ log_fatal("Circuit ID length %d out of range [1-255] on %s\n",
|
||||
+ (int)circuit_id_len, ip->name);
|
||||
+
|
||||
+ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len
|
||||
+
|
||||
+ //log_debug("Sending on %s option82:circuit_id='%s' (%d)",
|
||||
+ // ip->name, circuit_id_buf, (int)circuit_id_len);
|
||||
+ }
|
||||
+
|
||||
+ /* option82: custom string for remote_id */
|
||||
+ if (agent_remote_id_fmt) {
|
||||
+ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt,
|
||||
+ remote_id_buf, sizeof(remote_id_buf));
|
||||
+
|
||||
+ if (remote_id_len > 255 || remote_id_len < 1)
|
||||
+ log_fatal("Remote ID length %d out of range [1-255] on %s\n",
|
||||
+ (int)remote_id_len, ip->name);
|
||||
+
|
||||
+ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len
|
||||
+
|
||||
+ //log_debug("Sending on %s option82:remote_id='%s' (%d)",
|
||||
+ // ip->name, remote_id_buf, (int)remote_id_len);
|
||||
}
|
||||
|
||||
if (adding_link_select) {
|
||||
@@ -1224,7 +1347,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
* If not, forward without adding the option.
|
||||
*/
|
||||
if (max - sp >= optlen + 3) {
|
||||
- log_debug("Adding %d-byte relay agent option", 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;
|
||||
@@ -1232,16 +1355,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
|
||||
/* Copy in the circuit id... */
|
||||
*sp++ = RAI_CIRCUIT_ID;
|
||||
- *sp++ = ip->circuit_id_len;
|
||||
- memcpy(sp, ip->circuit_id, ip->circuit_id_len);
|
||||
- sp += ip->circuit_id_len;
|
||||
+ *sp++ = circuit_id_len;
|
||||
+ memcpy(sp, circuit_id_buf, circuit_id_len);
|
||||
+ sp += circuit_id_len;
|
||||
|
||||
/* Copy in remote ID... */
|
||||
- if (ip->remote_id) {
|
||||
+ if (remote_id_len > 0) {
|
||||
*sp++ = RAI_REMOTE_ID;
|
||||
- *sp++ = ip->remote_id_len;
|
||||
- memcpy(sp, ip->remote_id, ip->remote_id_len);
|
||||
- sp += ip->remote_id_len;
|
||||
+ *sp++ = remote_id_len;
|
||||
+ memcpy(sp, remote_id_buf, remote_id_len);
|
||||
+ sp += remote_id_len;
|
||||
}
|
||||
|
||||
/* RFC3527: Use the inbound packet's interface address in
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,114 +0,0 @@
|
||||
From caad3e05c31c9fad8cda378ce95a1969def771a2 Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Mon, 11 Dec 2017 23:39:10 +0000
|
||||
Subject: [PATCH 2/3] Support for obtaining name of physical interface that is
|
||||
a member of a bridge interface
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 67 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index b9f8326..8458ea9 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -758,6 +758,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
print_hw_addr(packet->htype, packet->hlen,
|
||||
packet->chaddr),
|
||||
inet_ntoa(sp->to.sin_addr));
|
||||
+
|
||||
++client_packets_relayed;
|
||||
}
|
||||
}
|
||||
@@ -917,6 +918,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
++corrupt_agent_options;
|
||||
return (-1);
|
||||
}
|
||||
+
|
||||
switch(buf[i]) {
|
||||
/* Remember where the circuit ID is... */
|
||||
case RAI_CIRCUIT_ID:
|
||||
@@ -959,6 +961,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
+static int
|
||||
+_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) {
|
||||
+
|
||||
+#define xstr(s) str(s)
|
||||
+#define str(s) #s
|
||||
+#define FDB_STRING_LEN 100
|
||||
+#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1)
|
||||
+
|
||||
+/*
|
||||
+ * Format for sscanf() to read the 1st, 3th, and 5th
|
||||
+ * space-delimited fields
|
||||
+ *
|
||||
+ * bridge fdb show output
|
||||
+ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent
|
||||
+ */
|
||||
+#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \
|
||||
+ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s"
|
||||
+
|
||||
+ char cmdstr[FDB_BUFFER_LEN];
|
||||
+ char buf[FDB_BUFFER_LEN];
|
||||
+ char macAddr[FDB_BUFFER_LEN];
|
||||
+
|
||||
+ if ((interface == NULL) || (vlanid == NULL)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr);
|
||||
+ FILE *cmd = popen(cmdstr, "r");
|
||||
+
|
||||
+ if (cmd != NULL) {
|
||||
+ while (fgets(buf, sizeof(buf), cmd)) {
|
||||
+ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid);
|
||||
+ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d",
|
||||
+ // macAddr, interface, *vlanid);
|
||||
+ }
|
||||
+ pclose(cmd);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Format the message that will be used by circuit_id and remote_id
|
||||
*/
|
||||
@@ -991,8 +1034,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
break;
|
||||
|
||||
case 'p': /* Name of interface that we received the request from */
|
||||
- strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
- str = ifname;
|
||||
+ /*
|
||||
+ * Query FDB to identify the exact physical interface only when source MAC address
|
||||
+ * is present and '20: DHCP relay agent IP address' (giaddr) is not present
|
||||
+ */
|
||||
+ if (packet->htype && !packet->giaddr.s_addr) {
|
||||
+ int ret = 0, vlanid = 0;
|
||||
+
|
||||
+ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr),
|
||||
+ ifname,
|
||||
+ &vlanid);
|
||||
+
|
||||
+ // If we failed to find a physical interface using the source mac, default
|
||||
+ // to the interface name we received it on.
|
||||
+ if (ret < 0) {
|
||||
+ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show",
|
||||
+ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr),
|
||||
+ // ip->name,
|
||||
+ // vlanid);
|
||||
+
|
||||
+ strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
+ }
|
||||
+
|
||||
+ str = ifname;
|
||||
+ }
|
||||
break;
|
||||
|
||||
case 'P': /* Physical address of interface that we received the request from */
|
||||
--
|
||||
2.1.4
|
||||
|
@ -1,187 +0,0 @@
|
||||
From 3a42b497716375c9347b51c3a28c5e91e7cd4cf4 Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Tue, 12 Dec 2017 00:49:09 +0000
|
||||
Subject: [PATCH 3/3] Support for loading port alias map file to replace port
|
||||
name with alias in circuit id
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 105 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 8458ea9..15f0acf 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -122,6 +122,14 @@ static void setup_streams(void);
|
||||
char *dhcrelay_sub_id = NULL;
|
||||
#endif
|
||||
|
||||
+struct interface_name_alias_tuple {
|
||||
+ char if_name[IFNAMSIZ];
|
||||
+ char if_alias[IFNAMSIZ];
|
||||
+};
|
||||
+
|
||||
+static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL;
|
||||
+static size_t g_interface_name_alias_map_size = 0;
|
||||
+
|
||||
static void do_relay4(struct interface_info *, struct dhcp_packet *,
|
||||
unsigned int, unsigned int, struct iaddr,
|
||||
struct hardware *);
|
||||
@@ -134,6 +142,10 @@ static int strip_relay_agent_options(struct interface_info *,
|
||||
struct interface_info **,
|
||||
struct dhcp_packet *, unsigned);
|
||||
|
||||
+static int load_interface_alias_map(const char *port_alias_map_file_path);
|
||||
+static int get_interface_alias_by_name(const char *if_name, char *if_alias_out);
|
||||
+static void free_interface_alias_map(void);
|
||||
+
|
||||
static const char copyright[] =
|
||||
"Copyright 2004-2015 Internet Systems Consortium.";
|
||||
static const char arr[] = "All rights reserved.";
|
||||
@@ -147,7 +159,7 @@ static const char url[] =
|
||||
"\n" \
|
||||
" %%%% A single %%\n" \
|
||||
" %%h Hostname of device\n" \
|
||||
-" %%p Name of interface that generated the request\n" \
|
||||
+" %%p Alias of interface that generated the request\n" \
|
||||
" %%P Hardware address of interface that generated the request\n" \
|
||||
" %%C Client hardware address\n" \
|
||||
" %%I DHCP relay agent IP Address\n" \
|
||||
@@ -158,10 +170,12 @@ static const char url[] =
|
||||
" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n"\
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
+" [--name-alias-map-file <name-alias-map-file>]\n" \
|
||||
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||
" server0 [ ... serverN]\n\n" \
|
||||
" dhcrelay -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n" \
|
||||
+" [--name-alias-map-file <name-alias-map-file>]\n" \
|
||||
" [-s <subscriber-id>]\n" \
|
||||
" -l lower0 [ ... -l lowerN]\n" \
|
||||
" -u upper0 [ ... -u upperN]\n" \
|
||||
@@ -405,6 +419,11 @@ main(int argc, char **argv) {
|
||||
no_dhcrelay_pid = ISC_TRUE;
|
||||
} else if (!strcmp(argv[i], "--no-pid")) {
|
||||
no_pid_file = ISC_TRUE;
|
||||
+ } else if (!strcmp(argv[i], "--name-alias-map-file")) {
|
||||
+ if (++i == argc)
|
||||
+ usage();
|
||||
+ if (load_interface_alias_map(argv[i]) != 0)
|
||||
+ log_fatal("Failed to load interface name-alias map.");
|
||||
} else if (!strcmp(argv[i], "--version")) {
|
||||
log_info("isc-dhcrelay-%s", PACKAGE_VERSION);
|
||||
exit(0);
|
||||
@@ -624,6 +643,8 @@ main(int argc, char **argv) {
|
||||
dispatch();
|
||||
|
||||
/* In fact dispatch() never returns. */
|
||||
+ free_interface_alias_map();
|
||||
+
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1040,6 +1061,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
*/
|
||||
if (packet->htype && !packet->giaddr.s_addr) {
|
||||
int ret = 0, vlanid = 0;
|
||||
+ char ifalias[IFNAMSIZ] = { 0 };
|
||||
|
||||
ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr),
|
||||
ifname,
|
||||
@@ -1056,6 +1078,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
}
|
||||
|
||||
+ // Attempt to translate SONiC interface name to vendor alias
|
||||
+ ret = get_interface_alias_by_name(ifname, ifalias);
|
||||
+ if (ret < 0) {
|
||||
+ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname);
|
||||
+ }
|
||||
+ else {
|
||||
+ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s",
|
||||
+ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr));
|
||||
+
|
||||
+ strncpy(ifname, ifalias, IFNAMSIZ);
|
||||
+ }
|
||||
+
|
||||
str = ifname;
|
||||
}
|
||||
break;
|
||||
@@ -1922,3 +1956,73 @@ dhcp_set_control_state(control_object_state_t oldstate,
|
||||
|
||||
exit(0);
|
||||
}
|
||||
+
|
||||
+#define MAX_PORT_CONFIG_LINE_LEN 1024
|
||||
+
|
||||
+// Allocates and loads global map g_interface_name_alias_map
|
||||
+// Also sets global g_interface_name_alias_map_size
|
||||
+static int
|
||||
+load_interface_alias_map(const char *port_alias_map_file_path) {
|
||||
+ int i = 0;
|
||||
+ FILE *fp = NULL;
|
||||
+ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 };
|
||||
+
|
||||
+ fp = fopen(port_alias_map_file_path,"r");
|
||||
+ if (fp == NULL) {
|
||||
+ log_error("Unable to open %s", port_alias_map_file_path);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ g_interface_name_alias_map_size = 0;
|
||||
+
|
||||
+ // Count the number of interfaces listed in the file
|
||||
+ while (fgets(line, sizeof(line), fp)) {
|
||||
+ g_interface_name_alias_map_size++;
|
||||
+ }
|
||||
+
|
||||
+ // Allocate our map accordingly
|
||||
+ g_interface_name_alias_map = ((struct interface_name_alias_tuple *)
|
||||
+ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size),
|
||||
+ MDL));
|
||||
+
|
||||
+ // Reset file position indicator to beginning of file
|
||||
+ fseek(fp, 0, SEEK_SET);
|
||||
+
|
||||
+ // Every line should contain exactly one name-alias pair
|
||||
+ while (fgets(line, sizeof(line), fp)) {
|
||||
+ // Each line should read as "<name><whitespace><alias>"
|
||||
+ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias);
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ log_info("Loaded %d interface name-alias mappings", i);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+// Locates alias for port named if_name, copies alias into if_alias_out, up to a
|
||||
+// max of IFNAMSIZ bytes.
|
||||
+// Returns 0 on success, -1 on failure
|
||||
+static int
|
||||
+get_interface_alias_by_name(const char *if_name, char *if_alias_out) {
|
||||
+ int i = 0;
|
||||
+
|
||||
+ for (i = 0; i < g_interface_name_alias_map_size; i++) {
|
||||
+ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) {
|
||||
+ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+// Frees global map g_interface_name_alias_map
|
||||
+// Sets g_interface_name_alias_map_size to 0
|
||||
+static void
|
||||
+free_interface_alias_map(void) {
|
||||
+ free(g_interface_name_alias_map);
|
||||
+ g_interface_name_alias_map_size = 0;
|
||||
+}
|
||||
--
|
||||
2.1.4
|
||||
|
@ -0,0 +1,98 @@
|
||||
From ab0be27d3862c7287e3b181cc6a70effa054be1c Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Fri, 26 Apr 2019 01:06:49 +0000
|
||||
Subject: [PATCH] Support for obtaining name of physical interface that is a
|
||||
member of a bridge interface
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 65 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 4659660..0f7d658 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -1072,6 +1072,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
+static int
|
||||
+_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) {
|
||||
+
|
||||
+#define xstr(s) str(s)
|
||||
+#define str(s) #s
|
||||
+#define FDB_STRING_LEN 100
|
||||
+#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1)
|
||||
+
|
||||
+/*
|
||||
+ * Format for sscanf() to read the 1st, 3th, and 5th
|
||||
+ * space-delimited fields
|
||||
+ *
|
||||
+ * bridge fdb show output
|
||||
+ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent
|
||||
+ */
|
||||
+#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \
|
||||
+ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s"
|
||||
+
|
||||
+ char cmdstr[FDB_BUFFER_LEN];
|
||||
+ char buf[FDB_BUFFER_LEN];
|
||||
+ char macAddr[FDB_BUFFER_LEN];
|
||||
+
|
||||
+ if ((interface == NULL) || (vlanid == NULL)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr);
|
||||
+ FILE *cmd = popen(cmdstr, "r");
|
||||
+
|
||||
+ if (cmd != NULL) {
|
||||
+ while (fgets(buf, sizeof(buf), cmd)) {
|
||||
+ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid);
|
||||
+ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d",
|
||||
+ // macAddr, interface, *vlanid);
|
||||
+ }
|
||||
+ pclose(cmd);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Format the message that will be used by circuit_id and remote_id
|
||||
*/
|
||||
@@ -1104,8 +1145,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
break;
|
||||
|
||||
case 'p': /* Name of interface that we received the request from */
|
||||
- strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
- str = ifname;
|
||||
+ /*
|
||||
+ * Query FDB to identify the exact physical interface only when source MAC address
|
||||
+ * is present and '20: DHCP relay agent IP address' (giaddr) is not present
|
||||
+ */
|
||||
+ if (packet->htype && !packet->giaddr.s_addr) {
|
||||
+ int ret = 0, vlanid = 0;
|
||||
+
|
||||
+ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr),
|
||||
+ ifname,
|
||||
+ &vlanid);
|
||||
+
|
||||
+ // If we failed to find a physical interface using the source mac, default
|
||||
+ // to the interface name we received it on.
|
||||
+ if (ret < 0) {
|
||||
+ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show",
|
||||
+ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr),
|
||||
+ // ip->name,
|
||||
+ // vlanid);
|
||||
+
|
||||
+ strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
+ }
|
||||
+
|
||||
+ str = ifname;
|
||||
+ }
|
||||
break;
|
||||
|
||||
case 'P': /* Physical address of interface that we received the request from */
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,189 @@
|
||||
From 9d255bbd7d7aadac5b57cba2ab4e29cecdf0180f Mon Sep 17 00:00:00 2001
|
||||
From: Joe LeVeque <jolevequ@microsoft.com>
|
||||
Date: Fri, 26 Apr 2019 01:26:45 +0000
|
||||
Subject: [PATCH] Support for loading port alias map file to replace port name
|
||||
with alias in circuit id
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 104 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 0f7d658..797dac6 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -126,6 +126,14 @@ static void setup_streams(void);
|
||||
char *dhcrelay_sub_id = NULL;
|
||||
#endif
|
||||
|
||||
+struct interface_name_alias_tuple {
|
||||
+ char if_name[IFNAMSIZ];
|
||||
+ char if_alias[IFNAMSIZ];
|
||||
+};
|
||||
+
|
||||
+static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL;
|
||||
+static size_t g_interface_name_alias_map_size = 0;
|
||||
+
|
||||
static void do_relay4(struct interface_info *, struct dhcp_packet *,
|
||||
unsigned int, unsigned int, struct iaddr,
|
||||
struct hardware *);
|
||||
@@ -140,6 +148,10 @@ static int strip_relay_agent_options(struct interface_info *,
|
||||
|
||||
static void request_v4_interface(const char* name, int flags);
|
||||
|
||||
+static int load_interface_alias_map(const char *port_alias_map_file_path);
|
||||
+static int get_interface_alias_by_name(const char *if_name, char *if_alias_out);
|
||||
+static void free_interface_alias_map(void);
|
||||
+
|
||||
static const char copyright[] =
|
||||
"Copyright 2004-2016 Internet Systems Consortium.";
|
||||
static const char arr[] = "All rights reserved.";
|
||||
@@ -155,7 +167,7 @@ char *progname;
|
||||
"\n" \
|
||||
" %%%% A single %%\n" \
|
||||
" %%h Hostname of device\n" \
|
||||
-" %%p Name of interface that generated the request\n" \
|
||||
+" %%p Alias of interface that generated the request\n" \
|
||||
" %%P Hardware address of interface that generated the request\n" \
|
||||
" %%C Client hardware address\n" \
|
||||
" %%I DHCP relay agent IP Address\n" \
|
||||
@@ -166,6 +178,7 @@ char *progname;
|
||||
" [-A <length>] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n"\
|
||||
" [-m append|replace|forward|discard]\n" \
|
||||
+" [--name-alias-map-file <name-alias-map-file>]\n" \
|
||||
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
@@ -173,6 +186,7 @@ char *progname;
|
||||
" server0 [ ... serverN]\n\n" \
|
||||
" %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n" \
|
||||
+" [--name-alias-map-file <name-alias-map-file>]\n" \
|
||||
" [-s <subscriber-id>]\n" \
|
||||
" -l lower0 [ ... -l lowerN]\n" \
|
||||
" -u upper0 [ ... -u upperN]\n" \
|
||||
@@ -503,6 +517,11 @@ main(int argc, char **argv) {
|
||||
no_dhcrelay_pid = ISC_TRUE;
|
||||
} else if (!strcmp(argv[i], "--no-pid")) {
|
||||
no_pid_file = ISC_TRUE;
|
||||
+ } else if (!strcmp(argv[i], "--name-alias-map-file")) {
|
||||
+ if (++i == argc)
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ if (load_interface_alias_map(argv[i]) != 0)
|
||||
+ log_fatal("Failed to load interface name-alias map.");
|
||||
} else if (!strcmp(argv[i], "--version")) {
|
||||
log_info("isc-dhcrelay-%s", PACKAGE_VERSION);
|
||||
exit(0);
|
||||
@@ -726,6 +745,7 @@ main(int argc, char **argv) {
|
||||
dispatch();
|
||||
|
||||
/* In fact dispatch() never returns. */
|
||||
+ free_interface_alias_map();
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1151,6 +1171,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
*/
|
||||
if (packet->htype && !packet->giaddr.s_addr) {
|
||||
int ret = 0, vlanid = 0;
|
||||
+ char ifalias[IFNAMSIZ] = { 0 };
|
||||
|
||||
ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr),
|
||||
ifname,
|
||||
@@ -1167,6 +1188,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
|
||||
strncpy(ifname, ip->name, IFNAMSIZ);
|
||||
}
|
||||
|
||||
+ // Attempt to translate SONiC interface name to vendor alias
|
||||
+ ret = get_interface_alias_by_name(ifname, ifalias);
|
||||
+ if (ret < 0) {
|
||||
+ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname);
|
||||
+ }
|
||||
+ else {
|
||||
+ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s",
|
||||
+ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr));
|
||||
+
|
||||
+ strncpy(ifname, ifalias, IFNAMSIZ);
|
||||
+ }
|
||||
+
|
||||
str = ifname;
|
||||
}
|
||||
break;
|
||||
@@ -2096,3 +2129,73 @@ void request_v4_interface(const char* name, int flags) {
|
||||
interface_snorf(tmp, (INTERFACE_REQUESTED | flags));
|
||||
interface_dereference(&tmp, MDL);
|
||||
}
|
||||
+
|
||||
+#define MAX_PORT_CONFIG_LINE_LEN 1024
|
||||
+
|
||||
+// Allocates and loads global map g_interface_name_alias_map
|
||||
+// Also sets global g_interface_name_alias_map_size
|
||||
+static int
|
||||
+load_interface_alias_map(const char *port_alias_map_file_path) {
|
||||
+ int i = 0;
|
||||
+ FILE *fp = NULL;
|
||||
+ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 };
|
||||
+
|
||||
+ fp = fopen(port_alias_map_file_path,"r");
|
||||
+ if (fp == NULL) {
|
||||
+ log_error("Unable to open %s", port_alias_map_file_path);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ g_interface_name_alias_map_size = 0;
|
||||
+
|
||||
+ // Count the number of interfaces listed in the file
|
||||
+ while (fgets(line, sizeof(line), fp)) {
|
||||
+ g_interface_name_alias_map_size++;
|
||||
+ }
|
||||
+
|
||||
+ // Allocate our map accordingly
|
||||
+ g_interface_name_alias_map = ((struct interface_name_alias_tuple *)
|
||||
+ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size),
|
||||
+ MDL));
|
||||
+
|
||||
+ // Reset file position indicator to beginning of file
|
||||
+ fseek(fp, 0, SEEK_SET);
|
||||
+
|
||||
+ // Every line should contain exactly one name-alias pair
|
||||
+ while (fgets(line, sizeof(line), fp)) {
|
||||
+ // Each line should read as "<name><whitespace><alias>"
|
||||
+ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias);
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ log_info("Loaded %d interface name-alias mappings", i);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+// Locates alias for port named if_name, copies alias into if_alias_out, up to a
|
||||
+// max of IFNAMSIZ bytes.
|
||||
+// Returns 0 on success, -1 on failure
|
||||
+static int
|
||||
+get_interface_alias_by_name(const char *if_name, char *if_alias_out) {
|
||||
+ int i = 0;
|
||||
+
|
||||
+ for (i = 0; i < g_interface_name_alias_map_size; i++) {
|
||||
+ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) {
|
||||
+ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+// Frees global map g_interface_name_alias_map
|
||||
+// Sets g_interface_name_alias_map_size to 0
|
||||
+static void
|
||||
+free_interface_alias_map(void) {
|
||||
+ free(g_interface_name_alias_map);
|
||||
+ g_interface_name_alias_map_size = 0;
|
||||
+}
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,47 +0,0 @@
|
||||
From: Thomas Markwalder <tmark@isc.org>
|
||||
Date: Thu, 7 Dec 2017 11:23:36 -0500
|
||||
Subject: [master] Plugs a socket descriptor leak in OMAPI
|
||||
Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=1a6b62fe17a42b00fa234d06b6dfde3d03451894
|
||||
Bug: https://bugs.isc.org/Public/Bug/Display.html?id=46767
|
||||
Bug-Debian: https://bugs.debian.org/887413
|
||||
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-3144
|
||||
|
||||
Merges in rt46767.
|
||||
---
|
||||
|
||||
diff --git a/omapip/buffer.c b/omapip/buffer.c
|
||||
index 6e0621b5..a21f0a80 100644
|
||||
--- a/omapip/buffer.c
|
||||
+++ b/omapip/buffer.c
|
||||
@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
|
||||
omapi_buffer_dereference (&buffer, MDL);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* If we had data left to write when we're told to disconnect,
|
||||
+ * we need recall disconnect, now that we're done writing.
|
||||
+ * See rt46767. */
|
||||
+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) {
|
||||
+ omapi_disconnect (h, 1);
|
||||
+ return ISC_R_SHUTTINGDOWN;
|
||||
+ }
|
||||
+
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
diff --git a/omapip/message.c b/omapip/message.c
|
||||
index ee15d821..37abbd25 100644
|
||||
--- a/omapip/message.c
|
||||
+++ b/omapip/message.c
|
||||
@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PROTOCOL
|
||||
-static const char *omapi_message_op_name(int op) {
|
||||
+const char *omapi_message_op_name(int op) {
|
||||
switch (op) {
|
||||
case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN";
|
||||
case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
|
||||
--
|
||||
2.16.2
|
||||
|
@ -1,145 +0,0 @@
|
||||
From: Zhenggen Xu <zxu@linkedin.com>
|
||||
Date: Thu, 11 Oct 2018 17:18:32 -0700
|
||||
Subject: [PATCH] Subject: [master] Corrected refcnt loss in option parsing
|
||||
Origin:
|
||||
https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=197b26f25309f947b97a83b8fdfc414b767798f8
|
||||
Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47140 Bug-Debian:
|
||||
https://bugs.debian.org/891785 Bug-Debian-Security:
|
||||
https://security-tracker.debian.org/tracker/CVE-2018-5733
|
||||
|
||||
Merges in 47140.
|
||||
---
|
||||
common/options.c | 2 +
|
||||
common/tests/Makefile.am | 11 ++++-
|
||||
common/tests/option_unittest.c | 79 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 91 insertions(+), 1 deletion(-)
|
||||
create mode 100644 common/tests/option_unittest.c
|
||||
|
||||
diff --git a/common/options.c b/common/options.c
|
||||
index 74f1fb5..db28b5c 100644
|
||||
--- a/common/options.c
|
||||
+++ b/common/options.c
|
||||
@@ -177,6 +177,8 @@ int parse_option_buffer (options, buffer, length, universe)
|
||||
|
||||
/* If the length is outrageous, the options are bad. */
|
||||
if (offset + len > length) {
|
||||
+ /* Avoid reference count overflow */
|
||||
+ option_dereference(&option, MDL);
|
||||
reason = "option length exceeds option buffer length";
|
||||
bogus:
|
||||
log_error("parse_option_buffer: malformed option "
|
||||
diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am
|
||||
index 32e055c..19521c9 100644
|
||||
--- a/common/tests/Makefile.am
|
||||
+++ b/common/tests/Makefile.am
|
||||
@@ -8,7 +8,8 @@ ATF_TESTS =
|
||||
|
||||
if HAVE_ATF
|
||||
|
||||
-ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest
|
||||
+ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest \
|
||||
+ option_unittest
|
||||
|
||||
alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||
alloc_unittest_LDADD = $(ATF_LDFLAGS)
|
||||
@@ -34,6 +35,14 @@ ns_name_unittest_LDADD += ../libdhcp.a \
|
||||
../../omapip/libomapi.a ../../bind/lib/libirs.a \
|
||||
../../bind/lib/libdns.a ../../bind/lib/libisccfg.a ../../bind/lib/libisc.a
|
||||
|
||||
+option_unittest_SOURCES = option_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||
+option_unittest_LDADD = $(ATF_LDFLAGS)
|
||||
+option_unittest_LDADD += ../libdhcp.@A@ ../../omapip/libomapi.@A@ \
|
||||
+ @BINDLIBIRSDIR@/libirs.@A@ \
|
||||
+ @BINDLIBDNSDIR@/libdns.@A@ \
|
||||
+ @BINDLIBISCCFGDIR@/libisccfg.@A@ \
|
||||
+ @BINDLIBISCDIR@/libisc.@A@
|
||||
+
|
||||
check: $(ATF_TESTS)
|
||||
sh ${top_srcdir}/tests/unittest.sh
|
||||
|
||||
diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c
|
||||
new file mode 100644
|
||||
index 0000000..36236b8
|
||||
--- /dev/null
|
||||
+++ b/common/tests/option_unittest.c
|
||||
@@ -0,0 +1,79 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
+ *
|
||||
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
+ * PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+#include <atf-c.h>
|
||||
+#include "dhcpd.h"
|
||||
+
|
||||
+ATF_TC(option_refcnt);
|
||||
+
|
||||
+ATF_TC_HEAD(option_refcnt, tc)
|
||||
+{
|
||||
+ atf_tc_set_md_var(tc, "descr",
|
||||
+ "Verify option reference count does not overflow.");
|
||||
+}
|
||||
+
|
||||
+/* This test does a simple check to see if option reference count is
|
||||
+ * decremented even an error path exiting parse_option_buffer()
|
||||
+ */
|
||||
+ATF_TC_BODY(option_refcnt, tc)
|
||||
+{
|
||||
+ struct option_state *options;
|
||||
+ struct option *option;
|
||||
+ unsigned code;
|
||||
+ int refcnt;
|
||||
+ unsigned char buffer[3] = { 15, 255, 0 };
|
||||
+
|
||||
+ initialize_common_option_spaces();
|
||||
+
|
||||
+ options = NULL;
|
||||
+ if (!option_state_allocate(&options, MDL)) {
|
||||
+ atf_tc_fail("can't allocate option state");
|
||||
+ }
|
||||
+
|
||||
+ option = NULL;
|
||||
+ code = 15; /* domain-name */
|
||||
+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
||||
+ &code, 0, MDL)) {
|
||||
+ atf_tc_fail("can't find option 15");
|
||||
+ }
|
||||
+ if (option == NULL) {
|
||||
+ atf_tc_fail("option is NULL");
|
||||
+ }
|
||||
+ refcnt = option->refcnt;
|
||||
+
|
||||
+ buffer[0] = 15;
|
||||
+ buffer[1] = 255; /* invalid */
|
||||
+ buffer[2] = 0;
|
||||
+
|
||||
+ if (parse_option_buffer(options, buffer, 3, &dhcp_universe)) {
|
||||
+ atf_tc_fail("parse_option_buffer is expected to fail");
|
||||
+ }
|
||||
+
|
||||
+ if (refcnt != option->refcnt) {
|
||||
+ atf_tc_fail("refcnt changed from %d to %d", refcnt, option->refcnt);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* This macro defines main() method that will call specified
|
||||
+ test cases. tp and simple_test_case names can be whatever you want
|
||||
+ as long as it is a valid variable identifier. */
|
||||
+ATF_TP_ADD_TCS(tp)
|
||||
+{
|
||||
+ ATF_TP_ADD_TC(tp, option_refcnt);
|
||||
+
|
||||
+ return (atf_no_error());
|
||||
+}
|
||||
|
@ -1,144 +0,0 @@
|
||||
From: Thomas Markwalder <tmark@isc.org>
|
||||
Date: Sat, 10 Feb 2018 12:15:27 -0500
|
||||
Subject: [master] Correct buffer overrun in pretty_print_option
|
||||
Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=c5931725b48b121d232df4ba9e45bc41e0ba114d
|
||||
Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47139
|
||||
Bug-Debian: https://bugs.debian.org/891786
|
||||
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5732
|
||||
|
||||
Merges in rt47139.
|
||||
---
|
||||
|
||||
diff --git a/common/options.c b/common/options.c
|
||||
index 6f23bc15..fc0e0889 100644
|
||||
--- a/common/options.c
|
||||
+++ b/common/options.c
|
||||
@@ -1776,7 +1776,8 @@ format_min_length(format, oc)
|
||||
|
||||
|
||||
/* Format the specified option so that a human can easily read it. */
|
||||
-
|
||||
+/* Maximum pretty printed size */
|
||||
+#define MAX_OUTPUT_SIZE 32*1024
|
||||
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
struct option *option;
|
||||
const unsigned char *data;
|
||||
@@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
int emit_commas;
|
||||
int emit_quotes;
|
||||
{
|
||||
- static char optbuf [32768]; /* XXX */
|
||||
- static char *endbuf = &optbuf[sizeof(optbuf)];
|
||||
+ /* We add 128 byte pad so we don't have to add checks everywhere. */
|
||||
+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */
|
||||
+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE;
|
||||
int hunksize = 0;
|
||||
int opthunk = 0;
|
||||
int hunkinc = 0;
|
||||
@@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
log_error ("Unexpected format code %c",
|
||||
fmtbuf [j]);
|
||||
}
|
||||
+
|
||||
op += strlen (op);
|
||||
+ if (op >= endbuf) {
|
||||
+ log_error ("Option data exceeds"
|
||||
+ " maximum size %d", MAX_OUTPUT_SIZE);
|
||||
+ return ("<error>");
|
||||
+ }
|
||||
+
|
||||
if (dp == data + len)
|
||||
break;
|
||||
if (j + 1 < numelem && comma != ':')
|
||||
diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c
|
||||
index 36236b84..cd52cfb4 100644
|
||||
--- a/common/tests/option_unittest.c
|
||||
+++ b/common/tests/option_unittest.c
|
||||
@@ -43,7 +43,7 @@ ATF_TC_BODY(option_refcnt, tc)
|
||||
if (!option_state_allocate(&options, MDL)) {
|
||||
atf_tc_fail("can't allocate option state");
|
||||
}
|
||||
-
|
||||
+
|
||||
option = NULL;
|
||||
code = 15; /* domain-name */
|
||||
if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
||||
@@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc)
|
||||
}
|
||||
}
|
||||
|
||||
+ATF_TC(pretty_print_option);
|
||||
+
|
||||
+ATF_TC_HEAD(pretty_print_option, tc)
|
||||
+{
|
||||
+ atf_tc_set_md_var(tc, "descr",
|
||||
+ "Verify pretty_print_option does not overrun its buffer.");
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * This test verifies that pretty_print_option() will not overrun its
|
||||
+ * internal, static buffer when given large 'x/X' format options.
|
||||
+ *
|
||||
+ */
|
||||
+ATF_TC_BODY(pretty_print_option, tc)
|
||||
+{
|
||||
+ struct option *option;
|
||||
+ unsigned code;
|
||||
+ unsigned char bad_data[32*1024];
|
||||
+ unsigned char good_data[] = { 1,2,3,4,5,6 };
|
||||
+ int emit_commas = 1;
|
||||
+ int emit_quotes = 1;
|
||||
+ const char *output_buf;
|
||||
+
|
||||
+ /* Initialize whole thing to non-printable chars */
|
||||
+ memset(bad_data, 0x1f, sizeof(bad_data));
|
||||
+
|
||||
+ initialize_common_option_spaces();
|
||||
+
|
||||
+ /* We'll use dhcp_client_identitifer because it happens to be format X */
|
||||
+ code = 61;
|
||||
+ option = NULL;
|
||||
+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
||||
+ &code, 0, MDL)) {
|
||||
+ atf_tc_fail("can't find option %d", code);
|
||||
+ }
|
||||
+
|
||||
+ if (option == NULL) {
|
||||
+ atf_tc_fail("option is NULL");
|
||||
+ }
|
||||
+
|
||||
+ /* First we will try a good value we know should fit. */
|
||||
+ output_buf = pretty_print_option (option, good_data, sizeof(good_data),
|
||||
+ emit_commas, emit_quotes);
|
||||
+
|
||||
+ /* Make sure we get what we expect */
|
||||
+ if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) {
|
||||
+ atf_tc_fail("pretty_print_option did not return \"<error>\"");
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* Now we'll try a data value that's too large */
|
||||
+ output_buf = pretty_print_option (option, bad_data, sizeof(bad_data),
|
||||
+ emit_commas, emit_quotes);
|
||||
+
|
||||
+ /* Make sure we safely get an error */
|
||||
+ if (!output_buf || strcmp(output_buf, "<error>")) {
|
||||
+ atf_tc_fail("pretty_print_option did not return \"<error>\"");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* This macro defines main() method that will call specified
|
||||
test cases. tp and simple_test_case names can be whatever you want
|
||||
as long as it is a valid variable identifier. */
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, option_refcnt);
|
||||
+ ATF_TP_ADD_TC(tp, pretty_print_option);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
--
|
||||
2.16.2
|
||||
|
@ -1,9 +1,6 @@
|
||||
# This series applies on GIT commit ee3dffdda38a8cfc6ad2005d8d64a165d2a709ba
|
||||
0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch
|
||||
0002-Support-for-obtaining-name-of-physical-interface-tha.patch
|
||||
0003-Support-for-loading-port-alias-map-file-to-replace-p.patch
|
||||
0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch
|
||||
0005-CVE-2017-3144.patch
|
||||
0006-CVE-2018-5733.patch
|
||||
0007-CVE-2018-5732.patch
|
||||
# This series applies on GIT commit d613b77d0473054fb0071b00d01eaa1623e50a07
|
||||
0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch
|
||||
0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch
|
||||
0003-Support-for-obtaining-name-of-physical-interface-tha.patch
|
||||
0004-Support-for-loading-port-alias-map-file-to-replace-p.patch
|
||||
|
||||
|
Reference in New Issue
Block a user