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
This commit is contained in:
@@ -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);
|
||||
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))
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user