summary refs log tree commit diff
path: root/src/dhcp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhcp')
-rw-r--r--src/dhcp/meson.build1
-rw-r--r--src/dhcp/nm-dhcp-client.c37
-rw-r--r--src/dhcp/nm-dhcp-client.h6
-rw-r--r--src/dhcp/nm-dhcp-dhclient-utils.c30
-rw-r--r--src/dhcp/nm-dhcp-dhclient.c2
-rw-r--r--src/dhcp/nm-dhcp-dhcpcanon.c2
-rw-r--r--src/dhcp/nm-dhcp-dhcpcd.c2
-rw-r--r--src/dhcp/nm-dhcp-helper.c2
-rw-r--r--src/dhcp/nm-dhcp-utils.c2
-rw-r--r--src/dhcp/tests/meson.build1
-rw-r--r--src/dhcp/tests/test-dhcp-dhclient.c135
11 files changed, 170 insertions, 50 deletions
diff --git a/src/dhcp/meson.build b/src/dhcp/meson.build
index 289a16ca..76707bca 100644
--- a/src/dhcp/meson.build
+++ b/src/dhcp/meson.build
@@ -3,7 +3,6 @@ name = 'nm-dhcp-helper'
 cflags = [
   '-DG_LOG_DOMAIN="@0@"'.format(name),
   '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_GLIB',
-  '-DNMRUNDIR="@0@"'.format(nm_pkgrundir),
 ]
 
 executable(
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 360bd367..9fc7d2c1 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -51,7 +51,7 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMDhcpClient,
 	PROP_ADDR_FAMILY,
 	PROP_FLAGS,
 	PROP_HWADDR,
@@ -163,6 +163,17 @@ nm_dhcp_client_get_route_table (NMDhcpClient *self)
 	return NM_DHCP_CLIENT_GET_PRIVATE (self)->route_table;
 }
 
+void
+nm_dhcp_client_set_route_table (NMDhcpClient *self, guint32 route_table)
+{
+	NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
+
+	if (route_table != priv->route_table) {
+		priv->route_table = route_table;
+		_notify (self, PROP_ROUTE_TABLE);
+	}
+}
+
 guint32
 nm_dhcp_client_get_route_metric (NMDhcpClient *self)
 {
@@ -171,6 +182,17 @@ nm_dhcp_client_get_route_metric (NMDhcpClient *self)
 	return NM_DHCP_CLIENT_GET_PRIVATE (self)->route_metric;
 }
 
+void
+nm_dhcp_client_set_route_metric (NMDhcpClient *self, guint32 route_metric)
+{
+	NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
+
+	if (route_metric != priv->route_metric) {
+		priv->route_metric = route_metric;
+		_notify (self, PROP_ROUTE_METRIC);
+	}
+}
+
 guint32
 nm_dhcp_client_get_timeout (NMDhcpClient *self)
 {
@@ -423,7 +445,7 @@ transaction_timeout (gpointer user_data)
 }
 
 static void
