-/* $OpenBSD: control.c,v 1.1 2017/06/03 10:00:29 florian Exp $ */
+/* $OpenBSD: control.c,v 1.2 2017/12/10 10:07:54 florian Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
return (-1);
}
- control_state.fd = fd;
-
- return (0);
+ return (fd);
}
int
-/* $OpenBSD: frontend.c,v 1.9 2017/11/04 17:23:05 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.10 2017/12/10 10:07:54 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
struct nd_opt_hdr nd_opt_hdr;
struct ether_addr nd_opt_source_link_addr;
struct sockaddr_in6 dst;
-int icmp6sock, routesock, ioctlsock;
+int icmp6sock = -1, ioctlsock;
struct icmp6_ev {
struct event ev;
}
void
-frontend(int debug, int verbose, char *sockname)
+frontend(int debug, int verbose)
{
struct event ev_sigint, ev_sigterm;
struct passwd *pw;
- struct icmp6_filter filt;
struct in6_pktinfo *pi;
struct cmsghdr *cm;
size_t rcvcmsglen, sndcmsglen;
- int hoplimit = 255, on = 1, rtfilter;
+ int hoplimit = 255;
uint8_t *rcvcmsgbuf, *sndcmsgbuf;
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
#ifndef SMALL
- /* Create slaacd control socket outside chroot. */
- if (control_init(sockname) == -1)
- fatalx("control socket setup failed");
+ control_state.fd = -1;
#endif /* SMALL */
if ((pw = getpwnam(SLAACD_USER)) == NULL)
setproctitle("%s", log_procnames[slaacd_process]);
log_procinit(log_procnames[slaacd_process]);
- if ((icmp6sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
- fatal("ICMPv6 socket");
-
- if ((routesock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
- fatal("route socket");
-
if ((ioctlsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
fatal("socket");
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
- if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
- sizeof(on)) < 0)
- fatal("IPV6_RECVPKTINFO");
-
- if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
- sizeof(on)) < 0)
- fatal("IPV6_RECVHOPLIMIT");
-
- /* only router advertisements */
- ICMP6_FILTER_SETBLOCKALL(&filt);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
- if (setsockopt(icmp6sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
- sizeof(filt)) == -1)
- fatal("ICMP6_FILTER");
-
- rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
- ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL);
- if (setsockopt(routesock, PF_ROUTE, ROUTE_MSGFILTER,
- &rtfilter, sizeof(rtfilter)) < 0)
- fatal("setsockopt(ROUTE_MSGFILTER)");
-
if (pledge("stdio inet recvfd route", NULL) == -1)
fatal("pledge");
iev_main->handler, iev_main);
event_add(&iev_main->ev, NULL);
-#ifndef SMALL
- /* Listen on control socket. */
- TAILQ_INIT(&ctl_conns);
- control_listen();
-#endif /* SMALL */
-
- event_set(&ev_route, routesock, EV_READ | EV_PERSIST, route_receive,
- NULL);
-
- event_set(&icmp6ev.ev, icmp6sock, EV_READ | EV_PERSIST, icmp6_receive,
- NULL);
-
rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int));
if((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL)
event_set(&iev_engine->ev, iev_engine->ibuf.fd,
iev_engine->events, iev_engine->handler, iev_engine);
event_add(&iev_engine->ev, NULL);
-
- if (pledge("stdio inet route", NULL) == -1)
- fatal("pledge");
-
+ break;
+ case IMSG_ICMP6SOCK:
+ if ((icmp6sock = imsg.fd) == -1)
+ fatalx("%s: expected to receive imsg "
+ "ICMPv6 fd but didn't receive any",
+ __func__);
+ event_set(&icmp6ev.ev, icmp6sock, EV_READ | EV_PERSIST,
+ icmp6_receive, NULL);
+ break;
+ case IMSG_ROUTESOCK:
+ if ((fd = imsg.fd) == -1)
+ fatalx("%s: expected to receive imsg "
+ "routesocket fd but didn't receive any",
+ __func__);
+ event_set(&ev_route, fd, EV_READ | EV_PERSIST,
+ route_receive, NULL);
+ break;
+#ifndef SMALL
+ case IMSG_CONTROLFD:
+ if ((fd = imsg.fd) == -1)
+ fatalx("%s: expected to receive imsg "
+ "control fd but didn't receive any",
+ __func__);
+ control_state.fd = fd;
+ /* Listen on control socket. */
+ TAILQ_INIT(&ctl_conns);
+ control_listen();
+#endif /* SMALL */
break;
case IMSG_STARTUP:
+ if (pledge("stdio inet route", NULL) == -1)
+ fatal("pledge");
frontend_startup();
break;
#ifndef SMALL
{
struct if_nameindex *ifnidxp, *ifnidx;
+ if (!event_initialized(&ev_route))
+ fatalx("%s: did not receive a route socket from the main "
+ "process", __func__);
+
event_add(&ev_route, NULL);
+
+ if (!event_initialized(&icmp6ev.ev))
+ fatalx("%s: did not receive a icmp6 socket fd from the main "
+ "process", __func__);
+
event_add(&icmp6ev.ev, NULL);
if ((ifnidxp = if_nameindex()) == NULL)
-/* $OpenBSD: frontend.h,v 1.2 2017/07/06 15:02:53 florian Exp $ */
+/* $OpenBSD: frontend.h,v 1.3 2017/12/10 10:07:54 florian Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns;
#endif /* SMALL */
-void frontend(int, int, char *);
+void frontend(int, int);
void frontend_dispatch_main(int, short, void *);
void frontend_dispatch_engine(int, short, void *);
int frontend_imsg_compose_main(int, pid_t, void *, uint16_t);
-/* $OpenBSD: slaacd.c,v 1.12 2017/11/03 12:28:41 florian Exp $ */
+/* $OpenBSD: slaacd.c,v 1.13 2017/12/10 10:07:54 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet6/in6_var.h>
+#include <netinet/icmp6.h>
#include <err.h>
#include <errno.h>
"IMSG_UPDATE_ADDRESS",
"IMSG_CTL_SEND_SOLICITATION",
"IMSG_SOCKET_IPC",
+ "IMSG_ICMP6SOCK",
+ "IMSG_ROUTESOCK",
+ "IMSG_CONTROLFD",
"IMSG_STARTUP",
"IMSG_UPDATE_IF",
"IMSG_REMOVE_IF",
void main_sig_handler(int, short, void *);
-static pid_t start_child(int, char *, int, int, int, char *);
+static pid_t start_child(int, char *, int, int, int);
void main_dispatch_frontend(int, short, void *);
void main_dispatch_engine(int, short, void *);
void delete_gateway(struct imsg_configure_dfr *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
+int main_imsg_compose_frontend(int, pid_t, void *, uint16_t);
+int main_imsg_compose_frontend_fd(int, pid_t, int);
+int main_imsg_compose_engine(int, pid_t, void *, uint16_t);
struct imsgev *iev_frontend;
struct imsgev *iev_engine;
int
main(int argc, char *argv[])
{
- struct event ev_sigint, ev_sigterm, ev_sighup;
- int ch;
- int debug = 0, engine_flag = 0, frontend_flag = 0;
- int verbose = 0;
- char *saved_argv0;
- int pipe_main2frontend[2];
- int pipe_main2engine[2];
+ struct event ev_sigint, ev_sigterm, ev_sighup;
+ struct icmp6_filter filt;
+ int ch;
+ int debug = 0, engine_flag = 0, frontend_flag = 0;
+ int verbose = 0;
+ char *saved_argv0;
+ int pipe_main2frontend[2];
+ int pipe_main2engine[2];
+ int icmp6sock, on = 1;
+ int frontend_routesock, rtfilter;
+ int control_fd;
csock = SLAACD_SOCKET;
if (engine_flag)
engine(debug, verbose);
else if (frontend_flag)
- frontend(debug, verbose, csock);
+ frontend(debug, verbose);
/* Check for root privileges. */
if (geteuid())
/* Start children. */
engine_pid = start_child(PROC_ENGINE, saved_argv0, pipe_main2engine[1],
- debug, verbose, NULL);
+ debug, verbose);
frontend_pid = start_child(PROC_FRONTEND, saved_argv0,
- pipe_main2frontend[1], debug, verbose, csock);
+ pipe_main2frontend[1], debug, verbose);
slaacd_process = PROC_MAIN;
fatal("pledge");
#endif
+ if ((icmp6sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
+ fatal("ICMPv6 socket");
+
+ if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
+ sizeof(on)) < 0)
+ fatal("IPV6_RECVPKTINFO");
+
+ if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
+ sizeof(on)) < 0)
+ fatal("IPV6_RECVHOPLIMIT");
+
+ /* only router advertisements */
+ ICMP6_FILTER_SETBLOCKALL(&filt);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
+ if (setsockopt(icmp6sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
+ sizeof(filt)) == -1)
+ fatal("ICMP6_FILTER");
+
+ main_imsg_compose_frontend_fd(IMSG_ICMP6SOCK, 0, icmp6sock);
+
+ if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
+ fatal("route socket");
+
+ rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
+ ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL);
+ if (setsockopt(frontend_routesock, PF_ROUTE, ROUTE_MSGFILTER,
+ &rtfilter, sizeof(rtfilter)) < 0)
+ fatal("setsockopt(ROUTE_MSGFILTER)");
+
+ main_imsg_compose_frontend_fd(IMSG_ROUTESOCK, 0, frontend_routesock);
+
+ if ((control_fd = control_init(csock)) == -1)
+ fatalx("control socket setup failed");
+
+ main_imsg_compose_frontend_fd(IMSG_CONTROLFD, 0, control_fd);
+
main_imsg_compose_frontend(IMSG_STARTUP, 0, NULL, 0);
event_dispatch();
}
static pid_t
-start_child(int p, char *argv0, int fd, int debug, int verbose, char *sockname)
+start_child(int p, char *argv0, int fd, int debug, int verbose)
{
char *argv[8];
int argc = 0;
argv[argc++] = "-v";
if (verbose > 1)
argv[argc++] = "-v";
- if (sockname) {
- argv[argc++] = "-s";
- argv[argc++] = sockname;
- }
argv[argc++] = NULL;
execvp(argv0, argv);
return (-1);
}
+int
+main_imsg_compose_frontend_fd(int type, pid_t pid, int fd)
+{
+ if (iev_frontend)
+ return (imsg_compose_event(iev_frontend, type, 0, pid, fd,
+ NULL, 0));
+ else
+ return (-1);
+}
+
int
main_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen)
{
-/* $OpenBSD: slaacd.h,v 1.10 2017/08/23 15:49:08 florian Exp $ */
+/* $OpenBSD: slaacd.h,v 1.11 2017/12/10 10:07:54 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
#endif /* SMALL */
IMSG_CTL_SEND_SOLICITATION,
IMSG_SOCKET_IPC,
+ IMSG_ICMP6SOCK,
+ IMSG_ROUTESOCK,
+ IMSG_CONTROLFD,
IMSG_STARTUP,
IMSG_UPDATE_IF,
IMSG_REMOVE_IF,
};
/* slaacd.c */
-int main_imsg_compose_frontend(int, pid_t, void *, uint16_t);
-int main_imsg_compose_engine(int, pid_t, void *, uint16_t);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, pid_t,
int, void *, uint16_t);