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;
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;
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;
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;
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;
struct sockaddr_in addr;
int sk, err;
- DBG("");
+ DBG("index %d", index);
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
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)
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)
struct sockaddr_in addr;
int sk, err;
- DBG("");
+ DBG("index %d", index);
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
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)
__connman_inet_rs_cb_t callback;
struct sockaddr_in6 addr;
guint rs_timeout;
+ guint watch_id;
void *user_data;
};
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);
+ if (data->watch_id > 0)
+ g_source_remove(data->watch_id);
+
g_free(data);
}
return FALSE;
if (data->callback != NULL)
- data->callback(NULL, data->user_data);
+ data->callback(NULL, 0, data->user_data);
data->rs_timeout = 0;
rs_cleanup(data);
len = recvmsg(fd, &mhdr, 0);
if (len < 0) {
- data->callback(NULL, data->user_data);
+ data->callback(NULL, 0, data->user_data);
rs_cleanup(data);
return -errno;
}
hdr = (struct nd_router_advert *)buf;
+ DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
+ sizeof(struct nd_router_advert));
if (hdr->nd_ra_code != 0)
return 0;
- data->callback(hdr, data->user_data);
+ data->callback(hdr, len, data->user_data);
rs_cleanup(data);
return len;
g_io_channel_set_encoding(data->channel, NULL, NULL);
g_io_channel_set_buffered(data->channel, FALSE);
- g_io_add_watch(data->channel,
+ data->watch_id = g_io_add_watch(data->channel,
G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
icmpv6_event, data);
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;
+}