summaryrefslogtreecommitdiffstats
path: root/src/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-01-15 14:28:24 +0000
committerRoy Marples <roy@marples.name>2020-01-15 14:28:24 +0000
commit4dcd539c2259273ae89a364069378ca7327cd428 (patch)
tree8bbadd0bf18d911402270bffeec30288a1635129 /src/if-bsd.c
parentdbf19b104503e4dea1616e03fa472f60d2cdfd4e (diff)
downloaddhcpcd-4dcd539c2259273ae89a364069378ca7327cd428.tar.xz
Implement Anonymity Profiles for DHCP Clients, RFC 7844
This works by randomising the hardware address when carrier is down and using this to construct a DUID LL which is used over any saved DUID. IAID is defaulted to zero and hostname + FQDN are disabled. Then every possible option is masked out except for essential ones. It's possible to request options *after* anonymous option which will enable it. This is RFC compliant and allows 100% flexability in letting the user decide what, if any, details leek out. This is disabled by default. Only works on NetBSD, other OS coming shortly.
Diffstat (limited to 'src/if-bsd.c')
-rw-r--r--src/if-bsd.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c
index 4d3dce4f..f44988ac 100644
--- a/src/if-bsd.c
+++ b/src/if-bsd.c
@@ -213,6 +213,55 @@ if_closesockets_os(struct dhcpcd_ctx *ctx)
priv = (struct priv *)ctx->priv;
if (priv->pf_inet6_fd != -1)
close(priv->pf_inet6_fd);
+ free(priv);
+ ctx->priv = NULL;
+}
+
+static int
+if_ioctllink(struct dhcpcd_ctx *ctx, unsigned long req, void *data, size_t len)
+{
+ int s;
+ int retval;
+
+#ifdef PRIVSEP
+ if (ctx->options & DHCPCD_PRIVSEP)
+ return (int)ps_root_ioctllink(ctx, req, data, len);
+#else
+ UNUSED(ctx);
+#endif
+
+ s = socket(PF_LINK, SOCK_DGRAM, 0);
+ if (s == -1)
+ return -1;
+ retval = ioctl(s, req, data, len);
+ close(s);
+ return retval;
+}
+
+int
+if_setmac(struct interface *ifp, void *mac, uint8_t maclen)
+{
+ struct if_laddrreq iflr = { .flags = IFLR_ACTIVE };
+ struct sockaddr_dl *sdl = satosdl(&iflr.addr);
+ int retval;
+
+ if (ifp->hwlen != maclen) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ strlcpy(iflr.iflr_name, ifp->name, sizeof(iflr.iflr_name));
+ sdl->sdl_family = AF_LINK;
+ sdl->sdl_len = sizeof(*sdl);
+ sdl->sdl_alen = maclen;
+ memcpy(LLADDR(sdl), mac, maclen);
+ retval = if_ioctllink(ifp->ctx, SIOCALIFADDR, &iflr, sizeof(iflr));
+
+ /* Try and remove the old address */
+ memcpy(LLADDR(sdl), ifp->hwaddr, ifp->hwlen);
+ if_ioctllink(ifp->ctx, SIOCDLIFADDR, &iflr, sizeof(iflr));
+
+ return retval;
}
static bool