-/* $OpenBSD: dhclient.c,v 1.453 2017/06/29 13:55:53 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.454 2017/07/01 23:27:55 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
int nullfd = -1;
int daemonize = 1;
int unknown_ok = 1;
-int routefd = -1;
volatile sig_atomic_t quit;
struct option_data *);
void go_daemon(void);
int rdaemon(int);
-void take_charge(struct interface_info *);
+void take_charge(struct interface_info *, int);
void set_default_client_identifier(struct interface_info *);
struct client_lease *get_recorded_lease(struct interface_info *);
}
void
-routehandler(struct interface_info *ifi)
+routehandler(struct interface_info *ifi, int routefd)
{
- char ntoabuf[INET_ADDRSTRLEN];
- struct in_addr a;
- struct sockaddr *sa;
- struct ifa_msghdr *ifam;
- struct ether_addr hw;
- struct rt_msghdr *rtm;
- struct if_msghdr *ifm;
- struct if_announcemsghdr *ifan;
- char *errmsg, *rtmmsg;
- ssize_t n;
- int linkstat, rslt;
+ char ntoabuf[INET_ADDRSTRLEN];
+ struct in_addr a;
+ struct ether_addr hw;
+ struct sockaddr *sa;
+ struct ifa_msghdr *ifam;
+ struct rt_msghdr *rtm;
+ struct if_msghdr *ifm;
+ struct if_announcemsghdr *ifan;
+ char *errmsg, *rtmmsg;
+ ssize_t n;
+ int linkstat, rslt;
rtmmsg = calloc(1, 2048);
if (rtmmsg == NULL)
char **saved_argv;
-int sock;
-
int
main(int argc, char *argv[])
{
- const char *tail_path = "/etc/resolv.conf.tail";
- struct interface_info *ifi;
- struct ifreq ifr;
- struct ieee80211_nwid nwid;
- struct stat sb;
- int ch, fd, socket_fd[2];
- struct passwd *pw;
- char *ignore_list = NULL;
- ssize_t tailn;
- int rtfilter, tailfd, q_flag, d_flag;
+ struct ieee80211_nwid nwid;
+ struct ifreq ifr;
+ struct stat sb;
+ const char *tail_path = "/etc/resolv.conf.tail";
+ struct interface_info *ifi;
+ struct passwd *pw;
+ char *ignore_list = NULL;
+ ssize_t tailn;
+ int fd, socket_fd[2];
+ int rtfilter, ioctlfd, routefd, tailfd;
+ int ch, q_flag, d_flag;
saved_argv = argv;
tzset();
/* Get the ssid if present. */
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- fatalx("Can't create socket to get ssid");
+ if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ fatalx("Can't create socket to do ioctl");
memset(&ifr, 0, sizeof(ifr));
memset(&nwid, 0, sizeof(nwid));
ifr.ifr_data = (caddr_t)&nwid;
strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
- if (ioctl(sock, SIOCG80211NWID, (caddr_t)&ifr) == 0) {
+ if (ioctl(ioctlfd, SIOCG80211NWID, (caddr_t)&ifr) == 0) {
memset(ifi->ssid, 0, sizeof(ifi->ssid));
memcpy(ifi->ssid, nwid.i_nwid, nwid.i_len);
ifi->ssid_len = nwid.i_len;
*/
ifi->linkstat = interface_status(ifi->name);
if (ifi->linkstat == 0)
- interface_link_forceup(ifi->name);
+ interface_link_forceup(ifi->name, ioctlfd);
+ close(ioctlfd);
+ ioctlfd = -1;
if ((routefd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) == -1)
fatal("socket(PF_ROUTE, SOCK_RAW)");
sizeof(ifi->rdomain)) == -1)
fatal("setsockopt(ROUTE_TABLEFILTER)");
- take_charge(ifi);
+ take_charge(ifi, routefd);
if ((fd = open(path_dhclient_db,
O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640)) == -1)
state_preboot(ifi);
}
- dispatch(ifi);
+ dispatch(ifi, routefd);
/* not reached */
return (0);
void
fork_privchld(struct interface_info *ifi, int fd, int fd2)
{
- struct pollfd pfd[1];
- struct imsgbuf *priv_ibuf;
- ssize_t n;
- int nfds, got_imsg_hup = 0;
+ struct pollfd pfd[1];
+ struct imsgbuf *priv_ibuf;
+ ssize_t n;
+ int ioctlfd, routefd, nfds, got_imsg_hup = 0;
switch (fork()) {
case -1:
imsg_init(priv_ibuf, fd);
+ if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ fatal("socket open failed");
+ if ((routefd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
+ fatal("opening socket to flush routes");
+
while (quit == 0) {
pfd[0].fd = priv_ibuf->fd;
pfd[0].events = POLLIN;
continue;
}
- got_imsg_hup = dispatch_imsg(ifi, priv_ibuf);
+ got_imsg_hup = dispatch_imsg(ifi, ioctlfd, routefd, priv_ibuf);
if (got_imsg_hup)
quit = SIGHUP;
}
+ close(routefd);
+ close(ioctlfd);
imsg_clear(priv_ibuf);
close(fd);
}
void
-take_charge(struct interface_info *ifi)
+take_charge(struct interface_info *ifi, int routefd)
{
- struct pollfd fds[1];
- struct rt_msghdr rtm;
- time_t start_time, cur_time;
- int retries;
+ struct pollfd fds[1];
+ struct rt_msghdr rtm;
+ time_t start_time, cur_time;
+ int retries;
if (time(&start_time) == -1)
fatal("time");
fatal("routefd poll");
}
if ((fds[0].revents & (POLLIN | POLLHUP)))
- routehandler(ifi);
+ routehandler(ifi, routefd);
}
}
-/* $OpenBSD: dhcpd.h,v 1.200 2017/06/29 21:37:43 krw Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.201 2017/07/01 23:27:56 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
struct ether_addr *);
/* dispatch.c */
-void dispatch(struct interface_info *);
+void dispatch(struct interface_info *, int);
void set_timeout( struct interface_info *, time_t,
void (*)(struct interface_info *));
void cancel_timeout(struct interface_info *);
-void interface_link_forceup(char *);
+void interface_link_forceup(char *, int);
int interface_status(char *);
void get_hw_address(struct interface_info *);
void sendhup(void);
/* dhclient.c */
extern char *path_dhclient_conf;
extern char *path_dhclient_db;
-extern int log_perror;
-extern int routefd;
void dhcpoffer(struct interface_info *, struct option_data *, char *);
void dhcpack(struct interface_info *, struct option_data *,char *);
void free_client_lease(struct client_lease *);
-void routehandler(struct interface_info *);
+void routehandler(struct interface_info *, int);
/* packet.c */
void assemble_eh_header(struct interface_info *, struct ether_header *);
-/* $OpenBSD: dispatch.c,v 1.129 2017/06/29 13:55:53 krw Exp $ */
+/* $OpenBSD: dispatch.c,v 1.130 2017/07/01 23:27:56 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
* Loop waiting for packets, timeouts or routing messages.
*/
void
-dispatch(struct interface_info *ifi)
+dispatch(struct interface_info *ifi, int routefd)
{
- int count, to_msec;
- struct pollfd fds[3];
- time_t cur_time, howlong;
- void (*func)(struct interface_info *);
+ struct pollfd fds[3];
+ void (*func)(struct interface_info *);
+ time_t cur_time, howlong;
+ int count, to_msec;
while (quit == 0 || quit == SIGHUP) {
if (quit == SIGHUP) {
if ((fds[0].revents & (POLLIN | POLLHUP)))
packethandler(ifi);
if ((fds[1].revents & (POLLIN | POLLHUP)))
- routehandler(ifi);
+ routehandler(ifi, routefd);
if (fds[2].revents & POLLOUT)
flush_unpriv_ibuf("dispatch");
if ((fds[2].revents & (POLLIN | POLLHUP))) {
}
void
-interface_link_forceup(char *name)
+interface_link_forceup(char *name, int ioctlfd)
{
struct ifreq ifr;
- extern int sock;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
- if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
+ if (ioctl(ioctlfd, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
log_warn("SIOCGIFFLAGS");
return;
}
/* Force it up if it isn't already. */
if ((ifr.ifr_flags & IFF_UP) == 0) {
ifr.ifr_flags |= IFF_UP;
- if (ioctl(sock, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
+ if (ioctl(ioctlfd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
log_warn("SIOCSIFFLAGS");
return;
}
-/* $OpenBSD: kroute.c,v 1.100 2017/06/29 13:55:53 krw Exp $ */
+/* $OpenBSD: kroute.c,v 1.101 2017/07/01 23:27:56 krw Exp $ */
/*
* Copyright 2012 Kenneth R Westerback <krw@openbsd.org>
int check_route_label(struct sockaddr_rtlabel *);
void populate_rti_info(struct sockaddr **, struct rt_msghdr *);
void delete_route(int, struct rt_msghdr *);
-int resolv_conf_priority(int);
+int resolv_conf_priority(int, int);
#define ROUTE_LABEL_NONE 1
}
void
-priv_flush_routes(char *name, int rdomain)
+priv_flush_routes(char *name, int routefd, int rdomain)
{
- char ifname[IF_NAMESIZE];
- struct sockaddr *rti_info[RTAX_MAX];
- int mib[7];
- size_t needed;
- char *lim, *buf = NULL, *bufp, *next, *errmsg = NULL;
- struct rt_msghdr *rtm;
- struct sockaddr_in *sa_in;
- struct sockaddr_rtlabel *sa_rl;
- int s;
+ int mib[7];
+ char ifname[IF_NAMESIZE];
+ struct sockaddr *rti_info[RTAX_MAX];
+ char *lim, *buf = NULL, *bufp, *next, *errmsg = NULL;
+ struct rt_msghdr *rtm;
+ struct sockaddr_in *sa_in;
+ struct sockaddr_rtlabel *sa_rl;
+ size_t needed;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
return;
}
- if ((s = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
- fatal("opening socket to flush routes");
-
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
switch (check_route_label(sa_rl)) {
case ROUTE_LABEL_DHCLIENT_OURS:
/* Always delete routes we labeled. */
- delete_route(s, rtm);
+ delete_route(routefd, rtm);
break;
case ROUTE_LABEL_DHCLIENT_DEAD:
- delete_route(s, rtm);
+ delete_route(routefd, rtm);
break;
case ROUTE_LABEL_DHCLIENT_LIVE:
case ROUTE_LABEL_DHCLIENT_UNKNOWN:
sa_in->sin_addr.s_addr == INADDR_ANY &&
rtm->rtm_tableid == rdomain &&
strcmp(name, ifname) == 0)
- delete_route(s, rtm);
+ delete_route(routefd, rtm);
break;
default:
break;
}
}
- close(s);
free(buf);
}
}
void
-priv_delete_address(char *name, struct imsg_delete_address *imsg)
+priv_delete_address(char *name, int ioctlfd, struct imsg_delete_address *imsg)
{
- struct ifaliasreq ifaliasreq;
- struct sockaddr_in *in;
- int s;
+ struct ifaliasreq ifaliasreq;
+ struct sockaddr_in *in;
/*
* Delete specified address on specified interface.
*/
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- fatal("socket open failed");
-
memset(&ifaliasreq, 0, sizeof(ifaliasreq));
strncpy(ifaliasreq.ifra_name, name, sizeof(ifaliasreq.ifra_name));
in->sin_addr.s_addr = imsg->addr.s_addr;
/* SIOCDIFADDR will result in a RTM_DELADDR message we must catch! */
- if (ioctl(s, SIOCDIFADDR, &ifaliasreq) == -1) {
+ if (ioctl(ioctlfd, SIOCDIFADDR, &ifaliasreq) == -1) {
if (errno != EADDRNOTAVAIL)
log_warn("SIOCDIFADDR failed (%s)",
inet_ntoa(imsg->addr));
}
-
- close(s);
}
/*
}
void
-priv_set_interface_mtu(char *name, struct imsg_set_interface_mtu *imsg)
+priv_set_interface_mtu(char *name, int ioctlfd,
+ struct imsg_set_interface_mtu *imsg)
{
struct ifreq ifr;
- int s;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_mtu = imsg->mtu;
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- fatal("socket open failed");
- if (ioctl(s, SIOCSIFMTU, &ifr) == -1)
+ if (ioctl(ioctlfd, SIOCSIFMTU, &ifr) == -1)
log_warn("SIOCSIFMTU failed (%d)", imsg->mtu);
- close(s);
}
/*
}
void
-priv_add_address(char *name, struct imsg_add_address *imsg)
+priv_add_address(char *name, int ioctlfd, struct imsg_add_address *imsg)
{
- struct ifaliasreq ifaliasreq;
- struct sockaddr_in *in;
- int s;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- fatal("socket open failed");
+ struct ifaliasreq ifaliasreq;
+ struct sockaddr_in *in;
memset(&ifaliasreq, 0, sizeof(ifaliasreq));
strncpy(ifaliasreq.ifra_name, name, sizeof(ifaliasreq.ifra_name));
/* No need to set broadcast address. Kernel can figure it out. */
- if (ioctl(s, SIOCAIFADDR, &ifaliasreq) == -1)
+ if (ioctl(ioctlfd, SIOCAIFADDR, &ifaliasreq) == -1)
log_warn("SIOCAIFADDR failed (%s)", inet_ntoa(imsg->addr));
-
- close(s);
}
/*
}
void
-priv_write_resolv_conf(int rdomain, u_int8_t *contents, size_t sz)
+priv_write_resolv_conf(u_int8_t *contents, size_t sz)
{
const char *path = "/etc/resolv.conf";
ssize_t n;
int fd;
- if (!resolv_conf_priority(rdomain))
- return;
-
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
* suppy the contents of the resolv.conf file.
*/
int
-resolv_conf_priority(int rdomain)
+resolv_conf_priority(int rdomain, int routefd)
{
struct iovec iov[3];
struct {
struct sockaddr_rtlabel *sa_rl;
pid_t pid;
ssize_t len;
- int s, seq, rslt, iovcnt = 0;
+ int seq, rslt, iovcnt = 0;
rslt = 0;
- s = socket(PF_ROUTE, SOCK_RAW, AF_INET);
- if (s == -1) {
- log_warn("default route socket");
- return (0);
- }
-
/* Build RTM header */
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
m_rtmsg.m_rtm.rtm_msglen += 2 * sizeof(sin);
- if (writev(s, iov, iovcnt) == -1) {
+ if (writev(routefd, iov, iovcnt) == -1) {
if (errno != ESRCH)
log_warn("RTM_GET of default route");
goto done;
pid = getpid();
do {
- len = read(s, &m_rtmsg, sizeof(m_rtmsg));
+ len = read(routefd, &m_rtmsg, sizeof(m_rtmsg));
if (len == -1) {
log_warn("get default route read");
break;
rslt = 1;
done:
- close(s);
return (rslt);
}
-/* $OpenBSD: privsep.c,v 1.52 2017/06/28 16:31:52 krw Exp $ */
+/* $OpenBSD: privsep.c,v 1.53 2017/07/01 23:27:56 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
#include "privsep.h"
int
-dispatch_imsg(struct interface_info *ifi, struct imsgbuf *ibuf)
+dispatch_imsg(struct interface_info *ifi, int ioctlfd, int routefd,
+ struct imsgbuf *ibuf)
{
- struct imsg imsg;
- ssize_t n;
+ struct imsg imsg;
+ ssize_t n;
for (;;) {
if ((n = imsg_get(ibuf, &imsg)) == -1)
sizeof(struct imsg_delete_address))
log_warnx("bad IMSG_DELETE_ADDRESS");
else
- priv_delete_address(ifi->name, imsg.data);
+ priv_delete_address(ifi->name, ioctlfd,
+ imsg.data);
break;
case IMSG_ADD_ADDRESS:
sizeof(struct imsg_add_address))
log_warnx("bad IMSG_ADD_ADDRESS");
else
- priv_add_address(ifi->name, imsg.data);
+ priv_add_address(ifi->name, ioctlfd, imsg.data);
break;
case IMSG_FLUSH_ROUTES:
if (imsg.hdr.len != IMSG_HEADER_SIZE)
log_warnx("bad IMSG_FLUSH_ROUTES");
else
- priv_flush_routes(ifi->name, ifi->rdomain);
+ priv_flush_routes(ifi->name, routefd,
+ ifi->rdomain);
break;
case IMSG_ADD_ROUTE:
sizeof(struct imsg_set_interface_mtu))
log_warnx("bad IMSG_SET_INTERFACE_MTU");
else
- priv_set_interface_mtu(ifi->name, imsg.data);
+ priv_set_interface_mtu(ifi->name, ioctlfd,
+ imsg.data);
break;
case IMSG_WRITE_RESOLV_CONF:
if (imsg.hdr.len <= IMSG_HEADER_SIZE)
log_warnx("short IMSG_WRITE_RESOLV_CONF");
- else
- priv_write_resolv_conf(ifi->rdomain, imsg.data,
+ else if (resolv_conf_priority(ifi->rdomain))
+ priv_write_resolv_conf(imsg.data,
imsg.hdr.len - IMSG_HEADER_SIZE);
break;
-/* $OpenBSD: privsep.h,v 1.40 2017/06/28 16:31:52 krw Exp $ */
+/* $OpenBSD: privsep.h,v 1.41 2017/07/01 23:27:56 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
int mtu;
};
-int dispatch_imsg(struct interface_info *, struct imsgbuf *);
+int dispatch_imsg(struct interface_info *, int, int, struct imsgbuf *);
void add_direct_route(struct in_addr, struct in_addr, struct in_addr);
void add_default_route(struct in_addr, struct in_addr);
void add_static_routes(struct option_data *, struct in_addr);
void add_classless_static_routes(struct option_data *, struct in_addr);
void priv_add_route(int, struct imsg_add_route *);
-void priv_flush_routes(char *, int);
+void priv_flush_routes(char *, int, int);
char *resolv_conf_contents(char *, struct option_data *,
struct option_data *, struct option_data *);
void write_resolv_conf(u_int8_t *, size_t);
-void priv_write_resolv_conf(int, u_int8_t *, size_t);
+void priv_write_resolv_conf(u_int8_t *, size_t);
-void priv_delete_address(char *, struct imsg_delete_address *);
-void priv_add_address(char *, struct imsg_add_address *);
+void priv_delete_address(char *, int, struct imsg_delete_address *);
+void priv_add_address(char *, int, struct imsg_add_address *);
-void priv_set_interface_mtu(char *, struct imsg_set_interface_mtu *);
+void priv_set_interface_mtu(char *, int, struct imsg_set_interface_mtu *);