diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-05-06 14:07:21 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-06-04 17:32:01 +0200 |
commit | 695a4ccf1684eb9892a96d8e721d8ccea02ef3ca (patch) | |
tree | 99972c23bb2efdf54242d65ceda6f3451809d40f | |
parent | 22eb15ba83ca90b46bbcead84f276ba6ecfcf0a5 (diff) | |
download | NetworkManager-695a4ccf1684eb9892a96d8e721d8ccea02ef3ca.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.
-rw-r--r-- | src/dhcp-manager/nm-dhcp-systemd.c | 7 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-utils.c | 3 | ||||
-rw-r--r-- | src/dhcp-manager/tests/test-dhcp-utils.c | 25 |
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 de5bf2a9be..05de2b340b 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -226,6 +226,8 @@ lease_to_ip4_config (const char *iface, guint16 mtu; int r, num; guint64 end_time; + uint8_t *data; + gboolean metered = FALSE; g_return_val_if_fail (lease != NULL, NULL); @@ -357,6 +359,11 @@ lease_to_ip4_config (const char *iface, 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 e50b4e3b8b..4dde1a4454 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -576,6 +576,9 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, 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 286c1d7476..3cdae732a7 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 (1, "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 (1, "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 (); } |