connman.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix DHCP renew handling
@ 2022-02-22  9:11 Lars Steubesand
  2022-02-22  9:11 ` [PATCH 1/3] gdhcp: Set packet length when receiving L3 packet Lars Steubesand
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lars Steubesand @ 2022-02-22  9:11 UTC (permalink / raw)
  To: connman

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

It appears that commit
58d397ba7487 ("gdhcp: Avoid reading invalid data in dhcp_get_option")
broke DHCP renew handling. Fix this and add more robust handling
of DHCP options with length checks.

The patch
[PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option
some minimal form of unit testing for parsing DHCP options.
If not required or not desired this way the patch can be
dropped.

Lars Steubesand (2):
  gdhcp: Further check invalid data in dhcp_get_option
  gdhcp: Add unit tests for dhcp_get_option

Lauser, Simon (1):
  gdhcp: Set packet length when receiving L3 packet

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


base-commit: b335791af9194d1bd7b9821f4c5abc5405109557
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] gdhcp: Set packet length when receiving L3 packet
  2022-02-22  9:11 [PATCH 0/3] Fix DHCP renew handling Lars Steubesand
@ 2022-02-22  9:11 ` 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 ` [PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option Lars Steubesand
  2 siblings, 0 replies; 4+ messages in thread
From: Lars Steubesand @ 2022-02-22  9:11 UTC (permalink / raw)
  To: connman

From: "Lauser, Simon" <simon.lauser@philips.com>

The L3 receive path was not setting the packet length. As a result, the
DHCP options could not be retrieved from the DHCP packet. Thus, renewing
was not properly working, e.g. IP address was proper but netmask
was default set to /32.

Fixes: 58d397ba7487 ("gdhcp: Avoid reading invalid data in
dhcp_get_option")
---
 gdhcp/client.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gdhcp/client.c b/gdhcp/client.c
index 3016dfc2582b..dcde98ea95b6 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -2314,6 +2314,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 		} else {
 			re = dhcp_recv_l3_packet(&packet,
 						dhcp_client->listener_sockfd);
+			pkt_len = (uint16_t)(unsigned int)re;
 			xid = packet.xid;
 		}
 	} else if (dhcp_client->listen_mode == L_ARP) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] gdhcp: Further check invalid data in dhcp_get_option
  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 ` Lars Steubesand
  2022-02-22  9:11 ` [PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option Lars Steubesand
  2 siblings, 0 replies; 4+ messages in thread
From: Lars Steubesand @ 2022-02-22  9:11 UTC (permalink / raw)
  To: connman

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

Improve error case handling for invalid DHCP options
by fixing dhcp_get_option and checking valid lengths
of known DHCP options.

Fixes: 58d397ba7487 ("gdhcp: Avoid reading invalid data in dhcp_get_option")
---
 gdhcp/common.c | 53 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/gdhcp/common.c b/gdhcp/common.c
index c8916aa81666..b3b725f5edc1 100644
--- a/gdhcp/common.c
+++ b/gdhcp/common.c
@@ -73,6 +73,36 @@ GDHCPOptionType dhcp_get_code_type(uint8_t code)
 	return OPTION_UNKNOWN;
 }
 
+bool dhcp_check_option(uint8_t code, uint8_t data_len)
+{
+	GDHCPOptionType type = dhcp_get_code_type(code);
+	uint8_t len;
+
+	if (type == OPTION_UNKNOWN)
+		return true;
+
+	len = dhcp_option_lengths[type & OPTION_TYPE_MASK];
+
+	if ((type & ~OPTION_TYPE_MASK) == OPTION_LIST) {
+		if ((data_len == 0) || (data_len % len != 0)) {
+			printf("Invalid option len %d (expecting multiple of %d) for code 0x%x\n",
+				data_len, len, code);
+			return false;
+		}
+	} else if (type == OPTION_STRING) {
+		if (data_len >= 1)
+			return true;
+		else
+			return false;
+	} else if (len != data_len) {
+		printf("Invalid option len %d (expecting %d) for code 0x%x\n",
+			data_len, len, code);
+		return false;
+	}
+
+	return true;
+}
+
 uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int code)
 {
 	int len, rem;
@@ -83,13 +113,18 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 	/* option bytes: [code][len][data1][data2]..[dataLEN] */
 	optionptr = packet->options;
 	rem = sizeof(packet->options);
-	options_len = packet_len - (sizeof(*packet) - sizeof(packet->options));
+
+	if (offsetof(struct dhcp_packet, options) >= packet_len)
+		return NULL;
+
+	options_len = packet_len - offsetof(struct dhcp_packet, options);
 	options_end = optionptr + options_len - 1;
 
 	while (1) {
-		if ((rem <= 0) && (optionptr + OPT_CODE > options_end))
+		if ((rem <= 0) || (optionptr + OPT_CODE > options_end)) {
 			/* Bad packet, malformed option field */
 			return NULL;
+		}
 
 		if (optionptr[OPT_CODE] == DHCP_PADDING) {
 			rem--;
@@ -125,17 +160,21 @@ uint8_t *dhcp_get_option(struct dhcp_packet *packet, uint16_t packet_len, int co
 
 		len = 2 + optionptr[OPT_LEN];
 
+		if (optionptr + len > options_end) {
+			/* bad packet, option length points OOB */
+			return NULL;
+		}
+
 		rem -= len;
 		if (rem < 0)
-			continue; /* complain and return NULL */
+			return NULL;
 
 		if (optionptr[OPT_CODE] == code) {
-			if (optionptr + len > options_end) {
-				/* bad packet, option length points OOB */
+			if (!dhcp_check_option(code, optionptr[OPT_LEN])) {
 				return NULL;
-			} else {
-				return optionptr + OPT_DATA;
 			}
+			else
+				return optionptr + OPT_DATA;
 		}
 
 		if (optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option
  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
  2 siblings, 0 replies; 4+ messages in thread
From: Lars Steubesand @ 2022-02-22  9:11 UTC (permalink / raw)
  To: connman

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-02-22  9:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 3/3] gdhcp: Add unit tests for dhcp_get_option Lars Steubesand

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).