Skip to content

Commit 6d411f2

Browse files
authored
dhcpsd: -w waits for dynmically created interfaces (#4)
* dhcpsd: -w waits for dynmically created interfaces The interface you may want to configure might not exist when dhcpsd first starts. The -w option will cause dhcpcd to only configure an interface when it recieves a message on it. We assume if we have received a message it's ready as we cannot guess which address to use. So ensure the server address is added before the interface is marked as up! If the interface is marked as down then the interface is deconfigured. This allows dhcpsd to be used in-place of the macOS DHCP server as provided by the UTM framework.
1 parent 66d1245 commit 6d411f2

23 files changed

Lines changed: 1795 additions & 292 deletions

configure

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,19 +311,19 @@ EOF
311311
esac
312312

313313
if [ "$SANITIZEADDRESS" = yes ]; then
314-
printf "Testing compiler supports address sanitisation ..."
314+
printf "Testing compiler supports address sanitisation ... "
315315
cat <<EOF >_test.c
316316
int main(void) {
317317
return 0;
318318
}
319319
EOF
320-
if $CC -fsanitize=address _test.c -o _test 2>&3; then
320+
if $CC -fsanitize=address,undefined _test.c -o _test 2>&3; then
321321
echo "yes"
322322
echo "SANITIZEADDRESS= yes" >>$CONFIG_MK
323323
echo "CPPFLAGS+= -DASAN" >>$CONFIG_MK
324-
echo "CFLAGS+= -fsanitize=address" >>$CONFIG_MK
324+
echo "CFLAGS+= -fsanitize=address,undefined" >>$CONFIG_MK
325325
echo "CFLAGS+= -fno-omit-frame-pointer" >>$CONFIG_MK
326-
echo "LDFLAGS+= -fsanitize=address" >>$CONFIG_MK
326+
echo "LDFLAGS+= -fsanitize=address,undefined" >>$CONFIG_MK
327327
else
328328
echo "no"
329329
fi
@@ -591,6 +591,50 @@ fi
591591
rm -rf _inet_ntoa.* _inet_ntoa
592592
$abort && exit 1
593593

594+
if [ -z "$LINK_SRC" ]; then
595+
printf "Testing for route ... "
596+
cat << EOF >_route.c
597+
#include <sys/socket.h>
598+
#include <sys/types.h>
599+
#include <net/route.h>
600+
int main(void) {
601+
struct rt_msghdr rtm = { .rtm_type = RTM_IFINFO };
602+
return (int)rtm.rtm_type;
603+
}
604+
EOF
605+
if $XCC _route.c -o _route 2>&3; then
606+
LINK_SRC="route.c"
607+
echo "yes"
608+
else
609+
echo "no"
610+
fi
611+
rm -rf _route.* _route
612+
fi
613+
614+
if [ -z "$LINK_SRC" ]; then
615+
printf "Testing for netlink ... "
616+
cat << EOF >_netlink.c
617+
#include <linux/netlink.h>
618+
#include <linux/rtnetlink.h>
619+
#include <sys/socket.h>
620+
int main(void) {
621+
return 0;
622+
}
623+
EOF
624+
if $XCC _netlink.c -o _netlink 2>&3; then
625+
LINK_SRC="netlink.c"
626+
echo "yes"
627+
else
628+
echo "no"
629+
fi
630+
rm -rf _netlink.* _netlink
631+
fi
632+
if [ -z "$LINK_SRC" ]; then
633+
echo "no mechanism for detecting interface departures found" >&2
634+
exit 1
635+
fi
636+
echo "LINK_SRC= $LINK_SRC" >>$CONFIG_MK
637+
594638
if [ -z "$SETPROCTITLE" ]; then
595639
printf "Testing for setproctitle ... "
596640
cat << EOF >_setproctitle.c
@@ -742,7 +786,5 @@ echo " LIBDIR = $LIBDIR"
742786
echo " DATADIR = $DATADIR"
743787
echo " RUNDIR = $RUNDIR"
744788
echo " MANDIR = $MANDIR"
745-
if [ "$PRIVSEP" = yes ]; then
746-
echo " PRIVSEPUSER = $PRIVSEP_USER"
747-
fi
789+
echo " DHCPSD_USER = $DHCPSD_USER"
748790
echo

src/Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ PROG= dhcpsd
44
SRCS= dhcpsd.c common.c eloop.c if.c logerr.c
55
SRCS+= bpf.c dhcp.c dhcp_lease.c
66
SRCS+= if_none.c if_ether.c
7-
SRCS+= service.c unpriv.c
7+
SRCS+= service.c priv.c unpriv.c
88
SRCS+= plugin.c
9-
OBJS+= ${SRCS:.c=.o}
9+
SRCS+= ${LINK_SRC}
10+
OBJS+= ${SRCS:.c=.o}
1011

1112
PVENDOR_SRCS= ${VENDOR_SRCS:vendor/%=${TOP}/vendor/%}
12-
OBJS+= ${PVENDOR_SRCS:.c=.o}
13+
OBJS+= ${PVENDOR_SRCS:.c=.o}
1314

1415
PCOMPAT_SRCS= ${COMPAT_SRCS:compat/%=${TOP}/compat/%}
15-
OBJS+= ${PCOMPAT_SRCS:.c=.o}
16+
OBJS+= ${PCOMPAT_SRCS:.c=.o}
1617

1718
CFLAGS?= -O2
1819
SUBDIRS= plugins

src/bpf.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ bpf_open(const struct interface *ifp, int (*filter)(const struct bpf *),
397397
#else
398398
struct bpf_version pv = { .bv_major = 0, .bv_minor = 0 };
399399
struct ifreq ifr = { .ifr_flags = 0 };
400-
#if 0
400+
#if 1
401401
int ibuf_len = 0;
402402
#endif
403403
unsigned int imm;
@@ -506,7 +506,6 @@ bpf_open(const struct interface *ifp, int (*filter)(const struct bpf *),
506506
#ifdef __linux__
507507
UNUSED(flags);
508508
#else
509-
#if 0
510509
if (flags & (O_RDONLY | O_RDWR)) {
511510
/* Get the required BPF buffer length from the kernel. */
512511
if (ioctl(bpf->bpf_fd, BIOCGBLEN, &ibuf_len) == -1)
@@ -517,7 +516,6 @@ bpf_open(const struct interface *ifp, int (*filter)(const struct bpf *),
517516
if (bpf->bpf_buffer == NULL)
518517
goto eexit;
519518
}
520-
#endif
521519
#endif
522520

523521
return bpf;
@@ -568,7 +566,8 @@ bpf_read(struct bpf *bpf, void *data, size_t len)
568566
bytes = (ssize_t)len;
569567
else
570568
bytes = (ssize_t)packet.bh_caplen;
571-
memcpy(data, payload, (size_t)bytes);
569+
if (data)
570+
memcpy(data, payload, (size_t)bytes);
572571
next:
573572
bpf->bpf_pos += BPF_WORDALIGN(
574573
packet.bh_hdrlen + packet.bh_caplen);

src/common.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
#include <netinet/in.h>
3232

33+
#ifdef AF_PACKET
34+
#include <netpacket/packet.h>
35+
#endif
36+
3337
#include <arpa/inet.h>
3438
#include <arpa/nameser.h>
3539
#include <ctype.h>
@@ -414,13 +418,30 @@ inet_ntocidr(struct in_addr *addr)
414418
return cidr;
415419
}
416420

417-
size_t
421+
int
422+
sa_is_link(const struct sockaddr *sa)
423+
{
424+
#ifdef AF_LINK
425+
return sa->sa_family == AF_LINK ? 1 : 0;
426+
#elif defined(AF_PACKET)
427+
return sa->sa_family == AF_PACKET ? 1 : 0;
428+
#else
429+
errno = EAFNOSUPPORT;
430+
return -1;
431+
#endif
432+
}
433+
434+
socklen_t
418435
sa_len(const struct sockaddr *sa)
419436
{
420437
#ifdef BSD
421438
return sa->sa_len;
422439
#else
423440
switch (sa->sa_family) {
441+
#ifdef AF_PACKET
442+
case AF_PACKET:
443+
return sizeof(struct sockaddr_ll);
444+
#endif
424445
case AF_INET:
425446
return sizeof(struct sockaddr_in);
426447
case AF_INET6:

src/common.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@
4949
#define UNUSED(a) (void)(a)
5050
#define ARRAYCOUNT(a) (sizeof((a)) / sizeof((a)[0]))
5151

52+
#ifndef ALIGNBYTES
53+
#define ALIGNBYTES (sizeof(int) - 1)
54+
#endif
55+
#ifndef ALIGN
56+
#define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
57+
#endif
58+
5259
/* Some systems don't define timespec macros */
5360
#ifndef timespecclear
5461
#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
@@ -100,7 +107,8 @@ uint8_t inet_ntocidr(struct in_addr *);
100107

101108
struct sockaddr;
102109

103-
size_t sa_len(const struct sockaddr *);
110+
int sa_is_link(const struct sockaddr *);
111+
socklen_t sa_len(const struct sockaddr *);
104112
int sa_cmp(const struct sockaddr *, const struct sockaddr *);
105113
#define ss_len(ss) sa_len((const struct sockaddr *)(ss))
106114
int sa_pton(struct sockaddr *, const char *restrict);

0 commit comments

Comments
 (0)