connman.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Lars Steubesand <lars@bbl.ms.philips.com>
To: connman@lists.linux.dev
Subject: [PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option
Date: Tue, 22 Feb 2022 10:11:29 +0100	[thread overview]
Message-ID: <20220222091129.29525-4-lars@bbl.ms.philips.com> (raw)
In-Reply-To: <20220222091129.29525-1-lars@bbl.ms.philips.com>

From: Lars Steubesand <lars.steubesand@philips.com>

---
 .gitignore               |   1 +
 Makefile.am              |   9 +
 gdhcp/client.c           |  10 +-
 gdhcp/common.c           |  20 ++-
 gdhcp/common.h           |   2 +-
 gdhcp/server.c           |   6 +-
 unit/test-dhcp-options.c | 365 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 402 insertions(+), 11 deletions(-)
 create mode 100644 unit/test-dhcp-options.c

diff --git a/.gitignore b/.gitignore
index 9e8d1a409bce..80441c38808d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,7 @@ tools/netlink-test
 unit/test-ippool
 unit/test-nat
 unit/test-iptables
+unit/test-dhcp-options
 
 doc/*.bak
 doc/*.stamp
diff --git a/Makefile.am b/Makefile.am
index e5718b191345..487873cb4af6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -324,6 +324,15 @@ unit_test_ippool_LDADD = gdbus/libgdbus-internal.la \
 
 TESTS = unit/test-ippool
 
+noinst_PROGRAMS += unit/test-dhcp-options
+
+unit_test_dhcp_options_SOURCES = $(backtrace_sources) src/log.c \
+					src/error.c src/util.c gdhcp/common.c unit/test-dhcp-options.c
+unit_test_dhcp_options_LDADD = gdbus/libgdbus-internal.la \
+				@GLIB_LIBS@ @DBUS_LIBS@ -ldl
+
+TESTS += unit/test-dhcp-options
+
 if WISPR
 noinst_PROGRAMS += tools/wispr
 
diff --git a/gdhcp/client.c b/gdhcp/client.c
index dcde98ea95b6..4701306b2166 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -1634,7 +1634,7 @@ static uint32_t get_lease(struct dhcp_packet *packet, uint16_t packet_len)
 	uint8_t *option;
 	uint32_t lease_seconds;
 
-	option = dhcp_get_option(packet, packet_len, DHCP_LEASE_TIME);
+	option = dhcp_get_option(packet, packet_len, DHCP_LEASE_TIME, NULL);
 	if (!option)
 		return 3600;
 
@@ -2238,7 +2238,7 @@ static void get_request(GDHCPClient *dhcp_client, struct dhcp_packet *packet,
 	for (list = dhcp_client->request_list; list; list = list->next) {
 		code = (uint8_t) GPOINTER_TO_INT(list->data);
 
-		option = dhcp_get_option(packet, packet_len, code);
+		option = dhcp_get_option(packet, packet_len, code, NULL);
 		if (!option) {
 			g_hash_table_remove(dhcp_client->code_value_hash,
 						GINT_TO_POINTER((int) code));
@@ -2364,7 +2364,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 			dhcp_client->status_code = status;
 		}
 	} else {
-		message_type = dhcp_get_option(&packet, pkt_len, DHCP_MESSAGE_TYPE);
+		message_type = dhcp_get_option(&packet, pkt_len, DHCP_MESSAGE_TYPE, NULL);
 		if (!message_type)
 			return TRUE;
 	}
@@ -2381,7 +2381,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 		dhcp_client->timeout = 0;
 		dhcp_client->retry_times = 0;
 
-		option = dhcp_get_option(&packet, pkt_len, DHCP_SERVER_ID);
+		option = dhcp_get_option(&packet, pkt_len, DHCP_SERVER_ID, NULL);
 		if (!option)
 			return TRUE;
 
@@ -2445,7 +2445,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 
 			if (dhcp_client->state == REBOOTING) {
 				option = dhcp_get_option(&packet, pkt_len,
-							DHCP_SERVER_ID);
+							DHCP_SERVER_ID, NULL);
 				if (!option)
 					return TRUE;
 				dhcp_client->server_ip = get_be32(option);
diff --git a/gdhcp/common.c b/gdhcp/common.c
index b3b725f5edc1..1e9dbb003754 100644
--- a/gdhcp/common.c
+++ b/gdhcp/common.c
@@ -103,7 +103,7 @@ bool dhcp_check_option(uint8_t code, uint8_t data_len)
 	return true;
 }
 
-uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int code)
+uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int code, int *error)
 {
 	int len, rem;
 	uint8_t *optionptr, *options_end;
@@ -115,7 +115,12 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 	rem = sizeof(packet->options);
 
 	if (offsetof(struct dhcp_packet, options) >= packet_len)
+	{
+		if (error)
+			*error = 1;
+
 		return NULL;
+	}
 
 	options_len = packet_len - offsetof(struct dhcp_packet, options);
 	options_end = optionptr + options_len - 1;
@@ -123,6 +128,8 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 	while (1) {
 		if ((rem <= 0) || (optionptr + OPT_CODE > options_end)) {
 			/* Bad packet, malformed option field */
+			if (error)
+				*error = 2;
 			return NULL;
 		}
 
