summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCristiano Fernandes <cristiano.fernandes@hp.com>2010-10-12 00:35:38 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-10-12 00:35:38 +0200
commit41433bb6cb698fa12564466d653471b1441e2a26 (patch)
tree7605a51afc2c8f4726fdc59c364208d5c25447fe
parentb0c90253ddbcdfbab4c0ea30a69f59bf71dcaa88 (diff)
downloadconnman-41433bb6cb698fa12564466d653471b1441e2a26.tar.gz
connman-41433bb6cb698fa12564466d653471b1441e2a26.tar.bz2
connman-41433bb6cb698fa12564466d653471b1441e2a26.zip
Using netlink to set and clear ipv6 addresses
-rw-r--r--src/inet.c75
1 files changed, 28 insertions, 47 deletions
diff --git a/src/inet.c b/src/inet.c
index 7501ad58..15c0138c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -76,6 +76,7 @@ int __connman_inet_modify_address(int cmd, int flags,
struct nlmsghdr *header;
struct sockaddr_nl nl_addr;
struct ifaddrmsg *ifaddrmsg;
+ struct in6_addr ipv6_addr;
struct in_addr ipv4_addr, ipv4_bcast;
int sk, err;
@@ -84,6 +85,9 @@ int __connman_inet_modify_address(int cmd, int flags,
if (address == NULL)
return -1;
+ if (family != AF_INET && family != AF_INET6)
+ return -1;
+
memset(&request, 0, sizeof(request));
header = (struct nlmsghdr *)request;
@@ -116,8 +120,14 @@ int __connman_inet_modify_address(int cmd, int flags,
if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
&ipv4_bcast, sizeof(ipv4_bcast))) < 0)
return err;
- } else {
- return -1;
+
+ } else if (family == AF_INET6) {
+ if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
+ return -1;
+
+ if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
+ &ipv6_addr, sizeof(ipv6_addr))) < 0)
+ return err;
}
sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
@@ -519,36 +529,25 @@ struct in6_ifreq {
int connman_inet_set_ipv6_address(int index,
struct connman_ipaddress *ipaddress)
{
- int sk, err;
- struct in6_ifreq ifr6;
-
- DBG("index %d ipaddress->local %s", index, ipaddress->local);
+ unsigned char prefix_len;
+ const char *address;
if (ipaddress->local == NULL)
return 0;
- sk = socket(PF_INET6, SOCK_DGRAM, 0);
- if (sk < 0) {
- err = -1;
- goto out;
- }
-
- memset(&ifr6, 0, sizeof(ifr6));
-
- err = inet_pton(AF_INET6, ipaddress->local, &ifr6.ifr6_addr);
- if (err < 0)
- goto out;
+ prefix_len = ipaddress->prefixlen;
+ address = ipaddress->local;
- ifr6.ifr6_ifindex = index;
- ifr6.ifr6_prefixlen = ipaddress->prefixlen;
+ DBG("index %d address %s prefix_len %d", index, address, prefix_len);
- err = ioctl(sk, SIOCSIFADDR, &ifr6);
- close(sk);
-out:
- if (err < 0)
+ if ((__connman_inet_modify_address(RTM_NEWADDR,
+ NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
+ address, prefix_len, NULL)) < 0) {
connman_error("Set IPv6 address error");
+ return -1;
+ }
- return err;
+ return 0;
}
int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
@@ -578,33 +577,15 @@ int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
int connman_inet_clear_ipv6_address(int index, const char *address,
int prefix_len)
{
- struct in6_ifreq ifr6;
- int sk, err;
-
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
- memset(&ifr6, 0, sizeof(ifr6));
-
- err = inet_pton(AF_INET6, address, &ifr6.ifr6_addr);
- if (err < 0)
- goto out;
-
- ifr6.ifr6_ifindex = index;
- ifr6.ifr6_prefixlen = prefix_len;
-
- sk = socket(PF_INET6, SOCK_DGRAM, 0);
- if (sk < 0) {
- err = -1;
- goto out;
- }
-
- err = ioctl(sk, SIOCDIFADDR, &ifr6);
- close(sk);
-out:
- if (err < 0)
+ if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
+ address, prefix_len, NULL)) < 0) {
connman_error("Clear IPv6 address error");
+ return -1;
+ }
- return err;
+ return 0;
}
int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)