diff options
| author | Roy Marples <roy@marples.name> | 2020-05-10 12:19:59 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-05-10 12:19:59 +0100 |
| commit | 82d7c0bc10c09e0fb5ae4df1eeaede78377d1c8b (patch) | |
| tree | cb279ed101c8eed6c078d41b1bdfe75b514c2aef /src/privsep-bsd.c | |
| parent | 6c1e0dbd92be10ba63fac479e545c95dd983ea26 (diff) | |
| download | dhcpcd-82d7c0bc10c09e0fb5ae4df1eeaede78377d1c8b.tar.xz | |
privsep: Add function for indirect ioctl
Diffstat (limited to 'src/privsep-bsd.c')
| -rw-r--r-- | src/privsep-bsd.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index b64040d6..1a105b63 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -29,6 +29,7 @@ #include <sys/ioctl.h> #include <errno.h> +#include <string.h> #include <unistd.h> #include "dhcpcd.h" @@ -41,12 +42,30 @@ ps_root_doioctldom(int domain, unsigned long req, void *data, size_t len) int s, err; s = socket(domain, SOCK_DGRAM, 0); - if (s != -1) - err = ioctl(s, req, data, len); - else - err = -1; - if (s != -1) - close(s); + if (s == -1) + return -1; + err = ioctl(s, req, data, len); + close(s); + return err; +} + +static ssize_t +ps_root_doindirectioctl(unsigned long req, void *data, size_t len) +{ + char *p = data; + struct ifreq ifr = { .ifr_flags = 0 }; + ssize_t err; + + if (len < IFNAMSIZ) { + errno = EINVAL; + return -1; + } + + strlcpy(ifr.ifr_name, p, IFNAMSIZ); + ifr.ifr_data = p + IFNAMSIZ; + err = ps_root_doioctldom(PF_INET, req, &ifr, sizeof(ifr)); + if (err != -1) + memmove(data, ifr.ifr_data, len - IFNAMSIZ); return err; } @@ -78,6 +97,8 @@ ps_root_os(struct ps_msghdr *psm, struct msghdr *msg) return ps_root_doioctldom(PF_LINK, psm->ps_flags, data, len); case PS_IOCTL6: return ps_root_doioctldom(PF_INET6, psm->ps_flags, data, len); + case PS_IOCTLINDIRECT: + return ps_root_doindirectioctl(psm->ps_flags, data, len); case PS_ROUTE: return ps_root_doroute(data, len); default: @@ -114,6 +135,20 @@ ps_root_ioctl6(struct dhcpcd_ctx *ctx, unsigned long request, } ssize_t +ps_root_indirectioctl(struct dhcpcd_ctx *ctx, unsigned long request, + const char *ifname, void *data, size_t len) +{ + char buf[PS_BUFLEN]; + + strlcpy(buf, ifname, IFNAMSIZ); + memcpy(buf + IFNAMSIZ, data, len); + if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_IOCTLINDIRECT, + request, buf, IFNAMSIZ + len) == -1) + return -1; + return ps_root_readerror(ctx, data, len); +} + +ssize_t ps_root_route(struct dhcpcd_ctx *ctx, void *data, size_t len) { |
