diff options
| author | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
| commit | 2c032d8f1c6292c1338a615e6ec40252889ba85c (patch) | |
| tree | 1f77182220b2b0264288ba4a476ab47e5bc48716 /src/dhcp-manager/nm-dhcp-dhclient-utils.c | |
| parent | 33491bc4279481db8ae47213e34a6d695a0e8830 (diff) | |
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/dhcp-manager/nm-dhcp-dhclient-utils.c')
| -rw-r--r-- | src/dhcp-manager/nm-dhcp-dhclient-utils.c | 152 |
1 files changed, 106 insertions, 46 deletions
diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index 8527e6c0..46e8e0b8 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -17,21 +17,24 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#include <config.h> +#include "config.h" #include <glib.h> #include <glib/gi18n.h> #include <string.h> #include <ctype.h> +#include <arpa/inet.h> #include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-utils.h" #include "nm-ip4-config.h" #include "nm-utils.h" +#include "nm-platform.h" #include "NetworkManagerUtils.h" +#include "gsystem-local-alloc.h" +#include "nm-utils-internal.h" #define CLIENTID_TAG "send dhcp-client-identifier" -#define CLIENTID_FORMAT CLIENTID_TAG " \"%s\"; # added by NetworkManager" -#define CLIENTID_FORMAT_OCTETS CLIENTID_TAG " %s; # added by NetworkManager" #define HOSTNAME4_TAG "send host-name" #define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager" @@ -71,32 +74,39 @@ add_hostname (GString *str, const char *format, const char *hostname) } static void -add_ip4_config (GString *str, const char *dhcp_client_id, const char *hostname) +add_ip4_config (GString *str, GBytes *client_id, const char *hostname) { - if (dhcp_client_id) { - gboolean is_octets = TRUE; - int i = 0; + if (client_id) { + const char *p; + gsize l; + guint i; - while (dhcp_client_id[i]) { - if ((i % 3) != 2 && !g_ascii_isxdigit (dhcp_client_id[i])) { - is_octets = FALSE; - break; - } - if ((i % 3) == 2 && dhcp_client_id[i] != ':') { - is_octets = FALSE; + p = g_bytes_get_data (client_id, &l); + g_assert (p); + + /* Allow type 0 (non-hardware address) to be represented as a string + * as long as all the characters are printable. + */ + for (i = 1; (p[0] == 0) && i < l; i++) { + if (!g_ascii_isprint (p[i])) break; - } - i++; } - /* If the client ID is just hex digits and : then don't use quotes, - * because dhclient expects either a quoted ASCII string, or a byte - * array formated as hex octets separated by : - */ - if (is_octets) - g_string_append_printf (str, CLIENTID_FORMAT_OCTETS "\n", dhcp_client_id); - else - g_string_append_printf (str, CLIENTID_FORMAT "\n", dhcp_client_id); + g_string_append (str, CLIENTID_TAG " "); + if (i < l) { + /* Unprintable; convert to a hex string */ + for (i = 0; i < l; i++) { + if (i > 0) + g_string_append_c (str, ':'); + g_string_append_printf (str, "%02x", (guint8) p[i]); + } + } else { + /* Printable; just add to the line minus the 'type' */ + g_string_append_c (str, '"'); + g_string_append_len (str, p + 1, l - 1); + g_string_append_c (str, '"'); + } + g_string_append (str, "; # added by NetworkManager\n"); } add_hostname (str, HOSTNAME4_FORMAT "\n", hostname); @@ -124,19 +134,74 @@ add_ip6_config (GString *str, const char *hostname) "send fqdn.server-update on;\n"); } +static GBytes * +read_client_id (const char *str) +{ + gs_free char *s = NULL; + char *p; + + g_assert (!strncmp (str, CLIENTID_TAG, STRLEN (CLIENTID_TAG))); + + str += STRLEN (CLIENTID_TAG); + while (g_ascii_isspace (*str)) + str++; + + if (*str == '"') { + s = g_strdup (str + 1); + p = strrchr (s, '"'); + if (p) + *p = '\0'; + else + return NULL; + } else + s = g_strdup (str); + + g_strchomp (s); + if (s[strlen (s) - 1] == ';') + s[strlen (s) - 1] = '\0'; + + return nm_dhcp_utils_client_id_string_to_bytes (s); +} + +GBytes * +nm_dhcp_dhclient_get_client_id_from_config_file (const char *path) +{ + gs_free char *contents = NULL; + gs_strfreev char **lines = NULL; + char **line; + + g_return_val_if_fail (path != NULL, NULL); + + if (!g_file_test (path, G_FILE_TEST_EXISTS)) + return NULL; + + if (!g_file_get_contents (path, &contents, NULL, NULL)) + return NULL; + + lines = g_strsplit_set (contents, "\n\r", 0); + for (line = lines; lines && *line; line++) { + if (!strncmp (*line, CLIENTID_TAG, STRLEN (CLIENTID_TAG))) + return read_client_id (*line); + } + return NULL; +} + char * nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, - const char *dhcp_client_id, - GByteArray *anycast_addr, + GBytes *client_id, + const char *anycast_addr, const char *hostname, const char *orig_path, - const char *orig_contents) + const char *orig_contents, + GBytes **out_new_client_id) { GString *new_contents; GPtrArray *alsoreq; int i; + g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL); + new_contents = g_string_new (_("# Created by NetworkManager\n")); alsoreq = g_ptr_array_sized_new (5); @@ -153,11 +218,15 @@ nm_dhcp_dhclient_create_config (const char *interface, if (!strlen (g_strstrip (p))) continue; - /* Override config file "dhcp-client-id" and use one from the - * connection. - */ - if (dhcp_client_id && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) - continue; + if (!strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) { + /* Override config file "dhcp-client-id" and use one from the connection */ + if (client_id) + continue; + + /* Otherwise capture and return the existing client id */ + if (out_new_client_id) + *out_new_client_id = read_client_id (p); + } /* Override config file hostname and use one from the connection */ if (hostname) { @@ -225,9 +294,8 @@ nm_dhcp_dhclient_create_config (const char *interface, add_also_request (alsoreq, "dhcp6.name-servers"); add_also_request (alsoreq, "dhcp6.domain-search"); add_also_request (alsoreq, "dhcp6.client-id"); - add_also_request (alsoreq, "dhcp6.server-id"); } else { - add_ip4_config (new_contents, dhcp_client_id, hostname); + add_ip4_config (new_contents, client_id, hostname); add_also_request (alsoreq, "rfc3442-classless-static-routes"); add_also_request (alsoreq, "ms-classless-static-routes"); add_also_request (alsoreq, "static-routes"); @@ -246,22 +314,14 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_c (new_contents, '\n'); - if (anycast_addr && anycast_addr->len == 6) { - const guint8 *p_anycast_addr = anycast_addr->data; - + if (anycast_addr) { g_string_append_printf (new_contents, "interface \"%s\" {\n" " initial-interval 1; \n" - " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" + " anycast-mac ethernet %s;\n" "}\n", - interface, - p_anycast_addr[0], p_anycast_addr[1], - p_anycast_addr[2], p_anycast_addr[3], - p_anycast_addr[4], p_anycast_addr[5]); + interface, anycast_addr); } - /* Finally, assert that anycast_addr was unset or a 48 bit mac address. */ - g_return_val_if_fail (!anycast_addr || anycast_addr->len == 6, g_string_free (new_contents, FALSE)); - return g_string_free (new_contents, FALSE); } @@ -629,7 +689,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, address.timestamp = now_monotonic_ts; address.lifetime = address.preferred = expiry; - address.source = NM_PLATFORM_SOURCE_DHCP; + address.source = NM_IP_CONFIG_SOURCE_DHCP; ip4 = nm_ip4_config_new (); nm_ip4_config_add_address (ip4, &address); |