@@ -155,6 +162,8 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 
 		if (optionptr + OPT_LEN > options_end) {
 			/* bad packet, would read length field from OOB */
+			if (error)
+				*error = 3;
 			return NULL;
 		}
 
@@ -162,15 +171,22 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 
 		if (optionptr + len > options_end) {
 			/* bad packet, option length points OOB */
+			if (error)
+				*error = 4;
 			return NULL;
 		}
 
 		rem -= len;
-		if (rem < 0)
+		if (rem < 0) {
+			if (error)
+				*error = 5;
 			return NULL;
+		}
 
 		if (optionptr[OPT_CODE] == code) {
 			if (!dhcp_check_option(code, optionptr[OPT_LEN])) {
+				if (error)
+					*error = 6;
 				return NULL;
 			}
 			else
diff --git a/gdhcp/common.h b/gdhcp/common.h
index 8f63fd755623..b99128df62e1 100644
--- a/gdhcp/common.h
+++ b/gdhcp/common.h
@@ -179,7 +179,7 @@ struct in6_pktinfo {
 };
 #endif
 
-uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int code);
+uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int code, int *error);
 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
 			int code, uint16_t *option_len, int *option_count);
 uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len,
diff --git a/gdhcp/server.c b/gdhcp/server.c
index 52ea2a55b230..75c502a1a601 100644
--- a/gdhcp/server.c
+++ b/gdhcp/server.c
@@ -423,7 +423,7 @@ static uint8_t check_packet_type(struct dhcp_packet *packet, uint16_t packet_len
 	if (packet->op != BOOTREQUEST)
 		return 0;
 
-	type = dhcp_get_option(packet, packet_len, DHCP_MESSAGE_TYPE);
+	type = dhcp_get_option(packet, packet_len, DHCP_MESSAGE_TYPE, NULL);
 
 	if (!type)
 		return 0;
@@ -668,7 +668,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 	if (type == 0)
 		return TRUE;
 
-	server_id_option = dhcp_get_option(&packet, packet_len, DHCP_SERVER_ID);
+	server_id_option = dhcp_get_option(&packet, packet_len, DHCP_SERVER_ID, NULL);
 	if (server_id_option) {
 		uint32_t server_nid =
 			get_unaligned((const uint32_t *) server_id_option);
@@ -677,7 +677,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 			return TRUE;
 	}
 
-	request_ip_option = dhcp_get_option(&packet, packet_len, DHCP_REQUESTED_IP);
+	request_ip_option = dhcp_get_option(&packet, packet_len, DHCP_REQUESTED_IP, NULL);
 	if (request_ip_option)
 		requested_nip = get_be32(request_ip_option);
 
diff --git a/unit/test-dhcp-options.c b/unit/test-dhcp-options.c
new file mode 100644
index 000000000000..e07c433f5cd1
--- /dev/null
+++ b/unit/test-dhcp-options.c
@@ -0,0 +1,365 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include "../src/connman.h"
+
+/* #define DEBUG */
+#ifdef DEBUG
+#include <stdio.h>
+
+#define LOG(fmt, arg...) do { \
+	fprintf(stdout, "%s:%s() " fmt "\n", \
+			__FILE__, __func__ , ## arg); \
+} while (0)
+#else
+#define LOG(fmt, arg...)
+#endif
+
+#include <netinet/if_ether.h>
+#include "../gdhcp/common.h"
+
+bool dhcp_check_option(uint8_t code, uint8_t data_len);
+
+/* proper packet */
+static int reply_len_1 = 240 + 16 + 4;
+static unsigned char reply_bin_1[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff,
+};
+
+/* packet too short, no options field */
+static int reply_len_2 = 240;
+static unsigned char reply_bin_2[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0xff,
+};
+
+/* packet too short, only opt code */
+static int reply_len_3 = 241;
+static unsigned char reply_bin_3[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0xff,
+};
+
+/* packet too short, only opt code and len */
+static int reply_len_4 = 242;
+static unsigned char reply_bin_4[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0xff,
+};
+
+/* option too long */
+static int reply_len_5 = 244;
+static unsigned char reply_bin_5[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x03, 0x05, 0xff,
+};
+
+/* bad length for u8 option */
+static int reply_len_6 = 245;
+static unsigned char reply_bin_6[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x02, 0x05, 0x05, 0xff,
+};
+
+/* bad length for u32 option */
+static int reply_len_7 = 251;
+static unsigned char reply_bin_7[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+};
+
+/* bad length for u32 list option */
+static int reply_len_8 = 251;
+static unsigned char reply_bin_8[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63,
+  0x35, 0x01, 0x05, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+};
+
+static void test_case_0(void)
+{
+	bool ret;
+
+	ret = dhcp_check_option(DHCP_SUBNET, 4);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_SUBNET, 3);
+	g_assert(!ret);
+	ret = dhcp_check_option(DHCP_ROUTER, 4);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_ROUTER, 8);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_ROUTER, 7);
+	g_assert(!ret);
+	ret = dhcp_check_option(DHCP_HOST_NAME, 1);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_HOST_NAME, 2);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_MAX_SIZE, 2);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_MAX_SIZE, 1);
+	g_assert(!ret);
+	ret = dhcp_check_option(DHCP_MESSAGE_TYPE, 1);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_MESSAGE_TYPE, 2);
+	g_assert(!ret);
+	ret = dhcp_check_option(DHCP_SERVER_ID, 4);
+	g_assert(ret);
+	ret = dhcp_check_option(DHCP_SERVER_ID, 5);
+	g_assert(!ret);
+	ret = dhcp_check_option(241, 5);
+	g_assert(ret);
+}
+
+static void test_case_1(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_1, reply_len_1, 241, &error);
+	g_assert_cmpint(error, ==, 0);
+	g_assert(!opt_ptr);
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_1, reply_len_1, DHCP_SUBNET, &error);
+	g_assert_cmpint(error, ==, 0);
+	g_assert(opt_ptr);
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_1, reply_len_1, DHCP_ROUTER, &error);
+	g_assert_cmpint(error, ==, 0);
+	g_assert(opt_ptr);
+}
+
+static void test_case_2(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_2, reply_len_2, 241, &error);
+
+	g_assert_cmpint(error, ==, 1);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_3(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_3, reply_len_3, 241, &error);
+
+	g_assert_cmpint(error, ==, 3);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_4(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_4, reply_len_4, 241, &error);
+
+	g_assert_cmpint(error, ==, 4);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_5(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_5, reply_len_5, 241, &error);
+
+	g_assert_cmpint(error, ==, 4);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_6(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_6, reply_len_6, DHCP_MESSAGE_TYPE, &error);
+
+	g_assert_cmpint(error, ==, 6);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_7(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_7, reply_len_7, DHCP_SUBNET, &error);
+
+	g_assert_cmpint(error, ==, 6);
+
+	g_assert(!opt_ptr);
+}
+
+static void test_case_8(void)
+{
+	uint8_t *opt_ptr;
+	int error = 0;
+
+	opt_ptr = dhcp_get_option((struct dhcp_packet*)reply_bin_8, reply_len_8, DHCP_ROUTER, &error);
+
+	g_assert_cmpint(error, ==, 6);
+
+	g_assert(!opt_ptr);
+}
+
+int main(int argc, char *argv[])
+{
+	g_test_init(&argc, &argv, NULL);
+
+	g_test_add_func("/dhcp parse options/Test case 0", test_case_0);
+	g_test_add_func("/dhcp parse options/Test case 1", test_case_1);
+	g_test_add_func("/dhcp parse options/Test case 2", test_case_2);
+	g_test_add_func("/dhcp parse options/Test case 3", test_case_3);
+	g_test_add_func("/dhcp parse options/Test case 4", test_case_4);
+	g_test_add_func("/dhcp parse options/Test case 5", test_case_5);
+	g_test_add_func("/dhcp parse options/Test case 6", test_case_6);
+	g_test_add_func("/dhcp parse options/Test case 7", test_case_7);
+	g_test_add_func("/dhcp parse options/Test case 8", test_case_8);
+
+	return g_test_run();
+}
-- 
2.17.1


      parent reply	other threads:[~2022-02-22  9:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-22  9:11 [PATCH 0/3] Fix DHCP renew handling Lars Steubesand
2022-02-22  9:11 ` [PATCH 1/3] gdhcp: Set packet length when receiving L3 packet Lars Steubesand
2022-02-22  9:11 ` [PATCH 2/3] gdhcp: Further check invalid data in dhcp_get_option Lars Steubesand
2022-02-22  9:11 ` Lars Steubesand [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220222091129.29525-4-lars@bbl.ms.philips.com \
    --to=lars@bbl.ms.philips.com \
    --cc=connman@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).