- memset(buf, 0, sizeof(buf));
-
- nlmsg = (struct nlmsghdr *)buf;
- nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(*ifa) + RTA_LENGTH(sizeof(*local_addr)) + RTA_LENGTH(sizeof(*remote_addr)));
- nlmsg->nlmsg_type = RTM_NEWADDR;
- nlmsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
- nlmsg->nlmsg_seq = 1;
- nlmsg->nlmsg_pid = 0;
-
- ifa = NLMSG_DATA(nlmsg);
- ifa->ifa_family = AF_INET6;
- ifa->ifa_prefixlen = 128;
- ifa->ifa_flags = 0;
- ifa->ifa_scope = RT_SCOPE_UNIVERSE;
- ifa->ifa_index = iface;
-
- local_rta = IFA_RTA(ifa);
- local_rta->rta_len = RTA_LENGTH(sizeof(*local_addr));
- local_rta->rta_type = IFA_LOCAL;
- memcpy(RTA_DATA(local_rta), local_addr, sizeof(*local_addr));
-
- remote_rta = (struct rtattr *)((char *)local_rta + local_rta->rta_len);
- remote_rta->rta_len = RTA_LENGTH(sizeof(*remote_addr));
- remote_rta->rta_type = IFA_ADDRESS;
- memcpy(RTA_DATA(remote_rta), remote_addr, sizeof(*remote_addr));
-
- memset(&sa, 0, sizeof(sa));
- sa.nl_family = AF_NETLINK;
- sa.nl_pid = 0;
- sa.nl_groups = 0;
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
+ nlreq.nlh.nlmsg_type = RTM_NEWADDR;
+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
+ nlreq.ifa.ifa_family = AF_INET6;
+ nlreq.ifa.ifa_prefixlen = 128;
+ nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
+ nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
+ nlreq.ifa.ifa_index = iface;
+ nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
+ nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
+ IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
+ nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
+ nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
+ IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;