Files
NetworkManager/src/dhcp/tests/test-dhcp-utils.c
Thomas Haller 89385bd968 core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.

For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.

The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-07-05 14:22:10 +02:00

745 lines
25 KiB
C

/* -*- 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) 2008 - 2014 Red Hat, Inc.
*
*/
#include "nm-default.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "nm-utils/nm-dedup-multi.h"
#include "nm-utils.h"
#include "dhcp/nm-dhcp-utils.h"
#include "platform/nm-platform.h"
#include "nm-test-utils-core.h"
static NMIP4Config *
_ip4_config_from_options (int ifindex,
const char *iface,
GHashTable *options,
guint32 priority)
{
nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new ();
NMIP4Config *config;
config = nm_dhcp_utils_ip4_config_from_options (multi_idx, ifindex, iface, options, priority);
g_assert (config);
return config;
}
typedef struct {
const char *name;
const char *value;
} Option;
static GHashTable *
fill_table (const Option *test_options, GHashTable *table)
{
const Option *opt;
if (!table)
table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
for (opt = test_options; opt->name; opt++)
g_hash_table_insert (table, (gpointer) opt->name, (gpointer) opt->value);
return table;
}
static const Option generic_options[] = {
{ "subnet_mask", "255.255.255.0" },
{ "ip_address", "192.168.1.106" },
{ "network_number", "192.168.1.0" },
{ "expiry", "1232324877" },
{ "dhcp_lease_time", "3600" },
{ "dhcp_server_identifier", "192.168.1.1" },
{ "routers", "192.168.1.1" },
{ "domain_name_servers", "216.254.95.2 216.231.41.2" },
{ "dhcp_message_type", "5" },
{ "broadcast_address", "192.168.1.255" },
{ "domain_search", "foobar.com blah.foobar.com" },
{ "host_name", "nmreallywhipsthe" },
{ "domain_name", "lamasass.com" },
{ "interface_mtu", "987" },
{ "static_routes", "10.1.1.5 10.1.1.1 100.99.88.56 10.1.1.1" },
{ NULL, NULL }
};
static void
test_generic_options (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const NMPlatformIP4Address *address;
const NMPlatformIP4Route *route;
guint32 tmp;
const char *expected_addr = "192.168.1.106";
const char *expected_gw = "192.168.1.1";
const char *expected_dns1 = "216.254.95.2";
const char *expected_dns2 = "216.231.41.2";
const char *expected_search1 = "foobar.com";
const char *expected_search2 = "blah.foobar.com";
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
options = fill_table (generic_options, NULL);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 address */
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
address = nm_ip4_config_get_address (ip4_config, 0);
g_assert (inet_pton (AF_INET, expected_addr, &tmp) > 0);
g_assert (address->address == tmp);
g_assert (address->peer_address == tmp);
g_assert_cmpint (address->plen, ==, 24);
/* Gateway */
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp);
g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 0);
g_assert_cmpint (nm_ip4_config_get_mtu (ip4_config), ==, 987);
/* Domain searches */
g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 2);
g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 0), ==, expected_search1);
g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 1), ==, expected_search2);
/* DNS servers */
g_assert_cmpint (nm_ip4_config_get_num_nameservers (ip4_config), ==, 2);
g_assert (inet_pton (AF_INET, expected_dns1, &tmp) > 0);
g_assert (nm_ip4_config_get_nameserver (ip4_config, 0) == tmp);
g_assert (inet_pton (AF_INET, expected_dns2, &tmp) > 0);
g_assert (nm_ip4_config_get_nameserver (ip4_config, 1) == tmp);
/* Routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
g_assert (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0);
g_assert (route->gateway == tmp);
g_assert_cmpint (route->plen, ==, 32);
g_assert_cmpint (route->metric, ==, 0);
/* Route #2 */
route = nm_ip4_config_get_route (ip4_config, 1);
g_assert (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0);
g_assert (route->gateway == tmp);
g_assert_cmpint (route->plen, ==, 32);
g_assert_cmpint (route->metric, ==, 0);
g_hash_table_destroy (options);
}
static void
test_wins_options (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const NMPlatformIP4Address *address;
guint32 tmp;
const char *expected_wins1 = "63.12.199.5";
const char *expected_wins2 = "150.4.88.120";
static const Option data[] = {
{ "netbios_name_servers", "63.12.199.5 150.4.88.120" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 address */
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
address = nm_ip4_config_get_address (ip4_config, 0);
g_assert (address);
g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 2);
g_assert (inet_pton (AF_INET, expected_wins1, &tmp) > 0);
g_assert (nm_ip4_config_get_wins (ip4_config, 0) == tmp);
g_assert (inet_pton (AF_INET, expected_wins2, &tmp) > 0);
g_assert (nm_ip4_config_get_wins (ip4_config, 1) == tmp);
g_hash_table_destroy (options);
}
static void
test_vendor_option_metered (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
static const Option data[] = {
{ "vendor_encapsulated_options", "ANDROID_METERED" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_assert (nm_ip4_config_get_metered (ip4_config) == FALSE);
g_hash_table_destroy (options);
g_clear_object (&ip4_config);
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_assert (nm_ip4_config_get_metered (ip4_config) == TRUE);
g_hash_table_destroy (options);
}
static void
ip4_test_route (NMIP4Config *ip4_config,
guint route_num,
const char *expected_dest,
const char *expected_gw,
guint expected_prefix)
{
const NMPlatformIP4Route *route;
guint32 tmp;
g_assert (expected_prefix <= 32);
route = nm_ip4_config_get_route (ip4_config, route_num);
g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
g_assert (route->gateway == tmp);
g_assert_cmpint (route->plen, ==, expected_prefix);
g_assert_cmpint (route->metric, ==, 0);
}
static void
ip4_test_gateway (NMIP4Config *ip4_config, const char *expected_gw)
{
guint32 tmp;
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp);
}
static void
test_classless_static_routes_1 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_route2_dest = "10.0.0.0";
const char *expected_route2_gw = "10.17.66.41";
static const Option data[] = {
/* dhclient custom format */
{ "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
g_hash_table_destroy (options);
}
static void
test_classless_static_routes_2 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_route2_dest = "10.0.0.0";
const char *expected_route2_gw = "10.17.66.41";
static const Option data[] = {
/* dhcpcd format */
{ "classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
g_hash_table_destroy (options);
}
static void
test_fedora_dhclient_classless_static_routes (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "129.210.177.128";
const char *expected_route1_gw = "192.168.0.113";
const char *expected_route2_dest = "2.0.0.0";
const char *expected_route2_gw = "10.34.255.6";
const char *expected_gateway = "192.168.0.113";
static const Option data[] = {
/* Fedora dhclient format */
{ "classless_static_routes", "0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 25);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 7);
/* Gateway */
ip4_test_gateway (ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
static void
test_dhclient_invalid_classless_routes_1 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static const Option data[] = {
/* dhclient format */
{ "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_1 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static const Option data[] = {
/* dhcpcd format */
{ "classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static void
test_dhclient_invalid_classless_routes_2 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static const Option data[] = {
{ "rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_2 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static const Option data[] = {
{ "classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
/* Routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static void
test_dhclient_invalid_classless_routes_3 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static const Option data[] = {
{ "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_3 (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static Option data[] = {
{ "classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*DHCP provided invalid classless static route*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static void
test_dhclient_gw_in_classless_routes (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_gateway = "192.2.3.4";
static Option data[] = {
{ "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
/* Gateway */
ip4_test_gateway (ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_gw_in_classless_routes (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_gateway = "192.2.3.4";
static Option data[] = {
{ "classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* IP4 routes */
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
/* Gateway */
ip4_test_gateway (ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
static void
test_escaped_domain_searches (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const char *expected_search0 = "host1";
const char *expected_search1 = "host2";
const char *expected_search2 = "host3";
static const Option data[] = {
{ "domain_search", "host1\\032host2\\032host3" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
/* domain searches */
g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 3);
g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 0), ==, expected_search0);
g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 1), ==, expected_search1);
g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 2), ==, expected_search2);
g_hash_table_destroy (options);
}
static void
test_invalid_escaped_domain_searches (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
static const Option data[] = {
{ "domain_search", "host1\\aahost2\\032host3" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*invalid domain search*");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_test_assert_expected_messages ();
/* domain searches */
g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 0);
g_hash_table_destroy (options);
}
static void
test_ip4_missing_prefix (const char *ip, guint32 expected_prefix)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const NMPlatformIP4Address *address;
options = fill_table (generic_options, NULL);
g_hash_table_insert (options, "ip_address", (gpointer) ip);
g_hash_table_remove (options, "subnet_mask");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
address = nm_ip4_config_get_address (ip4_config, 0);
g_assert (address);
g_assert_cmpint (address->plen, ==, expected_prefix);
g_hash_table_destroy (options);
}
static void
test_ip4_missing_prefix_24 (void)
{
test_ip4_missing_prefix ("192.168.1.10", 24);
}
static void
test_ip4_missing_prefix_16 (void)
{
test_ip4_missing_prefix ("172.16.54.50", 16);
}
static void
test_ip4_missing_prefix_8 (void)
{
test_ip4_missing_prefix ("10.1.2.3", 8);
}
static void
test_ip4_prefix_classless (void)
{
GHashTable *options;
gs_unref_object NMIP4Config *ip4_config = NULL;
const NMPlatformIP4Address *address;
/* Ensure that the missing-subnet-mask handler doesn't mangle classless
* subnet masks at all. The handler should trigger only if the server
* doesn't send the subnet mask.
*/
options = fill_table (generic_options, NULL);
g_hash_table_insert (options, "ip_address", "172.16.54.22");
g_hash_table_insert (options, "subnet_mask", "255.255.252.0");
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
address = nm_ip4_config_get_address (ip4_config, 0);
g_assert (address);
g_assert_cmpint (address->plen, ==, 22);
g_hash_table_destroy (options);
}
#define COMPARE_ID(src, is_str, expected, expected_len) \
G_STMT_START { \
gs_unref_bytes GBytes *b = NULL; \
const char *p; \
gsize l; \
\
b = nm_dhcp_utils_client_id_string_to_bytes (src); \
g_assert (b); \
p = g_bytes_get_data (b, &l); \
if (is_str) { \
g_assert_cmpint (l, ==, expected_len + 1); \
g_assert_cmpint (((const char *) p)[0], ==, 0); \
g_assert (memcmp (p + 1, expected, expected_len) == 0); \
} else { \
g_assert_cmpint (l, ==, expected_len); \
g_assert (memcmp (p, expected, expected_len) == 0); \
} \
} G_STMT_END
static void
test_client_id_from_string (void)
{
const char *nothex = "asdfasdfasdfasdfasdfasdfasdf";
const char *allhex = "00:11:22:33:4:55:66:77:88";
const guint8 allhex_bin[] = { 0x00, 0x11, 0x22, 0x33, 0x04, 0x55, 0x66, 0x77, 0x88 };
const char *somehex = "00:11:22:33:44:55:asdfasdfasdf:99:10";
const char *nocolons = "0011223344559910";
const char *endcolon = "00:11:22:33:44:55:";
COMPARE_ID (nothex, TRUE, nothex, strlen (nothex));
COMPARE_ID (allhex, FALSE, allhex_bin, sizeof (allhex_bin));
COMPARE_ID (somehex, TRUE, somehex, strlen (somehex));
COMPARE_ID (nocolons, TRUE, nocolons, strlen (nocolons));
COMPARE_ID (endcolon, TRUE, endcolon, strlen (endcolon));
}
NMTST_DEFINE ();
int main (int argc, char **argv)
{
nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT");
g_test_add_func ("/dhcp/generic-options", test_generic_options);
g_test_add_func ("/dhcp/wins-options", test_wins_options);
g_test_add_func ("/dhcp/classless-static-routes-1", test_classless_static_routes_1);
g_test_add_func ("/dhcp/classless-static-routes-2", test_classless_static_routes_2);
g_test_add_func ("/dhcp/fedora-dhclient-classless-static-routes", test_fedora_dhclient_classless_static_routes);
g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-1", test_dhclient_invalid_classless_routes_1);
g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-1", test_dhcpcd_invalid_classless_routes_1);
g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-2", test_dhclient_invalid_classless_routes_2);
g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-2", test_dhcpcd_invalid_classless_routes_2);
g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-3", test_dhclient_invalid_classless_routes_3);
g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-3", test_dhcpcd_invalid_classless_routes_3);
g_test_add_func ("/dhcp/dhclient-gw-in-classless-routes", test_dhclient_gw_in_classless_routes);
g_test_add_func ("/dhcp/dhcpcd-gw-in-classless-routes", test_dhcpcd_gw_in_classless_routes);
g_test_add_func ("/dhcp/escaped-domain-searches", test_escaped_domain_searches);
g_test_add_func ("/dhcp/invalid-escaped-domain-searches", test_invalid_escaped_domain_searches);
g_test_add_func ("/dhcp/ip4-missing-prefix-24", test_ip4_missing_prefix_24);
g_test_add_func ("/dhcp/ip4-missing-prefix-16", test_ip4_missing_prefix_16);
g_test_add_func ("/dhcp/ip4-missing-prefix-8", test_ip4_missing_prefix_8);
g_test_add_func ("/dhcp/ip4-prefix-classless", test_ip4_prefix_classless);
g_test_add_func ("/dhcp/client-id-from-string", test_client_id_from_string);
g_test_add_func ("/dhcp/vendor-option-metered", test_vendor_option_metered);
return g_test_run ();
}