Control DHCPv4 vs DHCPv6 dumping via the family option.
}
int
-dhcp_dump(struct dhcpcd_ctx *ctx, const char *ifname)
+dhcp_dump(struct interface *ifp)
{
- struct interface *ifp;
struct dhcp_state *state;
- if (ctx->ifaces == NULL) {
- ctx->ifaces = malloc(sizeof(*ctx->ifaces));
- if (ctx->ifaces == NULL)
- return -1;
- TAILQ_INIT(ctx->ifaces);
- }
- state = NULL;
- ifp = calloc(1, sizeof(*ifp));
- if (ifp == NULL)
- goto eexit;
- ifp->ctx = ctx;
- TAILQ_INSERT_HEAD(ctx->ifaces, ifp, next);
ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
if (state == NULL)
goto eexit;
- ifp->options = calloc(1, sizeof(*ifp->options));
- if (ifp->options == NULL)
- goto eexit;
- strlcpy(ifp->name, ifname, sizeof(ifp->name));
snprintf(state->leasefile, sizeof(state->leasefile),
LEASEFILE, ifp->name);
state->new = read_lease(ifp);
if (state->new == NULL && errno == ENOENT) {
- strlcpy(state->leasefile, ifname, sizeof(state->leasefile));
+ strlcpy(state->leasefile, ifp->name, sizeof(state->leasefile));
state->new = read_lease(ifp);
}
if (state->new == NULL) {
if (errno == ENOENT)
- syslog(LOG_ERR, "%s: no lease to dump", ifname);
+ syslog(LOG_ERR, "%s: no lease to dump", ifp->name);
return -1;
}
state->reason = "DUMP";
void dhcp_reboot_newopts(struct interface *, unsigned long long);
void dhcp_close(struct interface *);
void dhcp_free(struct interface *);
-int dhcp_dump(struct dhcpcd_ctx *, const char *);
+int dhcp_dump(struct interface *);
#else
#define dhcp_printoptions
#define dhcp_drop(a, b)
#define dhcp_reboot_newopts(a, b)
#define dhcp_close(a)
#define dhcp_free(a)
-#define dhcp_dump(a, b) -1
+#define dhcp_dump(a) -1
#endif
#endif
if (stat(state->leasefile, &st) == -1) {
if (errno == ENOENT)
return 0;
+ syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
return -1;
}
syslog(LOG_DEBUG, "%s: reading lease `%s'",
return -1;
}
state->new = malloc((size_t)st.st_size);
- if (state->new == NULL)
+ if (state->new == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
return -1;
+ }
state->new_len = (size_t)st.st_size;
fd = open(state->leasefile, O_RDONLY);
- if (fd == -1)
+ if (fd == -1) {
+ syslog(LOG_ERR, "%s: %s: %s: %m", ifp->name, __func__,
+ state->leasefile);
return -1;
+ }
bytes = read(fd, state->new, state->new_len);
close(fd);
if (bytes < (ssize_t)state->new_len) {
return (ssize_t)n;
}
+
+int
+dhcp6_dump(struct interface *ifp)
+{
+ struct dhcp6_state *state;
+ int r;
+
+ ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
+ if (state == NULL)
+ goto eexit;
+ TAILQ_INIT(&state->addrs);
+ snprintf(state->leasefile, sizeof(state->leasefile),
+ LEASEFILE6, ifp->name);
+ r = dhcp6_readlease(ifp);
+ if (r == -1 && errno == ENOENT) {
+ strlcpy(state->leasefile, ifp->name, sizeof(state->leasefile));
+ r = dhcp6_readlease(ifp);
+ }
+ if (r == -1) {
+ if (errno == ENOENT)
+ syslog(LOG_ERR, "%s: no lease to dump", ifp->name);
+ else
+ syslog(LOG_ERR, "%s: dhcp6_readlease: %m", ifp->name);
+ return -1;
+ }
+ state->reason = "DUMP6";
+ return script_runreason(ifp, state->reason);
+
+eexit:
+ syslog(LOG_ERR, "%s: %m", __func__);
+ return -1;
+}
void dhcp6_handleifa(struct dhcpcd_ctx *, int, const char *,
const struct in6_addr *addr, int);
void dhcp6_drop(struct interface *, const char *);
+int dhcp6_dump(struct interface *);
#else
#define dhcp6_printoptions()
#define dhcp6_addrexists(a, b) (0)
#define dhcp6_env(a, b, c, d, e)
#define dhcp6_free(a)
#define dhcp6_drop(a, b)
+#define dhcp6_dump(a) -1
#endif
#endif
# Just echo our DHCP options we have
-if [ "$reason" = "DUMP" ]; then
+case "$reason" in
+DUMP|DUMP6)
set | sed -ne 's/^new_//p' | sort
exit 0
-fi
+ ;;
+esac
if (chdir("/") == -1)
syslog(LOG_ERR, "chdir `/': %m");
+ /* Freeing allocated addresses from dumping leases can trigger
+ * eloop removals as well, so init here. */
+ ctx.eloop = eloop_init();
+ if (ctx.eloop == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ goto exit_failure;
+ }
+
if (ctx.options & DHCPCD_DUMPLEASE) {
if (optind != argc - 1) {
syslog(LOG_ERR, "dumplease requires an interface");
goto exit_failure;
}
- if (dhcp_dump(&ctx, argv[optind]) == -1)
+ i = 0;
+ if (ctx.ifaces == NULL) {
+ ctx.ifaces = malloc(sizeof(*ctx.ifaces));
+ if (ctx.ifaces == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ goto exit_failure;
+ }
+ TAILQ_INIT(ctx.ifaces);
+ }
+ ifp = calloc(1, sizeof(*ifp));
+ if (ifp == NULL)
+ goto exit_failure;
+ strlcpy(ifp->name, argv[optind], sizeof(ifp->name));
+ ifp->ctx = &ctx;
+ TAILQ_INSERT_HEAD(ctx.ifaces, ifp, next);
+ configure_interface(ifp, 0, NULL);
+ if (family == 0 || family == AF_INET) {
+ if (dhcp_dump(ifp) == -1)
+ i = 1;
+ }
+ if (family == 0 || family == AF_INET6) {
+ if (dhcp6_dump(ifp) == -1)
+ i = 1;
+ }
+ if (i == -1)
goto exit_failure;
goto exit_success;
}
syslog(LOG_WARNING,
PACKAGE " will not work correctly unless run as root");
- ctx.eloop = eloop_init();
- if (ctx.eloop == NULL) {
- syslog(LOG_ERR, "%s: %m", __func__);
- goto exit_failure;
- }
-
#ifdef USE_SIGNALS
if (sig != 0) {
pid = read_pid(pidfile);