diff options
-rw-r--r-- | plugins/icera/mm-modem-helpers-icera.c | 67 | ||||
-rw-r--r-- | plugins/icera/tests/test-modem-helpers-icera.c | 31 |
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); |