summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2017-03-19 16:10:24 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2017-03-19 16:10:24 +0000
commitdc4ae400ba93fa2cc9e6c9ceb988012aa8308033 (patch)
tree1c12f0f4efbe6aebc1e6c4920f4f94593a42ff74
parent0312d22588350ea98b5b6d485d064dba424484df (diff)
Get and display link local address, needed to generate addresses from
a router advertisement.
-rw-r--r--usr.sbin/slaacd/engine.c11
-rw-r--r--usr.sbin/slaacd/frontend.c51
-rw-r--r--usr.sbin/slaacd/slaacd.h4
-rw-r--r--usr.sbin/slaacdctl/slaacdctl.c9
4 files changed, 53 insertions, 22 deletions
diff --git a/usr.sbin/slaacd/engine.c b/usr.sbin/slaacd/engine.c
index 9ba7b4b6cca..5cc9d2568ea 100644
--- a/usr.sbin/slaacd/engine.c
+++ b/usr.sbin/slaacd/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.1 2017/03/18 17:33:13 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.2 2017/03/19 16:10:23 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -146,6 +146,7 @@ struct slaacd_iface {
int running;
int autoconfprivacy;
struct ether_addr hw_address;
+ struct sockaddr_in6 ll_address;
LIST_HEAD(, radv) radvs;
};
@@ -354,6 +355,9 @@ engine_dispatch_frontend(int fd, short event, void *bula)
memcpy(&iface->hw_address,
&imsg_ifinfo.hw_address,
sizeof(struct ether_addr));
+ memcpy(&iface->ll_address,
+ &imsg_ifinfo.ll_address,
+ sizeof(struct sockaddr_in6));
LIST_INIT(&iface->radvs);
LIST_INSERT_HEAD(&slaacd_interfaces,
iface, entries);
@@ -375,6 +379,9 @@ engine_dispatch_frontend(int fd, short event, void *bula)
memcpy(&iface->hw_address,
&imsg_ifinfo.hw_address,
sizeof(struct ether_addr));
+ memcpy(&iface->ll_address,
+ &imsg_ifinfo.ll_address,
+ sizeof(struct sockaddr_in6));
}
break;
case IMSG_REMOVE_IF:
@@ -526,6 +533,8 @@ send_interface_info(struct slaacd_iface *iface, pid_t pid)
cei.running = iface->running;
cei.autoconfprivacy = iface->autoconfprivacy;
memcpy(&cei.hw_address, &iface->hw_address, sizeof(struct ether_addr));
+ memcpy(&cei.ll_address, &iface->ll_address,
+ sizeof(struct sockaddr_in6));
engine_imsg_compose_frontend(IMSG_CTL_SHOW_INTERFACE_INFO, pid, &cei,
sizeof(cei));
LIST_FOREACH(ra, &iface->radvs, entries) {
diff --git a/usr.sbin/slaacd/frontend.c b/usr.sbin/slaacd/frontend.c
index 9596e1cf501..a6dee74849d 100644
--- a/usr.sbin/slaacd/frontend.c
+++ b/usr.sbin/slaacd/frontend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frontend.c,v 1.1 2017/03/18 17:33:13 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.2 2017/03/19 16:10:23 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -63,7 +63,7 @@ void route_receive(int, short, void *);
void icmp6_receive(int, short, void *);
int get_flags(char *);
int get_xflags(char *);
-int get_lladdr(char *, struct ether_addr *);
+void get_lladdr(char *, struct ether_addr *, struct sockaddr_in6 *);
void send_solicitation(uint32_t);
struct imsgev *iev_main;
@@ -498,8 +498,9 @@ frontend_startup(void)
imsg_ifinfo.running = (flags & (IFF_UP | IFF_RUNNING)) ==
(IFF_UP | IFF_RUNNING);
imsg_ifinfo.autoconfprivacy = !(xflags & IFXF_INET6_NOPRIVACY);
- if (get_lladdr(ifnidx->if_name, &imsg_ifinfo.hw_address) < 0)
- fatal("cannot get lladdr");
+ get_lladdr(ifnidx->if_name, &imsg_ifinfo.hw_address,
+ &imsg_ifinfo.ll_address);
+
frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 0,
&imsg_ifinfo, sizeof(imsg_ifinfo));
}
@@ -578,34 +579,48 @@ route_receive(int fd, short events, void *arg)
}
}
-int
-get_lladdr(char *if_name, struct ether_addr *hw_address)
+void
+get_lladdr(char *if_name, struct ether_addr *mac, struct sockaddr_in6 *ll)
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_dl *sdl;
+ struct sockaddr_in6 *sin6;
if (getifaddrs(&ifap) != 0)
fatal("getifaddrs");
+ memset(mac, 0, sizeof(*mac));
+ memset(ll, 0, sizeof(*ll));
+
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(if_name, ifa->ifa_name) != 0)
continue;
- if (ifa->ifa_addr->sa_family != AF_LINK)
- continue;
- sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- if (sdl->sdl_type != IFT_ETHER ||
- sdl->sdl_alen != ETHER_ADDR_LEN)
- continue;
+ switch(ifa->ifa_addr->sa_family) {
+ case AF_LINK:
+ sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+ if (sdl->sdl_type != IFT_ETHER ||
+ sdl->sdl_alen != ETHER_ADDR_LEN)
+ continue;
- memcpy(hw_address->ether_addr_octet, LLADDR(sdl),
- ETHER_ADDR_LEN);
- freeifaddrs(ifap);
- return (0);
+ memcpy(mac->ether_addr_octet, LLADDR(sdl),
+ ETHER_ADDR_LEN);
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sin6->sin6_scope_id = ntohs(*(u_int16_t *)
+ &sin6->sin6_addr.s6_addr[2]);
+ sin6->sin6_addr.s6_addr[2] =
+ sin6->sin6_addr.s6_addr[3] = 0;
+ memcpy(ll, sin6, sizeof(*ll));
+ }
+ break;
+ default:
+ break;
+ }
}
-
freeifaddrs(ifap);
- return (-1);
}
void
diff --git a/usr.sbin/slaacd/slaacd.h b/usr.sbin/slaacd/slaacd.h
index b21c715782a..1ba21609c70 100644
--- a/usr.sbin/slaacd/slaacd.h
+++ b/usr.sbin/slaacd/slaacd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.h,v 1.2 2017/03/18 21:22:08 florian Exp $ */
+/* $OpenBSD: slaacd.h,v 1.3 2017/03/19 16:10:23 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -78,6 +78,7 @@ struct ctl_engine_info {
int running;
int autoconfprivacy;
struct ether_addr hw_address;
+ struct sockaddr_in6 ll_address;
};
enum rpref {
@@ -123,6 +124,7 @@ struct imsg_ifinfo {
int running;
int autoconfprivacy;
struct ether_addr hw_address;
+ struct sockaddr_in6 ll_address;
};
struct imsg_ra {
diff --git a/usr.sbin/slaacdctl/slaacdctl.c b/usr.sbin/slaacdctl/slaacdctl.c
index db55e128e0f..6b233ec1d81 100644
--- a/usr.sbin/slaacdctl/slaacdctl.c
+++ b/usr.sbin/slaacdctl/slaacdctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacdctl.c,v 1.1 2017/03/18 17:33:13 florian Exp $ */
+/* $OpenBSD: slaacdctl.c,v 1.2 2017/03/19 16:10:23 florian Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -192,7 +192,12 @@ show_interface_msg(struct imsg *imsg)
printf("\t index: %3u ", cei->if_index);
printf("running: %3s ", cei->running ? "yes" : "no");
printf("privacy: %3s\n", cei->autoconfprivacy ? "yes" : "no");
- printf("\tlladdr: %s\n", ether_ntoa(&cei->hw_address));
+ printf("\tlladdr: %s\n", ether_ntoa(&cei->hw_address));
+ if (getnameinfo((struct sockaddr *)&cei->ll_address,
+ cei->ll_address.sin6_len, hbuf, sizeof(hbuf), NULL, 0,
+ NI_NUMERICHOST | NI_NUMERICSERV))
+ err(1, "cannot get link local address");
+ printf("\t inet6: %s\n", hbuf);
break;
case IMSG_CTL_SHOW_INTERFACE_INFO_RA:
cei_ra = imsg->data;