provider: Allow user to set routes when creating provider
[platform/upstream/connman.git] / src / inet.c
index a659ab0..5b81273 100644 (file)
@@ -654,6 +654,9 @@ int connman_inet_add_network_route(int index, const char *host,
        struct sockaddr_in addr;
        int sk, err;
 
+       DBG("index %d host %s gateway %s netmask %s", index,
+               host, gateway, netmask);
+
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
                return -1;
@@ -716,6 +719,8 @@ int connman_inet_del_network_route(int index, const char *host)
        struct sockaddr_in addr;
        int sk, err;
 
+       DBG("index %d host %s", index, host);
+
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
                return -1;
@@ -852,7 +857,7 @@ int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
        struct in6_rtmsg rt;
        int sk, err;
 
-       DBG("index %d, gateway %s", index, gateway);
+       DBG("index %d gateway %s", index, gateway);
 
        if (gateway == NULL)
                return -EINVAL;
@@ -889,7 +894,7 @@ int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
        struct in6_rtmsg rt;
        int sk, err;
 
-       DBG("index %d, gateway %s", index, gateway);
+       DBG("index %d gateway %s", index, gateway);
 
        if (gateway == NULL)
                return -EINVAL;
@@ -928,6 +933,8 @@ int connman_inet_set_gateway_address(int index, const char *gateway)
        struct sockaddr_in addr;
        int sk, err;
 
+       DBG("index %d gateway %s", index, gateway);
+
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
                return -1;
@@ -977,7 +984,7 @@ int connman_inet_set_gateway_interface(int index)
        struct sockaddr_in addr;
        int sk, err;
 
-       DBG("");
+       DBG("index %d", index);
 
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
@@ -1023,7 +1030,7 @@ int connman_inet_set_ipv6_gateway_interface(int index)
        const struct in6_addr any = IN6ADDR_ANY_INIT;
        int sk, err;
 
-       DBG("");
+       DBG("index %d", index);
 
        sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
@@ -1068,7 +1075,7 @@ int connman_inet_clear_gateway_address(int index, const char *gateway)
        struct sockaddr_in addr;
        int sk, err;
 
-       DBG("");
+       DBG("index %d gateway %s", index, gateway);
 
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
@@ -1119,7 +1126,7 @@ int connman_inet_clear_gateway_interface(int index)
        struct sockaddr_in addr;
        int sk, err;
 
-       DBG("");
+       DBG("index %d", index);
 
        sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
@@ -1165,7 +1172,7 @@ int connman_inet_clear_ipv6_gateway_interface(int index)
        const struct in6_addr any = IN6ADDR_ANY_INIT;
        int sk, err;
 
-       DBG("");
+       DBG("index %d", index);
 
        sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (sk < 0)
@@ -1433,9 +1440,11 @@ static const struct in6_addr in6addr_all_routers_mc =
 
 static void rs_cleanup(struct rs_cb_data *data)
 {
-       g_io_channel_shutdown(data->channel, TRUE, NULL);
-       g_io_channel_unref(data->channel);
-       data->channel = 0;
+       if (data->channel != NULL) {
+               g_io_channel_shutdown(data->channel, TRUE, NULL);
+               g_io_channel_unref(data->channel);
+               data->channel = NULL;
+       }
 
        if (data->rs_timeout > 0)
                g_source_remove(data->rs_timeout);
@@ -1722,3 +1731,53 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
 
        return 0;
 }
+
+GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
+                                       unsigned int length)
+{
+       GSList *prefixes = NULL;
+       uint8_t *pos;
+       int len;
+
+       if (length <= sizeof(struct nd_router_advert))
+               return NULL;
+
+       len = length - sizeof(struct nd_router_advert);
+       pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
+
+       while (len > 0) {
+               struct nd_opt_prefix_info *pinfo;
+               char prefix_str[INET6_ADDRSTRLEN+1], *str;
+               const char *prefix;
+               int optlen;
+
+               if (len < 2)
+                       break;
+
+               optlen = pos[1] << 3;
+               if (optlen == 0 || optlen > len)
+                       break;
+
+               switch (pos[0]) {
+               case ND_OPT_PREFIX_INFORMATION:
+                       pinfo = (struct nd_opt_prefix_info *)pos;
+                       prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
+                                       prefix_str, INET6_ADDRSTRLEN);
+                       if (prefix == NULL)
+                               break;
+
+                       str = g_strdup_printf("%s/%d", prefix,
+                                               pinfo->nd_opt_pi_prefix_len);
+                       prefixes = g_slist_append(prefixes, str);
+
+                       DBG("prefix %s", str);
+
+                       break;
+               }
+
+               len -= optlen;
+               pos += optlen;
+       }
+
+       return prefixes;
+}