-daemon_watch_cb (GPid pid, gint status, gpointer user_data)
+daemon_watch_cb (GPid pid, int status, gpointer user_data)
 {
 	NMDhcpClient *self = NM_DHCP_CLIENT (user_data);
 	NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
@@ -712,7 +734,7 @@ maybe_add_option (NMDhcpClient *self,
 gboolean
 nm_dhcp_client_handle_event (gpointer unused,
                              const char *iface,
-                             gint pid,
+                             int pid,
                              GVariant *options,
                              const char *reason,
                              NMDhcpClient *self)
@@ -834,6 +856,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_ROUTE_METRIC:
 		g_value_set_uint (value, priv->route_metric);
 		break;
+	case PROP_ROUTE_TABLE:
+		g_value_set_uint (value, priv->route_table);
+		break;
 	case PROP_TIMEOUT:
 		g_value_set_uint (value, priv->timeout);
 		break;
@@ -889,11 +914,9 @@ set_property (GObject *object, guint prop_id,
 		priv->uuid = g_value_dup_string (value);
 		break;
 	case PROP_ROUTE_TABLE:
-		/* construct-only */
 		priv->route_table = g_value_get_uint (value);
 		break;
 	case PROP_ROUTE_METRIC:
-		/* construct-only */
 		priv->route_metric = g_value_get_uint (value);
 		break;
 	case PROP_TIMEOUT:
@@ -1002,13 +1025,13 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class)
 	obj_properties[PROP_ROUTE_TABLE] =
 	    g_param_spec_uint (NM_DHCP_CLIENT_ROUTE_TABLE, "", "",
 	                       0, G_MAXUINT32, RT_TABLE_MAIN,
-	                       G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+	                       G_PARAM_READWRITE |
 	                       G_PARAM_STATIC_STRINGS);
 
 	obj_properties[PROP_ROUTE_METRIC] =
 	    g_param_spec_uint (NM_DHCP_CLIENT_ROUTE_METRIC, "", "",
 	                       0, G_MAXUINT32, 0,
-	                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+	                       G_PARAM_READWRITE |
 	                       G_PARAM_STATIC_STRINGS);
 
 	obj_properties[PROP_TIMEOUT] =
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h
index f3d0b7d1..b50ea515 100644
--- a/src/dhcp/nm-dhcp-client.h
+++ b/src/dhcp/nm-dhcp-client.h
@@ -131,8 +131,12 @@ GBytes *nm_dhcp_client_get_hw_addr (NMDhcpClient *self);
 
 guint32 nm_dhcp_client_get_route_table (NMDhcpClient *self);
 
+void nm_dhcp_client_set_route_table (NMDhcpClient *self, guint32 route_table);
+
 guint32 nm_dhcp_client_get_route_metric (NMDhcpClient *self);
 
+void nm_dhcp_client_set_route_metric (NMDhcpClient *self, guint32 route_metric);
+
 guint32 nm_dhcp_client_get_timeout (NMDhcpClient *self);
 
 GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self);
@@ -176,7 +180,7 @@ void nm_dhcp_client_set_state (NMDhcpClient *self,
 
 gboolean nm_dhcp_client_handle_event (gpointer unused,
                                       const char *iface,
-                                      gint pid,
+                                      int pid,
                                       GVariant *options,
                                       const char *reason,
                                       NMDhcpClient *self);
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c
index 3290dd65..d8f8dd98 100644
--- a/src/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c
@@ -316,6 +316,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
 
 	if (orig_contents) {
 		char **lines, **line;
+		int nest = 0;
 		gboolean in_alsoreq = FALSE;
 		gboolean in_req = FALSE;
 		char intf[IFNAMSIZ];
@@ -330,18 +331,24 @@ nm_dhcp_dhclient_create_config (const char *interface,
 			if (!strlen (g_strstrip (p)))
 				continue;
 
-			if (   !intf[0]
-			    && g_str_has_prefix (p, "interface")
-			    && !in_req) {
-				if (read_interface (p, intf, sizeof (intf)))
-					continue;
-			}
-
-			if (intf[0] && strchr (p, '}')) {
+			if (in_req) {
+				/* pass */
+			} else if (strchr (p, '{')) {
+				nest++;
+				if (   !intf[0]
+				    && g_str_has_prefix (p, "interface"))
+					if (read_interface (p, intf, sizeof (intf)))
+						continue;
+			} else if (strchr (p, '}')) {
+				if (nest)
+					nest--;
 				intf[0] = '\0';
 				continue;
 			}
 
+			if (nest && !intf[0])
+				continue;
+
 			if (intf[0] && !nm_streq (intf, interface))
 				continue;
 
@@ -523,6 +530,10 @@ nm_dhcp_dhclient_unescape_duid (const char *duid)
 	guint i, len;
 	guint8 octal;
 
+	/* FIXME: it's wrong to have an "unescape-duid" function. dhclient
+	 * defines a file format with escaping. So we need a general unescape
+	 * function that can handle dhclient syntax. */
+
 	len = strlen (duid);
 	unescaped = g_byte_array_sized_new (len);
 	for (i = 0; i < len; i++) {
@@ -536,6 +547,9 @@ nm_dhcp_dhclient_unescape_duid (const char *duid)
 				g_byte_array_append (unescaped, &octal, 1);
 				i += 2;
 			} else {
+				/* FIXME: don't warn on untrusted data. Either signal an error, or accept
+				 * it silently. */
+
 				/* One of ", ', $, `, \, |, or & */
 				g_warn_if_fail (p[i] == '"' || p[i] == '\'' || p[i] == '$' ||
 				                p[i] == '`' || p[i] == '\\' || p[i] == '|' ||
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c
index 3bd14ebe..8408e3f9 100644
--- a/src/dhcp/nm-dhcp-dhclient.c
+++ b/src/dhcp/nm-dhcp-dhclient.c
@@ -447,7 +447,7 @@ dhclient_start (NMDhcpClient *client,
 	g_ptr_array_add (argv, NULL);
 
 	_LOGD ("running: %s",
-	       (cmd_str = g_strjoinv (" ", (gchar **) argv->pdata)));
+	       (cmd_str = g_strjoinv (" ", (char **) argv->pdata)));
 
 	if (!g_spawn_async (NULL, (char **) argv->pdata, NULL,
 	                    G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
diff --git a/src/dhcp/nm-dhcp-dhcpcanon.c b/src/dhcp/nm-dhcp-dhcpcanon.c
index 12aa57aa..92aa7f8c 100644
--- a/src/dhcp/nm-dhcp-dhcpcanon.c
+++ b/src/dhcp/nm-dhcp-dhcpcanon.c
@@ -144,7 +144,7 @@ dhcpcanon_start (NMDhcpClient *client,
 	g_ptr_array_add (argv, (gpointer) iface);
 	g_ptr_array_add (argv, NULL);
 
-	cmd_str = g_strjoinv (" ", (gchar **) argv->pdata);
+	cmd_str = g_strjoinv (" ", (char **) argv->pdata);
 	g_free (cmd_str);
 
 	if (g_spawn_async (NULL, (char **) argv->pdata, NULL,
diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c
index c4bcb084..10094e5c 100644
--- a/src/dhcp/nm-dhcp-dhcpcd.c
+++ b/src/dhcp/nm-dhcp-dhcpcd.c
@@ -153,7 +153,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
 	g_ptr_array_add (argv, (gpointer) iface);
 	g_ptr_array_add (argv, NULL);
 
-	cmd_str = g_strjoinv (" ", (gchar **) argv->pdata);
+	cmd_str = g_strjoinv (" ", (char **) argv->pdata);
 	_LOGD ("running: %s", cmd_str);
 	g_free (cmd_str);
 
diff --git a/src/dhcp/nm-dhcp-helper.c b/src/dhcp/nm-dhcp-helper.c
index 8ea55061..2b48d7a5 100644
--- a/src/dhcp/nm-dhcp-helper.c
+++ b/src/dhcp/nm-dhcp-helper.c
@@ -31,7 +31,7 @@
 
 /*****************************************************************************/
 
-#ifdef NM_MORE_LOGGING
+#if NM_MORE_LOGGING
 #define _NMLOG_ENABLED(level) TRUE
 #else
 #define _NMLOG_ENABLED(level) ((level) <= LOG_ERR)
diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c
index 9185a135..6bbc670b 100644
--- a/src/dhcp/nm-dhcp-utils.c
+++ b/src/dhcp/nm-dhcp-utils.c
@@ -594,7 +594,7 @@ ip6_add_domain_search (gpointer data, gpointer user_data)
 NMPlatformIP6Address
 nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options)
 {
-	gs_strfreev gchar **split_addr = NULL;
+	gs_strfreev char **split_addr = NULL;
 	NMPlatformIP6Address address = { 0, };
 	struct in6_addr tmp_addr;
 	char *str = NULL;
diff --git a/src/dhcp/tests/meson.build b/src/dhcp/tests/meson.build
index 9d8be427..0fee26b2 100644
--- a/src/dhcp/tests/meson.build
+++ b/src/dhcp/tests/meson.build
@@ -8,7 +8,6 @@ foreach test_unit: test_units
     test_unit,
     test_unit + '.c',
     dependencies: test_nm_dep,
-    c_args: nm_build_cflags,
   )
 
   test(
diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c
index 2f369aac..14a1c786 100644
--- a/src/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/dhcp/tests/test-dhcp-dhclient.c
@@ -86,7 +86,7 @@ test_config (const char *orig,
 	if (expected_new_client_id) {
 		g_assert (new_client_id);
 		g_assert (g_bytes_equal (new_client_id, expected_new_client_id));
-	 } else
+	} else
 		g_assert (new_client_id == NULL);
 }
 
@@ -675,27 +675,18 @@ test_existing_multiline_alsoreq (void)
 static void
 test_one_duid (const char *escaped, const guint8 *unescaped, guint len)
 {
-	GBytes *t;
-	char *w;
-	gsize t_len;
-	gconstpointer t_arr;
-
-	t = nm_dhcp_dhclient_unescape_duid (escaped);
-	g_assert (t);
-	t_arr = g_bytes_get_data (t, &t_len);
-	g_assert (t_arr);
-	g_assert_cmpint (t_len, ==, len);
-	g_assert_cmpint (memcmp (t_arr, unescaped, len), ==, 0);
-	g_bytes_unref (t);
-
-	t = g_bytes_new_static (unescaped, len);
-	w = nm_dhcp_dhclient_escape_duid (t);
+	gs_unref_bytes GBytes *t1 = NULL;
+	gs_unref_bytes GBytes *t2 = NULL;
+	gs_free char *w = NULL;
+
+	t1 = nm_dhcp_dhclient_unescape_duid (escaped);
+	g_assert (t1);
+	g_assert (nm_utils_gbytes_equal_mem (t1, unescaped, len));
+
+	t2 = g_bytes_new (unescaped, len);
+	w = nm_dhcp_dhclient_escape_duid (t2);
 	g_assert (w);
-	g_assert_cmpint (strlen (escaped), ==, strlen (w));
 	g_assert_cmpstr (escaped, ==, w);
-
-	g_bytes_unref (t);
-	g_free (w);
 }
 
 static void
@@ -735,15 +726,11 @@ test_read_duid_from_leasefile (void)
 	                            0x13, 0x60, 0x67, 0x20, 0xec, 0x4c, 0x70 };
 	gs_unref_bytes GBytes *duid = NULL;
 	GError *error = NULL;
-	gconstpointer duid_arr;
-	gsize duid_len;
 
 	duid = nm_dhcp_dhclient_read_duid (TEST_DIR"/test-dhclient-duid.leases", &error);
-	g_assert_no_error (error);
-	g_assert (duid);
-	duid_arr = g_bytes_get_data (duid, &duid_len);
-	g_assert_cmpint (duid_len, ==, sizeof (expected));
-	g_assert_cmpint (memcmp (duid_arr, expected, duid_len), ==, 0);
+	nmtst_assert_success (duid, error);
+
+	g_assert (nm_utils_gbytes_equal_mem (duid, expected, G_N_ELEMENTS (expected)));
 }
 
 static void
@@ -962,6 +949,99 @@ test_interface2 (void)
 }
 
 static void
+test_structured (void)
+{
+	gs_unref_bytes GBytes *new_client_id = NULL;
+	const guint8 bytes[] = "sad-and-useless";
+
+	static const char *const orig = \
+		"interface \"eth0\"   {  \n"
+		"    send host-name \"useless.example.com\";\n"
+		"    hardware ethernet de:ad:80:86:ba:be;\n"
+		"    send dhcp-client-identifier \"sad-and-useless\";\n"
+		"    script \"/bin/useless\";\n"
+		"    send dhcp-lease-time 8086;\n"
+		"    request subnet-mask, broadcast-address, time-offset, routers,\n"
+		"        domain-search, domain-name, host-name;\n"
+		"    require subnet-mask;\n"
+		"}  \n"
+		"\n"
+		"    interface \"eth1\"   {  \n"
+		"    send host-name \"sad.example.com\";\n"
+		"    hardware ethernet de:ca:f6:66:ca:fe;\n"
+		"    send dhcp-client-identifier \"useless-and-miserable\";\n"
+		"    script \"/bin/miserable\";\n"
+		"    send dhcp-lease-time 1337;\n"
+		"    request subnet-mask, broadcast-address, time-offset, routers,\n"
+		"        domain-search, domain-name, domain-name-servers, host-name;\n"
+		"    require subnet-mask, domain-name-servers;\n"
+		"    }  \n"
+		"\n"
+		"pseudo \"secondary\" \"eth0\"   {  \n"
+		"    send dhcp-client-identifier \"sad-useless-and-secondary\";\n"
+		"    script \"/bin/secondary\";\n"
+		"    send host-name \"secondary.useless.example.com\";\n"
+		"    send dhcp-lease-time 666;\n"
+		"    request routers;\n"
+		"    require routers;\n"
+		"    }  \n"
+		"\n"
+		"    pseudo \"tertiary\" \"eth0\"   {  \n"
+		"   send dhcp-client-identifier \"sad-useless-and-tertiary\";\n"
+		"  script \"/bin/tertiary\";\n"
+		" send host-name \"tertiary.useless.example.com\";\n"
+		"}  \n"
+		"\n"
+		"  alias{  \n"
+		"    interface \"eth0\";\n"
+		"    fixed-address 192.0.2.1;\n"
+		"    option subnet-mask 255.255.255.0;\n"
+		"  }  \n"
+		"  lease   {  \n"
+		"    interface \"eth0\";\n"
+		"    fixed-address 192.0.2.2;\n"
+		"    option subnet-mask 255.255.255.0;\n"
+		"  }  \n";
+
+	static const char *const expected = \
+		"# Created by NetworkManager\n"
+		"# Merged from /path/to/dhclient.conf\n"
+		"\n"
+		"send host-name \"useless.example.com\";\n"
+		"hardware ethernet de:ad:80:86:ba:be;\n"
+		"send dhcp-client-identifier \"sad-and-useless\";\n"
+		"send dhcp-lease-time 8086;\n"
+		"require subnet-mask;\n"
+		"\n"
+		"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+		"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+		"option wpad code 252 = string;\n"
+		"\n"
+		"request; # override dhclient defaults\n"
+		"also request subnet-mask;\n"
+		"also request broadcast-address;\n"
+		"also request time-offset;\n"
+		"also request routers;\n"
+		"also request domain-search;\n"
+		"also request domain-name;\n"
+		"also request host-name;\n"
+		"also request rfc3442-classless-static-routes;\n"
+		"also request ms-classless-static-routes;\n"
+		"also request static-routes;\n"
+		"also request wpad;\n"
+		"also request ntp-servers;\n"
+		"\n";
+
+	new_client_id = g_bytes_new (bytes, sizeof (bytes) - 1);
+	test_config (orig, expected,
+	             AF_INET, NULL, 0, FALSE,
+	             NULL,
+	             new_client_id,
+	             "eth0",
+	             NULL);
+}
+
+static void
 test_config_req_intf (void)
 {
 	static const char *const orig = \
@@ -1046,6 +1126,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/dhcp/dhclient/interface/1", test_interface1);
 	g_test_add_func ("/dhcp/dhclient/interface/2", test_interface2);
 	g_test_add_func ("/dhcp/dhclient/config/req_intf", test_config_req_intf);
+	g_test_add_func ("/dhcp/dhclient/structured", test_structured);
 
 	g_test_add_func ("/dhcp/dhclient/read_duid_from_leasefile", test_read_duid_from_leasefile);
 	g_test_add_func ("/dhcp/dhclient/read_commented_duid_from_leasefile", test_read_commented_duid_from_leasefile);