aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2014-11-14 12:32:10 +0100
committerAleksander Morgado <aleksander@aleksander.es>2014-12-03 19:02:00 +0100
commitfd28a4d5cd6139f19f814328bfe860f69c418a25 (patch)
treea64d67a2696dae3a38d4366deb7c532414f1507d
parent71a1b64b3b60527a15dea72d0cc9a2bb31adcf9f (diff)
icera: IPv6 '::' is a placeholder for 'no IPv6', so don't error out if found
Also, allow IPDPADDR returns where only DNS IPv6 is given (i.e. no IPv6 address to set), and in that case default to DHCP method in the bearer. https://bugs.freedesktop.org/show_bug.cgi?id=85012
-rw-r--r--plugins/icera/mm-modem-helpers-icera.c67
-rw-r--r--plugins/icera/tests/test-modem-helpers-icera.c31
2 files changed, 61 insertions, 37 deletions
diff --git a/plugins/icera/mm-modem-helpers-icera.c b/plugins/icera/mm-modem-helpers-icera.c
index f9aa6125..1b64d633 100644
--- a/plugins/icera/mm-modem-helpers-icera.c
+++ b/plugins/icera/mm-modem-helpers-icera.c
@@ -145,43 +145,53 @@ parse_ipdpaddr_v6 (const gchar **items, guint num_items, GError **error)
if (num_items < 12)
return NULL;
+ /* No IPv6 IP and no IPv6 DNS, return NULL without error. */
+ if (g_strcmp0 (items[9], "::") == 0 && g_strcmp0 (items[11], "::") == 0)
+ return NULL;
+
+ config = mm_bearer_ip_config_new ();
+
/* It appears that for IPv6 %IPDPADDR returns only the expected
* link-local address and a DNS address, and that to retrieve the
* default router, extra DNS, and search domains, the host must listen
* for IPv6 Router Advertisements on the net port.
*/
-
- config = mm_bearer_ip_config_new ();
- mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_STATIC);
-
- /* IP address and prefix */
- if (inet_pton (AF_INET6, items[9], &tmp6) != 1 ||
+ if (g_strcmp0 (items[9], "::") != 0) {
+ mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_STATIC);
+ /* IP address and prefix */
+ if (inet_pton (AF_INET6, items[9], &tmp6) != 1 ||
IN6_IS_ADDR_UNSPECIFIED (&tmp6)) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Couldn't parse IPv6 address '%s'", items[9]);
- goto error;
- }
- mm_bearer_ip_config_set_address (config, items[9]);
- mm_bearer_ip_config_set_prefix (config, 64);
-
- /* If the address is a link-local one, then SLAAC or DHCP must be used
- * to get the real prefix and address. Change the method to DHCP to
- * indicate this to clients.
- */
- if (IN6_IS_ADDR_LINKLOCAL (&tmp6))
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't parse IPv6 address '%s'", items[9]);
+ goto error;
+ }
+ mm_bearer_ip_config_set_address (config, items[9]);
+ mm_bearer_ip_config_set_prefix (config, 64);
+
+ /* If the address is a link-local one, then SLAAC or DHCP must be used
+ * to get the real prefix and address. Change the method to DHCP to
+ * indicate this to clients.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL (&tmp6))
+ mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP);
+ } else {
+ /* No IPv6 given, but DNS will be available, try with DHCP */
mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP);
+ }
/* DNS server */
- memset (&tmp6, 0, sizeof (tmp6));
- if (inet_pton (AF_INET6, items[11], &tmp6) == 1 &&
+ if (g_strcmp0 (items[11], "::") != 0) {
+ memset (&tmp6, 0, sizeof (tmp6));
+ if (inet_pton (AF_INET6, items[11], &tmp6) == 1 &&
!IN6_IS_ADDR_UNSPECIFIED (&tmp6)) {
- dns[0] = items[11];
- dns[1] = NULL;
- mm_bearer_ip_config_set_dns (config, (const gchar **) dns);
- } else {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Couldn't parse DNS address '%s'", items[11]);
- goto error;
+ dns[0] = items[11];
+ dns[1] = NULL;
+ mm_bearer_ip_config_set_dns (config, (const gchar **) dns);
+ } else {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't parse DNS address '%s'", items[11]);
+ goto error;
+ }
}
return config;
@@ -223,7 +233,7 @@ mm_icera_parse_ipdpaddr_response (const gchar *response,
* Sierra USB305: %IPDPADDR: 2, 21.93.217.11, 21.93.217.10, 10.177.0.34, 10.161.171.220, 0.0.0.0, 0.0.0.0
* K3805-Z: %IPDPADDR: 2, 21.93.217.11, 21.93.217.10, 10.177.0.34, 10.161.171.220, 0.0.0.0, 0.0.0.0, 255.0.0.0, 255.255.255.0, 21.93.217.10,
* Nokia 21M: %IPDPADDR: 2, 33.196.7.127, 33.196.7.128, 10.177.0.34, 10.161.171.220, 0.0.0.0, 0.0.0.0, 255.0.0.0, 33.196.7.128, fe80::f:9135:5901, ::, fd00:976a::9, ::, ::, ::, ::, ::
- * Nokia 21M: %IPDPADDR: 3, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, fe80::2e:437b:7901, ::, fd00:976a::9, ::, ::, ::, ::, ::
+ * Nokia 21M: %IPDPADDR: 3, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, fe80::2e:437b:7901, ::, fd00:976a::9, ::, ::, ::, ::, ::
*/
response = mm_strip_tag (response, IPDPADDR_TAG);
items = g_strsplit_set (response, ",", 0);
@@ -274,4 +284,3 @@ out:
*out_ip6_config = ip6_config;
return success;
}
-
diff --git a/plugins/icera/tests/test-modem-helpers-icera.c b/plugins/icera/tests/test-modem-helpers-icera.c
index 8eaff4cb..e7d16454 100644
--- a/plugins/icera/tests/test-modem-helpers-icera.c
+++ b/plugins/icera/tests/test-modem-helpers-icera.c
@@ -49,7 +49,7 @@ typedef struct {
static const IpdpaddrTest ipdpaddr_tests[] = {
/* Sierra USB305 */
- { "%IPDPADDR: 2, 21.93.217.11, 21.93.217.10, 10.177.0.34, 10.161.171.220, 0.0.0.0, 0.0.0.0\r\n",
+ { "%IPDPADDR: 2, 21.93.217.11, 21.93.217.10, 10.177.0.34, 10.161.171.220, 0.0.0.0, 0.0.0.0\r\n",
2, "21.93.217.11", 32, "21.93.217.10", "10.177.0.34", "10.161.171.220",
NULL, NULL },
@@ -87,6 +87,18 @@ static const IpdpaddrTest ipdpaddr_tests[] = {
2, "188.150.116.13", 16, "188.150.116.14", "188.149.250.16", NULL,
"fe80::1:e414:eb01", "2a00:e18:0:3::6" },
+ { "%IPDPADDR: 1, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, fe80::1f:fad1:4c01, ::, 2001:4600:4:fff::54, 2001:4600:4:1fff::54, ::, ::, ::, ::\r\n",
+ 1, NULL, 0, NULL, NULL, NULL,
+ "fe80::1f:fad1:4c01", "2001:4600:4:fff::54" },
+
+ { "%IPDPADDR: 1, 46.157.76.179, 46.157.76.180, 193.213.112.4, 130.67.15.198, 0.0.0.0, 0.0.0.0, 255.0.0.0, 46.157.76.180, ::, ::, ::, ::, ::, ::, ::, ::\r\n",
+ 1, "46.157.76.179", 32, "46.157.76.180", "193.213.112.4", "130.67.15.198",
+ NULL, NULL },
+
+ { "%IPDPADDR: 1, 0.0.0.0, 0.0.0.0, 193.213.112.4, 130.67.15.198, 0.0.0.0, 0.0.0.0, 0.0.0.0, 0.0.0.0, ::, ::, 2001:4600:4:fff::52, 2001:4600:4:1fff::52, ::, ::, ::, ::",
+ 1, NULL, 0, NULL, NULL, NULL,
+ NULL, "2001:4600:4:fff::52" },
+
{ NULL }
};
@@ -133,18 +145,21 @@ test_ipdpaddr (void)
g_assert (ipv4 == NULL);
/* IPv6 */
- if (ipdpaddr_tests[i].ipv6_addr) {
+ if (ipdpaddr_tests[i].ipv6_addr || ipdpaddr_tests[i].ipv6_dns1) {
struct in6_addr a6;
g_assert (ipv6);
- g_assert_cmpstr (mm_bearer_ip_config_get_address (ipv6), ==, ipdpaddr_tests[i].ipv6_addr);
- g_assert_cmpint (mm_bearer_ip_config_get_prefix (ipv6), ==, 64);
+ if (ipdpaddr_tests[i].ipv6_addr) {
+ g_assert_cmpstr (mm_bearer_ip_config_get_address (ipv6), ==, ipdpaddr_tests[i].ipv6_addr);
+ g_assert_cmpint (mm_bearer_ip_config_get_prefix (ipv6), ==, 64);
- g_assert (inet_pton (AF_INET6, mm_bearer_ip_config_get_address (ipv6), &a6));
- if (IN6_IS_ADDR_LINKLOCAL (&a6))
+ g_assert (inet_pton (AF_INET6, mm_bearer_ip_config_get_address (ipv6), &a6));
+ if (IN6_IS_ADDR_LINKLOCAL (&a6))
+ g_assert_cmpint (mm_bearer_ip_config_get_method (ipv6), ==, MM_BEARER_IP_METHOD_DHCP);
+ else
+ g_assert_cmpint (mm_bearer_ip_config_get_method (ipv6), ==, MM_BEARER_IP_METHOD_STATIC);
+ } else
g_assert_cmpint (mm_bearer_ip_config_get_method (ipv6), ==, MM_BEARER_IP_METHOD_DHCP);
- else
- g_assert_cmpint (mm_bearer_ip_config_get_method (ipv6), ==, MM_BEARER_IP_METHOD_STATIC);
dns = mm_bearer_ip_config_get_dns (ipv6);
g_assert (dns);