summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-05-06 14:07:21 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-07-22 13:52:46 +0200
commitc41fe4c659c06aba39dd31c4fe7e39cc7d1ddc3d (patch)
treeddcb45187796169e11d05b4dc97ad6dddecec28b
parent75f0c7949420d913e2f14c9b71a4342a2c17dcd0 (diff)
downloadNetworkManager-c41fe4c659c06aba39dd31c4fe7e39cc7d1ddc3d.tar.gz
dhcp: detect NMIP4Config 'metered' flag based on ANDROID_METERED DHCP option
Some versions of Android's DHCP server send option 43 (Vendor specific information) with value "ANDROID_METERED" in Wi-Fi hotspot mode. Mark the NMIP4Config as metered when such option is received. (cherry picked from commit 1e39b2320dfe42ca33dfbf12746d63935818ac5a)
-rw-r--r--src/dhcp-manager/nm-dhcp-systemd.c7
-rw-r--r--src/dhcp-manager/nm-dhcp-utils.c3
-rw-r--r--src/dhcp-manager/tests/test-dhcp-utils.c25
3 files changed, 35 insertions, 0 deletions
diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c
index 12dc03cc84..2bd0d72ffc 100644
--- a/src/dhcp-manager/nm-dhcp-systemd.c
+++ b/src/dhcp-manager/nm-dhcp-systemd.c
@@ -224,6 +224,8 @@ lease_to_ip4_config (sd_dhcp_lease *lease,
guint16 mtu;
int r, num;
guint64 end_time;
+ uint8_t *data;
+ gboolean metered = FALSE;
g_return_val_if_fail (lease != NULL, NULL);
@@ -355,6 +357,11 @@ lease_to_ip4_config (sd_dhcp_lease *lease,
g_string_free (l, TRUE);
}
+ num = sd_dhcp_lease_get_vendor_specific (lease, &data);
+ if (num > 0)
+ metered = !!memmem (data, num, "ANDROID_METERED", STRLEN ("ANDROID_METERED"));
+ nm_ip4_config_set_metered (ip4_config, metered);
+
return ip4_config;
}
diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c
index 8cd4359abb..ab7f26d5fa 100644
--- a/src/dhcp-manager/nm-dhcp-utils.c
+++ b/src/dhcp-manager/nm-dhcp-utils.c
@@ -575,6 +575,9 @@ nm_dhcp_utils_ip4_config_from_options (const char *iface,
g_strfreev (nis);
}
+ str = g_hash_table_lookup (options, "vendor_encapsulated_options");
+ nm_ip4_config_set_metered (ip4_config, str && strstr (str, "ANDROID_METERED"));
+
return ip4_config;
error:
diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c
index 53688a5b1b..e022a1ae74 100644
--- a/src/dhcp-manager/tests/test-dhcp-utils.c
+++ b/src/dhcp-manager/tests/test-dhcp-utils.c
@@ -176,6 +176,30 @@ test_wins_options (void)
}
static void
+test_vendor_option_metered (void)
+{
+ GHashTable *options;
+ NMIP4Config *ip4_config;
+ static const Option data[] = {
+ { "vendor_encapsulated_options", "ANDROID_METERED" },
+ { NULL, NULL }
+ };
+
+ options = fill_table (generic_options, NULL);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0);
+ g_assert (ip4_config);
+ g_assert (nm_ip4_config_get_metered (ip4_config) == FALSE);
+ g_hash_table_destroy (options);
+
+ options = fill_table (generic_options, NULL);
+ options = fill_table (data, options);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0);
+ g_assert (ip4_config);
+ 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,
@@ -716,6 +740,7 @@ int main (int argc, char **argv)
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 ();
}