dhclient: split out dhclient config merging and add testcases
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -93,6 +93,7 @@ libnm-util/tests/test-need-secrets
|
|||||||
libnm-util/tests/test-setting-8021x
|
libnm-util/tests/test-setting-8021x
|
||||||
src/tests/test-dhcp-options
|
src/tests/test-dhcp-options
|
||||||
src/tests/test-policy-hosts
|
src/tests/test-policy-hosts
|
||||||
|
src/dhcp-manager/tests/test-dhcp-dhclient
|
||||||
|
|
||||||
system-settings/plugins/keyfile/tests/test-keyfile
|
system-settings/plugins/keyfile/tests/test-keyfile
|
||||||
system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh
|
system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh
|
||||||
|
@@ -518,6 +518,7 @@ src/logging/Makefile
|
|||||||
src/dns-manager/Makefile
|
src/dns-manager/Makefile
|
||||||
src/vpn-manager/Makefile
|
src/vpn-manager/Makefile
|
||||||
src/dhcp-manager/Makefile
|
src/dhcp-manager/Makefile
|
||||||
|
src/dhcp-manager/tests/Makefile
|
||||||
src/ip6-manager/Makefile
|
src/ip6-manager/Makefile
|
||||||
src/supplicant-manager/Makefile
|
src/supplicant-manager/Makefile
|
||||||
src/supplicant-manager/tests/Makefile
|
src/supplicant-manager/tests/Makefile
|
||||||
|
@@ -16,6 +16,7 @@ policy/org.freedesktop.NetworkManager.policy.in
|
|||||||
src/nm-netlink-monitor.c
|
src/nm-netlink-monitor.c
|
||||||
src/main.c
|
src/main.c
|
||||||
src/dhcp-manager/nm-dhcp-dhclient.c
|
src/dhcp-manager/nm-dhcp-dhclient.c
|
||||||
|
src/dhcp-manager/nm-dhcp-dhclient-utils.c
|
||||||
src/dhcp-manager/nm-dhcp-manager.c
|
src/dhcp-manager/nm-dhcp-manager.c
|
||||||
src/logging/nm-logging.c
|
src/logging/nm-logging.c
|
||||||
src/dns-manager/nm-dns-manager.c
|
src/dns-manager/nm-dns-manager.c
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
SUBDIRS=. tests
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I${top_srcdir} \
|
-I${top_srcdir} \
|
||||||
-I${top_srcdir}/include \
|
-I${top_srcdir}/include \
|
||||||
@@ -6,15 +8,40 @@ INCLUDES = \
|
|||||||
-I${top_srcdir}/libnm-util \
|
-I${top_srcdir}/libnm-util \
|
||||||
-I${top_srcdir}/src
|
-I${top_srcdir}/src
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libdhcp-manager.la
|
noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la
|
||||||
|
|
||||||
|
################## dhclient ##################
|
||||||
|
|
||||||
|
libdhcp_dhclient_la_SOURCES = \
|
||||||
|
nm-dhcp-dhclient-utils.h \
|
||||||
|
nm-dhcp-dhclient-utils.c \
|
||||||
|
nm-dhcp-dhclient.h \
|
||||||
|
nm-dhcp-dhclient.c
|
||||||
|
|
||||||
|
libdhcp_dhclient_la_CPPFLAGS = \
|
||||||
|
$(DBUS_CFLAGS) \
|
||||||
|
$(GLIB_CFLAGS) \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||||
|
-DLIBEXECDIR=\"$(libexecdir)\" \
|
||||||
|
-DLOCALSTATEDIR=\"$(localstatedir)\" \
|
||||||
|
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
|
||||||
|
-DDHCLIENT_V$(DHCLIENT_VERSION)
|
||||||
|
|
||||||
|
libdhcp_dhclient_la_LIBADD = \
|
||||||
|
$(top_builddir)/marshallers/libmarshallers.la \
|
||||||
|
$(top_builddir)/src/logging/libnm-logging.la \
|
||||||
|
$(top_builddir)/libnm-util/libnm-util.la \
|
||||||
|
$(DBUS_LIBS) \
|
||||||
|
$(GLIB_LIBS)
|
||||||
|
|
||||||
|
################## main lib ##################
|
||||||
|
|
||||||
libdhcp_manager_la_SOURCES = \
|
libdhcp_manager_la_SOURCES = \
|
||||||
nm-dhcp-client.c \
|
nm-dhcp-client.c \
|
||||||
nm-dhcp-client.h \
|
nm-dhcp-client.h \
|
||||||
nm-dhcp-manager.c \
|
nm-dhcp-manager.c \
|
||||||
nm-dhcp-manager.h \
|
nm-dhcp-manager.h \
|
||||||
nm-dhcp-dhclient.h \
|
|
||||||
nm-dhcp-dhclient.c \
|
|
||||||
nm-dhcp-dhcpcd.h \
|
nm-dhcp-dhcpcd.h \
|
||||||
nm-dhcp-dhcpcd.c
|
nm-dhcp-dhcpcd.c
|
||||||
|
|
||||||
@@ -22,18 +49,15 @@ libdhcp_manager_la_CPPFLAGS = \
|
|||||||
$(DBUS_CFLAGS) \
|
$(DBUS_CFLAGS) \
|
||||||
$(GLIB_CFLAGS) \
|
$(GLIB_CFLAGS) \
|
||||||
-DG_DISABLE_DEPRECATED \
|
-DG_DISABLE_DEPRECATED \
|
||||||
-DBINDIR=\"$(bindir)\" \
|
|
||||||
-DDATADIR=\"$(datadir)\" \
|
|
||||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
|
||||||
-DLIBEXECDIR=\"$(libexecdir)\" \
|
-DLIBEXECDIR=\"$(libexecdir)\" \
|
||||||
-DLOCALSTATEDIR=\"$(localstatedir)\" \
|
-DLOCALSTATEDIR=\"$(localstatedir)\" \
|
||||||
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
|
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
|
||||||
-DDHCLIENT_V$(DHCLIENT_VERSION) \
|
|
||||||
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
|
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
|
||||||
|
|
||||||
libdhcp_manager_la_LIBADD = \
|
libdhcp_manager_la_LIBADD = \
|
||||||
$(top_builddir)/marshallers/libmarshallers.la \
|
$(top_builddir)/marshallers/libmarshallers.la \
|
||||||
$(top_builddir)/src/logging/libnm-logging.la \
|
$(top_builddir)/src/logging/libnm-logging.la \
|
||||||
|
$(builddir)/libdhcp-dhclient.la \
|
||||||
$(DBUS_LIBS) \
|
$(DBUS_LIBS) \
|
||||||
$(GLIB_LIBS)
|
$(GLIB_LIBS)
|
||||||
|
|
||||||
|
214
src/dhcp-manager/nm-dhcp-dhclient-utils.c
Normal file
214
src/dhcp-manager/nm-dhcp-dhclient-utils.c
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "nm-dhcp-dhclient-utils.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 HOSTNAME_TAG "send host-name"
|
||||||
|
#define HOSTNAME_FORMAT HOSTNAME_TAG " \"%s\"; # added by NetworkManager"
|
||||||
|
|
||||||
|
#define ALSOREQ_TAG "also request "
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_also_request (GPtrArray *array, const char *item)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < array->len; i++) {
|
||||||
|
if (!strcmp (g_ptr_array_index (array, i), item))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_ptr_array_add (array, g_strdup (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nm_dhcp_dhclient_create_config (const char *interface,
|
||||||
|
NMSettingIP4Config *s_ip4,
|
||||||
|
guint8 *anycast_addr,
|
||||||
|
const char *hostname,
|
||||||
|
const char *orig_path,
|
||||||
|
const char *orig_contents)
|
||||||
|
{
|
||||||
|
GString *new_contents;
|
||||||
|
GPtrArray *alsoreq;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
new_contents = g_string_new (_("# Created by NetworkManager\n"));
|
||||||
|
alsoreq = g_ptr_array_sized_new (5);
|
||||||
|
|
||||||
|
if (orig_contents) {
|
||||||
|
char **lines, **line;
|
||||||
|
gboolean in_alsoreq = FALSE;
|
||||||
|
|
||||||
|
g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);
|
||||||
|
|
||||||
|
lines = g_strsplit_set (orig_contents, "\n\r", 0);
|
||||||
|
for (line = lines; lines && *line; line++) {
|
||||||
|
char *p = *line;
|
||||||
|
|
||||||
|
if (!strlen (g_strstrip (p)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Override config file "dhcp-client-id" and use one from the
|
||||||
|
* connection.
|
||||||
|
*/
|
||||||
|
if ( s_ip4
|
||||||
|
&& nm_setting_ip4_config_get_dhcp_client_id (s_ip4)
|
||||||
|
&& !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Override config file hostname and use one from the connection */
|
||||||
|
if (hostname && !strncmp (p, HOSTNAME_TAG, strlen (HOSTNAME_TAG)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check for "also require" */
|
||||||
|
if (!strncmp (p, ALSOREQ_TAG, strlen (ALSOREQ_TAG))) {
|
||||||
|
in_alsoreq = TRUE;
|
||||||
|
p += strlen (ALSOREQ_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_alsoreq) {
|
||||||
|
char **areq, **aiter;
|
||||||
|
|
||||||
|
/* Grab each 'also require' option and save for later */
|
||||||
|
areq = g_strsplit_set (p, "\t ,", -1);
|
||||||
|
for (aiter = areq; aiter && *aiter; aiter++) {
|
||||||
|
if (!strlen (g_strstrip (*aiter)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (*aiter[0] == ';') {
|
||||||
|
/* all done */
|
||||||
|
in_alsoreq = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isalnum ((*aiter)[0]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((*aiter)[strlen (*aiter) - 1] == ';') {
|
||||||
|
/* Remove the EOL marker */
|
||||||
|
(*aiter)[strlen (*aiter) - 1] = '\0';
|
||||||
|
in_alsoreq = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_also_request (alsoreq, *aiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areq)
|
||||||
|
g_strfreev (areq);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Existing configuration line is OK, add it to new configuration */
|
||||||
|
g_string_append (new_contents, *line);
|
||||||
|
g_string_append_c (new_contents, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines)
|
||||||
|
g_strfreev (lines);
|
||||||
|
} else
|
||||||
|
g_string_append_c (new_contents, '\n');
|
||||||
|
|
||||||
|
/* Add NM options from connection */
|
||||||
|
if (s_ip4) {
|
||||||
|
const char *tmp;
|
||||||
|
gboolean added = FALSE;
|
||||||
|
|
||||||
|
tmp = nm_setting_ip4_config_get_dhcp_client_id (s_ip4);
|
||||||
|
if (tmp) {
|
||||||
|
gboolean is_octets = TRUE;
|
||||||
|
const char *p = tmp;
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
|
if (!isxdigit (*p) && (*p != ':')) {
|
||||||
|
is_octets = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (new_contents, CLIENTID_FORMAT_OCTETS "\n", tmp);
|
||||||
|
else
|
||||||
|
g_string_append_printf (new_contents, CLIENTID_FORMAT "\n", tmp);
|
||||||
|
added = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostname) {
|
||||||
|
g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", hostname);
|
||||||
|
added = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added)
|
||||||
|
g_string_append_c (new_contents, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define options for classless static routes */
|
||||||
|
g_string_append (new_contents,
|
||||||
|
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n");
|
||||||
|
g_string_append (new_contents,
|
||||||
|
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n");
|
||||||
|
|
||||||
|
g_string_append_c (new_contents, '\n');
|
||||||
|
|
||||||
|
/* Everything we want to request from the DHCP server */
|
||||||
|
add_also_request (alsoreq, "rfc3442-classless-static-routes");
|
||||||
|
add_also_request (alsoreq, "ms-classless-static-routes");
|
||||||
|
add_also_request (alsoreq, "ntp-servers");
|
||||||
|
|
||||||
|
/* And add it to the dhclient configuration */
|
||||||
|
for (i = 0; i < alsoreq->len; i++) {
|
||||||
|
char *t = g_ptr_array_index (alsoreq, i);
|
||||||
|
|
||||||
|
g_string_append_printf (new_contents, "also request %s;\n", t);
|
||||||
|
g_free (t);
|
||||||
|
}
|
||||||
|
g_ptr_array_free (alsoreq, TRUE);
|
||||||
|
|
||||||
|
g_string_append_c (new_contents, '\n');
|
||||||
|
|
||||||
|
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"
|
||||||
|
"}\n",
|
||||||
|
interface,
|
||||||
|
anycast_addr[0], anycast_addr[1],
|
||||||
|
anycast_addr[2], anycast_addr[3],
|
||||||
|
anycast_addr[4], anycast_addr[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_string_free (new_contents, FALSE);
|
||||||
|
}
|
||||||
|
|
35
src/dhcp-manager/nm-dhcp-dhclient-utils.h
Normal file
35
src/dhcp-manager/nm-dhcp-dhclient-utils.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NM_DHCP_DHCLIENT_UTILS_H
|
||||||
|
#define NM_DHCP_DHCLIENT_UTILS_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <nm-setting-ip4-config.h>
|
||||||
|
|
||||||
|
char *nm_dhcp_dhclient_create_config (const char *interface,
|
||||||
|
NMSettingIP4Config *s_ip4,
|
||||||
|
guint8 *anycast_addr,
|
||||||
|
const char *hostname,
|
||||||
|
const char *orig_path,
|
||||||
|
const char *orig_contents);
|
||||||
|
|
||||||
|
#endif /* NM_DHCP_DHCLIENT_UTILS_H */
|
||||||
|
|
@@ -39,6 +39,7 @@
|
|||||||
#include "nm-dhcp-dhclient.h"
|
#include "nm-dhcp-dhclient.h"
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "nm-logging.h"
|
#include "nm-logging.h"
|
||||||
|
#include "nm-dhcp-dhclient-utils.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
|
G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
|
||||||
|
|
||||||
@@ -302,12 +303,6 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define DHCP_CLIENT_ID_TAG "send dhcp-client-identifier"
|
|
||||||
#define DHCP_CLIENT_ID_FORMAT DHCP_CLIENT_ID_TAG " \"%s\"; # added by NetworkManager"
|
|
||||||
#define DHCP_CLIENT_ID_FORMAT_OCTETS DHCP_CLIENT_ID_TAG " %s; # added by NetworkManager"
|
|
||||||
|
|
||||||
#define DHCP_HOSTNAME_TAG "send host-name"
|
|
||||||
#define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager"
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
merge_dhclient_config (const char *iface,
|
merge_dhclient_config (const char *iface,
|
||||||
@@ -318,105 +313,27 @@ merge_dhclient_config (const char *iface,
|
|||||||
const char *orig_path,
|
const char *orig_path,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GString *new_contents;
|
char *orig = NULL, *new;
|
||||||
char *orig_contents = NULL;
|
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
|
|
||||||
g_return_val_if_fail (iface != NULL, FALSE);
|
g_return_val_if_fail (iface != NULL, FALSE);
|
||||||
g_return_val_if_fail (conf_file != NULL, FALSE);
|
g_return_val_if_fail (conf_file != NULL, FALSE);
|
||||||
|
|
||||||
new_contents = g_string_new (_("# Created by NetworkManager\n"));
|
|
||||||
|
|
||||||
if (g_file_test (orig_path, G_FILE_TEST_EXISTS)) {
|
if (g_file_test (orig_path, G_FILE_TEST_EXISTS)) {
|
||||||
GError *read_error = NULL;
|
GError *read_error = NULL;
|
||||||
|
|
||||||
if (!g_file_get_contents (orig_path, &orig_contents, NULL, &read_error)) {
|
if (!g_file_get_contents (orig_path, &orig, NULL, &read_error)) {
|
||||||
nm_log_warn (LOGD_DHCP, "(%s): error reading dhclient configuration %s: %s",
|
nm_log_warn (LOGD_DHCP, "(%s): error reading dhclient configuration %s: %s",
|
||||||
iface, orig_path, read_error->message);
|
iface, orig_path, read_error->message);
|
||||||
g_error_free (read_error);
|
g_error_free (read_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add existing options, if any, but ignore stuff NM will replace. */
|
new = nm_dhcp_dhclient_create_config (iface, s_ip4, anycast_addr, hostname, orig_path, orig);
|
||||||
if (orig_contents) {
|
g_assert (new);
|
||||||
char **lines = NULL, **line;
|
success = g_file_set_contents (conf_file, new, -1, error);
|
||||||
|
g_free (new);
|
||||||
|
|
||||||
g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);
|
|
||||||
|
|
||||||
lines = g_strsplit_set (orig_contents, "\n\r", 0);
|
|
||||||
for (line = lines; lines && *line; line++) {
|
|
||||||
gboolean ignore = FALSE;
|
|
||||||
|
|
||||||
if (!strlen (g_strstrip (*line)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( s_ip4
|
|
||||||
&& nm_setting_ip4_config_get_dhcp_client_id (s_ip4)
|
|
||||||
&& !strncmp (*line, DHCP_CLIENT_ID_TAG, strlen (DHCP_CLIENT_ID_TAG)))
|
|
||||||
ignore = TRUE;
|
|
||||||
|
|
||||||
if ( s_ip4
|
|
||||||
&& hostname
|
|
||||||
&& !strncmp (*line, DHCP_HOSTNAME_TAG, strlen (DHCP_HOSTNAME_TAG)))
|
|
||||||
ignore = TRUE;
|
|
||||||
|
|
||||||
if (!ignore) {
|
|
||||||
g_string_append (new_contents, *line);
|
|
||||||
g_string_append_c (new_contents, '\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines)
|
|
||||||
g_strfreev (lines);
|
|
||||||
g_free (orig_contents);
|
|
||||||
} else
|
|
||||||
g_string_append_c (new_contents, '\n');
|
|
||||||
|
|
||||||
/* Add NM options from connection */
|
|
||||||
if (s_ip4) {
|
|
||||||
const char *tmp;
|
|
||||||
|
|
||||||
tmp = nm_setting_ip4_config_get_dhcp_client_id (s_ip4);
|
|
||||||
if (tmp) {
|
|
||||||
gboolean is_octets = TRUE;
|
|
||||||
const char *p = tmp;
|
|
||||||
|
|
||||||
while (*p) {
|
|
||||||
if (!isxdigit (*p) && (*p != ':')) {
|
|
||||||
is_octets = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 (new_contents, DHCP_CLIENT_ID_FORMAT_OCTETS "\n", tmp);
|
|
||||||
else
|
|
||||||
g_string_append_printf (new_contents, DHCP_CLIENT_ID_FORMAT "\n", tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostname)
|
|
||||||
g_string_append_printf (new_contents, DHCP_HOSTNAME_FORMAT "\n", hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
"}\n",
|
|
||||||
iface,
|
|
||||||
anycast_addr[0], anycast_addr[1],
|
|
||||||
anycast_addr[2], anycast_addr[3],
|
|
||||||
anycast_addr[4], anycast_addr[5]);
|
|
||||||
}
|
|
||||||
|
|
||||||
success = g_file_set_contents (conf_file, new_contents->str, -1, error);
|
|
||||||
|
|
||||||
g_string_free (new_contents, TRUE);
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
src/dhcp-manager/tests/Makefile.am
Normal file
28
src/dhcp-manager/tests/Makefile.am
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
INCLUDES = \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I${top_srcdir}/libnm-util \
|
||||||
|
-I$(top_srcdir)/src/dhcp-manager
|
||||||
|
|
||||||
|
noinst_PROGRAMS = test-dhcp-dhclient
|
||||||
|
|
||||||
|
####### policy /etc/hosts test #######
|
||||||
|
|
||||||
|
test_dhcp_dhclient_SOURCES = \
|
||||||
|
test-dhcp-dhclient.c
|
||||||
|
|
||||||
|
test_dhcp_dhclient_CPPFLAGS = \
|
||||||
|
$(GLIB_CFLAGS)
|
||||||
|
|
||||||
|
test_dhcp_dhclient_LDADD = \
|
||||||
|
-ldl \
|
||||||
|
$(top_builddir)/src/dhcp-manager/libdhcp-dhclient.la \
|
||||||
|
$(top_builddir)/libnm-util/libnm-util.la \
|
||||||
|
$(GLIB_LIBS)
|
||||||
|
|
||||||
|
if WITH_TESTS
|
||||||
|
|
||||||
|
check-local: test-dhcp-dhclient
|
||||||
|
$(abs_builddir)/test-dhcp-dhclient
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
203
src/dhcp-manager/tests/test-dhcp-dhclient.c
Normal file
203
src/dhcp-manager/tests/test-dhcp-dhclient.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "nm-dhcp-dhclient-utils.h"
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_config (const char *orig,
|
||||||
|
const char *expected,
|
||||||
|
const char *hostname,
|
||||||
|
const char *dhcp_client_id,
|
||||||
|
const char *iface,
|
||||||
|
guint8 *anycast_addr)
|
||||||
|
{
|
||||||
|
NMSettingIP4Config *s_ip4;
|
||||||
|
char *new;
|
||||||
|
|
||||||
|
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||||
|
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, dhcp_client_id, NULL);
|
||||||
|
|
||||||
|
new = nm_dhcp_dhclient_create_config (iface,
|
||||||
|
s_ip4,
|
||||||
|
anycast_addr,
|
||||||
|
hostname,
|
||||||
|
"/path/to/dhclient.conf",
|
||||||
|
orig);
|
||||||
|
g_assert (new != NULL);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
g_message ("\n- NEW ---------------------------------\n"
|
||||||
|
"%s"
|
||||||
|
"+ EXPECTED ++++++++++++++++++++++++++++++\n"
|
||||||
|
"%s"
|
||||||
|
"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
||||||
|
new, expected);
|
||||||
|
#endif
|
||||||
|
g_assert (strlen (new) == strlen (expected));
|
||||||
|
g_assert (strcmp (new, expected) == 0);
|
||||||
|
g_free (new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *orig_missing_expected = \
|
||||||
|
"# Created by NetworkManager\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"
|
||||||
|
"\n"
|
||||||
|
"also request rfc3442-classless-static-routes;\n"
|
||||||
|
"also request ms-classless-static-routes;\n"
|
||||||
|
"also request ntp-servers;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_orig_missing (void)
|
||||||
|
{
|
||||||
|
test_config (NULL, orig_missing_expected,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *override_client_id_orig = \
|
||||||
|
"send dhcp-client-identifier 00:30:04:20:7A:08;\n";
|
||||||
|
|
||||||
|
static const char *override_client_id_expected = \
|
||||||
|
"# Created by NetworkManager\n"
|
||||||
|
"# Merged from /path/to/dhclient.conf\n"
|
||||||
|
"\n"
|
||||||
|
"send dhcp-client-identifier 11:22:33:44:55:66; # added by NetworkManager\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"
|
||||||
|
"\n"
|
||||||
|
"also request rfc3442-classless-static-routes;\n"
|
||||||
|
"also request ms-classless-static-routes;\n"
|
||||||
|
"also request ntp-servers;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_override_client_id (void)
|
||||||
|
{
|
||||||
|
test_config (override_client_id_orig, override_client_id_expected,
|
||||||
|
NULL,
|
||||||
|
"11:22:33:44:55:66",
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *override_hostname_orig = \
|
||||||
|
"send host-name \"foobar\";\n";
|
||||||
|
|
||||||
|
static const char *override_hostname_expected = \
|
||||||
|
"# Created by NetworkManager\n"
|
||||||
|
"# Merged from /path/to/dhclient.conf\n"
|
||||||
|
"\n"
|
||||||
|
"send host-name \"blahblah\"; # added by NetworkManager\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"
|
||||||
|
"\n"
|
||||||
|
"also request rfc3442-classless-static-routes;\n"
|
||||||
|
"also request ms-classless-static-routes;\n"
|
||||||
|
"also request ntp-servers;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_override_hostname (void)
|
||||||
|
{
|
||||||
|
test_config (override_hostname_orig, override_hostname_expected,
|
||||||
|
"blahblah",
|
||||||
|
NULL,
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *existing_alsoreq_orig = \
|
||||||
|
"also request something;\n"
|
||||||
|
"also request another-thing;\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
static const char *existing_alsoreq_expected = \
|
||||||
|
"# Created by NetworkManager\n"
|
||||||
|
"# Merged from /path/to/dhclient.conf\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"
|
||||||
|
"\n"
|
||||||
|
"also request something;\n"
|
||||||
|
"also request another-thing;\n"
|
||||||
|
"also request rfc3442-classless-static-routes;\n"
|
||||||
|
"also request ms-classless-static-routes;\n"
|
||||||
|
"also request ntp-servers;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_existing_alsoreq (void)
|
||||||
|
{
|
||||||
|
test_config (existing_alsoreq_orig, existing_alsoreq_expected,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2,25,12)
|
||||||
|
typedef GTestFixtureFunc TCFunc;
|
||||||
|
#else
|
||||||
|
typedef void (*TCFunc)(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL)
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
GTestSuite *suite;
|
||||||
|
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_type_init ();
|
||||||
|
|
||||||
|
suite = g_test_get_root ();
|
||||||
|
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_orig_missing, NULL));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_override_client_id, NULL));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_override_hostname, NULL));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_existing_alsoreq, NULL));
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user