static void test_wins_options (void) { GHashTable *options; NMIP4Config *ip4_config; NMIP4Address *addr; struct in_addr tmp; const char *expected_wins1 = "63.12.199.5"; const char *expected_wins2 = "150.4.88.120"; options = fill_table (generic_options, NULL); options = fill_table (wins_options, options); ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ASSERT (ip4_config != NULL, "dhcp-wins", "failed to parse DHCP4 options"); /* IP4 address */ ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, "dhcp-wins", "unexpected number of IP addresses"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (nm_ip4_config_get_num_wins (ip4_config) == 2, "dhcp-wins", "unexpected number of WINS servers"); ASSERT (inet_pton (AF_INET, expected_wins1, &tmp) > 0, "dhcp-wins", "couldn't convert expected WINS server address #1"); ASSERT (nm_ip4_config_get_wins (ip4_config, 0) == tmp.s_addr, "dhcp-wins", "unexpected WINS server #1"); ASSERT (inet_pton (AF_INET, expected_wins2, &tmp) > 0, "dhcp-wins", "couldn't convert expected WINS server address #1"); ASSERT (nm_ip4_config_get_wins (ip4_config, 1) == tmp.s_addr, "dhcp-wins", "unexpected WINS server #1"); g_hash_table_destroy (options); }
static void test_ip4_prefix_classless (const char *client) { GHashTable *options; NMIP4Config *ip4_config; NMIP4Address *addr; /* 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, "new_ip_address", string_to_byte_array_gvalue ("172.16.54.22")); g_hash_table_insert (options, "new_subnet_mask", string_to_byte_array_gvalue ("255.255.252.0")); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); ASSERT (ip4_config != NULL, "dhcp-ip4-prefix-classless", "failed to parse DHCP4 options"); ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, "dhcp-ip4-prefix-classless", "unexpected number of IP4 addresses (not 1)"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (addr != NULL, "dhcp-ip4-prefix-classless", "missing IP4 address #1"); ASSERT (nm_ip4_address_get_prefix (addr) == 22, "dhcp-ip4-prefix-classless", "unexpected IP4 address prefix %d (expected 22)", nm_ip4_address_get_prefix (addr)); g_hash_table_destroy (options); }
static void test_ip4_missing_prefix (const char *client, const char *ip, guint32 expected_prefix) { GHashTable *options; NMIP4Config *ip4_config; NMIP4Address *addr; options = fill_table (generic_options, NULL); g_hash_table_insert (options, "new_ip_address", string_to_byte_array_gvalue (ip)); g_hash_table_remove (options, "new_subnet_mask"); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); ASSERT (ip4_config != NULL, "dhcp-ip4-missing-prefix", "failed to parse DHCP4 options"); ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, "dhcp-ip4-missing-prefix", "unexpected number of IP4 addresses (not 1)"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (addr != NULL, "dhcp-ip4-missing-prefix", "missing IP4 address #1"); ASSERT (nm_ip4_address_get_prefix (addr) == expected_prefix, "dhcp-ip4-missing-prefix", "unexpected IP4 address prefix %d (expected %d)", nm_ip4_address_get_prefix (addr), expected_prefix); g_hash_table_destroy (options); }
void nm_ip4_config_hash (NMIP4Config *config, GChecksum *sum, gboolean dns_only) { guint32 i, n; const char *s; g_return_if_fail (config != NULL); g_return_if_fail (sum != NULL); if (dns_only == FALSE) { for (i = 0; i < nm_ip4_config_get_num_addresses (config); i++) { NMIP4Address *a = nm_ip4_config_get_address (config, i); hash_u32 (sum, nm_ip4_address_get_address (a)); hash_u32 (sum, nm_ip4_address_get_prefix (a)); hash_u32 (sum, nm_ip4_address_get_gateway (a)); } for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) { NMIP4Route *r = nm_ip4_config_get_route (config, i); hash_u32 (sum, nm_ip4_route_get_dest (r)); hash_u32 (sum, nm_ip4_route_get_prefix (r)); hash_u32 (sum, nm_ip4_route_get_next_hop (r)); hash_u32 (sum, nm_ip4_route_get_metric (r)); } n = nm_ip4_config_get_ptp_address (config); if (n) hash_u32 (sum, n); for (i = 0; i < nm_ip4_config_get_num_nis_servers (config); i++) hash_u32 (sum, nm_ip4_config_get_nis_server (config, i)); s = nm_ip4_config_get_nis_domain (config); if (s) g_checksum_update (sum, (const guint8 *) s, strlen (s)); } for (i = 0; i < nm_ip4_config_get_num_nameservers (config); i++) hash_u32 (sum, nm_ip4_config_get_nameserver (config, i)); for (i = 0; i < nm_ip4_config_get_num_wins (config); i++) hash_u32 (sum, nm_ip4_config_get_wins (config, i)); for (i = 0; i < nm_ip4_config_get_num_domains (config); i++) { s = nm_ip4_config_get_domain (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } for (i = 0; i < nm_ip4_config_get_num_searches (config); i++) { s = nm_ip4_config_get_search (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } }
static void test_gateway_in_classless_routes (void) { GHashTable *options; NMIP4Config *ip4_config; NMIP4Address *addr; NMIP4Route *route; struct in_addr tmp; 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"; options = fill_table (generic_options, NULL); options = fill_table (gw_in_classless_routes, options); ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ASSERT (ip4_config != NULL, "dhcp-rfc3442-gateway", "failed to parse DHCP4 options"); /* IP4 routes */ ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, "dhcp-rfc3442-gateway", "unexpected number of IP routes"); /* Route #1 */ route = nm_ip4_config_get_route (ip4_config, 0); ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0, "dhcp-rfc3442-gateway", "couldn't convert expected route destination #1"); ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr, "dhcp-rfc3442-gateway", "unexpected route #1 destination"); ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0, "dhcp-rfc3442-gateway", "couldn't convert expected route next hop #1"); ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr, "dhcp-rfc3442-gateway", "unexpected route #1 next hop"); ASSERT (nm_ip4_route_get_prefix (route) == 24, "dhcp-rfc3442-gateway", "unexpected route #1 prefix"); ASSERT (nm_ip4_route_get_metric (route) == 0, "dhcp-rfc3442-gateway", "unexpected route #1 metric"); /* Address */ ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, "dhcp-rfc3442-gateway", "unexpected number of IP addresses"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (inet_pton (AF_INET, expected_gateway, &tmp) > 0, "dhcp-rfc3442-gateway", "couldn't convert expected IP gateway"); ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr, "dhcp-rfc3442-gateway", "unexpected IP gateway"); g_hash_table_destroy (options); }
static void ip4_test_gateway (const char *test, NMIP4Config *ip4_config, const char *expected_gw) { NMIP4Address *addr; struct in_addr tmp; ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, test, "unexpected number of IP addresses"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0, test, "couldn't convert expected IP gateway"); ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr, test, "unexpected IP gateway"); }
static NMDevice * get_best_ip4_device (NMManager *manager, NMActRequest **out_req) { GSList *devices, *iter; NMDevice *best = NULL; int best_prio = G_MAXINT; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); g_return_val_if_fail (out_req != NULL, NULL); g_return_val_if_fail (*out_req == NULL, NULL); devices = nm_manager_get_devices (manager); for (iter = devices; iter; iter = g_slist_next (iter)) { NMDevice *dev = NM_DEVICE (iter->data); NMActRequest *req; NMConnection *connection; NMIP4Config *ip4_config; NMSettingIP4Config *s_ip4; int prio; guint i; gboolean can_default = FALSE; const char *method = NULL; if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED) continue; ip4_config = nm_device_get_ip4_config (dev); if (!ip4_config) continue; req = nm_device_get_act_request (dev); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); /* Never set the default route through an IPv4LL-addressed device */ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) continue; /* Make sure at least one of this device's IP addresses has a gateway */ for (i = 0; i < nm_ip4_config_get_num_addresses (ip4_config); i++) { NMIP4Address *addr; addr = nm_ip4_config_get_address (ip4_config, i); if (nm_ip4_address_get_gateway (addr)) { can_default = TRUE; break; } } if (!can_default && !NM_IS_DEVICE_MODEM (dev)) continue; /* 'never-default' devices can't ever be the default */ if ( (s_ip4 && nm_setting_ip4_config_get_never_default (s_ip4)) || nm_ip4_config_get_never_default (ip4_config)) continue; prio = nm_device_get_priority (dev); if (prio > 0 && prio < best_prio) { best = dev; best_prio = prio; *out_req = req; } } return best; }
static void update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) { char *configured_hostname = NULL; NMActRequest *best_req4 = NULL; NMActRequest *best_req6 = NULL; const char *dhcp_hostname, *p; g_return_if_fail (policy != NULL); if (policy->lookup) { hostname_thread_kill (policy->lookup); policy->lookup = NULL; } /* Hostname precedence order: * * 1) a configured hostname (from system-settings) * 2) automatic hostname from the default device's config (DHCP, VPN, etc) * 3) the original hostname when NM started * 4) reverse-DNS of the best device's IPv4 address * */ /* Try a persistent hostname first */ g_object_get (G_OBJECT (policy->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL); if (configured_hostname) { _set_hostname (policy, TRUE, configured_hostname, "from system configuration"); g_free (configured_hostname); return; } /* Try automatically determined hostname from the best device's IP config */ if (!best4) best4 = get_best_ip4_device (policy->manager, &best_req4); if (!best6) best6 = get_best_ip6_device (policy->manager, &best_req6); if (!best4 && !best6) { /* No best device; fall back to original hostname or if there wasn't * one, 'localhost.localdomain' */ _set_hostname (policy, TRUE, policy->orig_hostname, "no default device"); return; } if (best4) { NMDHCP4Config *dhcp4_config; /* Grab a hostname out of the device's DHCP4 config */ dhcp4_config = nm_device_get_dhcp4_config (best4); if (dhcp4_config) { p = dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name"); if (dhcp_hostname && strlen (dhcp_hostname)) { /* Sanity check; strip leading spaces */ while (*p) { if (!isblank (*p++)) { _set_hostname (policy, TRUE, dhcp_hostname, "from DHCPv4"); return; } } nm_log_warn (LOGD_DNS, "DHCPv4-provided hostname '%s' looks invalid; ignoring it", dhcp_hostname); } } } else if (best6) { NMDHCP6Config *dhcp6_config; /* Grab a hostname out of the device's DHCP4 config */ dhcp6_config = nm_device_get_dhcp6_config (best6); if (dhcp6_config) { p = dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name"); if (dhcp_hostname && strlen (dhcp_hostname)) { /* Sanity check; strip leading spaces */ while (*p) { if (!isblank (*p++)) { _set_hostname (policy, TRUE, dhcp_hostname, "from DHCPv6"); return; } } nm_log_warn (LOGD_DNS, "DHCPv6-provided hostname '%s' looks invalid; ignoring it", dhcp_hostname); } } } /* If no automatically-configured hostname, try using the hostname from * when NM started up. */ if (policy->orig_hostname) { _set_hostname (policy, TRUE, policy->orig_hostname, "from system startup"); return; } /* No configured hostname, no automatically determined hostname, and no * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address. */ if (best4) { NMIP4Config *ip4_config; NMIP4Address *addr4; ip4_config = nm_device_get_ip4_config (best4); if ( !ip4_config || (nm_ip4_config_get_num_nameservers (ip4_config) == 0) || (nm_ip4_config_get_num_addresses (ip4_config) == 0)) { /* No valid IP4 config (!!); fall back to localhost.localdomain */ _set_hostname (policy, TRUE, NULL, "no IPv4 config"); return; } addr4 = nm_ip4_config_get_address (ip4_config, 0); g_assert (addr4); /* checked for > 1 address above */ /* Start the hostname lookup thread */ policy->lookup = hostname4_thread_new (nm_ip4_address_get_address (addr4), lookup_callback, policy); } else if (best6) { NMIP6Config *ip6_config; NMIP6Address *addr6; ip6_config = nm_device_get_ip6_config (best6); if ( !ip6_config || (nm_ip6_config_get_num_nameservers (ip6_config) == 0) || (nm_ip6_config_get_num_addresses (ip6_config) == 0)) { /* No valid IP6 config (!!); fall back to localhost.localdomain */ _set_hostname (policy, TRUE, NULL, "no IPv6 config"); return; } addr6 = nm_ip6_config_get_address (ip6_config, 0); g_assert (addr6); /* checked for > 1 address above */ /* Start the hostname lookup thread */ policy->lookup = hostname6_thread_new (nm_ip6_address_get_address (addr6), lookup_callback, policy); } if (!policy->lookup) { /* Fall back to 'localhost.localdomain' */ _set_hostname (policy, TRUE, NULL, "error starting hostname thread"); } }
void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) { int i, j; gboolean setting_never_default; if (!setting) return; /* Defaults are just fine */ if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) { nm_ip4_config_reset_nameservers (ip4_config); nm_ip4_config_reset_domains (ip4_config); nm_ip4_config_reset_searches (ip4_config); } if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) nm_ip4_config_reset_routes (ip4_config); for (i = 0; i < nm_setting_ip4_config_get_num_dns (setting); i++) { guint32 ns; gboolean found = FALSE; /* Avoid dupes */ ns = nm_setting_ip4_config_get_dns (setting, i); for (j = 0; j < nm_ip4_config_get_num_nameservers (ip4_config); j++) { if (nm_ip4_config_get_nameserver (ip4_config, j) == ns) { found = TRUE; break; } } if (!found) nm_ip4_config_add_nameserver (ip4_config, ns); } /* DNS search domains */ for (i = 0; i < nm_setting_ip4_config_get_num_dns_searches (setting); i++) { const char *search = nm_setting_ip4_config_get_dns_search (setting, i); gboolean found = FALSE; /* Avoid dupes */ for (j = 0; j < nm_ip4_config_get_num_searches (ip4_config); j++) { if (!strcmp (search, nm_ip4_config_get_search (ip4_config, j))) { found = TRUE; break; } } if (!found) nm_ip4_config_add_search (ip4_config, search); } /* IPv4 addresses */ for (i = 0; i < nm_setting_ip4_config_get_num_addresses (setting); i++) { NMIP4Address *setting_addr = nm_setting_ip4_config_get_address (setting, i); guint32 num; num = nm_ip4_config_get_num_addresses (ip4_config); for (j = 0; j < num; j++) { NMIP4Address *cfg_addr = nm_ip4_config_get_address (ip4_config, j); /* Dupe, override with user-specified address */ if (nm_ip4_address_get_address (cfg_addr) == nm_ip4_address_get_address (setting_addr)) { nm_ip4_config_replace_address (ip4_config, j, setting_addr); break; } } if (j == num) nm_ip4_config_add_address (ip4_config, setting_addr); } /* IPv4 routes */ for (i = 0; i < nm_setting_ip4_config_get_num_routes (setting); i++) { NMIP4Route *setting_route = nm_setting_ip4_config_get_route (setting, i); guint32 num; num = nm_ip4_config_get_num_routes (ip4_config); for (j = 0; j < num; j++) { NMIP4Route *cfg_route = nm_ip4_config_get_route (ip4_config, j); /* Dupe, override with user-specified route */ if ( (nm_ip4_route_get_dest (cfg_route) == nm_ip4_route_get_dest (setting_route)) && (nm_ip4_route_get_prefix (cfg_route) == nm_ip4_route_get_prefix (setting_route)) && (nm_ip4_route_get_next_hop (cfg_route) == nm_ip4_route_get_next_hop (setting_route))) { nm_ip4_config_replace_route (ip4_config, j, setting_route); break; } } if (j == num) nm_ip4_config_add_route (ip4_config, setting_route); } setting_never_default = nm_setting_ip4_config_get_never_default (setting); if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) nm_ip4_config_set_never_default (ip4_config, setting_never_default); else { if (setting_never_default) nm_ip4_config_set_never_default (ip4_config, TRUE); } }
static void dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder) { GVariantBuilder int_builder; guint n, i; const NMPlatformIP4Address *addr; const NMPlatformIP4Route *route; guint32 array[4]; /* Addresses */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau")); n = nm_ip4_config_get_num_addresses (ip4); for (i = 0; i < n; i++) { addr = nm_ip4_config_get_address (ip4, i); array[0] = addr->address; array[1] = addr->plen; array[2] = (i == 0) ? nm_ip4_config_get_gateway (ip4) : 0; g_variant_builder_add (&int_builder, "@au", g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, array, 3, sizeof (guint32))); } g_variant_builder_add (builder, "{sv}", "addresses", g_variant_builder_end (&int_builder)); /* DNS servers */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au")); n = nm_ip4_config_get_num_nameservers (ip4); for (i = 0; i < n; i++) g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_nameserver (ip4, i)); g_variant_builder_add (builder, "{sv}", "nameservers", g_variant_builder_end (&int_builder)); /* Search domains */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as")); n = nm_ip4_config_get_num_domains (ip4); for (i = 0; i < n; i++) g_variant_builder_add (&int_builder, "s", nm_ip4_config_get_domain (ip4, i)); g_variant_builder_add (builder, "{sv}", "domains", g_variant_builder_end (&int_builder)); /* WINS servers */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au")); n = nm_ip4_config_get_num_wins (ip4); for (i = 0; i < n; i++) g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_wins (ip4, i)); g_variant_builder_add (builder, "{sv}", "wins-servers", g_variant_builder_end (&int_builder)); /* Static routes */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau")); n = nm_ip4_config_get_num_routes (ip4); for (i = 0; i < n; i++) { route = nm_ip4_config_get_route (ip4, i); array[0] = route->network; array[1] = route->plen; array[2] = route->gateway; array[3] = route->metric; g_variant_builder_add (&int_builder, "@au", g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, array, 4, sizeof (guint32))); } g_variant_builder_add (builder, "{sv}", "routes", g_variant_builder_end (&int_builder)); }
static void test_generic_options (void) { GHashTable *options; NMIP4Config *ip4_config; NMIP4Address *addr; NMIP4Route *route; struct in_addr 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 = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ASSERT (ip4_config != NULL, "dhcp-generic", "failed to parse DHCP4 options"); /* IP4 address */ ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, "dhcp-generic", "unexpected number of IP addresses"); addr = nm_ip4_config_get_address (ip4_config, 0); ASSERT (inet_pton (AF_INET, expected_addr, &tmp) > 0, "dhcp-generic", "couldn't convert expected IP address"); ASSERT (nm_ip4_address_get_address (addr) == tmp.s_addr, "dhcp-generic", "unexpected IP address"); ASSERT (nm_ip4_address_get_prefix (addr) == 24, "dhcp-generic", "unexpected IP address prefix length"); /* Gateway */ ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0, "dhcp-generic", "couldn't convert expected IP gateway"); ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr, "dhcp-generic", "unexpected IP gateway"); ASSERT (nm_ip4_config_get_ptp_address (ip4_config) == 0, "dhcp-generic", "unexpected PTP address"); ASSERT (nm_ip4_config_get_num_wins (ip4_config) == 0, "dhcp-generic", "unexpected number of WINS servers"); ASSERT (nm_ip4_config_get_mtu (ip4_config) == 987, "dhcp-generic", "unexpected MTU"); /* Domain searches */ ASSERT (nm_ip4_config_get_num_searches (ip4_config) == 2, "dhcp-generic", "unexpected number of domain searches"); ASSERT (strcmp (nm_ip4_config_get_search (ip4_config, 0), expected_search1) == 0, "dhcp-generic", "unexpected domain search #1"); ASSERT (strcmp (nm_ip4_config_get_search (ip4_config, 1), expected_search2) == 0, "dhcp-generic", "unexpected domain search #2"); /* DNS servers */ ASSERT (nm_ip4_config_get_num_nameservers (ip4_config) == 2, "dhcp-generic", "unexpected number of domain name servers"); ASSERT (inet_pton (AF_INET, expected_dns1, &tmp) > 0, "dhcp-generic", "couldn't convert expected DNS server address #1"); ASSERT (nm_ip4_config_get_nameserver (ip4_config, 0) == tmp.s_addr, "dhcp-generic", "unexpected domain name server #1"); ASSERT (inet_pton (AF_INET, expected_dns2, &tmp) > 0, "dhcp-generic", "couldn't convert expected DNS server address #2"); ASSERT (nm_ip4_config_get_nameserver (ip4_config, 1) == tmp.s_addr, "dhcp-generic", "unexpected domain name server #2"); /* Routes */ ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, "dhcp-generic", "unexpected number of routes"); /* Route #1 */ route = nm_ip4_config_get_route (ip4_config, 0); ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0, "dhcp-generic", "couldn't convert expected route destination #1"); ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr, "dhcp-generic", "unexpected route #1 destination"); ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0, "dhcp-generic", "couldn't convert expected route next hop #1"); ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr, "dhcp-generic", "unexpected route #1 next hop"); ASSERT (nm_ip4_route_get_prefix (route) == 32, "dhcp-generic", "unexpected route #1 prefix"); ASSERT (nm_ip4_route_get_metric (route) == 0, "dhcp-generic", "unexpected route #1 metric"); /* Route #2 */ route = nm_ip4_config_get_route (ip4_config, 1); ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0, "dhcp-generic", "couldn't convert expected route destination #2"); ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr, "dhcp-generic", "unexpected route #2 destination"); ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0, "dhcp-generic", "couldn't convert expected route next hop #2"); ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr, "dhcp-generic", "unexpected route #2 next hop"); ASSERT (nm_ip4_route_get_prefix (route) == 32, "dhcp-generic", "unexpected route #2 prefix"); ASSERT (nm_ip4_route_get_metric (route) == 0, "dhcp-generic", "unexpected route #2 metric"); g_hash_table_destroy (options); }