Mercurial > hg > dhcpcd
changeset 5288:30958d539e6c draft
Restore dumping a lease from stdin
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sun, 31 May 2020 21:06:32 +0100 |
| parents | d31a4f016043 |
| children | b32000689362 |
| files | src/Makefile src/dhcp.c src/dhcp.h src/dhcp6.c src/dhcp6.h src/dhcpcd.8.in src/dhcpcd.c src/script.c src/script.h |
| diffstat | 9 files changed, 148 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Makefile Sun May 31 12:14:28 2020 +0100 +++ b/src/Makefile Sun May 31 21:06:32 2020 +0100 @@ -43,7 +43,6 @@ ${SED_SYS} ${SED_SCRIPT} ${SED_DATADIR} \ ${SED_SERVICEEXISTS} ${SED_SERVICECMD} ${SED_SERVICESTATUS} \ ${SED_STATUSARG} \ - ${SED_CHROOT} ${SED_PRIVSEP_USER} \ $< > $@ all: ${TOP}/config.h ${PROG} ${SCRIPTS} ${MAN5} ${MAN8}
--- a/src/dhcp.c Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcp.c Sun May 31 21:06:32 2020 +0100 @@ -4176,3 +4176,24 @@ return ia; } + +#ifndef SMALL +int +dhcp_dump(struct interface *ifp) +{ + struct dhcp_state *state; + + ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state)); + if (state == NULL) { + logerr(__func__); + return -1; + } + state->new_len = read_lease(ifp, &state->new); + if (state->new == NULL) { + logerr("read_lease"); + return -1; + } + state->reason = "DUMP"; + return script_runreason(ifp, state->reason); +} +#endif
--- a/src/dhcp.h Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcp.h Sun May 31 21:06:32 2020 +0100 @@ -276,6 +276,7 @@ void dhcp_reboot_newopts(struct interface *, unsigned long long); void dhcp_close(struct interface *); void dhcp_free(struct interface *); +int dhcp_dump(struct interface *); #endif /* INET */ #endif /* DHCP_H */
--- a/src/dhcp6.c Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcp6.c Sun May 31 21:06:32 2020 +0100 @@ -1483,7 +1483,7 @@ dhcp6_startrenew(ifp); } -int +bool dhcp6_dadcompleted(const struct interface *ifp) { const struct dhcp6_state *state; @@ -1493,9 +1493,9 @@ TAILQ_FOREACH(ap, &state->addrs, next) { if (ap->flags & IPV6_AF_ADDED && !(ap->flags & IPV6_AF_DADCOMPLETED)) - return 0; + return false; } - return 1; + return true; } static void @@ -4293,3 +4293,24 @@ return 1; } #endif + +#ifndef SMALL +int +dhcp6_dump(struct interface *ifp) +{ + struct dhcp6_state *state; + + ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state)); + if (state == NULL) { + logerr(__func__); + return -1; + } + TAILQ_INIT(&state->addrs); + if (dhcp6_readlease(ifp, 0) == -1) { + logerr("dhcp6_readlease"); + return -1; + } + state->reason = "DUMP6"; + return script_runreason(ifp, state->reason); +} +#endif
--- a/src/dhcp6.h Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcp6.h Sun May 31 21:06:32 2020 +0100 @@ -243,9 +243,10 @@ const struct dhcp6_message *, size_t); void dhcp6_free(struct interface *); void dhcp6_handleifa(int, struct ipv6_addr *, pid_t); -int dhcp6_dadcompleted(const struct interface *); +bool dhcp6_dadcompleted(const struct interface *); void dhcp6_abort(struct interface *); void dhcp6_drop(struct interface *, const char *); +int dhcp6_dump(struct interface *); #endif /* DHCP6 */ #endif /* DHCP6_H */
--- a/src/dhcpcd.8.in Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcpcd.8.in Sun May 31 21:06:32 2020 +0100 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 21, 2020 +.Dd May 31, 2020 .Dt DHCPCD 8 .Os .Sh NAME @@ -72,7 +72,7 @@ .Op interface .Nm .Fl U , Fl Fl dumplease -.Ar interface +.Op Ar interface .Nm .Fl Fl version .Nm @@ -685,15 +685,20 @@ To test INFORM the interface needs to be configured with the desired address before starting .Nm . -.It Fl U , Fl Fl dumplease Ar interface +.It Fl U , Fl Fl dumplease Op Ar interface Dumps the current lease for the .Ar interface to stdout. +If no +.Ar interface +is given then all interfaces are dumped. Use the .Fl 4 or .Fl 6 flags to specify an address family. +If a lease is piped in via standard input then that is dumped. +In this case, specifying an address family is mandatory. .It Fl V , Fl Fl variables Display a list of option codes, the associated variable and encoding for use in .Xr dhcpcd-run-hooks 8 .
--- a/src/dhcpcd.c Sun May 31 12:14:28 2020 +0100 +++ b/src/dhcpcd.c Sun May 31 21:06:32 2020 +0100 @@ -29,6 +29,7 @@ const char dhcpcd_copyright[] = "Copyright (c) 2006-2020 Roy Marples"; #include <sys/file.h> +#include <sys/ioctl.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/time.h> @@ -1663,20 +1664,13 @@ return 0; } -static const char *dumpskip[] = { - "PATH=", - "pid=", - "chroot=", -}; - static int dhcpcd_readdump(struct dhcpcd_ctx *ctx) { int error = 0; - size_t nifaces, buflen = 0, dlen, i; + size_t nifaces, buflen = 0, dlen; ssize_t len; - char *buf = NULL, *dp, *de; - const char *skip; + char *buf = NULL; again1: len = read(ctx->control_fd, &nifaces, sizeof(nifaces)); @@ -1723,26 +1717,7 @@ error = -1; goto out; } - dp = buf; - de = dp + dlen; - if (*(de - 1) != '\0') { - errno = EINVAL; - error = -1; - goto out; - } - while (dp < de) { - for (i = 0; i < __arraycount(dumpskip); i++) { - skip = dumpskip[i]; - if (strncmp(dp, skip, strlen(skip)) == 0) - break; - } - if (i == __arraycount(dumpskip)) { - if (strncmp(dp, "new_", 4) == 0) - dp += 4; - printf("%s\n", dp); - } - dp += strlen(dp) + 1; - } + script_dump(buf, dlen); fflush(stdout); if (nifaces != 1) putchar('\n'); @@ -2107,6 +2082,45 @@ } #endif +#ifndef SMALL + if (ctx.options & DHCPCD_DUMPLEASE && + ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 && + i > 0) + { + ifp = calloc(1, sizeof(*ifp)); + if (ifp == NULL) { + logerr(__func__); + goto exit_failure; + } + ifp->ctx = &ctx; + ifp->options = ifo; + switch (family) { + case AF_INET: +#ifdef INET + if (dhcp_dump(ifp) == -1) + goto exit_failure; + break; +#else + logerrx("No DHCP support"); + goto exit_failure +#endif + case AF_INET6: +#ifdef DHCP6 + if (dhcp6_dump(ifp) == -1) + goto exit_failure; + break; +#else + logerrx("No DHCP6 support"); + goto exit_failure +#endif + default: + logerrx("Family not specified. Please use -4 or -6."); + goto exit_failure; + } + goto exit_success; + } +#endif + /* Test against siga instead of sig to avoid gcc * warning about a bogus potential signed overflow. * The end result will be the same. */
--- a/src/script.c Sun May 31 12:14:28 2020 +0100 +++ b/src/script.c Sun May 31 21:06:32 2020 +0100 @@ -1,4 +1,4 @@ -/* stSPDX-License-Identifier: BSD-2-Clause */ +/* SPDX-License-Identifier: BSD-2-Clause */ /* * dhcpcd - DHCP client daemon * Copyright (c) 2006-2020 Roy Marples <roy@marples.name> @@ -193,6 +193,8 @@ } } assert(*(bufp - 1) == '\0'); + if (nenv == 0) + return NULL; if (ctx->script_envlen < nenv) { env = reallocarray(ctx->script_env, nenv + 1, sizeof(*env)); @@ -235,6 +237,7 @@ #ifdef DHCP6 const struct dhcp6_state *d6_state; #endif + bool is_stdin = ifp->name[0] == '\0'; #ifdef HAVE_OPEN_MEMSTREAM if (ctx->script_fp == NULL) { @@ -264,23 +267,19 @@ } #endif - /* Needed for scripts */ - path = getenv("PATH"); - if (efprintf(fp, "PATH=%s", path == NULL ? DEFAULT_PATH:path) == -1) - goto eexit; - if (efprintf(fp, "reason=%s", reason) == -1) - goto eexit; - if (efprintf(fp, "pid=%d", getpid()) == -1) - goto eexit; - -#ifdef PRIVSEP - if (ctx->options & DHCPCD_PRIVSEP && ctx->ps_user != NULL) { - if (efprintf(fp, "chroot=%s", ctx->ps_user->pw_dir) == -1) + if (!(ifp->ctx->options & DHCPCD_DUMPLEASE)) { + /* Needed for scripts */ + path = getenv("PATH"); + if (efprintf(fp, "PATH=%s", + path == NULL ? DEFAULT_PATH : path) == -1) + goto eexit; + if (efprintf(fp, "pid=%d", getpid()) == -1) goto eexit; } - if (strcmp(reason, "CHROOT") == 0) - goto make; -#endif + if (!is_stdin) { + if (efprintf(fp, "reason=%s", reason) == -1) + goto eexit; + } ifo = ifp->options; #ifdef INET @@ -340,9 +339,10 @@ protocol = PROTO_DHCP; #endif - - if (efprintf(fp, "interface=%s", ifp->name) == -1) - goto eexit; + if (!is_stdin) { + if (efprintf(fp, "interface=%s", ifp->name) == -1) + goto eexit; + } if (ifp->ctx->options & DHCPCD_DUMPLEASE) goto dumplease; if (efprintf(fp, "ifcarrier=%s", @@ -508,9 +508,6 @@ goto eexit; } -#ifdef PRIVSEP -make: -#endif /* Convert buffer to argv */ fflush(fp); @@ -536,6 +533,9 @@ fp = NULL; #endif + if (is_stdin) + return buf_pos; + if (script_buftoenv(ctx, ctx->script_buf, (size_t)buf_pos) == NULL) goto eexit; @@ -686,23 +686,48 @@ } int +script_dump(const char *env, size_t len) +{ + const char *ep = env + len; + + if (len == 0) + return 0; + + if (*(ep - 1) != '\0') { + errno = EINVAL; + return -1; + } + + for (; env < ep; env += strlen(env) + 1) { + if (strncmp(env, "new_", 4) == 0) + env += 4; + printf("%s\n", env); + } + return 0; +} + +int script_runreason(const struct interface *ifp, const char *reason) { struct dhcpcd_ctx *ctx = ifp->ctx; char *argv[2]; int status = 0; struct fd_list *fd; + long buflen; if (ctx->script == NULL && TAILQ_FIRST(&ifp->ctx->control_fds) == NULL) return 0; /* Make our env */ - if (make_env(ifp->ctx, ifp, reason) == -1) { + if ((buflen = make_env(ifp->ctx, ifp, reason)) == -1) { logerr(__func__); return -1; } + if (strncmp(reason, "DUMP", 4) == 0) + return script_dump(ctx->script_buf, (size_t)buflen); + if (ctx->script == NULL) goto send_listeners;
--- a/src/script.h Sun May 31 12:14:28 2020 +0100 +++ b/src/script.h Sun May 31 21:06:32 2020 +0100 @@ -36,5 +36,6 @@ char ** script_buftoenv(struct dhcpcd_ctx *, char *, size_t); pid_t script_exec(char *const *, char *const *); int send_interface(struct fd_list *, const struct interface *, int); +int script_dump(const char *, size_t); int script_runreason(const struct interface *, const char *); #endif
