summaryrefslogtreecommitdiff
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:04:45 +0100
commit1820dc314b7827097f4f2371e4b32de04e18ca6f (patch)
tree3f5b064695cf6001b47292feb802fb2647e618b3
parent6a1b3e13b63c5416e89006ee9d0d406bb7ac3bb2 (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);