}
static int
-make_path(char *path, size_t len, const char *ifname, sa_family_t family,
- bool unpriv)
-{
- const char *per;
- const char *sunpriv;
-
- switch(family) {
- case AF_INET:
- per = "-4";
- break;
- case AF_INET6:
- per = "-6";
- break;
- default:
- per = "";
- break;
- }
- if (unpriv)
- sunpriv = ifname ? ".unpriv" : "unpriv.";
- else
- sunpriv = "";
- return snprintf(path, len, CONTROLSOCKET,
- ifname ? ifname : "", ifname ? per : "",
- sunpriv, ifname ? "." : "");
-}
-
-static int
-make_sock(struct sockaddr_un *sa, const char *ifname, sa_family_t family,
- bool unpriv)
+make_sock(struct sockaddr_un *sa, bool unpriv)
{
int fd;
return -1;
memset(sa, 0, sizeof(*sa));
sa->sun_family = AF_UNIX;
- make_path(sa->sun_path, sizeof(sa->sun_path), ifname, family, unpriv);
+ snprintf(sa->sun_path, sizeof(sa->sun_path),
+ unpriv ? CONTROLSOCKET_UNPRIV : CONTROLSOCKET);
return fd;
}
#define S_UNPRIV (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
static int
-control_start1(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family,
- mode_t fmode)
+control_start1(struct dhcpcd_ctx *ctx, mode_t fmode)
{
struct sockaddr_un sa;
int fd;
socklen_t len;
- fd = make_sock(&sa, ifname, family, (fmode & S_UNPRIV) == S_UNPRIV);
+ fd = make_sock(&sa, (fmode & S_UNPRIV) == S_UNPRIV);
if (fd == -1)
return -1;
}
#endif
- if ((fmode & S_UNPRIV) == S_UNPRIV)
- strlcpy(ctx->control_sock_unpriv, sa.sun_path,
- sizeof(ctx->control_sock_unpriv));
- else
- strlcpy(ctx->control_sock, sa.sun_path,
- sizeof(ctx->control_sock));
return fd;
}
int
-control_start(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family)
+control_start(struct dhcpcd_ctx *ctx)
{
int fd;
#ifdef PRIVSEP
- if (IN_PRIVSEP_SE(ctx)) {
- make_path(ctx->control_sock, sizeof(ctx->control_sock),
- ifname, family, false);
- make_path(ctx->control_sock_unpriv,
- sizeof(ctx->control_sock_unpriv),
- ifname, family, true);
+ if (IN_PRIVSEP_SE(ctx))
return 0;
- }
#endif
- if ((fd = control_start1(ctx, ifname, family, S_PRIV)) == -1)
+ if ((fd = control_start1(ctx, S_PRIV)) == -1)
return -1;
ctx->control_fd = fd;
control_handle, ctx) == -1)
logerr("%s: eloop_event_add", __func__);
- if ((fd = control_start1(ctx, ifname, family, S_UNPRIV)) != -1) {
+ if ((fd = control_start1(ctx, S_UNPRIV)) != -1) {
ctx->control_unpriv_fd = fd;
if (eloop_event_add(ctx->eloop, fd, ELE_READ,
control_handle_unpriv, ctx) == -1)
}
#ifdef PRIVSEP
+ /* Only the manager process can delete the sockets */
if (IN_PRIVSEP_SE(ctx)) {
- if (ctx->control_sock[0] != '\0' &&
- ps_root_unlink(ctx, ctx->control_sock) == -1)
+ if (ps_root_unlink(ctx, CONTROLSOCKET) == -1)
retval = -1;
- if (ctx->control_sock_unpriv[0] != '\0' &&
- ps_root_unlink(ctx, ctx->control_sock_unpriv) == -1)
+ if (ps_root_unlink(ctx, CONTROLSOCKET_UNPRIV) == -1)
retval = -1;
+
return retval;
- } else if (ctx->options & DHCPCD_FORKED)
- return retval;
+ }
#endif
if (ctx->control_fd != -1) {
eloop_event_delete(ctx->eloop, ctx->control_fd);
close(ctx->control_fd);
ctx->control_fd = -1;
- if (control_unlink(ctx, ctx->control_sock) == -1)
+ if (!IN_PRIVSEP(ctx) &&
+ control_unlink(ctx, CONTROLSOCKET_UNPRIV) == -1)
retval = -1;
}
eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd);
close(ctx->control_unpriv_fd);
ctx->control_unpriv_fd = -1;
- if (control_unlink(ctx, ctx->control_sock_unpriv) == -1)
+ if (!IN_PRIVSEP(ctx) &&
+ control_unlink(ctx, CONTROLSOCKET_UNPRIV) == -1)
retval = -1;
}
}
int
-control_open(const char *ifname, sa_family_t family, bool unpriv)
+control_open(bool unpriv)
{
struct sockaddr_un sa;
int fd;
- if ((fd = make_sock(&sa, ifname, family, unpriv)) != -1) {
+ if ((fd = make_sock(&sa, unpriv)) != -1) {
socklen_t len;
len = (socklen_t)SUN_LEN(&sa);
#define FD_UNPRIV 0x02U
#define FD_SENDLEN 0x04U
-int control_start(struct dhcpcd_ctx *, const char *, sa_family_t);
+int control_start(struct dhcpcd_ctx *);
int control_stop(struct dhcpcd_ctx *);
-int control_open(const char *, sa_family_t, bool);
+int control_open(bool);
ssize_t control_send(struct dhcpcd_ctx *, int, char * const *);
struct fd_list *control_new(struct dhcpcd_ctx *, int, unsigned int);
void control_free(struct fd_list *);
# define LEASEFILE6 LEASEFILE "6"
#endif
#ifndef PIDFILE
-# define PIDFILE RUNDIR "/%s%s%spid"
+# define PIDFILE RUNDIR "/pid"
#endif
#ifndef CONTROLSOCKET
-# define CONTROLSOCKET RUNDIR "/%s%s%s%ssock"
+# define CONTROLSOCKET RUNDIR "/sock"
+#endif
+#ifndef CONTROLSOCKET_UNPRIV
+# define CONTROLSOCKET_UNPRIV RUNDIR "/unpriv.sock"
#endif
#ifndef RDM_MONOFILE
# define RDM_MONOFILE DBDIR "/rdm_monotonic"
{
char ssid[1 + (IF_SSIDLEN * 4) + 1]; /* - prefix and NUL terminated. */
+#if 0
if (ifp->name[0] == '\0') {
strlcpy(leasefile, ifp->ctx->pidfile, len);
return 0;
}
+#endif
switch (family) {
case AF_INET:
#endif
static void dhcp_handledhcp(struct interface *, struct bootp *, size_t,
const struct in_addr *);
-static void dhcp_handleifudp(void *, unsigned short);
static int dhcp_initstate(struct interface *);
void
}
if (type == DHCP_DISCOVER &&
- !(ifp->ctx->options & DHCPCD_TEST) &&
DHC_REQ(ifo->requestmask, ifo->nomask, DHO_RAPIDCOMMIT))
{
/* RFC 4039 Section 3 */
struct dhcpcd_ctx *ctx = ifp->ctx;
struct dhcp_state *state = D_STATE(ifp);
-#ifdef PRIVSEP
- if (IN_PRIVSEP_SE(ctx)) {
- if (state->addr != NULL)
- ps_inet_closebootp(state->addr);
- }
-#endif
-
if (state->udp_rfd != -1) {
eloop_event_delete(ctx->eloop, state->udp_rfd);
close(state->udp_rfd);
case ENOBUFS:
break;
default:
- if (!(ifp->ctx->options & DHCPCD_TEST))
- dhcp_drop(ifp, "FAIL");
+ dhcp_drop(ifp, "FAIL");
eloop_timeout_delete(ifp->ctx->eloop,
NULL, ifp);
callback = NULL;
if (opts & (DHCPCD_STATIC | DHCPCD_INFORM)) {
state->reason = "EXPIRE";
script_runreason(ifp, state->reason);
-#define NOT_ONLY_SELF (DHCPCD_MANAGER | DHCPCD_IPV6RS | DHCPCD_DHCP6)
- if (!(ctx->options & NOT_ONLY_SELF))
- eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
return deleted;
}
eloop_timeout_add_sec(ifp->ctx->eloop,
struct dhcp_state *state = D_STATE(ifp);
struct if_options *ifo = ifp->options;
struct dhcp_lease *lease = &state->lease;
- uint8_t old_state;
state->reason = NULL;
/* If we don't have an offer, we are re-binding a lease on preference,
lease->leasetime);
}
}
- if (ctx->options & DHCPCD_TEST) {
- state->reason = "TEST";
- script_runreason(ifp, state->reason);
- eloop_exit(ctx->eloop, EXIT_SUCCESS);
- return;
- }
if (state->reason == NULL) {
if (state->old &&
!(state->added & (STATE_FAKE | STATE_EXPIRED)))
logerr("dhcp_writefile: %s", state->leasefile);
}
- old_state = state->added;
-
if (!(ifo->options & DHCPCD_CONFIGURE)) {
struct ipv4_addr *ia;
state->addr = ia;
state->added = STATE_ADDED;
dhcp_closebpf(ifp);
- goto openudp;
}
return;
}
* on a UDP socket. */
dhcp_closebpf(ifp);
-openudp:
- /* If not in manager mode, open an address specific socket. */
- if (ctx->options & DHCPCD_MANAGER ||
- ifo->options & DHCPCD_STATIC ||
- (state->old != NULL &&
- state->old->yiaddr == state->new->yiaddr &&
- old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
- return;
-
- dhcp_closeinet(ifp);
-#ifdef PRIVSEP
- if (IN_PRIVSEP_SE(ctx)) {
- if (ps_inet_openbootp(state->addr) == -1)
- logerr(__func__);
- return;
- }
-#endif
-
- state->udp_rfd = dhcp_openudp(&state->addr->addr);
- if (state->udp_rfd == -1) {
- logerr(__func__);
- /* Address sharing without manager mode is not supported.
- * It's also possible another DHCP client could be running,
- * which is even worse.
- * We still need to work, so re-open BPF. */
- dhcp_openbpf(ifp);
- return;
- }
- if (eloop_event_add(ctx->eloop, state->udp_rfd, ELE_READ,
- dhcp_handleifudp, ifp) == -1)
- logerr("%s: eloop_event_add", __func__);
}
static size_t
dhcp_arp_bind(struct interface *ifp)
{
- if (ifp->ctx->options & DHCPCD_TEST ||
- dhcp_arp_address(ifp) == 1)
+ if (dhcp_arp_address(ifp) == 1)
dhcp_bind(ifp);
}
#endif
loginfox("%s: waiting for 3rd party to "
"configure IP address",
ifp->name);
- if (!(ifp->ctx->options & DHCPCD_TEST)) {
- state->reason = "3RDPARTY";
- script_runreason(ifp, state->reason);
- }
+ state->reason = "3RDPARTY";
+ script_runreason(ifp, state->reason);
return;
}
} else {
ia = ipv4_iffindaddr(ifp, &ifo->req_addr, &ifo->req_mask);
if (ia == NULL) {
- if (ifp->ctx->options & DHCPCD_TEST) {
- logerrx("%s: cannot add IP address in test mode",
- ifp->name);
- return;
- }
ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL);
if (ia != NULL)
/* Netmask must be different, delete it. */
* interface gets the reply. */
ia = ipv4_iffindaddr(ifp, &state->lease.addr, NULL);
if (ia != NULL &&
- !(ifp->ctx->options & DHCPCD_TEST) &&
#ifdef IN_IFF_NOTUSEABLE
!(ia->addr_flags & IN_IFF_NOTUSEABLE) &&
#endif
}
if (state->state == DHS_INFORM) /* INFORM should not be NAKed */
return;
- if (!(ifp->ctx->options & DHCPCD_TEST)) {
- dhcp_drop(ifp, "NAK");
- dhcp_unlink(ifp->ctx, state->leasefile);
- }
+ dhcp_drop(ifp, "NAK");
+ dhcp_unlink(ifp->ctx, state->leasefile);
/* If we constantly get NAKS then we should slowly back off */
eloop_timeout_add_sec(ifp->ctx->eloop,
lease->server.s_addr = INADDR_ANY;
/* Test for rapid commit in the OFFER */
- if (!(ifp->ctx->options & DHCPCD_TEST) &&
- has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT) &&
+ if (has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT) &&
get_option(ifp->ctx, bootp, bootp_len,
DHO_RAPIDCOMMIT, NULL))
{
state->offer_len = bootp_len;
memcpy(state->offer, bootp, bootp_len);
bootp_copied = true;
- if (ifp->ctx->options & DHCPCD_TEST) {
- free(state->old);
- state->old = state->new;
- state->old_len = state->new_len;
- state->new = state->offer;
- state->new_len = state->offer_len;
- state->offer = NULL;
- state->offer_len = 0;
- state->reason = "TEST";
- script_runreason(ifp, state->reason);
- eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
- if (state->bpf)
- state->bpf->bpf_flags |= BPF_EOF;
- return;
- }
eloop_timeout_delete(ifp->ctx->eloop, send_discover, ifp);
/* We don't request BOOTP addresses */
if (type) {
}
static void
-dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp,
- unsigned short events)
+dhcp_readudp(struct dhcpcd_ctx *ctx, unsigned short events)
{
- const struct dhcp_state *state;
struct sockaddr_in from;
union {
struct bootp bootp;
if (events != ELE_READ)
logerrx("%s: unexpected event 0x%04x", __func__, events);
- if (ifp != NULL) {
- state = D_CSTATE(ifp);
- s = state->udp_rfd;
- } else
- s = ctx->udp_rfd;
-
+ s = ctx->udp_rfd;
bytes = recvmsg(s, &msg, 0);
if (bytes == -1) {
logerr(__func__);
{
struct dhcpcd_ctx *ctx = arg;
- dhcp_readudp(ctx, NULL, events);
-}
-
-static void
-dhcp_handleifudp(void *arg, unsigned short events)
-{
- struct interface *ifp = arg;
-
- dhcp_readudp(ifp->ctx, ifp, events);
+ dhcp_readudp(ctx, events);
}
static int
struct if_options *ifo = ifp->options;
struct dhcp_state *state;
uint32_t l;
- int nolease;
if (!(ifo->options & DHCPCD_IPV4))
return;
- /* Listen on *.*.*.*:bootpc so that the kernel never sends an
- * ICMP port unreachable message back to the DHCP server.
- * Only do this in manager mode so we don't swallow messages
- * for dhcpcd running on another interface. */
- if ((ctx->options & (DHCPCD_MANAGER|DHCPCD_PRIVSEP)) == DHCPCD_MANAGER
- && ctx->udp_rfd == -1)
- {
- ctx->udp_rfd = dhcp_openudp(NULL);
+ if (!IN_PRIVSEP(ctx)) {
if (ctx->udp_rfd == -1) {
- logerr(__func__);
- return;
+ ctx->udp_rfd = dhcp_openudp(NULL);
+ if (ctx->udp_rfd == -1) {
+ logerr(__func__);
+ return;
+ }
+ if (eloop_event_add(ctx->eloop, ctx->udp_rfd, ELE_READ,
+ dhcp_handleudp, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
- if (eloop_event_add(ctx->eloop, ctx->udp_rfd, ELE_READ,
- dhcp_handleudp, ctx) == -1)
- logerr("%s: eloop_event_add", __func__);
- }
- if (!IN_PRIVSEP(ctx) && ctx->udp_wfd == -1) {
- ctx->udp_wfd = xsocket(PF_INET, SOCK_RAW|SOCK_CXNB,IPPROTO_UDP);
if (ctx->udp_wfd == -1) {
- logerr(__func__);
- return;
+ ctx->udp_wfd = xsocket(PF_INET, SOCK_RAW | SOCK_CXNB,
+ IPPROTO_UDP);
+ if (ctx->udp_wfd == -1) {
+ logerr(__func__);
+ return;
+ }
}
}
}
/* We don't want to read the old lease if we NAK an old test */
- nolease = state->offer && ifp->ctx->options & DHCPCD_TEST;
- if (!nolease && ifo->options & DHCPCD_DHCP) {
+ if (ifo->options & DHCPCD_DHCP) {
state->offer_len = read_lease(ifp, &state->offer);
/* Check the saved lease matches the type we want */
if (state->offer) {
#ifdef PRIVSEP
if (IN_PRIVSEP_SE(ifp->ctx) &&
- !(ifp->ctx->options & (DHCPCD_MANAGER | DHCPCD_CONFIGURE)) &&
+ !(ifp->ctx->options & DHCPCD_CONFIGURE) &&
IN_ARE_ADDR_EQUAL(&state->lease.addr, &ia->addr))
{
state->addr = ia;
state->added = STATE_ADDED;
dhcp_closebpf(ifp);
- if (ps_inet_openbootp(ia) == -1)
- logerr(__func__);
}
#endif
static void dhcp6_bind(struct interface *, const char *, const char *);
static void dhcp6_failinform(void *);
-static void dhcp6_recvaddr(void *, unsigned short);
static void dhcp6_startdecline(struct interface *);
#ifdef SMALL
}
if (state->state == DH6S_DISCOVER &&
- !(ifp->ctx->options & DHCPCD_TEST) &&
DHC_REQ(ifo->requestmask6, ifo->nomask6, D6_OPTION_RAPID_COMMIT))
len += sizeof(o);
break;
}
- /* In non manager mode we listen and send from fixed addresses.
- * We should try and match an address we have to unicast to,
- * but for now this is the safest policy. */
- if (unicast != NULL && !(ifp->ctx->options & DHCPCD_MANAGER)) {
- logdebugx("%s: ignoring unicast option as not manager",
- ifp->name);
- unicast = NULL;
- }
-
#ifdef AUTH
auth_len = 0;
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len));
if (state->state == DH6S_DISCOVER &&
- !(ifp->ctx->options & DHCPCD_TEST) &&
DHC_REQ(ifo->requestmask6, ifo->nomask6, D6_OPTION_RAPID_COMMIT))
COPYIN1(D6_OPTION_RAPID_COMMIT, 0);
state->lerror = code;
errno = 0;
- /* code cannot be D6_STATUS_OK, so there is a failure */
- if (ifp->ctx->options & DHCPCD_TEST)
- eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
-
return (int)code;
}
}
}
- if (!(ifp->ctx->options & DHCPCD_TEST) &&
- !(has_ta && !has_non_ta) &&
- ifp->options->reboot != 0)
- {
+ if (!(has_ta && !has_non_ta) && ifp->options->reboot != 0) {
r = dhcp6_readlease(ifp, 1);
if (r == -1) {
if (errno != ENOENT && errno != ESRCH)
confirmed = true;
}
- if (ifp->ctx->options & DHCPCD_TEST)
- script_runreason(ifp, "TEST");
- else {
- if (state->state == DH6S_INFORM)
- state->state = DH6S_INFORMED;
- else
- state->state = DH6S_BOUND;
- state->failed = false;
-
- if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
- eloop_timeout_add_sec(ifp->ctx->eloop,
- state->renew,
- state->state == DH6S_INFORMED ?
- dhcp6_startinform : dhcp6_startrenew, ifp);
- if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME)
- eloop_timeout_add_sec(ifp->ctx->eloop,
- state->rebind, dhcp6_startrebind, ifp);
- if (state->expire != ND6_INFINITE_LIFETIME)
- eloop_timeout_add_sec(ifp->ctx->eloop,
- state->expire, dhcp6_startexpire, ifp);
-
- if (ifp->options->options & DHCPCD_CONFIGURE) {
- ipv6_addaddrs(&state->addrs);
- if (!timedout)
- dhcp6_deprecateaddrs(&state->addrs);
- }
+ if (state->state == DH6S_INFORM)
+ state->state = DH6S_INFORMED;
+ else
+ state->state = DH6S_BOUND;
+ state->failed = false;
- if (state->state == DH6S_INFORMED)
- logmessage(loglevel, "%s: refresh in %"PRIu32" seconds",
- ifp->name, state->renew);
- else if (state->renew == ND6_INFINITE_LIFETIME)
- logmessage(loglevel, "%s: leased for infinity",
- ifp->name);
- else if (state->renew || state->rebind)
- logmessage(loglevel, "%s: renew in %"PRIu32", "
- "rebind in %"PRIu32", "
- "expire in %"PRIu32" seconds",
- ifp->name,
- state->renew, state->rebind, state->expire);
- else if (state->expire == 0)
- logmessage(loglevel, "%s: will expire", ifp->name);
- else
- logmessage(loglevel, "%s: expire in %"PRIu32" seconds",
- ifp->name, state->expire);
- rt_build(ifp->ctx, AF_INET6);
- if (!confirmed && !timedout) {
- logdebugx("%s: writing lease: %s",
- ifp->name, state->leasefile);
- if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
- state->new, state->new_len) == -1)
- logerr("dhcp_writefile: %s",state->leasefile);
- }
-#ifndef SMALL
- dhcp6_delegate_prefix(ifp);
-#endif
- dhcp6_script_try_run(ifp, 0);
+ if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ state->renew,
+ state->state == DH6S_INFORMED ?
+ dhcp6_startinform : dhcp6_startrenew, ifp);
+ if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME)
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ state->rebind, dhcp6_startrebind, ifp);
+ if (state->expire != ND6_INFINITE_LIFETIME)
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ state->expire, dhcp6_startexpire, ifp);
+
+ if (ifp->options->options & DHCPCD_CONFIGURE) {
+ ipv6_addaddrs(&state->addrs);
+ if (!timedout)
+ dhcp6_deprecateaddrs(&state->addrs);
}
- if (ifp->ctx->options & DHCPCD_TEST ||
- (ifp->options->options & DHCPCD_INFORM &&
- !(ifp->ctx->options & DHCPCD_MANAGER)))
- {
- eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
+ if (state->state == DH6S_INFORMED)
+ logmessage(loglevel, "%s: refresh in %"PRIu32" seconds",
+ ifp->name, state->renew);
+ else if (state->renew == ND6_INFINITE_LIFETIME)
+ logmessage(loglevel, "%s: leased for infinity",
+ ifp->name);
+ else if (state->renew || state->rebind)
+ logmessage(loglevel, "%s: renew in %"PRIu32", "
+ "rebind in %"PRIu32", "
+ "expire in %"PRIu32" seconds",
+ ifp->name,
+ state->renew, state->rebind, state->expire);
+ else if (state->expire == 0)
+ logmessage(loglevel, "%s: will expire", ifp->name);
+ else
+ logmessage(loglevel, "%s: expire in %"PRIu32" seconds",
+ ifp->name, state->expire);
+ rt_build(ifp->ctx, AF_INET6);
+ if (!confirmed && !timedout) {
+ logdebugx("%s: writing lease: %s",
+ ifp->name, state->leasefile);
+ if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
+ state->new, state->new_len) == -1)
+ logerr("dhcp_writefile: %s",state->leasefile);
}
+#ifndef SMALL
+ dhcp6_delegate_prefix(ifp);
+#endif
+ dhcp6_script_try_run(ifp, 0);
}
static void
}
void
-dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
+dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
{
struct sockaddr_in6 *from = msg->msg_name;
size_t len = msg->msg_iov[0].iov_len;
return;
}
- if (ia != NULL)
- ifp = ia->iface;
- else {
- ifp = if_findifpfromcmsg(ctx, msg, NULL);
- if (ifp == NULL) {
- logerr(__func__);
- return;
- }
+ ifp = if_findifpfromcmsg(ctx, msg, NULL);
+ if (ifp == NULL) {
+ logerr(__func__);
+ return;
}
r = (struct dhcp6_message *)msg->msg_iov[0].iov_base;
}
static void
-dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia, unsigned short events)
+dhcp6_recv(void *arg, unsigned short events)
{
+ struct dhcpcd_ctx *ctx = arg;
struct sockaddr_in6 from;
union {
struct dhcp6_message dhcp6;
.msg_iov = &iov, .msg_iovlen = 1,
.msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf),
};
- int s;
ssize_t bytes;
if (events != ELE_READ)
logerrx("%s: unexpected event 0x%04x", __func__, events);
- s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_rfd;
- bytes = recvmsg(s, &msg, 0);
+ bytes = recvmsg(ctx->dhcp6_rfd, &msg, 0);
if (bytes == -1) {
logerr(__func__);
return;
}
iov.iov_len = (size_t)bytes;
- dhcp6_recvmsg(ctx, &msg, ia);
-}
-
-static void
-
-dhcp6_recvaddr(void *arg, unsigned short events)
-{
- struct ipv6_addr *ia = arg;
-
- dhcp6_recv(ia->iface->ctx, ia, events);
-}
-
-static void
-dhcp6_recvctx(void *arg, unsigned short events)
-{
- struct dhcpcd_ctx *ctx = arg;
-
- dhcp6_recv(ctx, NULL, events);
+ dhcp6_recvmsg(ctx, &msg);
}
int
size_t i;
const struct dhcp_compat *dhc;
- if ((ctx->options & (DHCPCD_MANAGER|DHCPCD_PRIVSEP)) == DHCPCD_MANAGER &&
- ctx->dhcp6_rfd == -1)
- {
- ctx->dhcp6_rfd = dhcp6_openudp(0, NULL);
+ if (!IN_PRIVSEP(ctx)) {
if (ctx->dhcp6_rfd == -1) {
- logerr(__func__);
- return;
+ ctx->dhcp6_rfd = dhcp6_openudp(0, NULL);
+ if (ctx->dhcp6_rfd == -1) {
+ logerr(__func__);
+ return;
+ }
+ if (eloop_event_add(ctx->eloop, ctx->dhcp6_rfd,
+ ELE_READ, dhcp6_recv, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
- if (eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, ELE_READ,
- dhcp6_recvctx, ctx) == -1)
- logerr("%s: eloop_event_add", __func__);
- }
- if (!IN_PRIVSEP(ctx) && ctx->dhcp6_wfd == -1) {
- ctx->dhcp6_wfd = dhcp6_openraw();
if (ctx->dhcp6_wfd == -1) {
- logerr(__func__);
- return;
+ ctx->dhcp6_wfd = dhcp6_openraw();
+ if (ctx->dhcp6_wfd == -1) {
+ logerr(__func__);
+ return;
+ }
}
}
struct dhcp6_state *state;
struct interface *ifp = ia->iface;
- /* If not running in manager mode, listen to this address */
- if (cmd == RTM_NEWADDR &&
- !(ia->addr_flags & IN6_IFF_NOTUSEABLE) &&
- ifp->active == IF_ACTIVE_USER &&
- !(ifp->ctx->options & DHCPCD_MANAGER) &&
- ifp->options->options & DHCPCD_DHCP6)
- {
-#ifdef PRIVSEP
- if (IN_PRIVSEP_SE(ifp->ctx)) {
- if (ps_inet_opendhcp6(ia) == -1)
- logerr(__func__);
- } else
-#endif
- {
- if (ia->dhcp6_fd == -1)
- ia->dhcp6_fd = dhcp6_openudp(ia->iface->index,
- &ia->addr);
- if (ia->dhcp6_fd != -1 &&
- eloop_event_add(ia->iface->ctx->eloop,
- ia->dhcp6_fd, ELE_READ, dhcp6_recvaddr, ia) == -1)
- logerr("%s: eloop_event_add", __func__);
- }
- }
-
if ((state = D6_STATE(ifp)) != NULL)
ipv6_handleifa_addrs(cmd, &state->addrs, ia, pid);
}
int dhcp6_openraw(void);
int dhcp6_openudp(unsigned int, struct in6_addr *);
-void dhcp6_recvmsg(struct dhcpcd_ctx *, struct msghdr *, struct ipv6_addr *);
+void dhcp6_recvmsg(struct dhcpcd_ctx *, struct msghdr *);
void dhcp6_printoptions(const struct dhcpcd_ctx *,
const struct dhcp_opt *, size_t);
const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp,
static void
handle_exit_timeout(void *arg)
{
- struct dhcpcd_ctx *ctx;
+ struct dhcpcd_ctx *ctx = arg;
- ctx = arg;
logerrx("timed out");
- if (!(ctx->options & DHCPCD_MANAGER)) {
- struct interface *ifp;
-
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (ifp->active == IF_ACTIVE_USER)
- script_runreason(ifp, "STOPPED");
- }
- eloop_exit(ctx->eloop, EXIT_FAILURE);
- return;
- }
ctx->options |= DHCPCD_NOWAITIP;
dhcpcd_daemonise(ctx);
}
/* De-activate the interface */
ifp->active = IF_INACTIVE;
ifp->options->options &= ~DHCPCD_STOPPING;
-
- if (!(ctx->options & (DHCPCD_MANAGER | DHCPCD_TEST)))
- eloop_exit(ctx->eloop, EXIT_FAILURE);
}
static void
/* We want to setup INET6 on the interface as soon as possible. */
if (ifp->active == IF_ACTIVE_USER &&
ifo->options & DHCPCD_IPV6 &&
- !(ifp->ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST)))
+ !(ifp->ctx->options & DHCPCD_DUMPLEASE))
{
/* If not doing any DHCP, disable the RDNSS requirement. */
if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6)))
dhcpcd_prestartinterface(void *arg)
{
struct interface *ifp = arg;
- struct dhcpcd_ctx *ctx = ifp->ctx;
bool randmac_down;
if (ifp->carrier <= LINK_DOWN &&
} else
randmac_down = false;
- if ((!(ctx->options & DHCPCD_MANAGER) ||
- ifp->options->options & DHCPCD_IF_UP || randmac_down) &&
+ if ((ifp->options->options & DHCPCD_IF_UP || randmac_down) &&
!(ifp->flags & IFF_UP))
{
if (ifp->options->randomise_hwaddr &&
run_preinit(struct interface *ifp)
{
- if (ifp->ctx->options & DHCPCD_TEST)
- return;
-
script_runreason(ifp, "PREINIT");
if (ifp->wireless && if_is_link_up(ifp))
dhcpcd_reportssid(ifp);
/* We need to preserve these options. */
if (ctx->options & DHCPCD_STARTED)
ifo->options |= DHCPCD_STARTED;
- if (ctx->options & DHCPCD_MANAGER)
- ifo->options |= DHCPCD_MANAGER;
if (ctx->options & DHCPCD_DAEMONISED)
ifo->options |= DHCPCD_DAEMONISED;
if (ctx->options & DHCPCD_PRIVSEP)
return;
dhcpcd_exiting = true;
- if (!(ctx->options & DHCPCD_TEST))
- stop_all_interfaces(ctx, opts);
+ stop_all_interfaces(ctx, opts);
eloop_exit(ctx->eloop, exit_code);
dhcpcd_exiting = false;
}
struct dhcpcd_ctx *ctx = arg;
pid_t pid;
- pid = pidfile_read(ctx->pidfile);
+ pid = pidfile_read(PIDFILE);
if(pid == -1)
eloop_exit(ctx->eloop, EXIT_SUCCESS);
struct interface *ifp;
sa_family_t family = AF_UNSPEC;
int opt, oi = 0, i;
- unsigned int logopts, t;
+ unsigned int logopts;
ssize_t len;
#if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
pid_t pid;
logopts &= ~(LOGERR_LOG | LOGERR_ERR);
break;
case 'T':
- i = 1;
- logopts &= ~LOGERR_LOG;
+ // Test is no longer supported
+ //i = 1;
break;
case 'U':
i = 3;
}
}
- if (optind != argc - 1)
- ctx.options |= DHCPCD_MANAGER;
-
logsetopts(logopts);
logopen(ctx.logfile);
}
ctx.options |= ifo->options;
- if (i == 1 || i == 3) {
- if (i == 1)
- ctx.options |= DHCPCD_TEST;
- else
- ctx.options |= DHCPCD_DUMPLEASE;
+ if (i == 3) {
+ ctx.options |= DHCPCD_DUMPLEASE;
ctx.options |= DHCPCD_PERSISTENT;
ctx.options &= ~DHCPCD_DAEMONISE;
}
if (ctx.options & DHCPCD_DEBUG)
logsetopts(logopts | LOGERR_DEBUG);
- if (!(ctx.options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) {
+ if (!(ctx.options & (DHCPCD_DUMPLEASE))) {
printpidfile:
- /* If we have any other args, we should run as a single dhcpcd
- * instance for that interface. */
- if (optind == argc - 1 && !(ctx.options & DHCPCD_MANAGER)) {
- const char *per;
- const char *ifname;
-
- ifname = *ctx.ifv;
- if (ifname == NULL || strlen(ifname) > IF_NAMESIZE) {
- errno = ifname == NULL ? EINVAL : E2BIG;
- logerr("%s: ", ifname);
- goto exit_failure;
- }
- /* Allow a dhcpcd interface per address family */
- switch(family) {
- case AF_INET:
- per = "-4";
- break;
- case AF_INET6:
- per = "-6";
- break;
- default:
- per = "";
- }
- snprintf(ctx.pidfile, sizeof(ctx.pidfile),
- PIDFILE, ifname, per, ".");
- } else {
- snprintf(ctx.pidfile, sizeof(ctx.pidfile),
- PIDFILE, "", "", "");
- ctx.options |= DHCPCD_MANAGER;
-
- /*
- * If we are given any interfaces, we
- * cannot send a signal as that would impact
- * other interfaces.
- */
- if (optind != argc)
- sig = 0;
- }
+ /*
+ * If we are given any interfaces, we
+ * cannot send a signal as that would impact
+ * other interfaces.
+ */
+ if (optind != argc)
+ sig = 0;
if (ctx.options & DHCPCD_PRINT_PIDFILE) {
- printf("%s\n", ctx.pidfile);
+ printf("%s\n", PIDFILE);
goto exit_success;
}
}
}
if (sig != 0) {
- pid = pidfile_read(ctx.pidfile);
+ pid = pidfile_read(PIDFILE);
if (pid != 0 && pid != -1)
loginfox("sending signal %s to pid %d", siga, pid);
if (pid == 0 || pid == -1 || kill(pid, sig) != 0) {
logerr("kill");
goto exit_failure;
}
- unlink(ctx.pidfile);
+ unlink(PIDFILE);
/* We can still continue and send the command
* via the control socket. */
} else {
#endif
/* Try and contact the manager process to send the instruction. */
- if (!(ctx.options & DHCPCD_TEST)) {
- ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */
- if (!(ctx.options & DHCPCD_MANAGER))
- ctx.control_fd = control_open(argv[optind], family,
- ctx.options & DHCPCD_DUMPLEASE);
- if (!(ctx.options & DHCPCD_MANAGER) && ctx.control_fd == -1)
- ctx.control_fd = control_open(argv[optind], AF_UNSPEC,
- ctx.options & DHCPCD_DUMPLEASE);
- if (ctx.control_fd == -1)
- ctx.control_fd = control_open(NULL, AF_UNSPEC,
- ctx.options & DHCPCD_DUMPLEASE);
- if (ctx.control_fd != -1) {
+ ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */
+ ctx.control_fd = control_open(ctx.options & DHCPCD_DUMPLEASE);
+ if (ctx.control_fd != -1) {
#ifdef PRIVSEP
- if (IN_PRIVSEP(&ctx) &&
- ps_managersandbox(&ctx, NULL) == -1)
- goto exit_failure;
+ if (IN_PRIVSEP(&ctx) &&
+ ps_managersandbox(&ctx, NULL) == -1)
+ goto exit_failure;
#endif
- if (!(ctx.options & DHCPCD_DUMPLEASE))
- loginfox("sending commands to dhcpcd process");
- len = control_send(&ctx, argc, argv);
- if (len > 0)
- logdebugx("send OK");
- else {
- logerr("%s: control_send", __func__);
- goto exit_failure;
- }
- if (ctx.options & DHCPCD_DUMPLEASE) {
- if (dhcpcd_readdump(&ctx) == -1) {
- logerr("%s: dhcpcd_readdump", __func__);
- goto exit_failure;
- }
- goto run_loop;
- }
- goto exit_success;
- } else {
- if (errno != ENOENT)
- logerr("%s: control_open", __func__);
- /* If asking dhcpcd to exit and we failed to
- * send a signal or a message then we
- * don't proceed past here. */
- if (ctx.options & DHCPCD_DUMPLEASE ||
- sig == SIGTERM || sig == SIGALRM)
- {
- if (errno == ENOENT)
- logerrx(PACKAGE" is not running");
+ if (!(ctx.options & DHCPCD_DUMPLEASE))
+ loginfox("sending commands to dhcpcd process");
+ len = control_send(&ctx, argc, argv);
+ if (len > 0)
+ logdebugx("send OK");
+ else {
+ logerr("%s: control_send", __func__);
+ goto exit_failure;
+ }
+ if (ctx.options & DHCPCD_DUMPLEASE) {
+ if (dhcpcd_readdump(&ctx) == -1) {
+ logerr("%s: dhcpcd_readdump", __func__);
goto exit_failure;
}
- if (errno == EPERM || errno == EACCES)
- goto exit_failure;
+ goto run_loop;
}
- ctx.options &= ~DHCPCD_FORKED;
- }
-
- if (!(ctx.options & DHCPCD_TEST)) {
- /* Ensure we have the needed directories */
- if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST)
- logerr("%s: mkdir: %s", __func__, DBDIR);
- if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
- logerr("%s: mkdir: %s", __func__, RUNDIR);
- if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
- if (pid == -1)
- logerr("%s: pidfile_lock: %s",
- __func__, ctx.pidfile);
- else
- logerrx(PACKAGE
- " already running on pid %d (%s)",
- pid, ctx.pidfile);
+ goto exit_success;
+ } else {
+ if (errno != ENOENT)
+ logerr("%s: control_open", __func__);
+ /* If asking dhcpcd to exit and we failed to
+ * send a signal or a message then we
+ * don't proceed past here. */
+ if (ctx.options & DHCPCD_DUMPLEASE ||
+ sig == SIGTERM || sig == SIGALRM)
+ {
+ if (errno == ENOENT)
+ logerrx(PACKAGE" is not running");
goto exit_failure;
}
+ if (errno == EPERM || errno == EACCES)
+ goto exit_failure;
+ }
+ ctx.options &= ~DHCPCD_FORKED;
+
+ /* Ensure we have the needed directories */
+ if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST)
+ logerr("%s: mkdir: %s", __func__, DBDIR);
+ if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
+ logerr("%s: mkdir: %s", __func__, RUNDIR);
+ if ((pid = pidfile_lock(PIDFILE)) != 0) {
+ if (pid == -1)
+ logerr("%s: pidfile_lock: %s",
+ __func__, PIDFILE);
+ else
+ logerrx(PACKAGE
+ " already running on pid %d (%s)",
+ pid, PIDFILE);
+ goto exit_failure;
}
loginfox(PACKAGE "-" VERSION " starting");
logdebugx("spawned manager process on PID %d", getpid());
start_manager:
ctx.options |= DHCPCD_STARTED;
- if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
+ if ((pid = pidfile_lock(PIDFILE)) != 0) {
logerr("%s: pidfile_lock %d", __func__, pid);
#ifdef PRIVSEP
/* privsep has not started ... */
goto run_loop;
#endif
- if (!(ctx.options & DHCPCD_TEST)) {
- if (control_start(&ctx,
- ctx.options & DHCPCD_MANAGER ?
- NULL : argv[optind], family) == -1)
- {
- logerr("%s: control_start", __func__);
- goto exit_failure;
- }
+ if (control_start(&ctx) == -1) {
+ logerr("%s: control_start", __func__);
+ goto exit_failure;
}
#ifdef PLUGIN_DEV
/* Start any dev listening plugin which may want to
* change the interface name provided by the kernel */
if (!IN_PRIVSEP(&ctx) &&
- (ctx.options & (DHCPCD_MANAGER | DHCPCD_DEV)) ==
- (DHCPCD_MANAGER | DHCPCD_DEV))
+ ctx.options & DHCPCD_DEV)
dev_start(&ctx, dhcpcd_handleinterface);
#endif
- setproctitle("%s%s%s",
- ctx.options & DHCPCD_MANAGER ? "[manager]" : argv[optind],
- ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
- ctx.options & DHCPCD_IPV6 ? " [ip6]" : "");
+ setproctitle("[manager]");
if (if_opensockets(&ctx) == -1) {
logerr("%s: if_opensockets", __func__);
}
if (!(ctx.options & DHCPCD_BACKGROUND)) {
- if (ctx.options & DHCPCD_MANAGER)
- t = ifo->timeout;
- else {
- t = 0;
- TAILQ_FOREACH(ifp, ctx.ifaces, next) {
- if (ifp->active) {
- t = ifp->options->timeout;
- break;
- }
- }
- }
if (opt == 0 &&
ctx.options & DHCPCD_LINK &&
!(ctx.options & DHCPCD_WAITIP))
LOG_DEBUG : LOG_WARNING;
logmessage(loglevel, "no interfaces have a carrier");
dhcpcd_daemonise(&ctx);
- } else if (t > 0 &&
- /* Test mode removes the daemonise bit, so check for both */
- ctx.options & (DHCPCD_DAEMONISE | DHCPCD_TEST))
+ }
+ else if (ifo->timeout > 0 && ctx.options & DHCPCD_DAEMONISE)
{
- eloop_timeout_add_sec(ctx.eloop, t,
+ eloop_timeout_add_sec(ctx.eloop, ifo->timeout,
handle_exit_timeout, &ctx);
}
}
i = EXIT_FAILURE;
exit1:
- if (!(ctx.options & DHCPCD_TEST) && control_stop(&ctx) == -1)
+ if (control_stop(&ctx) == -1)
logerr("%s: control_stop", __func__);
if_freeifaddrs(&ctx, &ifaddrs);
#ifdef PRIVSEP
struct passwd;
struct dhcpcd_ctx {
- char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1];
char vendor[256];
int fork_fd; /* FD for the fork init signal pipe */
const char *cffile;
int control_fd;
int control_unpriv_fd;
struct fd_list_head control_fds;
- char control_sock[sizeof(CONTROLSOCKET) + IF_NAMESIZE];
- char control_sock_unpriv[sizeof(CONTROLSOCKET) + IF_NAMESIZE + 7];
gid_t control_group;
/* DHCP Enterprise options, RFC3925 */
ifo->options &= ~DHCPCD_IPV4LL;
break;
case 'M':
- ifo->options |= DHCPCD_MANAGER;
+ // Manager mode is always on now.
break;
case 'O':
ARG_REQUIRED;
#endif
case O_IAID:
ARG_REQUIRED;
- if (ctx->options & DHCPCD_MANAGER && !IN_CONFIG_BLOCK(ifo)) {
+ if (!IN_CONFIG_BLOCK(ifo)) {
logerrx("IAID must belong in an interface block");
return -1;
}
logwarnx("%s: IA_PD not compiled in", ifname);
return -1;
#else
- if (ctx->options & DHCPCD_MANAGER &&
- !IN_CONFIG_BLOCK(ifo))
- {
+ if (!IN_CONFIG_BLOCK(ifo)) {
logerrx("IA PD must belong in an "
"interface block");
return -1;
i = D6_OPTION_IA_PD;
#endif
}
- if (ctx->options & DHCPCD_MANAGER &&
- !IN_CONFIG_BLOCK(ifo) && arg)
- {
+ if (!IN_CONFIG_BLOCK(ifo) && arg) {
logerrx("IA with IAID must belong in an "
"interface block");
return -1;
#define DHCPCD_PERSISTENT (1ULL << 12)
#define DHCPCD_DAEMONISE (1ULL << 14)
#define DHCPCD_DAEMONISED (1ULL << 15)
-#define DHCPCD_TEST (1ULL << 16)
-#define DHCPCD_MANAGER (1ULL << 17)
+//#define DHCPCD_TEST (1ULL << 16)
+//#define DHCPCD_MANAGER (1ULL << 17)
#define DHCPCD_HOSTNAME (1ULL << 18)
#define DHCPCD_CLIENTID (1ULL << 19)
#define DHCPCD_LINK (1ULL << 20)
}
#endif
- if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) {
+ if (!(ctx->options & DHCPCD_DUMPLEASE)) {
/* Handle any platform init for the interface */
if (active != IF_INACTIVE && if_init(ifp) == -1) {
logerr("%s: if_init", ifp->name);
if (!(ifp->options->options & DHCPCD_CONFIGURE))
goto run;
if (ia == NULL) {
- if (ifp->ctx->options & DHCPCD_TEST)
- goto test;
ia = ipv4_addaddr(ifp, &state->pickedaddr,
&inaddr_llmask, &inaddr_llbcast,
DHCP_INFINITE_LIFETIME, DHCP_INFINITE_LIFETIME);
logdebugx("%s: DAD completed for %s", ifp->name, ia->saddr);
#endif
-test:
state->addr = ia;
state->down = false;
- if (ifp->ctx->options & DHCPCD_TEST) {
- script_runreason(ifp, "TEST");
- eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
- return;
- }
rt_build(ifp->ctx, AF_INET);
run:
astate = arp_announceaddr(ifp->ctx, &ia->addr);
ipv6_deletedaddr(struct ipv6_addr *ia)
{
-#ifdef DHCP6
-#ifdef PRIVSEP
- if (!(ia->iface->ctx->options & DHCPCD_MANAGER))
- ps_inet_closedhcp6(ia);
-#elif defined(SMALL)
- UNUSED(ia);
-#else
+#if defined(DHCP6) || !defined(SMALL)
/* NOREJECT is set if we delegated exactly the prefix to another
* address.
* This can only be one address, so just clear the flag.
* This should ensure the reject route will be restored. */
if (ia->delegating_prefix != NULL)
ia->delegating_prefix->flags &= ~IPV6_AF_NOREJECT;
-#endif
#else
UNUSED(ia);
#endif
if (new_data)
ipv6nd_sortrouters(ifp->ctx);
- if (ifp->ctx->options & DHCPCD_TEST) {
- script_runreason(ifp, "TEST");
- goto handle_flag;
- }
-
if (!(ifp->options->options & DHCPCD_CONFIGURE))
goto run;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */
-handle_flag:
if (!(ifp->options->options & DHCPCD_DHCP6))
goto nodhcp6;
/* Only log a DHCPv6 start error if compiled in or debugging is enabled. */
if (new_data)
logdebugx("%s: No DHCPv6 instruction in RA", ifp->name);
#endif
-nodhcp6:
- if (ifp->ctx->options & DHCPCD_TEST) {
- eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
- return;
- }
}
+nodhcp6:
/* Expire should be called last as the rap object could be destroyed */
ipv6nd_expirera(ifp);
}
ps_ctl_startcb(struct ps_process *psp)
{
struct dhcpcd_ctx *ctx = psp->psp_ctx;
- sa_family_t af;
-
- if (ctx->options & DHCPCD_MANAGER) {
- setproctitle("[control proxy]");
- af = AF_UNSPEC;
- } else {
- setproctitle("[control proxy] %s%s%s",
- ctx->ifv[0],
- ctx->options & DHCPCD_IPV4 ? " [ip4]" : "",
- ctx->options & DHCPCD_IPV6 ? " [ip6]" : "");
- if ((ctx->options &
- (DHCPCD_IPV4 | DHCPCD_IPV6)) == DHCPCD_IPV4)
- af = AF_INET;
- else if ((ctx->options &
- (DHCPCD_IPV4 | DHCPCD_IPV6)) == DHCPCD_IPV6)
- af = AF_INET6;
- else
- af = AF_UNSPEC;
- }
- return control_start(ctx,
- ctx->options & DHCPCD_MANAGER ? NULL : *ctx->ifv, af);
+ setproctitle("[control proxy]");
+ return control_start(ctx);
}
static void
}
#endif
-bool
-ps_inet_canstart(const struct dhcpcd_ctx *ctx)
-{
-
-#ifdef INET
- if ((ctx->options & (DHCPCD_IPV4 | DHCPCD_MANAGER)) ==
- (DHCPCD_IPV4 | DHCPCD_MANAGER))
- return true;
-#endif
-#if defined(INET6) && !defined(__sun)
- if (ctx->options & DHCPCD_IPV6)
- return true;
-#endif
-#ifdef DHCP6
- if ((ctx->options & (DHCPCD_IPV6 | DHCPCD_MANAGER)) ==
- (DHCPCD_IPV6 | DHCPCD_MANAGER))
- return true;
-#endif
-
- return false;
-}
-
static int
ps_inet_startcb(struct ps_process *psp)
{
struct dhcpcd_ctx *ctx = psp->psp_ctx;
int ret = 0;
- if (ctx->options & DHCPCD_MANAGER)
- setproctitle("[network proxy]");
- else
- setproctitle("[network proxy] %s%s%s",
- ctx->ifc != 0 ? ctx->ifv[0] : "",
- ctx->options & DHCPCD_IPV4 ? " [ip4]" : "",
- ctx->options & DHCPCD_IPV6 ? " [ip6]" : "");
+ setproctitle("[network proxy]");
/* This end is the main engine, so it's useless for us. */
close(ctx->ps_data_fd);
errno = 0;
#ifdef INET
- if ((ctx->options & (DHCPCD_IPV4 | DHCPCD_MANAGER)) ==
- (DHCPCD_IPV4 | DHCPCD_MANAGER))
- {
- ctx->udp_rfd = dhcp_openudp(NULL);
- if (ctx->udp_rfd == -1)
- logerr("%s: dhcp_open", __func__);
+ ctx->udp_rfd = dhcp_openudp(NULL);
+ if (ctx->udp_rfd == -1)
+ logerr("%s: dhcp_open", __func__);
#ifdef PRIVSEP_RIGHTS
- else if (ps_rights_limit_fd_rdonly(ctx->udp_rfd) == -1) {
- logerr("%s: ps_rights_limit_fd_rdonly", __func__);
- close(ctx->udp_rfd);
- ctx->udp_rfd = -1;
- }
-#endif
- else if (eloop_event_add(ctx->eloop, ctx->udp_rfd, ELE_READ,
- ps_inet_recvbootp, ctx) == -1)
- {
- logerr("%s: eloop_event_add DHCP", __func__);
- close(ctx->udp_rfd);
- ctx->udp_rfd = -1;
- } else
- ret++;
+ else if (ps_rights_limit_fd_rdonly(ctx->udp_rfd) == -1) {
+ logerr("%s: ps_rights_limit_fd_rdonly", __func__);
+ close(ctx->udp_rfd);
+ ctx->udp_rfd = -1;
}
#endif
+ else if (eloop_event_add(ctx->eloop, ctx->udp_rfd, ELE_READ,
+ ps_inet_recvbootp, ctx) == -1)
+ {
+ logerr("%s: eloop_event_add DHCP", __func__);
+ close(ctx->udp_rfd);
+ ctx->udp_rfd = -1;
+ } else
+ ret++;
+#endif
+
#if defined(INET6) && !defined(__sun)
- if (ctx->options & DHCPCD_IPV6) {
- ctx->nd_fd = ipv6nd_open(true);
- if (ctx->nd_fd == -1)
- logerr("%s: ipv6nd_open", __func__);
+ ctx->nd_fd = ipv6nd_open(true);
+ if (ctx->nd_fd == -1)
+ logerr("%s: ipv6nd_open", __func__);
#ifdef PRIVSEP_RIGHTS
- else if (ps_rights_limit_fd_rdonly(ctx->nd_fd) == -1) {
- logerr("%s: ps_rights_limit_fd_rdonly", __func__);
- close(ctx->nd_fd);
- ctx->nd_fd = -1;
- }
-#endif
- else if (eloop_event_add(ctx->eloop, ctx->nd_fd, ELE_READ,
- ps_inet_recvra, ctx) == -1)
- {
- logerr("%s: eloop_event_add RA", __func__);
- close(ctx->nd_fd);
- ctx->nd_fd = -1;
- } else
- ret++;
+ else if (ps_rights_limit_fd_rdonly(ctx->nd_fd) == -1) {
+ logerr("%s: ps_rights_limit_fd_rdonly", __func__);
+ close(ctx->nd_fd);
+ ctx->nd_fd = -1;
}
#endif
-#ifdef DHCP6
- if ((ctx->options & (DHCPCD_IPV6 | DHCPCD_MANAGER)) ==
- (DHCPCD_IPV6 | DHCPCD_MANAGER))
+ else if (eloop_event_add(ctx->eloop, ctx->nd_fd, ELE_READ,
+ ps_inet_recvra, ctx) == -1)
{
- ctx->dhcp6_rfd = dhcp6_openudp(0, NULL);
- if (ctx->dhcp6_rfd == -1)
- logerr("%s: dhcp6_open", __func__);
-#ifdef PRIVSEP_RIGHTS
- else if (ps_rights_limit_fd_rdonly(ctx->dhcp6_rfd) == -1) {
- logerr("%s: ps_rights_limit_fd_rdonly", __func__);
- close(ctx->dhcp6_rfd);
- ctx->dhcp6_rfd = -1;
- }
+ logerr("%s: eloop_event_add RA", __func__);
+ close(ctx->nd_fd);
+ ctx->nd_fd = -1;
+ } else
+ ret++;
#endif
- else if (eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, ELE_READ,
- ps_inet_recvdhcp6, ctx) == -1)
- {
- logerr("%s: eloop_event_add DHCP6", __func__);
- close(ctx->dhcp6_rfd);
- ctx->dhcp6_rfd = -1;
- } else
- ret++;
+
+#ifdef DHCP6
+ ctx->dhcp6_rfd = dhcp6_openudp(0, NULL);
+ if (ctx->dhcp6_rfd == -1)
+ logerr("%s: dhcp6_open", __func__);
+#ifdef PRIVSEP_RIGHTS
+ else if (ps_rights_limit_fd_rdonly(ctx->dhcp6_rfd) == -1) {
+ logerr("%s: ps_rights_limit_fd_rdonly", __func__);
+ close(ctx->dhcp6_rfd);
+ ctx->dhcp6_rfd = -1;
}
#endif
+ else if (eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, ELE_READ,
+ ps_inet_recvdhcp6, ctx) == -1)
+ {
+ logerr("%s: eloop_event_add DHCP6", __func__);
+ close(ctx->dhcp6_rfd);
+ ctx->dhcp6_rfd = -1;
+ } else
+ ret++;
+#endif
if (ret == 0 && errno == 0) {
errno = ENXIO;
#endif
#ifdef DHCP6
case PS_DHCP6:
- dhcp6_recvmsg(ctx, msg, NULL);
+ dhcp6_recvmsg(ctx, msg);
break;
#endif
default:
return ps_stopprocess(ctx->ps_inet);
}
-#ifdef INET
-static void
-ps_inet_recvinbootp(void *arg, unsigned short events)
-{
- struct ps_process *psp = arg;
-
- if (ps_recvmsg(psp->psp_work_fd, events,
- PS_BOOTP, psp->psp_ctx->ps_data_fd) == -1)
- logerr(__func__);
-}
-
-static int
-ps_inet_listenin(struct ps_process *psp)
-{
- struct in_addr *ia = &psp->psp_id.psi_addr.psa_in_addr;
- char buf[INET_ADDRSTRLEN];
-
- inet_ntop(AF_INET, ia, buf, sizeof(buf));
- setproctitle("[%s proxy] %s", psp->psp_protostr, buf);
-
- psp->psp_work_fd = dhcp_openudp(ia);
- if (psp->psp_work_fd == -1) {
- logerr(__func__);
- return -1;
- }
-
-#ifdef PRIVSEP_RIGHTS
- if (ps_rights_limit_fd_rdonly(psp->psp_work_fd) == -1) {
- logerr("%s: ps_rights_limit_fd_rdonly", __func__);
- return -1;
- }
-#endif
-
- if (eloop_event_add(psp->psp_ctx->eloop, psp->psp_work_fd, ELE_READ,
- ps_inet_recvinbootp, psp) == -1)
- {
- logerr("%s: eloop_event_add DHCP", __func__);
- return -1;
- }
- return 0;
-}
-#endif
-
#if defined(INET6) && defined(__sun)
static void
ps_inet_recvin6nd(void *arg)
}
#endif
-#ifdef DHCP6
-static void
-ps_inet_recvin6dhcp6(void *arg, unsigned short events)
-{
- struct ps_process *psp = arg;
-
- if (ps_recvmsg(psp->psp_work_fd, events,
- PS_DHCP6, psp->psp_ctx->ps_data_fd) == -1)
- logerr(__func__);
-}
-
-static int
-ps_inet_listenin6(struct ps_process *psp)
-{
- struct in6_addr *ia = &psp->psp_id.psi_addr.psa_in6_addr;
- char buf[INET6_ADDRSTRLEN];
-
- inet_ntop(AF_INET6, ia, buf, sizeof(buf));
- setproctitle("[%s proxy] %s", psp->psp_protostr, buf);
-
- psp->psp_work_fd = dhcp6_openudp(psp->psp_id.psi_ifindex, ia);
- if (psp->psp_work_fd == -1) {
- logerr(__func__);
- return -1;
- }
-
-#ifdef PRIVSEP_RIGHTS
- if (ps_rights_limit_fd_rdonly(psp->psp_work_fd) == -1) {
- logerr("%s: ps_rights_limit_fd_rdonly", __func__);
- return -1;
- }
-#endif
-
- if (eloop_event_add(psp->psp_ctx->eloop, psp->psp_work_fd, ELE_READ,
- ps_inet_recvin6dhcp6, psp) == -1)
- {
- logerr("%s: eloop_event_add DHCP", __func__);
- return -1;
- }
- return 0;
-}
-#endif
-
-static void
-ps_inet_recvmsgpsp(void *arg, unsigned short events)
-{
- struct ps_process *psp = arg;
-
- /* Receive shutdown. */
- if (ps_recvpsmsg(psp->psp_ctx, psp->psp_fd, events, NULL, NULL) == -1)
- logerr(__func__);
-}
-
ssize_t
ps_inet_cmd(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg)
{
uint16_t cmd;
- struct ps_process *psp;
- int (*start_func)(struct ps_process *);
- pid_t start;
- struct ps_addr *psa = &psm->ps_id.psi_addr;
- void *ia;
- char buf[INET_MAX_ADDRSTRLEN];
cmd = (uint16_t)(psm->ps_cmd & ~(PS_START | PS_STOP));
if (cmd == psm->ps_cmd)
return ps_inet_sendmsg(ctx, psm, msg);
- psp = ps_findprocess(ctx, &psm->ps_id);
-
-#ifdef PRIVSEP_DEBUG
- logerrx("%s: IN cmd %x, psp %p", __func__, psm->ps_cmd, psp);
-#endif
-
- if (psm->ps_cmd & PS_STOP) {
- assert(psp == NULL);
- return 0;
- }
-
- if (!(psm->ps_cmd & PS_START)) {
- errno = EINVAL;
- return -1;
- }
-
- if (psp != NULL)
- return 1;
-
- psp = ps_newprocess(ctx, &psm->ps_id);
- if (psp == NULL)
- return -1;
-
-
- switch (cmd) {
-#ifdef INET
- case PS_BOOTP:
- start_func = ps_inet_listenin;
- psp->psp_protostr = "BOOTP";
- ia = &psa->psa_in_addr;
- break;
-#endif
-#ifdef INET6
-#ifdef __sun
- case PS_ND:
- start_func = ps_inet_listennd;
- psp->psp_protostr = "ND";
- ia = &psa->psa_in6_addr;
- break;
-#endif
-#ifdef DHCP6
- case PS_DHCP6:
- start_func = ps_inet_listenin6;
- psp->psp_protostr = "DHCP6";
- ia = &psa->psa_in6_addr;
- break;
-#endif
-#endif
- default:
- logerrx("%s: unknown command %x", __func__, psm->ps_cmd);
- errno = ENOTSUP;
- return -1;
- }
-
- snprintf(psp->psp_name, sizeof(psp->psp_name),
- "%s proxy %s", psp->psp_protostr,
- inet_ntop(psa->psa_family, ia, buf, sizeof(buf)));
- start = ps_startprocess(psp, ps_inet_recvmsgpsp, NULL,
- start_func, NULL, PSF_DROPPRIVS);
- switch (start) {
- case -1:
- ps_freeprocess(psp);
- return -1;
- case 0:
- ps_entersandbox("stdio", NULL);
- break;
- default:
- logdebugx("%s: spawned %s on PID %d",
- psp->psp_ifname, psp->psp_name, psp->psp_pid);
- break;
- }
- return start;
+ logerrx("%s: WHY HERE?", __func__);
+ return 0;
}
#ifdef INET
-static ssize_t
-ps_inet_in_docmd(struct ipv4_addr *ia, uint16_t cmd, const struct msghdr *msg)
-{
- assert(ia != NULL);
- struct dhcpcd_ctx *ctx = ia->iface->ctx;
- struct ps_msghdr psm = {
- .ps_cmd = cmd,
- .ps_id = {
- .psi_cmd = (uint8_t)(cmd & ~(PS_START | PS_STOP)),
- .psi_ifindex = ia->iface->index,
- .psi_addr.psa_family = AF_INET,
- .psi_addr.psa_in_addr = ia->addr,
- },
- };
-
- return ps_sendpsmmsg(ctx, PS_ROOT_FD(ctx), &psm, msg);
-}
-
-ssize_t
-ps_inet_openbootp(struct ipv4_addr *ia)
-{
-
- return ps_inet_in_docmd(ia, PS_START | PS_BOOTP, NULL);
-}
-
-ssize_t
-ps_inet_closebootp(struct ipv4_addr *ia)
-{
-
- return ps_inet_in_docmd(ia, PS_STOP | PS_BOOTP, NULL);
-}
-
ssize_t
ps_inet_sendbootp(struct interface *ifp, const struct msghdr *msg)
{
#endif
#ifdef DHCP6
-static ssize_t
-ps_inet_in6_docmd(struct ipv6_addr *ia, uint16_t cmd, const struct msghdr *msg)
-{
- struct dhcpcd_ctx *ctx = ia->iface->ctx;
- struct ps_msghdr psm = {
- .ps_cmd = cmd,
- .ps_id = {
- .psi_cmd = (uint8_t)(cmd & ~(PS_START | PS_STOP)),
- .psi_ifindex = ia->iface->index,
- .psi_addr.psa_family = AF_INET6,
- .psi_addr.psa_in6_addr = ia->addr,
- },
- };
-
- return ps_sendpsmmsg(ctx, PS_ROOT_FD(ctx), &psm, msg);
-}
-
-ssize_t
-ps_inet_opendhcp6(struct ipv6_addr *ia)
-{
-
- return ps_inet_in6_docmd(ia, PS_DHCP6 | PS_START, NULL);
-}
-
-ssize_t
-ps_inet_closedhcp6(struct ipv6_addr *ia)
-{
-
- return ps_inet_in6_docmd(ia, PS_DHCP6 | PS_STOP, NULL);
-}
-
ssize_t
ps_inet_senddhcp6(struct interface *ifp, const struct msghdr *msg)
{
#ifndef PRIVSEP_INET_H
#define PRIVSEP_INET_H
-bool ps_inet_canstart(const struct dhcpcd_ctx *);
pid_t ps_inet_start(struct dhcpcd_ctx *);
int ps_inet_stop(struct dhcpcd_ctx *);
ssize_t ps_inet_cmd(struct dhcpcd_ctx *, struct ps_msghdr *, struct msghdr *);
ssize_t ps_inet_dispatch(void *, struct ps_msghdr *, struct msghdr *);
#ifdef INET
-struct ipv4_addr;
-ssize_t ps_inet_openbootp(struct ipv4_addr *);
-ssize_t ps_inet_closebootp(struct ipv4_addr *);
ssize_t ps_inet_sendbootp(struct interface *, const struct msghdr *);
#endif
#ifdef INET6
-struct ipv6_addr;
#ifdef __sun
ssize_t ps_inet_opennd(struct interface *);
ssize_t ps_inet_closend(struct interface *);
#endif
ssize_t ps_inet_sendnd(struct interface *, const struct msghdr *);
#ifdef DHCP6
-ssize_t ps_inet_opendhcp6(struct ipv6_addr *);
-ssize_t ps_inet_closedhcp6(struct ipv6_addr *);
ssize_t ps_inet_senddhcp6(struct interface *, const struct msghdr *);
#endif /* DHCP6 */
#endif /* INET6 */
{
struct dhcpcd_ctx *ctx = psp->psp_ctx;
- if (ctx->options & DHCPCD_MANAGER)
- setproctitle("[privileged proxy]");
- else
- setproctitle("[privileged proxy] %s%s%s",
- ctx->ifv[0],
- ctx->options & DHCPCD_IPV4 ? " [ip4]" : "",
- ctx->options & DHCPCD_IPV6 ? " [ip6]" : "");
+ setproctitle("[privileged proxy]");
ctx->options |= DHCPCD_PRIVSEPROOT;
if (if_opensockets(ctx) == -1)
#ifdef PLUGIN_DEV
/* Start any dev listening plugin which may want to
* change the interface name provided by the kernel */
- if ((ctx->options & (DHCPCD_MANAGER | DHCPCD_DEV)) ==
- (DHCPCD_MANAGER | DHCPCD_DEV))
+ if (ctx->options & DHCPCD_DEV)
dev_start(ctx, ps_root_handleinterface);
#endif
return 0;
/* If we are the root process then remove the pidfile */
- if (ctx->options & DHCPCD_PRIVSEPROOT &&
- !(ctx->options & DHCPCD_TEST))
- {
- if (unlink(ctx->pidfile) == -1)
- logerr("%s: unlink: %s", __func__, ctx->pidfile);
+ if (ctx->options & DHCPCD_PRIVSEPROOT) {
+ if (unlink(PIDFILE) == -1)
+ logerr("%s: unlink: %s", __func__, PIDFILE);
}
/* Only the manager process gets past this point. */
logdebugx("spawned privileged proxy on PID %d", pid);
}
- /* No point in spawning the generic network listener if we're
- * not going to use it. */
- if (!ps_inet_canstart(ctx))
- goto started_net;
-
switch (pid = ps_inet_start(ctx)) {
case -1:
return -1;
logdebugx("spawned network proxy on PID %d", pid);
}
-started_net:
- if (!(ctx->options & DHCPCD_TEST)) {
- switch (pid = ps_ctl_start(ctx)) {
- case -1:
- return -1;
- case 0:
- return 0;
- default:
- logdebugx("spawned controller proxy on PID %d", pid);
- }
+ switch (pid = ps_ctl_start(ctx)) {
+ case -1:
+ return -1;
+ case 0:
+ return 0;
+ default:
+ logdebugx("spawned controller proxy on PID %d", pid);
}
#ifdef ARC4RANDOM_H
logerr("%s: %s", __func__, sandbox);
return -1;
} else if (ctx->options & DHCPCD_LAUNCHER ||
- ((!(ctx->options & DHCPCD_DAEMONISE)) &&
- ctx->options & DHCPCD_MANAGER))
+ !(ctx->options & DHCPCD_DAEMONISE))
logdebugx("sandbox: %s", sandbox);
return 0;
}
psp->psp_pfd = -1;
#endif
- if (!(ctx->options & DHCPCD_MANAGER))
- strlcpy(psp->psp_ifname, ctx->ifv[0], sizeof(psp->psp_ifname));
TAILQ_INSERT_TAIL(&ctx->ps_processes, psp, next);
return psp;
}