Import NetBSD dhcpcd(8)

The port could be improved by adding support for pselect(2).

Other than that, this port has a few MINIX-specific changes:

- we undefine IN_IFF_ flags to stop dhcpcd from thinking that we have
  operating system support for link-local IPv4 address management;
- we work around one crash bug that seems triggered by using dhcpcd
  on some but not all interfaces;
- we add "noalias" to the default dhcpcd.conf(5) configuration file.

Change-Id: I8a81c2c2af353c5ce08335673b1ab2d4b39178da
This commit is contained in:
David van Moolenbroek 2017-02-16 15:54:23 +00:00
parent d642636d2d
commit 9f20bfa6c4
72 changed files with 31203 additions and 2 deletions

View File

@ -94,6 +94,7 @@
./etc/devmand/scripts/singlechar minix-base
./etc/devmand/usb_hub.cfg minix-base
./etc/devmand/usb_storage.cfg minix-base
./etc/dhcpcd.conf minix-base
./etc/fonts minix-base xorg
./etc/fonts/conf.avail minix-base xorg
./etc/fonts/conf.d minix-base xorg
@ -134,6 +135,7 @@
./etc/rc.d/SERVERS minix-base
./etc/rc.d/blacklistd minix-base
./etc/rc.d/bootconf.sh minix-base
./etc/rc.d/dhcpcd minix-base
./etc/rc.d/fsck minix-base
./etc/rc.d/ftpd minix-base
./etc/rc.d/inetd minix-base
@ -197,6 +199,16 @@
./home/bin/.profile minix-base obsolete
./lib minix-base
./libexec minix-base
./libexec/dhcpcd-hooks minix-base
./libexec/dhcpcd-hooks/01-test minix-base
./libexec/dhcpcd-hooks/02-dump minix-base
./libexec/dhcpcd-hooks/10-wpa_supplicant minix-base
./libexec/dhcpcd-hooks/15-timezone minix-base
./libexec/dhcpcd-hooks/20-resolv.conf minix-base
./libexec/dhcpcd-hooks/29-lookup-hostname minix-base
./libexec/dhcpcd-hooks/30-hostname minix-base
./libexec/dhcpcd-hooks/50-ntp.conf minix-base
./libexec/dhcpcd-run-hooks minix-base
./libexec/resolvconf minix-base
./libexec/resolvconf/dnsmasq minix-base
./libexec/resolvconf/libc minix-base
@ -214,6 +226,7 @@
./sbin/blacklistctl minix-base
./sbin/blacklistd minix-base
./sbin/chown minix-base
./sbin/dhcpcd minix-base
./sbin/fsck minix-base
./sbin/fsck_ext2fs minix-base
./sbin/fsck_mfs minix-base

View File

@ -160,6 +160,7 @@
./usr/libdata/debug/sbin/blacklistctl.debug minix-debug debug
./usr/libdata/debug/sbin/blacklistd.debug minix-debug debug
./usr/libdata/debug/sbin/chown.debug minix-debug debug
./usr/libdata/debug/sbin/dhcpcd.debug minix-debug debug
./usr/libdata/debug/sbin/fsck.debug minix-debug debug
./usr/libdata/debug/sbin/fsck_ext2fs.debug minix-debug debug
./usr/libdata/debug/sbin/fsck_mfs.debug minix-debug debug

View File

@ -3281,6 +3281,7 @@
./usr/man/man5/cpio.5 minix-man
./usr/man/man5/crontab.5 minix-man
./usr/man/man5/dhcp.conf.5 minix-man obsolete
./usr/man/man5/dhcpcd.conf.5 minix-man
./usr/man/man5/dir.5 minix-man obsolete
./usr/man/man5/editrc.5 minix-man
./usr/man/man5/ethers.5 minix-man obsolete
@ -3396,6 +3397,8 @@
./usr/man/man8/cron.8 minix-man
./usr/man/man8/dev_mkdb.8 minix-man
./usr/man/man8/devsize.8 minix-man
./usr/man/man8/dhcpcd-run-hooks.8 minix-man
./usr/man/man8/dhcpcd.8 minix-man
./usr/man/man8/dhcpd.8 minix-man obsolete
./usr/man/man8/diskctl.8 minix-man
./usr/man/man8/fbdctl.8 minix-man

View File

@ -485,6 +485,7 @@ install-etc-files-safe: .PHONY .MAKE check_DESTDIR MAKEDEV
.for subdir in . defaults mtree rc.d root skel
${MAKEDIRTARGET} ${subdir} configinstall
.endfor
${MAKEDIRTARGET} ${NETBSDSRCDIR}/external/bsd/dhcpcd/sbin/dhcpcd configinstall
${_MKMSG_INSTALL} ${DESTDIR}/usr/lib/fonts
${INSTALL_DIR} ${DESTDIR}/usr/lib/fonts
${INSTALL_FILE} -m ${BINMODE} -o ${BINOWN} -g ${BINGRP} ${NETBSDSRCDIR}/etc/fonts/*.fnt ${DESTDIR}/usr/lib/fonts/

View File

@ -57,6 +57,7 @@
./home
./lib
./libexec
./libexec/dhcpcd-hooks
./libexec/resolvconf
./mnt
./proc

View File

@ -30,7 +30,7 @@ CONFIGFILES=\
\
bootconf.sh \
\
\
dhcpcd \
fsck ftpd \
\
\

36
etc/rc.d/dhcpcd Executable file
View File

@ -0,0 +1,36 @@
#!/bin/sh
# PROVIDE: dhcpcd
# REQUIRE: network mountcritlocal
# BEFORE: NETWORKING
$_rc_subr_loaded . /etc/rc.subr
name=dhcpcd
rcvar=$name
command=/sbin/$name
extra_commands="reload"
load_rc_config $name
# If the last argument to dhcpcd is a valid interface and the prior argument
# is not then dhcpcd will start on one interface only and create a pidfile
# based on the interface name. See PR bin/43490.
if [ -n "$flags" ]; then
myflags=$flags
else
eval myflags=\$${name}_flags
fi
ifname="${myflags##* }"
myflags="${myflags%% $ifname}"
last_flag="${myflags##* }"
if /sbin/ifconfig "$ifname" >/dev/null 2>&1 &&
! /sbin/ifconfig "$last_flag" >/dev/null 2>&1
then
pidfile=/var/run/$name-"$ifname".pid
else
pidfile=/var/run/$name.pid
fi
unset myflags ifname last_flag
run_rc_command "$1"

View File

@ -3,7 +3,7 @@
.include <bsd.own.mk>
#MINIX:
SUBDIR= byacc \
SUBDIR= byacc dhcpcd \
fetch file flex less \
libarchive libevent mdocml \
openresolv tmux top

5
external/bsd/dhcpcd/Makefile vendored Normal file
View File

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2008/07/27 19:31:03 joerg Exp $
SUBDIR= sbin
.include <bsd.subdir.mk>

442
external/bsd/dhcpcd/dist/arp.c vendored Normal file
View File

@ -0,0 +1,442 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: arp.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ELOOP_QUEUE 5
#include "config.h"
#include "arp.h"
#include "if.h"
#include "ipv4.h"
#include "common.h"
#include "dhcpcd.h"
#include "eloop.h"
#include "if.h"
#include "if-options.h"
#include "ipv4ll.h"
#define ARP_LEN \
(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
static ssize_t
arp_request(const struct interface *ifp, in_addr_t sip, in_addr_t tip)
{
uint8_t arp_buffer[ARP_LEN];
struct arphdr ar;
size_t len;
uint8_t *p;
ar.ar_hrd = htons(ifp->family);
ar.ar_pro = htons(ETHERTYPE_IP);
ar.ar_hln = ifp->hwlen;
ar.ar_pln = sizeof(sip);
ar.ar_op = htons(ARPOP_REQUEST);
p = arp_buffer;
len = 0;
#define CHECK(fun, b, l) \
do { \
if (len + (l) > sizeof(arp_buffer)) \
goto eexit; \
fun(p, (b), (l)); \
p += (l); \
len += (l); \
} while (/* CONSTCOND */ 0)
#define APPEND(b, l) CHECK(memcpy, b, l)
#define ZERO(l) CHECK(memset, 0, l)
APPEND(&ar, sizeof(ar));
APPEND(ifp->hwaddr, ifp->hwlen);
APPEND(&sip, sizeof(sip));
ZERO(ifp->hwlen);
APPEND(&tip, sizeof(tip));
return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len);
eexit:
errno = ENOBUFS;
return -1;
}
void
arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
{
if (amsg != NULL) {
char buf[HWADDR_LEN * 3];
logger(astate->iface->ctx, LOG_ERR,
"%s: hardware address %s claims %s",
astate->iface->name,
hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
buf, sizeof(buf)),
inet_ntoa(astate->failed));
} else
logger(astate->iface->ctx, LOG_ERR,
"%s: DAD detected %s",
astate->iface->name, inet_ntoa(astate->failed));
}
static void
arp_packet(void *arg)
{
struct interface *ifp = arg;
const struct interface *ifn;
uint8_t arp_buffer[ARP_LEN];
struct arphdr ar;
struct arp_msg arm;
ssize_t bytes;
struct iarp_state *state;
struct arp_state *astate, *astaten;
unsigned char *hw_s, *hw_t;
int flags;
state = ARP_STATE(ifp);
flags = 0;
while (!(flags & RAW_EOF)) {
bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
arp_buffer, sizeof(arp_buffer), &flags);
if (bytes == -1) {
logger(ifp->ctx, LOG_ERR,
"%s: arp if_readrawpacket: %m", ifp->name);
arp_close(ifp);
return;
}
/* We must have a full ARP header */
if ((size_t)bytes < sizeof(ar))
continue;
memcpy(&ar, arp_buffer, sizeof(ar));
/* Families must match */
if (ar.ar_hrd != htons(ifp->family))
continue;
/* Protocol must be IP. */
if (ar.ar_pro != htons(ETHERTYPE_IP))
continue;
if (ar.ar_pln != sizeof(arm.sip.s_addr))
continue;
/* Only these types are recognised */
if (ar.ar_op != htons(ARPOP_REPLY) &&
ar.ar_op != htons(ARPOP_REQUEST))
continue;
/* Get pointers to the hardware addreses */
hw_s = arp_buffer + sizeof(ar);
hw_t = hw_s + ar.ar_hln + ar.ar_pln;
/* Ensure we got all the data */
if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
continue;
/* Ignore messages from ourself */
TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
if (ar.ar_hln == ifn->hwlen &&
memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
break;
}
if (ifn)
continue;
/* Copy out the HW and IP addresses */
memcpy(&arm.sha, hw_s, ar.ar_hln);
memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
memcpy(&arm.tha, hw_t, ar.ar_hln);
memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
/* Run the conflicts */
TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
if (astate->conflicted_cb)
astate->conflicted_cb(astate, &arm);
}
}
}
static void
arp_open(struct interface *ifp)
{
struct iarp_state *state;
state = ARP_STATE(ifp);
if (state->fd == -1) {
state->fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
if (state->fd == -1) {
logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
__func__, ifp->name);
return;
}
eloop_event_add(ifp->ctx->eloop, state->fd,
arp_packet, ifp, NULL, NULL);
}
}
static void
arp_announced(void *arg)
{
struct arp_state *astate = arg;
if (astate->announced_cb) {
astate->announced_cb(astate);
return;
}
/* Nothing more to do, so free us */
arp_free(astate);
}
static void
arp_announce1(void *arg)
{
struct arp_state *astate = arg;
struct interface *ifp = astate->iface;
if (++astate->claims < ANNOUNCE_NUM)
logger(ifp->ctx, LOG_DEBUG,
"%s: ARP announcing %s (%d of %d), "
"next in %d.0 seconds",
ifp->name, inet_ntoa(astate->addr),
astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
else
logger(ifp->ctx, LOG_DEBUG,
"%s: ARP announcing %s (%d of %d)",
ifp->name, inet_ntoa(astate->addr),
astate->claims, ANNOUNCE_NUM);
if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr) == -1)
logger(ifp->ctx, LOG_ERR, "send_arp: %m");
eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
astate);
}
void
arp_announce(struct arp_state *astate)
{
arp_open(astate->iface);
astate->claims = 0;
arp_announce1(astate);
}
static void
arp_probed(void *arg)
{
struct arp_state *astate = arg;
astate->probed_cb(astate);
}
static void
arp_probe1(void *arg)
{
struct arp_state *astate = arg;
struct interface *ifp = astate->iface;
struct timespec tv;
if (++astate->probes < PROBE_NUM) {
tv.tv_sec = PROBE_MIN;
tv.tv_nsec = (suseconds_t)arc4random_uniform(
(PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
timespecnorm(&tv);
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
} else {
tv.tv_sec = ANNOUNCE_WAIT;
tv.tv_nsec = 0;
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
}
logger(ifp->ctx, LOG_DEBUG,
"%s: ARP probing %s (%d of %d), next in %0.1f seconds",
ifp->name, inet_ntoa(astate->addr),
astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
timespec_to_double(&tv));
if (arp_request(ifp, 0, astate->addr.s_addr) == -1)
logger(ifp->ctx, LOG_ERR, "send_arp: %m");
}
void
arp_probe(struct arp_state *astate)
{
arp_open(astate->iface);
astate->probes = 0;
logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s",
astate->iface->name, inet_ntoa(astate->addr));
arp_probe1(astate);
}
struct arp_state *
arp_find(struct interface *ifp, const struct in_addr *addr)
{
struct iarp_state *state;
struct arp_state *astate;
if ((state = ARP_STATE(ifp)) == NULL)
goto out;
TAILQ_FOREACH(astate, &state->arp_states, next) {
if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
return astate;
}
out:
errno = ESRCH;
return NULL;
}
struct arp_state *
arp_new(struct interface *ifp, const struct in_addr *addr)
{
struct iarp_state *state;
struct arp_state *astate;
if ((state = ARP_STATE(ifp)) == NULL) {
ifp->if_data[IF_DATA_ARP] = malloc(sizeof(*state));
state = ARP_STATE(ifp);
if (state == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
state->fd = -1;
TAILQ_INIT(&state->arp_states);
} else {
if (addr && (astate = arp_find(ifp, addr)))
return astate;
}
if ((astate = calloc(1, sizeof(*astate))) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
return NULL;
}
astate->iface = ifp;
if (addr)
astate->addr = *addr;
state = ARP_STATE(ifp);
TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
return astate;
}
void
arp_cancel(struct arp_state *astate)
{
eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
}
void
arp_free(struct arp_state *astate)
{
if (astate != NULL) {
struct interface *ifp;
struct iarp_state *state;
ifp = astate->iface;
eloop_timeout_delete(ifp->ctx->eloop, NULL, astate);
state = ARP_STATE(ifp);
TAILQ_REMOVE(&state->arp_states, astate, next);
if (astate->free_cb)
astate->free_cb(astate);
free(astate);
/* If there are no more ARP states, close the socket. */
if (state->fd != -1 &&
TAILQ_FIRST(&state->arp_states) == NULL)
{
eloop_event_delete(ifp->ctx->eloop, state->fd);
close(state->fd);
free(state);
ifp->if_data[IF_DATA_ARP] = NULL;
}
}
}
void
arp_free_but(struct arp_state *astate)
{
struct iarp_state *state;
struct arp_state *p, *n;
state = ARP_STATE(astate->iface);
TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
if (p != astate)
arp_free(p);
}
}
void
arp_close(struct interface *ifp)
{
struct iarp_state *state;
struct arp_state *astate;
/* Freeing the last state will also free the main state,
* so test for both. */
for (;;) {
if ((state = ARP_STATE(ifp)) == NULL ||
(astate = TAILQ_FIRST(&state->arp_states)) == NULL)
break;
arp_free(astate);
}
}
void
arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
int flags)
{
#ifdef IN_IFF_DUPLICATED
struct iarp_state *state;
struct arp_state *astate, *asn;
if (cmd != RTM_NEWADDR || (state = ARP_STATE(ifp)) == NULL)
return;
TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
if (astate->addr.s_addr == addr->s_addr) {
if (flags & IN_IFF_DUPLICATED) {
if (astate->conflicted_cb)
astate->conflicted_cb(astate, NULL);
} else if (!(flags & IN_IFF_NOTUSEABLE)) {
if (astate->probed_cb)
astate->probed_cb(astate);
}
}
}
#else
UNUSED(cmd);
UNUSED(ifp);
UNUSED(addr);
UNUSED(flags);
#endif
}

96
external/bsd/dhcpcd/dist/arp.h vendored Normal file
View File

@ -0,0 +1,96 @@
/* $NetBSD: arp.h,v 1.11 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ARP_H
#define ARP_H
/* ARP timings from RFC5227 */
#define PROBE_WAIT 1
#define PROBE_NUM 3
#define PROBE_MIN 1
#define PROBE_MAX 2
#define ANNOUNCE_WAIT 2
#define ANNOUNCE_NUM 2
#define ANNOUNCE_INTERVAL 2
#define MAX_CONFLICTS 10
#define RATE_LIMIT_INTERVAL 60
#define DEFEND_INTERVAL 10
#include "dhcpcd.h"
struct arp_msg {
uint16_t op;
unsigned char sha[HWADDR_LEN];
struct in_addr sip;
unsigned char tha[HWADDR_LEN];
struct in_addr tip;
};
struct arp_state {
TAILQ_ENTRY(arp_state) next;
struct interface *iface;
void (*probed_cb)(struct arp_state *);
void (*announced_cb)(struct arp_state *);
void (*conflicted_cb)(struct arp_state *, const struct arp_msg *);
void (*free_cb)(struct arp_state *);
struct in_addr addr;
int probes;
int claims;
struct in_addr failed;
};
TAILQ_HEAD(arp_statehead, arp_state);
struct iarp_state {
int fd;
struct arp_statehead arp_states;
};
#define ARP_STATE(ifp) \
((struct iarp_state *)(ifp)->if_data[IF_DATA_ARP])
#define ARP_CSTATE(ifp) \
((const struct iarp_state *)(ifp)->if_data[IF_DATA_ARP])
#ifdef INET
void arp_report_conflicted(const struct arp_state *, const struct arp_msg *);
void arp_announce(struct arp_state *);
void arp_probe(struct arp_state *);
struct arp_state *arp_new(struct interface *, const struct in_addr *);
void arp_cancel(struct arp_state *);
void arp_free(struct arp_state *);
void arp_free_but(struct arp_state *);
struct arp_state *arp_find(struct interface *, const struct in_addr *);
void arp_close(struct interface *);
void arp_handleifa(int, struct interface *, const struct in_addr *, int);
#else
#define arp_close(a) {}
#endif
#endif

674
external/bsd/dhcpcd/dist/auth.c vendored Normal file
View File

@ -0,0 +1,674 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: auth.c,v 1.10 2015/07/09 10:15:34 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/file.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "config.h"
#include "auth.h"
#include "crypt/crypt.h"
#include "dhcp.h"
#include "dhcp6.h"
#include "dhcpcd.h"
#ifdef __sun
#define htonll
#define ntohll
#endif
#ifndef htonll
#if (BYTE_ORDER == LITTLE_ENDIAN)
static inline uint64_t
htonll(uint64_t x)
{
return (uint64_t)htonl((uint32_t)(x >> 32)) |
(uint64_t)htonl((uint32_t)(x & 0xffffffff)) << 32;
}
#else /* (BYTE_ORDER == LITTLE_ENDIAN) */
#define htonll(x) (x)
#endif
#endif /* htonll */
#ifndef ntohll
#if (BYTE_ORDER == LITTLE_ENDIAN)
static inline uint64_t
ntohll(uint64_t x)
{
return (uint64_t)ntohl((uint32_t)(x >> 32)) |
(uint64_t)ntohl((uint32_t)(x & 0xffffffff)) << 32;
}
#else /* (BYTE_ORDER == LITTLE_ENDIAN) */
#define ntohll(x) (x)
#endif
#endif /* ntohll */
#define HMAC_LENGTH 16
void
dhcp_auth_reset(struct authstate *state)
{
state->replay = 0;
if (state->token) {
free(state->token->key);
free(state->token->realm);
free(state->token);
state->token = NULL;
}
if (state->reconf) {
free(state->reconf->key);
free(state->reconf->realm);
free(state->reconf);
state->reconf = NULL;
}
}
/*
* Authenticate a DHCP message.
* m and mlen refer to the whole message.
* t is the DHCP type, pass it 4 or 6.
* data and dlen refer to the authentication option within the message.
*/
const struct token *
dhcp_auth_validate(struct authstate *state, const struct auth *auth,
const uint8_t *m, size_t mlen, int mp, int mt,
const uint8_t *data, size_t dlen)
{
uint8_t protocol, algorithm, rdm, *mm, type;
uint64_t replay;
uint32_t secretid;
const uint8_t *d, *realm;
size_t realm_len;
const struct token *t;
time_t now;
uint8_t hmac[HMAC_LENGTH];
if (dlen < 3 + sizeof(replay)) {
errno = EINVAL;
return NULL;
}
/* Ensure that d is inside m which *may* not be the case for DHPCPv4 */
if (data < m || data > m + mlen || data + dlen > m + mlen) {
errno = ERANGE;
return NULL;
}
d = data;
protocol = *d++;
algorithm = *d++;
rdm = *d++;
if (!(auth->options & DHCPCD_AUTH_SEND)) {
/* If we didn't send any authorisation, it can only be a
* reconfigure key */
if (protocol != AUTH_PROTO_RECONFKEY) {
errno = EINVAL;
return NULL;
}
} else if (protocol != auth->protocol ||
algorithm != auth->algorithm ||
rdm != auth->rdm)
{
/* As we don't require authentication, we should still
* accept a reconfigure key */
if (protocol != AUTH_PROTO_RECONFKEY ||
auth->options & DHCPCD_AUTH_REQUIRE)
{
errno = EPERM;
return NULL;
}
}
dlen -= 3;
memcpy(&replay, d, sizeof(replay));
replay = ntohll(replay);
if (state->token) {
if (state->replay == (replay ^ 0x8000000000000000ULL)) {
/* We don't know if the singular point is increasing
* or decreasing. */
errno = EPERM;
return NULL;
}
if ((uint64_t)(replay - state->replay) <= 0) {
/* Replay attack detected */
errno = EPERM;
return NULL;
}
}
d+= sizeof(replay);
dlen -= sizeof(replay);
realm = NULL;
realm_len = 0;
/* Extract realm and secret.
* Rest of data is MAC. */
switch (protocol) {
case AUTH_PROTO_TOKEN:
secretid = 0;
break;
case AUTH_PROTO_DELAYED:
if (dlen < sizeof(secretid) + sizeof(hmac)) {
errno = EINVAL;
return NULL;
}
memcpy(&secretid, d, sizeof(secretid));
d += sizeof(secretid);
dlen -= sizeof(secretid);
break;
case AUTH_PROTO_DELAYEDREALM:
if (dlen < sizeof(secretid) + sizeof(hmac)) {
errno = EINVAL;
return NULL;
}
realm_len = dlen - (sizeof(secretid) + sizeof(hmac));
if (realm_len) {
realm = d;
d += realm_len;
dlen -= realm_len;
}
memcpy(&secretid, d, sizeof(secretid));
d += sizeof(secretid);
dlen -= sizeof(secretid);
break;
case AUTH_PROTO_RECONFKEY:
if (dlen != 1 + 16) {
errno = EINVAL;
return NULL;
}
type = *d++;
dlen--;
switch (type) {
case 1:
if ((mp == 4 && mt == DHCP_ACK) ||
(mp == 6 && mt == DHCP6_REPLY))
{
if (state->reconf == NULL) {
state->reconf =
malloc(sizeof(*state->reconf));
if (state->reconf == NULL)
return NULL;
state->reconf->key = malloc(16);
if (state->reconf->key == NULL) {
free(state->reconf);
state->reconf = NULL;
return NULL;
}
state->reconf->secretid = 0;
state->reconf->expire = 0;
state->reconf->realm = NULL;
state->reconf->realm_len = 0;
state->reconf->key_len = 16;
}
memcpy(state->reconf->key, d, 16);
} else {
errno = EINVAL;
return NULL;
}
if (state->reconf == NULL)
errno = ENOENT;
/* Free the old token so we log acceptance */
if (state->token) {
free(state->token);
state->token = NULL;
}
/* Nothing to validate, just accepting the key */
return state->reconf;
case 2:
if (!((mp == 4 && mt == DHCP_FORCERENEW) ||
(mp == 6 && mt == DHCP6_RECONFIGURE)))
{
errno = EINVAL;
return NULL;
}
if (state->reconf == NULL) {
errno = ENOENT;
return NULL;
}
t = state->reconf;
goto gottoken;
default:
errno = EINVAL;
return NULL;
}
default:
errno = ENOTSUP;
return NULL;
}
/* Find a token for the realm and secret */
secretid = ntohl(secretid);
TAILQ_FOREACH(t, &auth->tokens, next) {
if (t->secretid == secretid &&
t->realm_len == realm_len &&
(t->realm_len == 0 ||
memcmp(t->realm, realm, t->realm_len) == 0))
break;
}
if (t == NULL) {
errno = ESRCH;
return NULL;
}
if (t->expire) {
if (time(&now) == -1)
return NULL;
if (t->expire < now) {
errno = EFAULT;
return NULL;
}
}
gottoken:
/* First message from the server */
if (state->token &&
(state->token->secretid != t->secretid ||
state->token->realm_len != t->realm_len ||
memcmp(state->token->realm, t->realm, t->realm_len)))
{
errno = EPERM;
return NULL;
}
/* Special case as no hashing needs to be done. */
if (protocol == AUTH_PROTO_TOKEN) {
if (dlen != t->key_len || memcmp(d, t->key, dlen)) {
errno = EPERM;
return NULL;
}
goto finish;
}
/* Make a duplicate of the message, but zero out the MAC part */
mm = malloc(mlen);
if (mm == NULL)
return NULL;
memcpy(mm, m, mlen);
memset(mm + (d - m), 0, dlen);
/* RFC3318, section 5.2 - zero giaddr and hops */
if (mp == 4) {
*(mm + offsetof(struct dhcp_message, hwopcount)) = '\0';
memset(mm + offsetof(struct dhcp_message, giaddr), 0, 4);
}
memset(hmac, 0, sizeof(hmac));
switch (algorithm) {
case AUTH_ALG_HMAC_MD5:
hmac_md5(mm, mlen, t->key, t->key_len, hmac);
break;
default:
errno = ENOSYS;
free(mm);
return NULL;
}
free(mm);
if (memcmp(d, &hmac, dlen)) {
errno = EPERM;
return NULL;
}
finish:
/* If we got here then authentication passed */
state->replay = replay;
if (state->token == NULL) {
/* We cannot just save a pointer because a reconfigure will
* recreate the token list. So we duplicate it. */
state->token = malloc(sizeof(*state->token));
if (state->token) {
state->token->secretid = t->secretid;
state->token->key = malloc(t->key_len);
if (state->token->key) {
state->token->key_len = t->key_len;
memcpy(state->token->key, t->key, t->key_len);
} else {
free(state->token);
state->token = NULL;
return NULL;
}
if (t->realm_len) {
state->token->realm = malloc(t->realm_len);
if (state->token->realm) {
state->token->realm_len = t->realm_len;
memcpy(state->token->realm, t->realm,
t->realm_len);
} else {
free(state->token->key);
free(state->token);
state->token = NULL;
return NULL;
}
} else {
state->token->realm = NULL;
state->token->realm_len = 0;
}
}
/* If we cannot save the token, we must invalidate */
if (state->token == NULL)
return NULL;
}
return t;
}
static uint64_t
get_next_rdm_monotonic_counter(struct auth *auth)
{
FILE *fp;
uint64_t rdm;
#ifdef LOCK_EX
int flocked;
#endif
fp = fopen(RDM_MONOFILE, "r+");
if (fp == NULL) {
if (errno != ENOENT)
return ++auth->last_replay; /* report error? */
fp = fopen(RDM_MONOFILE, "w");
if (fp == NULL)
return ++auth->last_replay; /* report error? */
#ifdef LOCK_EX
flocked = flock(fileno(fp), LOCK_EX);
#endif
rdm = 0;
} else {
#ifdef LOCK_EX
flocked = flock(fileno(fp), LOCK_EX);
#endif
if (fscanf(fp, "0x%016" PRIu64, &rdm) != 1)
rdm = 0; /* truncated? report error? */
}
rdm++;
if (fseek(fp, 0, SEEK_SET) == -1 ||
ftruncate(fileno(fp), 0) == -1 ||
fprintf(fp, "0x%016" PRIu64 "\n", rdm) != 19 ||
fflush(fp) == EOF)
{
if (!auth->last_replay_set) {
auth->last_replay = rdm;
auth->last_replay_set = 1;
} else
rdm = ++auth->last_replay;
/* report error? */
}
#ifdef LOCK_EX
if (flocked == 0)
flock(fileno(fp), LOCK_UN);
#endif
fclose(fp);
return rdm;
}
#define JAN_1970 2208988800U /* 1970 - 1900 in seconds */
static uint64_t
get_next_rdm_monotonic_clock(struct auth *auth)
{
struct timespec ts;
uint32_t pack[2];
double frac;
uint64_t rdm;
if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
return ++auth->last_replay; /* report error? */
pack[0] = htonl((uint32_t)ts.tv_sec + JAN_1970);
frac = ((double)ts.tv_nsec / 1e9 * 0x100000000ULL);
pack[1] = htonl((uint32_t)frac);
memcpy(&rdm, &pack, sizeof(rdm));
return rdm;
}
static uint64_t
get_next_rdm_monotonic(struct auth *auth)
{
if (auth->options & DHCPCD_AUTH_RDM_COUNTER)
return get_next_rdm_monotonic_counter(auth);
return get_next_rdm_monotonic_clock(auth);
}
/*
* Encode a DHCP message.
* Either we know which token to use from the server response
* or we are using a basic configuration token.
* token is the token to encrypt with.
* m and mlen refer to the whole message.
* mp is the DHCP type, pass it 4 or 6.
* mt is the DHCP message type.
* data and dlen refer to the authentication option within the message.
*/
ssize_t
dhcp_auth_encode(struct auth *auth, const struct token *t,
uint8_t *m, size_t mlen, int mp, int mt,
uint8_t *data, size_t dlen)
{
uint64_t rdm;
uint8_t hmac[HMAC_LENGTH];
time_t now;
uint8_t hops, *p, info;
uint32_t giaddr, secretid;
if (auth->protocol == 0 && t == NULL) {
TAILQ_FOREACH(t, &auth->tokens, next) {
if (t->secretid == 0 &&
t->realm_len == 0)
break;
}
if (t == NULL) {
errno = EINVAL;
return -1;
}
if (t->expire) {
if (time(&now) == -1)
return -1;
if (t->expire < now) {
errno = EPERM;
return -1;
}
}
}
switch(auth->protocol) {
case AUTH_PROTO_TOKEN:
case AUTH_PROTO_DELAYED:
case AUTH_PROTO_DELAYEDREALM:
/* We don't ever send a reconf key */
break;
default:
errno = ENOTSUP;
return -1;
}
switch(auth->algorithm) {
case AUTH_ALG_HMAC_MD5:
break;
default:
errno = ENOTSUP;
return -1;
}
switch(auth->rdm) {
case AUTH_RDM_MONOTONIC:
break;
default:
errno = ENOTSUP;
return -1;
}
/* DISCOVER or INFORM messages don't write auth info */
if ((mp == 4 && (mt == DHCP_DISCOVER || mt == DHCP_INFORM)) ||
(mp == 6 && (mt == DHCP6_SOLICIT || mt == DHCP6_INFORMATION_REQ)))
info = 0;
else
info = 1;
/* Work out the auth area size.
* We only need to do this for DISCOVER messages */
if (data == NULL) {
dlen = 1 + 1 + 1 + 8;
switch(auth->protocol) {
case AUTH_PROTO_TOKEN:
dlen += t->key_len;
break;
case AUTH_PROTO_DELAYEDREALM:
if (info && t)
dlen += t->realm_len;
/* FALLTHROUGH */
case AUTH_PROTO_DELAYED:
if (info && t)
dlen += sizeof(t->secretid) + sizeof(hmac);
break;
}
return (ssize_t)dlen;
}
if (dlen < 1 + 1 + 1 + 8) {
errno = ENOBUFS;
return -1;
}
/* Ensure that d is inside m which *may* not be the case for DHPCPv4 */
if (data < m || data > m + mlen || data + dlen > m + mlen) {
errno = ERANGE;
return -1;
}
/* Write out our option */
*data++ = auth->protocol;
*data++ = auth->algorithm;
*data++ = auth->rdm;
switch (auth->rdm) {
case AUTH_RDM_MONOTONIC:
rdm = get_next_rdm_monotonic(auth);
break;
default:
/* This block appeases gcc, clang doesn't need it */
rdm = get_next_rdm_monotonic(auth);
break;
}
rdm = htonll(rdm);
memcpy(data, &rdm, 8);
data += 8;
dlen -= 1 + 1 + 1 + 8;
/* Special case as no hashing needs to be done. */
if (auth->protocol == AUTH_PROTO_TOKEN) {
/* Should be impossible, but still */
if (t == NULL) {
errno = EINVAL;
return -1;
}
if (dlen < t->key_len) {
errno = ENOBUFS;
return -1;
}
memcpy(data, t->key, t->key_len);
return (ssize_t)(dlen - t->key_len);
}
/* DISCOVER or INFORM messages don't write auth info */
if (!info)
return (ssize_t)dlen;
/* Loading a saved lease without an authentication option */
if (t == NULL)
return 0;
/* Write out the Realm */
if (auth->protocol == AUTH_PROTO_DELAYEDREALM) {
if (dlen < t->realm_len) {
errno = ENOBUFS;
return -1;
}
memcpy(data, t->realm, t->realm_len);
data += t->realm_len;
dlen -= t->realm_len;
}
/* Write out the SecretID */
if (auth->protocol == AUTH_PROTO_DELAYED ||
auth->protocol == AUTH_PROTO_DELAYEDREALM)
{
if (dlen < sizeof(t->secretid)) {
errno = ENOBUFS;
return -1;
}
secretid = htonl(t->secretid);
memcpy(data, &secretid, sizeof(secretid));
data += sizeof(secretid);
dlen -= sizeof(secretid);
}
/* Zero what's left, the MAC */
memset(data, 0, dlen);
/* RFC3318, section 5.2 - zero giaddr and hops */
if (mp == 4) {
p = m + offsetof(struct dhcp_message, hwopcount);
hops = *p;
*p = '\0';
p = m + offsetof(struct dhcp_message, giaddr);
memcpy(&giaddr, p, sizeof(giaddr));
memset(p, 0, sizeof(giaddr));
} else {
/* appease GCC again */
hops = 0;
giaddr = 0;
}
/* Create our hash and write it out */
switch(auth->algorithm) {
case AUTH_ALG_HMAC_MD5:
hmac_md5(m, mlen, t->key, t->key_len, hmac);
memcpy(data, hmac, sizeof(hmac));
break;
}
/* RFC3318, section 5.2 - restore giaddr and hops */
if (mp == 4) {
p = m + offsetof(struct dhcp_message, hwopcount);
*p = hops;
p = m + offsetof(struct dhcp_message, giaddr);
memcpy(p, &giaddr, sizeof(giaddr));
}
/* Done! */
return (int)(dlen - sizeof(hmac)); /* should be zero */
}

92
external/bsd/dhcpcd/dist/auth.h vendored Normal file
View File

@ -0,0 +1,92 @@
/* $NetBSD: auth.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef AUTH_H
#define AUTH_H
#include "config.h"
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h>
#endif
#define DHCPCD_AUTH_SEND (1 << 0)
#define DHCPCD_AUTH_REQUIRE (1 << 1)
#define DHCPCD_AUTH_RDM_COUNTER (1 << 2)
#define DHCPCD_AUTH_SENDREQUIRE (DHCPCD_AUTH_SEND | DHCPCD_AUTH_REQUIRE)
#define AUTH_PROTO_TOKEN 0
#define AUTH_PROTO_DELAYED 1
#define AUTH_PROTO_DELAYEDREALM 2
#define AUTH_PROTO_RECONFKEY 3
#define AUTH_ALG_HMAC_MD5 1
#define AUTH_RDM_MONOTONIC 0
struct token {
TAILQ_ENTRY(token) next;
uint32_t secretid;
size_t realm_len;
unsigned char *realm;
size_t key_len;
unsigned char *key;
time_t expire;
};
TAILQ_HEAD(token_head, token);
struct auth {
int options;
uint8_t protocol;
uint8_t algorithm;
uint8_t rdm;
uint64_t last_replay;
uint8_t last_replay_set;
struct token_head tokens;
};
struct authstate {
uint64_t replay;
struct token *token;
struct token *reconf;
};
void dhcp_auth_reset(struct authstate *);
const struct token * dhcp_auth_validate(struct authstate *,
const struct auth *,
const uint8_t *, size_t, int, int,
const uint8_t *, size_t);
ssize_t dhcp_auth_encode(struct auth *, const struct token *,
uint8_t *, size_t, int, int,
uint8_t *, size_t);
#endif

101
external/bsd/dhcpcd/dist/bpf-filter.h vendored Normal file
View File

@ -0,0 +1,101 @@
/* $NetBSD: bpf-filter.h,v 1.9 2014/11/07 20:51:02 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2008 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef BPF_ETHCOOK
# define BPF_ETHCOOK 0
#endif
#ifndef BPF_WHOLEPACKET
# define BPF_WHOLEPACKET ~0U
#endif
static const struct bpf_insn arp_bpf_filter [] = {
#ifndef BPF_SKIPTYPE
/* Make sure this is an ARP packet... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 0, 3),
#endif
/* Make sure this is an ARP REQUEST... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20 + BPF_ETHCOOK),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 2, 0),
/* or ARP REPLY... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20 + BPF_ETHCOOK),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1),
/* If we passed all the tests, ask for the whole packet. */
BPF_STMT(BPF_RET + BPF_K, BPF_WHOLEPACKET),
/* Otherwise, drop it. */
BPF_STMT(BPF_RET + BPF_K, 0),
};
#define arp_bpf_filter_len sizeof(arp_bpf_filter) / sizeof(arp_bpf_filter[0])
/* dhcp_bpf_filter taken from bpf.c in dhcp-3.1.0
*
* Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
* http://www.isc.org/
*/
static const struct bpf_insn dhcp_bpf_filter [] = {
#ifndef BPF_SKIPTYPE
/* Make sure this is an IP packet... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
#endif
/* Make sure it's a UDP packet... */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23 + BPF_ETHCOOK),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
/* Make sure this isn't a fragment... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20 + BPF_ETHCOOK),
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
/* Get the IP header length... */
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14 + BPF_ETHCOOK),
/* Make sure it's to the right port... */
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16 + BPF_ETHCOOK),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1),
/* If we passed all the tests, ask for the whole packet. */
BPF_STMT(BPF_RET + BPF_K, BPF_WHOLEPACKET),
/* Otherwise, drop it. */
BPF_STMT(BPF_RET + BPF_K, 0),
};
#define dhcp_bpf_filter_len sizeof(dhcp_bpf_filter) / sizeof(dhcp_bpf_filter[0])

321
external/bsd/dhcpcd/dist/common.c vendored Normal file
View File

@ -0,0 +1,321 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: common.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/time.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#ifdef BSD
# include <paths.h>
#endif
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "common.h"
#include "dhcpcd.h"
#include "if-options.h"
#ifndef _PATH_DEVNULL
# define _PATH_DEVNULL "/dev/null"
#endif
const char *
get_hostname(char *buf, size_t buflen, int short_hostname)
{
char *p;
if (gethostname(buf, buflen) != 0)
return NULL;
buf[buflen - 1] = '\0';
if (strcmp(buf, "(none)") == 0 ||
strcmp(buf, "localhost") == 0 ||
strncmp(buf, "localhost.", strlen("localhost.")) == 0 ||
buf[0] == '.')
return NULL;
if (short_hostname) {
p = strchr(buf, '.');
if (p)
*p = '\0';
}
return buf;
}
#if USE_LOGFILE
void
logger_open(struct dhcpcd_ctx *ctx)
{
if (ctx->logfile) {
int f = O_CREAT | O_APPEND | O_TRUNC;
#ifdef O_CLOEXEC
f |= O_CLOEXEC;
#endif
ctx->log_fd = open(ctx->logfile, O_WRONLY | f, 0644);
if (ctx->log_fd == -1)
warn("open: %s", ctx->logfile);
#ifndef O_CLOEXEC
else {
if (fcntl(ctx->log_fd, F_GETFD, &f) == -1 ||
fcntl(ctx->log_fd, F_SETFD, f | FD_CLOEXEC) == -1)
warn("fcntl: %s", ctx->logfile);
}
#endif
} else
openlog(PACKAGE, LOG_PID, LOG_DAEMON);
}
void
logger_close(struct dhcpcd_ctx *ctx)
{
if (ctx->log_fd != -1) {
close(ctx->log_fd);
ctx->log_fd = -1;
}
closelog();
}
void
logger(struct dhcpcd_ctx *ctx, int pri, const char *fmt, ...)
{
va_list va;
int serrno;
#ifndef HAVE_PRINTF_M
char fmt_cpy[1024];
#endif
if (pri >= LOG_DEBUG && ctx && !(ctx->options & DHCPCD_DEBUG))
return;
serrno = errno;
va_start(va, fmt);
#ifndef HAVE_PRINTF_M
/* Print strerrno(errno) in place of %m */
if (ctx == NULL || !(ctx->options & DHCPCD_QUIET) || ctx->log_fd != -1)
{
const char *p;
char *fp = fmt_cpy, *serr = NULL;
size_t fmt_left = sizeof(fmt_cpy) - 1, fmt_wrote;
for (p = fmt; *p != '\0'; p++) {
if (p[0] == '%' && p[1] == '%') {
if (fmt_left < 2)
break;
*fp++ = '%';
*fp++ = '%';
fmt_left -= 2;
p++;
} else if (p[0] == '%' && p[1] == 'm') {
if (serr == NULL)
serr = strerror(serrno);
fmt_wrote = strlcpy(fp, serr, fmt_left);
if (fmt_wrote > fmt_left)
break;
fp += fmt_wrote;
fmt_left -= fmt_wrote;
p++;
} else {
*fp++ = *p;
--fmt_left;
}
if (fmt_left == 0)
break;
}
*fp++ = '\0';
fmt = fmt_cpy;
}
#endif
if (ctx == NULL || !(ctx->options & DHCPCD_QUIET)) {
va_list vac;
va_copy(vac, va);
vfprintf(pri <= LOG_ERR ? stderr : stdout, fmt, vac);
fputc('\n', pri <= LOG_ERR ? stderr : stdout);
va_end(vac);
}
#ifdef HAVE_PRINTF_M
errno = serrno;
#endif
if (ctx && ctx->log_fd != -1) {
struct timeval tv;
char buf[32];
/* Write the time, syslog style. month day time - */
if (gettimeofday(&tv, NULL) != -1) {
time_t now;
struct tm tmnow;
tzset();
now = tv.tv_sec;
localtime_r(&now, &tmnow);
strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
dprintf(ctx->log_fd, "%s", buf);
}
vdprintf(ctx->log_fd, fmt, va);
dprintf(ctx->log_fd, "\n");
} else
vsyslog(pri, fmt, va);
va_end(va);
}
#endif
ssize_t
setvar(struct dhcpcd_ctx *ctx,
char **e, const char *prefix, const char *var, const char *value)
{
size_t len = strlen(var) + strlen(value) + 3;
if (prefix)
len += strlen(prefix) + 1;
*e = malloc(len);
if (*e == NULL) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
if (prefix)
snprintf(*e, len, "%s_%s=%s", prefix, var, value);
else
snprintf(*e, len, "%s=%s", var, value);
return (ssize_t)len;
}
ssize_t
setvard(struct dhcpcd_ctx *ctx,
char **e, const char *prefix, const char *var, size_t value)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "%zu", value);
return setvar(ctx, e, prefix, var, buffer);
}
ssize_t
addvar(struct dhcpcd_ctx *ctx,
char ***e, const char *prefix, const char *var, const char *value)
{
ssize_t len;
len = setvar(ctx, *e, prefix, var, value);
if (len != -1)
(*e)++;
return (ssize_t)len;
}
ssize_t
addvard(struct dhcpcd_ctx *ctx,
char ***e, const char *prefix, const char *var, size_t value)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "%zu", value);
return addvar(ctx, e, prefix, var, buffer);
}
char *
hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen, char *buf, size_t buflen)
{
char *p;
size_t i;
if (buf == NULL) {
return NULL;
}
if (hwlen * 3 > buflen) {
errno = ENOBUFS;
return 0;
}
p = buf;
for (i = 0; i < hwlen; i++) {
if (i > 0)
*p ++= ':';
p += snprintf(p, 3, "%.2x", hwaddr[i]);
}
*p ++= '\0';
return buf;
}
size_t
hwaddr_aton(unsigned char *buffer, const char *addr)
{
char c[3];
const char *p = addr;
unsigned char *bp = buffer;
size_t len = 0;
c[2] = '\0';
while (*p) {
c[0] = *p++;
c[1] = *p++;
/* Ensure that digits are hex */
if (isxdigit((unsigned char)c[0]) == 0 ||
isxdigit((unsigned char)c[1]) == 0)
{
errno = EINVAL;
return 0;
}
/* We should have at least two entries 00:01 */
if (len == 0 && *p == '\0') {
errno = EINVAL;
return 0;
}
/* Ensure that next data is EOL or a seperator with data */
if (!(*p == '\0' || (*p == ':' && *(p + 1) != '\0'))) {
errno = EINVAL;
return 0;
}
if (*p)
p++;
if (bp)
*bp++ = (unsigned char)strtol(c, NULL, 16);
len++;
}
return len;
}

201
external/bsd/dhcpcd/dist/common.h vendored Normal file
View File

@ -0,0 +1,201 @@
/* $NetBSD: common.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef COMMON_H
#define COMMON_H
#include <sys/param.h>
#include <sys/time.h>
#include <stdio.h>
#include <syslog.h>
#include "config.h"
#include "defs.h"
#include "dhcpcd.h"
#ifndef HOSTNAME_MAX_LEN
#define HOSTNAME_MAX_LEN 250 /* 255 - 3 (FQDN) - 2 (DNS enc) */
#endif
#ifndef MIN
#define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
#define MAX(a,b) ((/*CONSTCOND*/(a)>(b))?(a):(b))
#endif
#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#define STRINGIFY(a) #a
#define TOSTRING(a) STRINGIFY(a)
#define UNUSED(a) (void)(a)
#define USEC_PER_SEC 1000000L
#define USEC_PER_NSEC 1000L
#define NSEC_PER_SEC 1000000000L
#define NSEC_PER_MSEC 1000000L
#define MSEC_PER_SEC 1000L
#define CSEC_PER_SEC 100L
#define NSEC_PER_CSEC 10000000L
/* Some systems don't define timespec macros */
#ifndef timespecclear
#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
#define timespeccmp(tsp, usp, cmp) \
(((tsp)->tv_sec == (usp)->tv_sec) ? \
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
((tsp)->tv_sec cmp (usp)->tv_sec))
#define timespecadd(tsp, usp, vsp) \
do { \
(vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
(vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
if ((vsp)->tv_nsec >= 1000000000L) { \
(vsp)->tv_sec++; \
(vsp)->tv_nsec -= 1000000000L; \
} \
} while (/* CONSTCOND */ 0)
#define timespecsub(tsp, usp, vsp) \
do { \
(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
if ((vsp)->tv_nsec < 0) { \
(vsp)->tv_sec--; \
(vsp)->tv_nsec += 1000000000L; \
} \
} while (/* CONSTCOND */ 0)
#endif
#define timespec_to_double(tv) \
((double)(tv)->tv_sec + (double)((tv)->tv_nsec) / 1000000000.0)
#define timespecnorm(tv) do { \
while ((tv)->tv_nsec >= NSEC_PER_SEC) { \
(tv)->tv_sec++; \
(tv)->tv_nsec -= NSEC_PER_SEC; \
} \
} while (0 /* CONSTCOND */);
#define ts_to_ms(ms, tv) do { \
ms = (tv)->tv_sec * MSEC_PER_SEC; \
ms += (tv)->tv_nsec / NSEC_PER_MSEC; \
} while (0 /* CONSTCOND */);
#define ms_to_ts(tv, ms) do { \
(tv)->tv_sec = ms / MSEC_PER_SEC; \
(tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC)) \
* NSEC_PER_MSEC; \
} while (0 /* CONSTCOND */);
#ifndef TIMEVAL_TO_TIMESPEC
#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * USEC_PER_NSEC; \
} while (0 /* CONSTCOND */)
#endif
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
# ifndef __dead
# define __dead __attribute__((__noreturn__))
# endif
# ifndef __packed
# define __packed __attribute__((__packed__))
# endif
# ifndef __printflike
# define __printflike(a, b) __attribute__((format(printf, a, b)))
# endif
# ifndef __unused
# define __unused __attribute__((__unused__))
# endif
#else
# ifndef __dead
# define __dead
# endif
# ifndef __packed
# define __packed
# endif
# ifndef __printflike
# define __printflike
# endif
# ifndef __unused
# define __unused
# endif
#endif
#ifndef __arraycount
#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
#endif
/* We don't really need this as our supported systems define __restrict
* automatically for us, but it is here for completeness. */
#ifndef __restrict
# if defined(__lint__)
# define __restrict
# elif __STDC_VERSION__ >= 199901L
# define __restrict restrict
# elif !(2 < __GNUC__ || (2 == __GNU_C && 95 <= __GNUC_VERSION__))
# define __restrict
# endif
#endif
void get_line_free(void);
const char *get_hostname(char *, size_t, int);
extern int clock_monotonic;
int get_monotonic(struct timespec *);
/* We could shave a few k off the binary size by just using the
* syslog(3) interface.
* However, this results in a ugly output on the command line
* and relies on syslogd(8) starting before dhcpcd which is not
* always the case. */
#ifndef USE_LOGFILE
# define USE_LOGFILE 1
#endif
#if USE_LOGFILE
void logger_open(struct dhcpcd_ctx *);
#define logger_mask(ctx, lvl) setlogmask((lvl))
__printflike(3, 4) void logger(struct dhcpcd_ctx *, int, const char *, ...);
void logger_close(struct dhcpcd_ctx *);
#else
#define logger_open(ctx) openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON)
#define logger_mask(ctx, lvl) setlogmask((lvl))
#define logger(ctx, pri, fmt, ...) \
do { \
UNUSED((ctx)); \
syslog((pri), (fmt), ##__VA_ARGS__); \
} while (0 /*CONSTCOND */)
#define logger_close(ctx) closelog()
#endif
ssize_t setvar(struct dhcpcd_ctx *,
char **, const char *, const char *, const char *);
ssize_t setvard(struct dhcpcd_ctx *,
char **, const char *, const char *, size_t);
ssize_t addvar(struct dhcpcd_ctx *,
char ***, const char *, const char *, const char *);
ssize_t addvard(struct dhcpcd_ctx *,
char ***, const char *, const char *, size_t);
char *hwaddr_ntoa(const unsigned char *, size_t, char *, size_t);
size_t hwaddr_aton(unsigned char *, const char *);
#endif

17
external/bsd/dhcpcd/dist/config.h vendored Normal file
View File

@ -0,0 +1,17 @@
/* $NetBSD: config.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/* netbsd */
#define SYSCONFDIR "/etc"
#define SBINDIR "/sbin"
#define LIBDIR "/lib"
#define LIBEXECDIR "/libexec"
#define DBDIR "/var/db"
#define RUNDIR "/var/run"
#define HAVE_SYS_QUEUE_H
#define HAVE_SPAWN_H
#if !defined(__minix)
#define HAVE_KQUEUE
#define HAVE_KQUEUE1
#endif /* !defined(__minix) */
#define HAVE_MD5_H
#define SHA2_H <sha2.h>

427
external/bsd/dhcpcd/dist/control.c vendored Normal file
View File

@ -0,0 +1,427 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: control.c,v 1.10 2015/08/21 10:39:00 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "config.h"
#include "common.h"
#include "dhcpcd.h"
#include "control.h"
#include "eloop.h"
#include "if.h"
#ifndef SUN_LEN
#define SUN_LEN(su) \
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
static void
control_queue_purge(struct dhcpcd_ctx *ctx, char *data)
{
int found;
struct fd_list *fp;
struct fd_data *fpd;
/* If no other fd queue has the same data, free it */
found = 0;
TAILQ_FOREACH(fp, &ctx->control_fds, next) {
TAILQ_FOREACH(fpd, &fp->queue, next) {
if (fpd->data == data) {
found = 1;
break;
}
}
}
if (!found)
free(data);
}
static void
control_queue_free(struct fd_list *fd)
{
struct fd_data *fdp;
while ((fdp = TAILQ_FIRST(&fd->queue))) {
TAILQ_REMOVE(&fd->queue, fdp, next);
if (fdp->freeit)
control_queue_purge(fd->ctx, fdp->data);
free(fdp);
}
while ((fdp = TAILQ_FIRST(&fd->free_queue))) {
TAILQ_REMOVE(&fd->free_queue, fdp, next);
free(fdp);
}
}
static void
control_delete(struct fd_list *fd)
{
TAILQ_REMOVE(&fd->ctx->control_fds, fd, next);
eloop_event_delete(fd->ctx->eloop, fd->fd);
close(fd->fd);
control_queue_free(fd);
free(fd);
}
static void
control_handle_data(void *arg)
{
struct fd_list *fd = arg;
char buffer[1024], *e, *p, *argvp[255], **ap, *a;
ssize_t bytes;
size_t len;
int argc;
bytes = read(fd->fd, buffer, sizeof(buffer) - 1);
if (bytes == -1 || bytes == 0) {
/* Control was closed or there was an error.
* Remove it from our list. */
control_delete(fd);
return;
}
buffer[bytes] = '\0';
p = buffer;
e = buffer + bytes;
/* Each command is \n terminated
* Each argument is NULL separated */
while (p < e) {
argc = 0;
ap = argvp;
while (p < e) {
argc++;
if ((size_t)argc >= sizeof(argvp) / sizeof(argvp[0])) {
errno = ENOBUFS;
return;
}
a = *ap++ = p;
len = strlen(p);
p += len + 1;
if (len && a[len - 1] == '\n') {
a[len - 1] = '\0';
break;
}
}
*ap = NULL;
if (dhcpcd_handleargs(fd->ctx, fd, argc, argvp) == -1) {
logger(fd->ctx, LOG_ERR,
"%s: dhcpcd_handleargs: %m", __func__);
if (errno != EINTR && errno != EAGAIN) {
control_delete(fd);
return;
}
}
}
}
static void
control_handle1(struct dhcpcd_ctx *ctx, int lfd, unsigned int fd_flags)
{
struct sockaddr_un run;
socklen_t len;
struct fd_list *l;
int fd, flags;
len = sizeof(run);
if ((fd = accept(lfd, (struct sockaddr *)&run, &len)) == -1)
return;
if ((flags = fcntl(fd, F_GETFD, 0)) == -1 ||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
{
close(fd);
return;
}
if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
{
close(fd);
return;
}
l = malloc(sizeof(*l));
if (l) {
l->ctx = ctx;
l->fd = fd;
l->flags = fd_flags;
TAILQ_INIT(&l->queue);
TAILQ_INIT(&l->free_queue);
TAILQ_INSERT_TAIL(&ctx->control_fds, l, next);
eloop_event_add(ctx->eloop, l->fd,
control_handle_data, l, NULL, NULL);
} else
close(fd);
}
static void
control_handle(void *arg)
{
struct dhcpcd_ctx *ctx = arg;
control_handle1(ctx, ctx->control_fd, 0);
}
static void
control_handle_unpriv(void *arg)
{
struct dhcpcd_ctx *ctx = arg;
control_handle1(ctx, ctx->control_unpriv_fd, FD_UNPRIV);
}
static int
make_sock(struct sockaddr_un *sa, const char *ifname, int unpriv)
{
int fd;
if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, O_NONBLOCK|O_CLOEXEC)) == -1)
return -1;
memset(sa, 0, sizeof(*sa));
sa->sun_family = AF_UNIX;
if (unpriv)
strlcpy(sa->sun_path, UNPRIVSOCKET, sizeof(sa->sun_path));
else {
snprintf(sa->sun_path, sizeof(sa->sun_path), CONTROLSOCKET,
ifname ? "-" : "", ifname ? ifname : "");
}
return fd;
}
#define S_PRIV (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
#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, mode_t fmode)
{
struct sockaddr_un sa;
int fd;
socklen_t len;
if ((fd = make_sock(&sa, ifname, (fmode & S_UNPRIV) == S_UNPRIV)) == -1)
return -1;
len = (socklen_t)SUN_LEN(&sa);
unlink(sa.sun_path);
if (bind(fd, (struct sockaddr *)&sa, len) == -1 ||
chmod(sa.sun_path, fmode) == -1 ||
(ctx->control_group &&
chown(sa.sun_path, geteuid(), ctx->control_group) == -1) ||
listen(fd, sizeof(ctx->control_fds)) == -1)
{
close(fd);
unlink(sa.sun_path);
return -1;
}
if ((fmode & S_UNPRIV) != S_UNPRIV)
strlcpy(ctx->control_sock, sa.sun_path,
sizeof(ctx->control_sock));
return fd;
}
int
control_start(struct dhcpcd_ctx *ctx, const char *ifname)
{
int fd;
if ((fd = control_start1(ctx, ifname, S_PRIV)) == -1)
return -1;
ctx->control_fd = fd;
eloop_event_add(ctx->eloop, fd, control_handle, ctx, NULL, NULL);
if (ifname == NULL && (fd = control_start1(ctx, NULL, S_UNPRIV)) != -1){
/* We must be in master mode, so create an unpriviledged socket
* to allow normal users to learn the status of dhcpcd. */
ctx->control_unpriv_fd = fd;
eloop_event_add(ctx->eloop, fd, control_handle_unpriv,
ctx, NULL, NULL);
}
return ctx->control_fd;
}
int
control_stop(struct dhcpcd_ctx *ctx)
{
int retval = 0;
struct fd_list *l;
if (ctx->options & DHCPCD_FORKED)
goto freeit;
if (ctx->control_fd == -1)
return 0;
eloop_event_delete(ctx->eloop, ctx->control_fd);
close(ctx->control_fd);
ctx->control_fd = -1;
if (unlink(ctx->control_sock) == -1)
retval = -1;
if (ctx->control_unpriv_fd != -1) {
eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd);
close(ctx->control_unpriv_fd);
ctx->control_unpriv_fd = -1;
if (unlink(UNPRIVSOCKET) == -1)
retval = -1;
}
freeit:
while ((l = TAILQ_FIRST(&ctx->control_fds))) {
TAILQ_REMOVE(&ctx->control_fds, l, next);
eloop_event_delete(ctx->eloop, l->fd);
close(l->fd);
control_queue_free(l);
free(l);
}
return retval;
}
int
control_open(struct dhcpcd_ctx *ctx, const char *ifname)
{
struct sockaddr_un sa;
socklen_t len;
if ((ctx->control_fd = make_sock(&sa, ifname, 0)) == -1)
return -1;
len = (socklen_t)SUN_LEN(&sa);
if (connect(ctx->control_fd, (struct sockaddr *)&sa, len) == -1) {
close(ctx->control_fd);
ctx->control_fd = -1;
return -1;
}
return 0;
}
ssize_t
control_send(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
{
char buffer[1024];
int i;
size_t len, l;
if (argc > 255) {
errno = ENOBUFS;
return -1;
}
len = 0;
for (i = 0; i < argc; i++) {
l = strlen(argv[i]) + 1;
if (len + l > sizeof(buffer)) {
errno = ENOBUFS;
return -1;
}
memcpy(buffer + len, argv[i], l);
len += l;
}
return write(ctx->control_fd, buffer, len);
}
static void
control_writeone(void *arg)
{
struct fd_list *fd;
struct iovec iov[2];
struct fd_data *data;
fd = arg;
data = TAILQ_FIRST(&fd->queue);
iov[0].iov_base = &data->data_len;
iov[0].iov_len = sizeof(size_t);
iov[1].iov_base = data->data;
iov[1].iov_len = data->data_len;
if (writev(fd->fd, iov, 2) == -1) {
logger(fd->ctx, LOG_ERR,
"%s: writev fd %d: %m", __func__, fd->fd);
if (errno != EINTR && errno != EAGAIN)
control_delete(fd);
return;
}
TAILQ_REMOVE(&fd->queue, data, next);
if (data->freeit)
control_queue_purge(fd->ctx, data->data);
data->data = NULL; /* safety */
data->data_len = 0;
TAILQ_INSERT_TAIL(&fd->free_queue, data, next);
if (TAILQ_FIRST(&fd->queue) == NULL)
eloop_event_remove_writecb(fd->ctx->eloop, fd->fd);
}
int
control_queue(struct fd_list *fd, char *data, size_t data_len, uint8_t fit)
{
struct fd_data *d;
size_t n;
d = TAILQ_FIRST(&fd->free_queue);
if (d) {
TAILQ_REMOVE(&fd->free_queue, d, next);
} else {
n = 0;
TAILQ_FOREACH(d, &fd->queue, next) {
if (++n == CONTROL_QUEUE_MAX) {
errno = ENOBUFS;
return -1;
}
}
d = malloc(sizeof(*d));
if (d == NULL)
return -1;
}
d->data = data;
d->data_len = data_len;
d->freeit = fit;
TAILQ_INSERT_TAIL(&fd->queue, d, next);
eloop_event_add(fd->ctx->eloop, fd->fd,
NULL, NULL, control_writeone, fd);
return 0;
}
void
control_close(struct dhcpcd_ctx *ctx)
{
if (ctx->control_fd != -1) {
close(ctx->control_fd);
ctx->control_fd = -1;
}
}

66
external/bsd/dhcpcd/dist/control.h vendored Normal file
View File

@ -0,0 +1,66 @@
/* $NetBSD: control.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef CONTROL_H
#define CONTROL_H
#include "dhcpcd.h"
/* Limit queue size per fd */
#define CONTROL_QUEUE_MAX 100
struct fd_data {
TAILQ_ENTRY(fd_data) next;
char *data;
size_t data_len;
uint8_t freeit;
};
TAILQ_HEAD(fd_data_head, fd_data);
struct fd_list {
TAILQ_ENTRY(fd_list) next;
struct dhcpcd_ctx *ctx;
int fd;
unsigned int flags;
struct fd_data_head queue;
struct fd_data_head free_queue;
};
TAILQ_HEAD(fd_list_head, fd_list);
#define FD_LISTEN (1<<0)
#define FD_UNPRIV (1<<1)
int control_start(struct dhcpcd_ctx *, const char *);
int control_stop(struct dhcpcd_ctx *);
int control_open(struct dhcpcd_ctx *, const char *);
ssize_t control_send(struct dhcpcd_ctx *, int, char * const *);
int control_queue(struct fd_list *fd, char *data, size_t data_len, uint8_t fit);
void control_close(struct dhcpcd_ctx *ctx);
#endif

35
external/bsd/dhcpcd/dist/crypt/crypt.h vendored Normal file
View File

@ -0,0 +1,35 @@
/* $NetBSD: crypt.h,v 1.6 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef CRYPT_H
#define CRYPT_H
void hmac_md5(const uint8_t *, size_t, const uint8_t *, size_t, uint8_t *);
#endif

View File

@ -0,0 +1,92 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: hmac_md5.c,v 1.7 2015/03/27 11:33:47 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <inttypes.h>
#include <string.h>
#include "crypt.h"
#include "../config.h"
#ifdef HAVE_MD5_H
# ifndef DEPGEN
# include <md5.h>
# endif
#else
# include "md5.h"
#endif
#define HMAC_PAD_LEN 64
#define IPAD 0x36
#define OPAD 0x5C
/* hmac_md5 as per RFC3118 */
void
hmac_md5(const uint8_t *text, size_t text_len,
const uint8_t *key, size_t key_len,
uint8_t *digest)
{
uint8_t k_ipad[HMAC_PAD_LEN], k_opad[HMAC_PAD_LEN];
uint8_t tk[MD5_DIGEST_LENGTH];
int i;
MD5_CTX context;
/* Ensure key is no bigger than HMAC_PAD_LEN */
if (key_len > HMAC_PAD_LEN) {
MD5Init(&context);
MD5Update(&context, key, (unsigned int)key_len);
MD5Final(tk, &context);
key = tk;
key_len = MD5_DIGEST_LENGTH;
}
/* store key in pads */
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
memset(k_ipad + key_len, 0, sizeof(k_ipad) - key_len);
memset(k_opad + key_len, 0, sizeof(k_opad) - key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < HMAC_PAD_LEN; i++) {
k_ipad[i] ^= IPAD;
k_opad[i] ^= OPAD;
}
/* inner MD5 */
MD5Init(&context);
MD5Update(&context, k_ipad, HMAC_PAD_LEN);
MD5Update(&context, text, (unsigned int)text_len);
MD5Final(digest, &context);
/* outer MD5 */
MD5Init(&context);
MD5Update(&context, k_opad, HMAC_PAD_LEN);
MD5Update(&context, digest, MD5_DIGEST_LENGTH);
MD5Final(digest, &context);
}

78
external/bsd/dhcpcd/dist/defs.h vendored Normal file
View File

@ -0,0 +1,78 @@
/* $NetBSD: defs.h,v 1.21 2015/09/04 12:25:01 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef CONFIG_H
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "6.9.3"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
#endif
#ifndef SCRIPT
# define SCRIPT LIBEXECDIR "/" PACKAGE "-run-hooks"
#endif
#ifndef DEVDIR
# define DEVDIR LIBDIR "/" PACKAGE "/dev"
#endif
#ifndef DUID
# define DUID SYSCONFDIR "/" PACKAGE ".duid"
#endif
#ifndef SECRET
# define SECRET SYSCONFDIR "/" PACKAGE ".secret"
#endif
#ifndef LEASEFILE
# define LEASEFILE DBDIR "/" PACKAGE "-%s%s.lease"
#endif
#ifndef LEASEFILE6
# define LEASEFILE6 LEASEFILE "6"
#endif
#ifndef PIDFILE
# define PIDFILE RUNDIR "/" PACKAGE "%s%s%s.pid"
#endif
#ifndef CONTROLSOCKET
# define CONTROLSOCKET RUNDIR "/" PACKAGE "%s%s.sock"
#endif
#ifndef UNPRIVSOCKET
# define UNPRIVSOCKET RUNDIR "/" PACKAGE ".unpriv.sock"
#endif
#ifndef RDM_MONOFILE
# define RDM_MONOFILE DBDIR "/" PACKAGE "-rdm.monotonic"
#endif
#ifndef NO_SIGNALS
# define USE_SIGNALS
#endif
#ifndef USE_SIGNALS
# ifndef THERE_IS_NO_FORK
# define THERE_IS_NO_FORK
# endif
#endif
#endif

62
external/bsd/dhcpcd/dist/dev.h vendored Normal file
View File

@ -0,0 +1,62 @@
/* $NetBSD: dev.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DEV_H
#define DEV_H
// dev plugin setup
struct dev {
const char *name;
int (*initialized)(const char *);
int (*listening)(void);
int (*handle_device)(void *);
int (*start)(void);
void (*stop)(void);
};
struct dev_dhcpcd {
int (*handle_interface)(void *, int, const char *);
};
int dev_init(struct dev *, const struct dev_dhcpcd *);
// hooks for dhcpcd
#ifdef PLUGIN_DEV
#include "dhcpcd.h"
int dev_initialized(struct dhcpcd_ctx *, const char *);
int dev_listening(struct dhcpcd_ctx *);
int dev_start(struct dhcpcd_ctx *);
void dev_stop(struct dhcpcd_ctx *);
#else
#define dev_initialized(a, b) (1)
#define dev_listening(a) (0)
#define dev_start(a) {}
#define dev_stop(a) {}
#endif
#endif

1003
external/bsd/dhcpcd/dist/dhcp-common.c vendored Normal file

File diff suppressed because it is too large Load Diff

121
external/bsd/dhcpcd/dist/dhcp-common.h vendored Normal file
View File

@ -0,0 +1,121 @@
/* $NetBSD: dhcp-common.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DHCPCOMMON_H
#define DHCPCOMMON_H
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdint.h>
#include "common.h"
#include "dhcpcd.h"
/* Max MTU - defines dhcp option length */
#define MTU_MAX 1500
#define MTU_MIN 576
#define REQUEST (1 << 0)
#define UINT8 (1 << 1)
#define UINT16 (1 << 2)
#define SINT16 (1 << 3)
#define UINT32 (1 << 4)
#define SINT32 (1 << 5)
#define ADDRIPV4 (1 << 6)
#define STRING (1 << 7)
#define ARRAY (1 << 8)
#define RFC3361 (1 << 9)
#define RFC1035 (1 << 10)
#define RFC3442 (1 << 11)
#define RFC5969 (1 << 12)
#define ADDRIPV6 (1 << 13)
#define BINHEX (1 << 14)
#define FLAG (1 << 15)
#define NOREQ (1 << 16)
#define EMBED (1 << 17)
#define ENCAP (1 << 18)
#define INDEX (1 << 19)
#define OPTION (1 << 20)
#define DOMAIN (1 << 21)
#define ASCII (1 << 22)
#define RAW (1 << 23)
#define ESCSTRING (1 << 24)
#define ESCFILE (1 << 25)
#define BITFLAG (1 << 26)
#define RESERVED (1 << 27)
struct dhcp_opt {
uint32_t option; /* Also used for IANA Enterpise Number */
int type;
size_t len;
char *var;
int index; /* Index counter for many instances of the same option */
char bitflags[8];
/* Embedded options.
* The option code is irrelevant here. */
struct dhcp_opt *embopts;
size_t embopts_len;
/* Encapsulated options */
struct dhcp_opt *encopts;
size_t encopts_len;
};
struct dhcp_opt *vivso_find(uint32_t, const void *);
ssize_t dhcp_vendor(char *, size_t);
void dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols);
#define add_option_mask(var, val) \
((var)[(val) >> 3] = (uint8_t)((var)[(val) >> 3] | 1 << ((val) & 7)))
#define del_option_mask(var, val) \
((var)[(val) >> 3] = (uint8_t)((var)[(val) >> 3] & ~(1 << ((val) & 7))))
#define has_option_mask(var, val) \
((var)[(val) >> 3] & (uint8_t)(1 << ((val) & 7)))
int make_option_mask(const struct dhcp_opt *, size_t,
const struct dhcp_opt *, size_t,
uint8_t *, const char *, int);
size_t encode_rfc1035(const char *src, uint8_t *dst);
ssize_t decode_rfc1035(char *, size_t, const uint8_t *, size_t);
ssize_t print_string(char *, size_t, int, const uint8_t *, size_t);
int dhcp_set_leasefile(char *, size_t, int, const struct interface *);
size_t dhcp_envoption(struct dhcpcd_ctx *,
char **, const char *, const char *, struct dhcp_opt *,
const uint8_t *(*dgetopt)(struct dhcpcd_ctx *,
size_t *, unsigned int *, size_t *,
const uint8_t *, size_t, struct dhcp_opt **),
const uint8_t *od, size_t ol);
void dhcp_zero_index(struct dhcp_opt *);
#endif

3488
external/bsd/dhcpcd/dist/dhcp.c vendored Normal file

File diff suppressed because it is too large Load Diff

288
external/bsd/dhcpcd/dist/dhcp.h vendored Normal file
View File

@ -0,0 +1,288 @@
/* $NetBSD: dhcp.h,v 1.11 2015/08/21 10:39:00 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DHCP_H
#define DHCP_H
#include <arpa/inet.h>
#include <netinet/in.h>
#include <limits.h>
#include <stdint.h>
#include "arp.h"
#include "auth.h"
#include "dhcp-common.h"
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
#define MAGIC_COOKIE 0x63825363
#define BROADCAST_FLAG 0x8000
/* DHCP message OP code */
#define DHCP_BOOTREQUEST 1
#define DHCP_BOOTREPLY 2
/* DHCP message type */
#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
#define DHCP_FORCERENEW 9
/* Constants taken from RFC 2131. */
#define T1 0.5
#define T2 0.875
#define DHCP_BASE 4
#define DHCP_MAX 64
#define DHCP_RAND_MIN -1
#define DHCP_RAND_MAX 1
#ifdef RFC2131_STRICT
/* Be strictly conformant for section 4.1.1 */
# define DHCP_MIN_DELAY 1
# define DHCP_MAX_DELAY 10
#else
/* or mirror the more modern IPv6RS and DHCPv6 delays */
# define DHCP_MIN_DELAY 0
# define DHCP_MAX_DELAY 1
#endif
/* DHCP options */
enum DHO {
DHO_PAD = 0,
DHO_SUBNETMASK = 1,
DHO_ROUTER = 3,
DHO_DNSSERVER = 6,
DHO_HOSTNAME = 12,
DHO_DNSDOMAIN = 15,
DHO_MTU = 26,
DHO_BROADCAST = 28,
DHO_STATICROUTE = 33,
DHO_NISDOMAIN = 40,
DHO_NISSERVER = 41,
DHO_NTPSERVER = 42,
DHO_VENDOR = 43,
DHO_IPADDRESS = 50,
DHO_LEASETIME = 51,
DHO_OPTIONSOVERLOADED = 52,
DHO_MESSAGETYPE = 53,
DHO_SERVERID = 54,
DHO_PARAMETERREQUESTLIST = 55,
DHO_MESSAGE = 56,
DHO_MAXMESSAGESIZE = 57,
DHO_RENEWALTIME = 58,
DHO_REBINDTIME = 59,
DHO_VENDORCLASSID = 60,
DHO_CLIENTID = 61,
DHO_USERCLASS = 77, /* RFC 3004 */
DHO_RAPIDCOMMIT = 80, /* RFC 4039 */
DHO_FQDN = 81,
DHO_AUTHENTICATION = 90, /* RFC 3118 */
DHO_AUTOCONFIGURE = 116, /* RFC 2563 */
DHO_DNSSEARCH = 119, /* RFC 3397 */
DHO_CSR = 121, /* RFC 3442 */
DHO_VIVCO = 124, /* RFC 3925 */
DHO_VIVSO = 125, /* RFC 3925 */
DHO_FORCERENEW_NONCE = 145, /* RFC 6704 */
DHO_SIXRD = 212, /* RFC 5969 */
DHO_MSCSR = 249, /* MS code for RFC 3442 */
DHO_END = 255
};
/* FQDN values - lsnybble used in flags
* hsnybble to create order
* and to allow 0x00 to mean disable
*/
enum FQDN {
FQDN_DISABLE = 0x00,
FQDN_NONE = 0x18,
FQDN_PTR = 0x20,
FQDN_BOTH = 0x31
};
/* Sizes for DHCP options */
#define DHCP_CHADDR_LEN 16
#define SERVERNAME_LEN 64
#define BOOTFILE_LEN 128
#define DHCP_UDP_LEN (14 + 20 + 8)
#define DHCP_FIXED_LEN (DHCP_UDP_LEN + 226)
#define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN)
/* Some crappy DHCP servers require the BOOTP minimum length */
#define BOOTP_MESSAGE_LENTH_MIN 300
/* Don't import common.h as that defines __unused which causes problems
* on some Linux systems which define it as part of a structure */
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
# ifndef __packed
# define __packed __attribute__((__packed__))
# endif
#else
# ifndef __packed
# define __packed
# endif
#endif
struct dhcp_message {
uint8_t op; /* message type */
uint8_t hwtype; /* hardware address type */
uint8_t hwlen; /* hardware address length */
uint8_t hwopcount; /* should be zero in client message */
uint32_t xid; /* transaction id */
uint16_t secs; /* elapsed time in sec. from boot */
uint16_t flags;
uint32_t ciaddr; /* (previously allocated) client IP */
uint32_t yiaddr; /* 'your' client IP address */
uint32_t siaddr; /* should be zero in client's messages */
uint32_t giaddr; /* should be zero in client's messages */
uint8_t chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */
uint8_t servername[SERVERNAME_LEN]; /* server host name */
uint8_t bootfile[BOOTFILE_LEN]; /* boot file name */
uint32_t cookie;
uint8_t options[DHCP_OPTION_LEN]; /* message options - cookie */
} __packed;
struct dhcp_lease {
struct in_addr addr;
struct in_addr net;
struct in_addr brd;
uint32_t leasetime;
uint32_t renewaltime;
uint32_t rebindtime;
struct in_addr server;
uint8_t frominfo;
uint32_t cookie;
};
enum DHS {
DHS_INIT,
DHS_DISCOVER,
DHS_REQUEST,
DHS_BOUND,
DHS_RENEW,
DHS_REBIND,
DHS_REBOOT,
DHS_INFORM,
DHS_RENEW_REQUESTED,
DHS_RELEASE
};
struct dhcp_state {
enum DHS state;
struct dhcp_message *sent;
struct dhcp_message *offer;
struct dhcp_message *new;
struct dhcp_message *old;
struct dhcp_lease lease;
const char *reason;
time_t interval;
time_t nakoff;
uint32_t xid;
int socket;
int raw_fd;
struct in_addr addr;
struct in_addr net;
struct in_addr dst;
uint8_t added;
char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDSIZE * 4)];
struct timespec started;
unsigned char *clientid;
struct authstate auth;
size_t arping_index;
};
#define D_STATE(ifp) \
((struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP])
#define D_CSTATE(ifp) \
((const struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP])
#define D_STATE_RUNNING(ifp) \
(D_CSTATE((ifp)) && D_CSTATE((ifp))->new && D_CSTATE((ifp))->reason)
#include "dhcpcd.h"
#include "if-options.h"
#ifdef INET
char *decode_rfc3361(const uint8_t *, size_t);
ssize_t decode_rfc3442(char *, size_t, const uint8_t *p, size_t);
ssize_t decode_rfc5969(char *, size_t, const uint8_t *p, size_t);
void dhcp_printoptions(const struct dhcpcd_ctx *,
const struct dhcp_opt *, size_t);
int get_option_addr(struct dhcpcd_ctx *,struct in_addr *,
const struct dhcp_message *, uint8_t);
#define IS_BOOTP(i, m) ((m) != NULL && \
get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1)
uint16_t dhcp_get_mtu(const struct interface *);
struct rt_head *dhcp_get_routes(struct interface *);
ssize_t dhcp_env(char **, const char *, const struct dhcp_message *,
const struct interface *);
uint32_t dhcp_xid(const struct interface *);
struct dhcp_message *dhcp_message_new(const struct in_addr *addr,
const struct in_addr *mask);
int dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr);
ssize_t make_message(struct dhcp_message **, const struct interface *,
uint8_t);
int valid_dhcp_packet(unsigned char *);
void dhcp_handleifa(int, struct interface *,
const struct in_addr *, const struct in_addr *, const struct in_addr *,
int);
void dhcp_drop(struct interface *, const char *);
void dhcp_start(struct interface *);
void dhcp_abort(struct interface *);
void dhcp_discover(void *);
void dhcp_inform(struct interface *);
void dhcp_bind(struct interface *);
void dhcp_reboot_newopts(struct interface *, unsigned long long);
void dhcp_close(struct interface *);
void dhcp_free(struct interface *);
int dhcp_dump(struct interface *);
#else
#define dhcp_drop(a, b) {}
#define dhcp_start(a) {}
#define dhcp_abort(a) {}
#define dhcp_reboot(a, b) (b = b)
#define dhcp_reboot_newopts(a, b) (b = b)
#define dhcp_close(a) {}
#define dhcp_free(a) {}
#define dhcp_dump(a) (-1)
#endif
#endif

3533
external/bsd/dhcpcd/dist/dhcp6.c vendored Normal file

File diff suppressed because it is too large Load Diff

265
external/bsd/dhcpcd/dist/dhcp6.h vendored Normal file
View File

@ -0,0 +1,265 @@
/* $NetBSD: dhcp6.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DHCP6_H
#define DHCP6_H
#include "dhcpcd.h"
#define IN6ADDR_LINKLOCAL_ALLDHCP_INIT \
{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 }}}
/* UDP port numbers for DHCP */
#define DHCP6_CLIENT_PORT 546
#define DHCP6_SERVER_PORT 547
/* DHCP message type */
#define DHCP6_SOLICIT 1
#define DHCP6_ADVERTISE 2
#define DHCP6_REQUEST 3
#define DHCP6_CONFIRM 4
#define DHCP6_RENEW 5
#define DHCP6_REBIND 6
#define DHCP6_REPLY 7
#define DHCP6_RELEASE 8
#define DHCP6_DECLINE 9
#define DHCP6_RECONFIGURE 10
#define DHCP6_INFORMATION_REQ 11
#define DHCP6_RELAY_FLOW 12
#define DHCP6_RELAY_REPL 13
#define DHCP6_RECONFIGURE_REQ 18
#define DHCP6_RECONFIGURE_REPLY 19
#define D6_OPTION_CLIENTID 1
#define D6_OPTION_SERVERID 2
#define D6_OPTION_IA_NA 3
#define D6_OPTION_IA_TA 4
#define D6_OPTION_ORO 6
#define D6_OPTION_IA_ADDR 5
#define D6_OPTION_PREFERENCE 7
#define D6_OPTION_ELAPSED 8
#define D6_OPTION_AUTH 11
#define D6_OPTION_UNICAST 12
#define D6_OPTION_STATUS_CODE 13
#define D6_OPTION_RAPID_COMMIT 14
#define D6_OPTION_VENDOR_CLASS 16
#define D6_OPTION_VENDOR_OPTS 17
#define D6_OPTION_INTERFACE_ID 18
#define D6_OPTION_RECONF_MSG 19
#define D6_OPTION_RECONF_ACCEPT 20
#define D6_OPTION_SIP_SERVERS_NAME 21
#define D6_OPTION_SIP_SERVERS_ADDRESS 22
#define D6_OPTION_DNS_SERVERS 23
#define D6_OPTION_DOMAIN_LIST 24
#define D6_OPTION_IA_PD 25
#define D6_OPTION_IAPREFIX 26
#define D6_OPTION_NIS_SERVERS 27
#define D6_OPTION_NISP_SERVERS 28
#define D6_OPTION_NIS_DOMAIN_NAME 29
#define D6_OPTION_NISP_DOMAIN_NAME 30
#define D6_OPTION_SNTP_SERVERS 31
#define D6_OPTION_INFO_REFRESH_TIME 32
#define D6_OPTION_BCMS_SERVER_D 33
#define D6_OPTION_BCMS_SERVER_A 34
#define D6_OPTION_FQDN 39
#define D6_OPTION_POSIX_TIMEZONE 41
#define D6_OPTION_TZDB_TIMEZONE 42
#define D6_OPTION_PD_EXCLUDE 67
#define D6_OPTION_SOL_MAX_RT 82
#define D6_OPTION_INF_MAX_RT 83
#define D6_FQDN_PTR 0x00
#define D6_FQDN_BOTH 0x01
#define D6_FQDN_NONE 0x04
#include "dhcp.h"
#include "ipv6.h"
struct dhcp6_message {
uint8_t type;
uint8_t xid[3];
/* followed by options */
} __packed;
struct dhcp6_option {
uint16_t code;
uint16_t len;
/* followed by data */
} __packed;
#define D6_STATUS_OK 0
#define D6_STATUS_FAIL 1
#define D6_STATUS_NOADDR 2
#define D6_STATUS_NOBINDING 3
#define D6_STATUS_NOTONLINK 4
#define D6_STATUS_USEMULTICAST 5
#define SOL_MAX_DELAY 1
#define SOL_TIMEOUT 1
#define SOL_MAX_RT 3600 /* RFC7083 */
#define REQ_TIMEOUT 1
#define REQ_MAX_RT 30
#define REQ_MAX_RC 10
#define CNF_MAX_DELAY 1
#define CNF_TIMEOUT 1
#define CNF_MAX_RT 4
#define CNF_MAX_RD 10
#define REN_TIMEOUT 10
#define REN_MAX_RT 600
#define REB_TIMEOUT 10
#define REB_MAX_RT 600
#define INF_MAX_DELAY 1
#define INF_TIMEOUT 1
#define INF_MAX_RT 3600 /* RFC7083 */
#define REL_TIMEOUT 1
#define REL_MAX_RC 5
#define DEC_TIMEOUT 1
#define DEC_MAX_RC 5
#define REC_TIMEOUT 2
#define REC_MAX_RC 8
#define HOP_COUNT_LIMIT 32
/* RFC4242 3.1 */
#define IRT_DEFAULT 86400
#define IRT_MINIMUM 600
#define DHCP6_RAND_MIN -100
#define DHCP6_RAND_MAX 100
enum DH6S {
DH6S_INIT,
DH6S_DISCOVER,
DH6S_REQUEST,
DH6S_BOUND,
DH6S_RENEW,
DH6S_REBIND,
DH6S_CONFIRM,
DH6S_INFORM,
DH6S_INFORMED,
DH6S_RENEW_REQUESTED,
DH6S_PROBE,
DH6S_DELEGATED,
DH6S_RELEASE,
DH6S_RELEASED
};
struct dhcp6_state {
enum DH6S state;
struct timespec started;
/* Message retransmission timings */
struct timespec RT;
unsigned int IMD;
unsigned int RTC;
time_t IRT;
unsigned int MRC;
time_t MRT;
void (*MRCcallback)(void *);
time_t sol_max_rt;
time_t inf_max_rt;
struct dhcp6_message *send;
size_t send_len;
struct dhcp6_message *recv;
size_t recv_len;
struct dhcp6_message *new;
size_t new_len;
struct dhcp6_message *old;
size_t old_len;
uint32_t renew;
uint32_t rebind;
uint32_t expire;
struct in6_addr unicast;
struct ipv6_addrhead addrs;
uint32_t lowpl;
/* The +3 is for the possible .pd extension for prefix delegation */
char leasefile[sizeof(LEASEFILE6) + IF_NAMESIZE + (IF_SSIDSIZE * 4) +3];
const char *reason;
struct authstate auth;
};
#define D6_STATE(ifp) \
((struct dhcp6_state *)(ifp)->if_data[IF_DATA_DHCP6])
#define D6_CSTATE(ifp) \
((const struct dhcp6_state *)(ifp)->if_data[IF_DATA_DHCP6])
#define D6_STATE_RUNNING(ifp) \
(D6_CSTATE((ifp)) && \
D6_CSTATE((ifp))->reason && dhcp6_dadcompleted((ifp)))
#define D6_FIRST_OPTION(m) \
((struct dhcp6_option *) \
((uint8_t *)(m) + sizeof(struct dhcp6_message)))
#define D6_NEXT_OPTION(o) \
((struct dhcp6_option *) \
(((uint8_t *)o) + sizeof(struct dhcp6_option) + ntohs((o)->len)))
#define D6_OPTION_DATA(o) \
((uint8_t *)(o) + sizeof(struct dhcp6_option))
#define D6_CFIRST_OPTION(m) \
((const struct dhcp6_option *) \
((const uint8_t *)(m) + sizeof(struct dhcp6_message)))
#define D6_CNEXT_OPTION(o) \
((const struct dhcp6_option *) \
(((const uint8_t *)o) + sizeof(struct dhcp6_option) + ntohs((o)->len)))
#define D6_COPTION_DATA(o) \
((const uint8_t *)(o) + sizeof(struct dhcp6_option))
#ifdef INET6
void dhcp6_printoptions(const struct dhcpcd_ctx *,
const struct dhcp_opt *, size_t);
const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp,
const struct in6_addr *addr, short flags);
struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
short);
size_t dhcp6_find_delegates(struct interface *);
int dhcp6_has_public_addr(const struct interface *);
int dhcp6_start(struct interface *, enum DH6S);
void dhcp6_reboot(struct interface *);
ssize_t dhcp6_env(char **, const char *, const struct interface *,
const struct dhcp6_message *, size_t);
void dhcp6_free(struct interface *);
void dhcp6_handleifa(struct dhcpcd_ctx *, int, const char *,
const struct in6_addr *addr, int);
int dhcp6_dadcompleted(const struct interface *);
void dhcp6_drop(struct interface *, const char *);
int dhcp6_dump(struct interface *);
#else
#define dhcp6_find_delegates(a) {}
#define dhcp6_start(a, b) (0)
#define dhcp6_reboot(a) {}
#define dhcp6_env(a, b, c, d, e) {}
#define dhcp6_free(a) {}
#define dhcp6_dadcompleted(a) (0)
#define dhcp6_drop(a, b) {}
#define dhcp6_dump(a) (-1)
#endif
#endif

View File

@ -0,0 +1,572 @@
# $NetBSD: dhcpcd-definitions.conf,v 1.9 2015/07/09 10:15:34 roy Exp $
# Copyright (c) 2006-2015 Roy Marples
# All rights reserved
# DHCP option definitions for dhcpcd(8)
# These are used to translate DHCP options into shell variables
# for use in dhcpcd-run-hooks(8)
# See dhcpcd.conf(5) for details
##############################################################################
# DHCP RFC2132 options unless otheriwse stated
define 1 request ipaddress subnet_mask
# RFC3442 states that the CSR has to come before all other routes
# For completeness we also specify static routes then routers
define 121 rfc3442 classless_static_routes
# Option 249 is an IANA assigned private number used by Windows DHCP servers
# to provide the exact same information as option 121, classless static routes
define 249 rfc3442 ms_classless_static_routes
define 33 request array ipaddress static_routes
define 3 request array ipaddress routers
define 2 uint32 time_offset
define 4 array ipaddress time_servers
define 5 array ipaddress ien116_name_servers
define 6 array ipaddress domain_name_servers
define 7 array ipaddress log_servers
define 8 array ipaddress cookie_servers
define 9 array ipaddress lpr_servers
define 10 array ipaddress impress_servers
define 11 array ipaddress resource_location_servers
define 12 dname host_name
define 13 uint16 boot_size
define 14 string merit_dump
# Technically domain_name is not an array, but many servers expect clients
# to treat it as one.
define 15 array dname domain_name
define 16 ipaddress swap_server
define 17 string root_path
define 18 string extensions_path
define 19 byte ip_forwarding
define 20 byte non_local_source_routing
define 21 array ipaddress policy_filter
define 22 int16 max_dgram_reassembly
define 23 uint16 default_ip_ttl
define 24 uint32 path_mtu_aging_timeout
define 25 array uint16 path_mtu_plateau_table
define 26 uint16 interface_mtu
define 27 byte all_subnets_local
define 28 request ipaddress broadcast_address
define 29 byte perform_mask_discovery
define 30 byte mask_supplier
define 31 byte router_discovery
define 32 ipaddress router_solicitation_address
define 34 byte trailer_encapsulation
define 35 uint32 arp_cache_timeout
define 36 uint16 ieee802_3_encapsulation
define 37 byte default_tcp_ttl
define 38 uint32 tcp_keepalive_interval
define 39 byte tcp_keepalive_garbage
define 40 string nis_domain
define 41 array ipaddress nis_servers
define 42 array ipaddress ntp_servers
define 43 binhex vendor_encapsulated_options
define 44 array ipaddress netbios_name_servers
define 45 ipaddress netbios_dd_server
define 46 byte netbios_node_type
define 47 string netbios_scope
define 48 array ipaddress font_servers
define 49 array ipaddress x_display_manager
define 50 ipaddress dhcp_requested_address
define 51 request uint32 dhcp_lease_time
define 52 byte dhcp_option_overload
define 53 byte dhcp_message_type
define 54 ipaddress dhcp_server_identifier
define 55 array byte dhcp_parameter_request_list
define 56 string dhcp_message
define 57 uint16 dhcp_max_message_size
define 58 request uint32 dhcp_renewal_time
define 59 request uint32 dhcp_rebinding_time
define 60 string vendor_class_identifier
define 61 binhex dhcp_client_identifier
define 64 string nisplus_domain
define 65 array ipaddress nisplus_servers
define 66 dname tftp_server_name
define 67 string bootfile_name
define 68 array ipaddress mobile_ip_home_agent
define 69 array ipaddress smtp_server
define 70 array ipaddress pop_server
define 71 array ipaddress nntp_server
define 72 array ipaddress www_server
define 73 array ipaddress finger_server
define 74 array ipaddress irc_server
define 75 array ipaddress streettalk_server
define 76 array ipaddress streettalk_directory_assistance_server
# DHCP User Class, RFC3004
define 77 binhex user_class
# DHCP SLP Directory Agent, RFC2610
define 78 embed slp_agent
embed byte mandatory
embed array ipaddress address
define 79 embed slp_service
embed byte mandatory
embed ascii scope_list
# DHCP Rapid Commit, RFC4039
define 80 norequest flag rapid_commit
# DHCP Fully Qualified Domain Name, RFC4702
define 81 embed fqdn
embed bitflags=0000NEOS flags
embed byte rcode1
embed byte rcode2
# dhcpcd always sets the E bit which means the fqdn itself is always
# RFC1035 encoded.
# The server MUST use the encoding as specified by the client as noted
# in RFC4702 Section 2.1.
embed domain fqdn
# Option 82 is for Relay Agents and DHCP servers
# Options 83 ad 84 are unused, RFC3679
# DHCP Novell Directory Services, RFC2241
define 85 array ipaddress nds_servers
define 86 raw nds_tree_name
define 87 raw nds_context
# DHCP Broadcast and Multicast Control Server, RFC4280
define 88 array domain bcms_controller_names
define 89 array ipaddress bcms_controller_address
# DHCP Authentication, RFC3118
define 90 embed auth
embed byte protocol
embed byte algorithm
embed byte rdm
embed binhex:8 replay
embed binhex information
# DHCP Leasequery, RFC4388
define 91 uint32 client_last_transaction_time
define 92 array ipaddress associated_ip
# DHCP Options for Intel Preboot eXecution Environent (PXE), RFC4578
# Options 93, 94 and 97 are used but of no use to dhcpcd
# Option 95 used by Apple but never published RFC3679
# Option 96 is unused, RFC3679
# DHCP The Open Group's User Authentication Protocol, RFC2485
define 98 string uap_servers
# DHCP Civic Addresses Configuration Information, RFC4776
define 99 encap geoconf_civic
embed byte what
embed uint16 country_code
# The rest of this option is not supported
# DHCP Timezone, RFC4883
define 100 string posix_timezone
define 101 string tzdb_timezone
# Options 102-115 are unused, RFC3679
# DHCP Auto-Configuration, RFC2563
define 116 byte auto_configure
# DHCP Name Service Search, RFC2937
define 117 array uint16 name_service_search
# DHCP Subnet Selection, RFC3011
define 118 ipaddress subnet_selection
# DHCP Domain Search, RFC3397
define 119 array domain domain_search
# DHCP Session Initiated Protocol Servers, RFC3361
define 120 rfc3361 sip_server
# Option 121 is defined at the top of this file
# DHCP CableLabs Client, RFC3495
define 122 encap tsp
encap 1 ipaddress dhcp_server
encap 2 ipaddress dhcp_secondary_server
encap 3 rfc3361 provisioning_server
encap 4 embed as_req_as_rep_backoff
embed uint32 nominal
embed uint32 maximum
embed uint32 retry
encap 5 embed ap_req_ap_rep_backoff
embed uint32 nominal
embed uint32 maximum
embed uint32 retry
encap 6 domain kerberos_realm
encap 7 byte ticket_granting_server_utilization
encap 8 byte provisioning_timer
# DHCP Coordinate LCI, RFC6225
# We have no means of expressing 6 bit lengths
define 123 binhex geoconf
# DHCP Vendor-Identifying Vendor Options, RFC3925
define 124 binhex vivco
define 125 embed vivso
embed uint32 enterprise_number
# Vendor options are shared between DHCP/DHCPv6
# Their code is matched to the enterprise number defined above
# see the end of this file for an example
# Options 126 and 127 are unused, RFC3679
# DHCP Options for Intel Preboot eXecution Environent (PXE), RFC4578
# Options 128-135 are used but of no use to dhcpcd
# DHCP PANA Authentication Agent, RFC5192
define 136 array ipaddress pana_agent
# DHCP Lost Server, RFC5223
define 137 domain lost_server
# DHCP CAPWAP, RFC5417
define 138 array ipaddress capwap_ac
# DHCP Mobility Services, RFC5678
define 139 encap mos_ip
encap 1 array ipaddress is
encap 2 array ipaddress cs
encap 3 array ipaddress es
define 140 encap mos_domain
encap 1 domain is
encap 2 domain cs
encap 3 domain es
# DHCP SIP UA, RFC6011
define 141 array domain sip_ua_cs_list
# DHCP ANDSF, RFC6153
define 142 array ipaddress andsf
define 143 array ip6address andsf6
# DHCP Coordinate LCI, RFC6225
# We have no means of expressing 6 bit lengths
define 144 binhex geoloc
# DHCP FORCERENEW Nonce Capability, RFC6704
define 145 array byte forcerenew_nonce_capable
# DHCP RDNSS Selection for MIF Nodes, RFC6731
define 146 embed rdnss_selection
embed byte prf
embed ipaddress primary
embed ipaddress secondary
embed array domain domains
# Options 147, 148 and 149 are unused, RFC3942
# DHCP TFTP Server Address, RFC5859
define 150 array ipaddress tftp_servers
# Options 151-157 are used for Lease Query, RFC6926 and not for dhcpcd
# Options 158-174 are unused, RFC3942
# Options 175-177 are tentativel assigned for Etherboot
# Options 178-207 are unused, RFC3942
# DHCP PXELINUX, RFC5071
define 208 binhex pxelinux_magic
define 209 string config_file
define 210 string path_prefix
define 211 uint32 reboot_time
# DHCP IPv6 Rapid Deployment on IPv4 Infrastructures, RFC5969
define 212 rfc5969 sixrd
# DHCP Access Network Domain Name, RFC5986
define 213 domain access_domain
# Options 214-219 are unused, RFC3942
# DHCP Subnet Allocation, RFC6656
# Option 220 looks specific to Cisco hardware.
# DHCP Virtual Subnet Selection, RFC6607
define 221 encap vss
encap 0 string nvt
encap 1 binhex vpn_id
encap 255 flag global
# Options 222 and 223 are unused, RFC3942
# Options 224-254 are reserved for Private Use
# However, an expired RFC for Web Proxy Auto Discovery Protocol does define
# Option 252 which is commonly used by major browsers.
# Apparently the code was assigned by agreement of the DHC working group chair.
define 252 string wpad_url
# Option 255 End
##############################################################################
# ND6 options, RFC4861
definend 1 binhex source_address
definend 2 binhex target_address
definend 3 index embed prefix_information
embed byte length
embed bitflags=LA flags
embed uint32 vltime
embed uint32 pltime
embed uint32 reserved
embed array ip6address prefix
# option 4 is only for Redirect messages
definend 5 embed mtu
embed uint16 reserved
embed uint32 mtu
# ND6 options, RFC6101
definend 25 index embed rdnss
embed uint16 reserved
embed uint32 lifetime
embed array ip6address servers
definend 31 index embed dnssl
embed uint16 reserved
embed uint32 lifetime
embed domain search
##############################################################################
# DHCPv6 options, RFC3315
define6 1 binhex client_id
define6 2 binhex server_id
define6 3 norequest index embed ia_na
embed binhex:4 iaid
embed uint32 t1
embed uint32 t2
encap 5 option
encap 13 option
define6 4 norequest index embed ia_ta
embed uint32 iaid
encap 5 option
encap 13 option
define6 5 norequest index embed ia_addr
embed ip6address ia_addr
embed uint32 pltime
embed uint32 vltime
encap 13 option
define6 6 array uint16 option_request
define6 7 byte preference
define6 8 uint16 elased_time
define6 9 binhex dhcp_relay_msg
# Option 10 is unused
define6 11 embed auth
embed byte protocol
embed byte algorithm
embed byte rdm
embed binhex:8 replay
embed binhex information
define6 12 ip6address unicast
define6 13 norequest embed status_code
embed uint16 status_code
embed string message
define6 14 norequest flag rapid_commit
define6 15 binhex user_class
define6 16 binhex vivco
define6 17 embed vivso
embed uint32 enterprise_number
# Vendor options are shared between DHCP/DHCPv6
# Their code is matched to the enterprise number defined above
# See the end of this file for an example
define6 18 binhex interface_id
define6 19 byte reconfigure_msg
define6 20 flag reconfigure_accept
# DHCPv6 Session Initiation Protocol Options, RFC3319
define6 21 array domain sip_servers_names
define6 22 array ip6address sip_servers_addresses
# DHCPv6 DNS Configuration Options, RFC3646
define6 23 array ip6address name_servers
define6 24 array domain domain_search
# DHCPv6 Prefix Options, RFC6603
define6 25 norequest index embed ia_pd
embed binhex:4 iaid
embed uint32 t1
embed uint32 t2
encap 26 option
define6 26 index embed prefix
embed uint32 pltime
embed uint32 vltime
embed byte length
embed ip6address prefix
encap 13 option
encap 67 option
# DHCPv6 Network Information Service Options, RFC3898
define6 27 array ip6address nis_servers
define6 28 array ip6address nisp_servers
define6 29 string nis_domain_name
define6 30 string nisp_domain_name
# DHCPv6 Simple Network Time Protocol Servers Option, RFC4075
define6 31 array ip6address sntp_servers
# DHCPv6 Information Refresh Time, RFC4242
define6 32 uint32 info_refresh_time
# DHCPv6 Broadcast and Multicast Control Server, RFC4280
define6 33 array domain bcms_server_d
define6 34 array ip6address bcms_server_a
# DHCP Civic Addresses Configuration Information, RFC4776
define6 36 encap geoconf_civic
embed byte what
embed uint16 country_code
# The rest of this option is not supported
# DHCP Relay Agent Remote-ID, RFC4649
define6 37 embed remote_id
embed uint32 enterprise_number
embed binhex remote_id
# DHCP Relay Agent Subscriber-ID, RFC4580
define6 38 binhex subscriber_id
# DHCPv6 Fully Qualified Domain Name, RFC4704
define6 39 embed fqdn
embed bitflags=00000NOS flags
embed domain fqdn
# DHCPv6 PANA Authentication Agnet, RC5192
define6 40 array ip6address pana_agent
# DHCPv6 Timezone options, RFC4883
define6 41 string posix_timezone
define6 42 string tzdb_timezone
# DHCPv6 Relay Agent Echo Request
define6 43 array uint16 ero
# Options 44-48 are used for Lease Query, RFC5007 and not for dhcpcd
# DHCPv6 Home Info Discovery in MIPv6, RFC6610
define6 49 domain mip6_hnidf
define6 50 encap mip6_vdinf
encap 71 option
encap 72 option
encap 73 option
# DHCPv6 Lost Server, RFC5223
define6 51 domain lost_server
# DHCPv6 CAPWAP, RFC5417
define6 52 array ip6address capwap_ac
# DHCPv6 Relay-ID, RFC5460
define6 53 binhex relay_id
# DHCP Mobility Services, RFC5678
define6 54 encap mos_ip
encap 1 array ip6address is
encap 2 array ip6address cs
encap 3 array ip6address es
define6 55 encap mos_domain
encap 1 domain is
encap 2 domain cs
encap 3 domain es
# DHCPv6 Network Time Protocol Server, RFC5908
define6 56 encap ntp_server
encap 1 ip6address addr
encap 2 ip6address mcast_addr
encap 3 ip6address fqdn
# DHCPv6 LIS Discovery, RFC5986
define6 57 domain access_domain
# DHCPv6 SIP UA, RFC6011
define6 58 array domain sip_ua_cs_list
# DHCPv6 Network Boot, RFC5970
define6 59 string bootfile_url
# We presently cannot decode bootfile_param
define6 60 binhex bootfile_param
define6 61 array uint16 architecture_types
define6 62 embed nii
embed byte type
embed byte major
embed byte minor
# DHCPv6 Coordinate LCI, RFC6225
# We have no means of expressing 6 bit lengths
define6 63 binhex geoloc
# DHCPv6 AFTR-Name, RFC6334
define6 64 domain aftr_name
# DHCPv6 Prefix Exclude Option, RFC6603
define6 67 embed pd_exclude
embed byte prefix_len
embed binhex subnetID
# DHCPv6 Home Info Discovery in MIPv6, RFC6610
define6 69 encap mip6_idinf
encap 71 option
encap 72 option
encap 73 option
define6 70 encap mip6_udinf
encap 71 option
encap 72 option
encap 73 option
define6 71 embed mip6_hnp
embed byte prefix_len
embed ip6address prefix
define6 72 ip6address mip6_haa
define6 73 domain mip6_haf
# DHCPv6 RDNSS Selection for MIF Nodes, RFC6731
define6 74 embed rdnss_selection
embed ip6address server
embed byte prf
embed array domain domains
# DHCPv6 Kerberos, RFC6784
define6 75 string krb_principal_name
define6 76 string krb_realm_name
define6 78 embed krb_kdc
embed uint16 priority
embed uint16 weight
embed byte transport_type
embed uint16 port
embed ip6address address
embed string realm_name
# DHCPv6 Client Link-Layer Address, RFC6939
# Section 7 states that clients MUST ignore the option 79
# DHCPv6 Relay-Triggered Reconfiguraion, RFC6977
define6 80 ip6address link_address
# DHCPv6 Radius, RFC7037
# Section 7 states that clients MUST ignore the option 81
# DHCPv6 SOL_MAX_RT, RFC7083
define6 82 request uint32 sol_max_rt
define6 83 request uint32 inf_max_rt
# DHCPv6 Address Selection Policy
# Currently not supported
# Options 86-65535 are unasssinged
##############################################################################
# Vendor-Identifying Vendor Options
# An example:
#vendopt 12345 encap frobozzco
#encap 1 string maze_location
#encap 2 byte grue_probability

View File

@ -0,0 +1,366 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcpcd-embedded.c,v 1.10 2015/07/09 10:15:34 roy Exp $");
/*
* DO NOT EDIT!
* Automatically generated from dhcpcd-embedded.conf
* Ths allows us to simply generate DHCP structure without any C programming.
*/
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
const char * const dhcpcd_embedded_conf[] = {
"define 1 request ipaddress subnet_mask",
"define 121 rfc3442 classless_static_routes",
"define 249 rfc3442 ms_classless_static_routes",
"define 33 request array ipaddress static_routes",
"define 3 request array ipaddress routers",
"define 2 uint32 time_offset",
"define 4 array ipaddress time_servers",
"define 5 array ipaddress ien116_name_servers",
"define 6 array ipaddress domain_name_servers",
"define 7 array ipaddress log_servers",
"define 8 array ipaddress cookie_servers",
"define 9 array ipaddress lpr_servers",
"define 10 array ipaddress impress_servers",
"define 11 array ipaddress resource_location_servers",
"define 12 dname host_name",
"define 13 uint16 boot_size",
"define 14 string merit_dump",
"define 15 array dname domain_name",
"define 16 ipaddress swap_server",
"define 17 string root_path",
"define 18 string extensions_path",
"define 19 byte ip_forwarding",
"define 20 byte non_local_source_routing",
"define 21 array ipaddress policy_filter",
"define 22 int16 max_dgram_reassembly",
"define 23 uint16 default_ip_ttl",
"define 24 uint32 path_mtu_aging_timeout",
"define 25 array uint16 path_mtu_plateau_table",
"define 26 uint16 interface_mtu",
"define 27 byte all_subnets_local",
"define 28 request ipaddress broadcast_address",
"define 29 byte perform_mask_discovery",
"define 30 byte mask_supplier",
"define 31 byte router_discovery",
"define 32 ipaddress router_solicitation_address",
"define 34 byte trailer_encapsulation",
"define 35 uint32 arp_cache_timeout",
"define 36 uint16 ieee802_3_encapsulation",
"define 37 byte default_tcp_ttl",
"define 38 uint32 tcp_keepalive_interval",
"define 39 byte tcp_keepalive_garbage",
"define 40 string nis_domain",
"define 41 array ipaddress nis_servers",
"define 42 array ipaddress ntp_servers",
"define 43 binhex vendor_encapsulated_options",
"define 44 array ipaddress netbios_name_servers",
"define 45 ipaddress netbios_dd_server",
"define 46 byte netbios_node_type",
"define 47 string netbios_scope",
"define 48 array ipaddress font_servers",
"define 49 array ipaddress x_display_manager",
"define 50 ipaddress dhcp_requested_address",
"define 51 request uint32 dhcp_lease_time",
"define 52 byte dhcp_option_overload",
"define 53 byte dhcp_message_type",
"define 54 ipaddress dhcp_server_identifier",
"define 55 array byte dhcp_parameter_request_list",
"define 56 string dhcp_message",
"define 57 uint16 dhcp_max_message_size",
"define 58 request uint32 dhcp_renewal_time",
"define 59 request uint32 dhcp_rebinding_time",
"define 60 string vendor_class_identifier",
"define 61 binhex dhcp_client_identifier",
"define 64 string nisplus_domain",
"define 65 array ipaddress nisplus_servers",
"define 66 dname tftp_server_name",
"define 67 string bootfile_name",
"define 68 array ipaddress mobile_ip_home_agent",
"define 69 array ipaddress smtp_server",
"define 70 array ipaddress pop_server",
"define 71 array ipaddress nntp_server",
"define 72 array ipaddress www_server",
"define 73 array ipaddress finger_server",
"define 74 array ipaddress irc_server",
"define 75 array ipaddress streettalk_server",
"define 76 array ipaddress streettalk_directory_assistance_server",
"define 77 binhex user_class",
"define 78 embed slp_agent",
"embed byte mandatory",
"embed array ipaddress address",
"define 79 embed slp_service",
"embed byte mandatory",
"embed ascii scope_list",
"define 80 norequest flag rapid_commit",
"define 81 embed fqdn",
"embed bitflags=0000NEOS flags",
"embed byte rcode1",
"embed byte rcode2",
"embed domain fqdn",
"define 85 array ipaddress nds_servers",
"define 86 raw nds_tree_name",
"define 87 raw nds_context",
"define 88 array domain bcms_controller_names",
"define 89 array ipaddress bcms_controller_address",
"define 90 embed auth",
"embed byte protocol",
"embed byte algorithm",
"embed byte rdm",
"embed binhex:8 replay",
"embed binhex information",
"define 91 uint32 client_last_transaction_time",
"define 92 array ipaddress associated_ip",
"define 98 string uap_servers",
"define 99 encap geoconf_civic",
"embed byte what",
"embed uint16 country_code",
"define 100 string posix_timezone",
"define 101 string tzdb_timezone",
"define 116 byte auto_configure",
"define 117 array uint16 name_service_search",
"define 118 ipaddress subnet_selection",
"define 119 array domain domain_search",
"define 120 rfc3361 sip_server",
"define 122 encap tsp",
"encap 1 ipaddress dhcp_server",
"encap 2 ipaddress dhcp_secondary_server",
"encap 3 rfc3361 provisioning_server",
"encap 4 embed as_req_as_rep_backoff",
"embed uint32 nominal",
"embed uint32 maximum",
"embed uint32 retry",
"encap 5 embed ap_req_ap_rep_backoff",
"embed uint32 nominal",
"embed uint32 maximum",
"embed uint32 retry",
"encap 6 domain kerberos_realm",
"encap 7 byte ticket_granting_server_utilization",
"encap 8 byte provisioning_timer",
"define 123 binhex geoconf",
"define 124 binhex vivco",
"define 125 embed vivso",
"embed uint32 enterprise_number",
"define 136 array ipaddress pana_agent",
"define 137 domain lost_server",
"define 138 array ipaddress capwap_ac",
"define 139 encap mos_ip",
"encap 1 array ipaddress is",
"encap 2 array ipaddress cs",
"encap 3 array ipaddress es",
"define 140 encap mos_domain",
"encap 1 domain is",
"encap 2 domain cs",
"encap 3 domain es",
"define 141 array domain sip_ua_cs_list",
"define 142 array ipaddress andsf",
"define 143 array ip6address andsf6",
"define 144 binhex geoloc",
"define 145 array byte forcerenew_nonce_capable",
"define 146 embed rdnss_selection",
"embed byte prf",
"embed ipaddress primary",
"embed ipaddress secondary",
"embed array domain domains",
"define 150 array ipaddress tftp_servers",
"define 208 binhex pxelinux_magic",
"define 209 string config_file",
"define 210 string path_prefix",
"define 211 uint32 reboot_time",
"define 212 rfc5969 sixrd",
"define 213 domain access_domain",
"define 221 encap vss",
"encap 0 string nvt",
"encap 1 binhex vpn_id",
"encap 255 flag global",
"define 252 string wpad_url",
"definend 1 binhex source_address",
"definend 2 binhex target_address",
"definend 3 index embed prefix_information",
"embed byte length",
"embed bitflags=LA flags",
"embed uint32 vltime",
"embed uint32 pltime",
"embed uint32 reserved",
"embed array ip6address prefix",
"definend 5 embed mtu",
"embed uint16 reserved",
"embed uint32 mtu",
"definend 25 index embed rdnss",
"embed uint16 reserved",
"embed uint32 lifetime",
"embed array ip6address servers",
"definend 31 index embed dnssl",
"embed uint16 reserved",
"embed uint32 lifetime",
"embed domain search",
"define6 1 binhex client_id",
"define6 2 binhex server_id",
"define6 3 norequest index embed ia_na",
"embed binhex:4 iaid",
"embed uint32 t1",
"embed uint32 t2",
"encap 5 option",
"encap 13 option",
"define6 4 norequest index embed ia_ta",
"embed uint32 iaid",
"encap 5 option",
"encap 13 option",
"define6 5 norequest index embed ia_addr",
"embed ip6address ia_addr",
"embed uint32 pltime",
"embed uint32 vltime",
"encap 13 option",
"define6 6 array uint16 option_request",
"define6 7 byte preference",
"define6 8 uint16 elased_time",
"define6 9 binhex dhcp_relay_msg",
"define6 11 embed auth",
"embed byte protocol",
"embed byte algorithm",
"embed byte rdm",
"embed binhex:8 replay",
"embed binhex information",
"define6 12 ip6address unicast",
"define6 13 norequest embed status_code",
"embed uint16 status_code",
"embed string message",
"define6 14 norequest flag rapid_commit",
"define6 15 binhex user_class",
"define6 16 binhex vivco",
"define6 17 embed vivso",
"embed uint32 enterprise_number",
"define6 18 binhex interface_id",
"define6 19 byte reconfigure_msg",
"define6 20 flag reconfigure_accept",
"define6 21 array domain sip_servers_names",
"define6 22 array ip6address sip_servers_addresses",
"define6 23 array ip6address name_servers",
"define6 24 array domain domain_search",
"define6 25 norequest index embed ia_pd",
"embed binhex:4 iaid",
"embed uint32 t1",
"embed uint32 t2",
"encap 26 option",
"define6 26 index embed prefix",
"embed uint32 pltime",
"embed uint32 vltime",
"embed byte length",
"embed ip6address prefix",
"encap 13 option",
"encap 67 option",
"define6 27 array ip6address nis_servers",
"define6 28 array ip6address nisp_servers",
"define6 29 string nis_domain_name",
"define6 30 string nisp_domain_name",
"define6 31 array ip6address sntp_servers",
"define6 32 uint32 info_refresh_time",
"define6 33 array domain bcms_server_d",
"define6 34 array ip6address bcms_server_a",
"define6 36 encap geoconf_civic",
"embed byte what",
"embed uint16 country_code",
"define6 37 embed remote_id",
"embed uint32 enterprise_number",
"embed binhex remote_id",
"define6 38 binhex subscriber_id",
"define6 39 embed fqdn",
"embed bitflags=00000NOS flags",
"embed domain fqdn",
"define6 40 array ip6address pana_agent",
"define6 41 string posix_timezone",
"define6 42 string tzdb_timezone",
"define6 43 array uint16 ero",
"define6 49 domain mip6_hnidf",
"define6 50 encap mip6_vdinf",
"encap 71 option",
"encap 72 option",
"encap 73 option",
"define6 51 domain lost_server",
"define6 52 array ip6address capwap_ac",
"define6 53 binhex relay_id",
"define6 54 encap mos_ip",
"encap 1 array ip6address is",
"encap 2 array ip6address cs",
"encap 3 array ip6address es",
"define6 55 encap mos_domain",
"encap 1 domain is",
"encap 2 domain cs",
"encap 3 domain es",
"define6 56 encap ntp_server",
"encap 1 ip6address addr",
"encap 2 ip6address mcast_addr",
"encap 3 ip6address fqdn",
"define6 57 domain access_domain",
"define6 58 array domain sip_ua_cs_list",
"define6 59 string bootfile_url",
"define6 60 binhex bootfile_param",
"define6 61 array uint16 architecture_types",
"define6 62 embed nii",
"embed byte type",
"embed byte major",
"embed byte minor",
"define6 63 binhex geoloc",
"define6 64 domain aftr_name",
"define6 67 embed pd_exclude",
"embed byte prefix_len",
"embed binhex subnetID",
"define6 69 encap mip6_idinf",
"encap 71 option",
"encap 72 option",
"encap 73 option",
"define6 70 encap mip6_udinf",
"encap 71 option",
"encap 72 option",
"encap 73 option",
"define6 71 embed mip6_hnp",
"embed byte prefix_len",
"embed ip6address prefix",
"define6 72 ip6address mip6_haa",
"define6 73 domain mip6_haf",
"define6 74 embed rdnss_selection",
"embed ip6address server",
"embed byte prf",
"embed array domain domains",
"define6 75 string krb_principal_name",
"define6 76 string krb_realm_name",
"define6 78 embed krb_kdc",
"embed uint16 priority",
"embed uint16 weight",
"embed byte transport_type",
"embed uint16 port",
"embed ip6address address",
"embed string realm_name",
"define6 80 ip6address link_address",
"define6 82 request uint32 sol_max_rt",
"define6 83 request uint32 inf_max_rt",
NULL
};

36
external/bsd/dhcpcd/dist/dhcpcd-embedded.c.in vendored Executable file
View File

@ -0,0 +1,36 @@
/*
* DO NOT EDIT!
* Automatically generated from dhcpcd-embedded.conf
* Ths allows us to simply generate DHCP structure without any C programming.
*/
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
const char * const dhcpcd_embedded_conf[] = {

View File

@ -0,0 +1,34 @@
/* $NetBSD: dhcpcd-embedded.h,v 1.9 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define INITDEFINES 122
#define INITDEFINENDS 6
#define INITDEFINE6S 68
extern const char * const dhcpcd_embedded_conf[];

View File

@ -0,0 +1,32 @@
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define INITDEFINES @INITDEFINES@
#define INITDEFINENDS @INITDEFINENDS@
#define INITDEFINE6S @INITDEFINE6S@
extern const char * const dhcpcd_embedded_conf[];

View File

@ -0,0 +1,10 @@
# $NetBSD: 01-test,v 1.8 2015/07/09 10:15:34 roy Exp $
# Echo the interface flags, reason and message options
if [ "$reason" = "TEST" ]; then
set | grep "^\(interface\|pid\|reason\|profile\|skip_hooks\)=" | sort
set | grep "^if\(carrier\|flags\|mtu\|wireless\|ssid\)=" | sort
set | grep "^\(new_\|old_\|nd[0-9]*_\)" | sort
exit 0
fi

View File

@ -0,0 +1,10 @@
# $NetBSD: 02-dump,v 1.6 2014/11/07 20:51:03 roy Exp $
# Just echo our DHCP options we have
case "$reason" in
DUMP|DUMP6)
set | sed -ne 's/^new_//p' | sort
exit 0
;;
esac

View File

@ -0,0 +1,121 @@
# $NetBSD: 10-wpa_supplicant,v 1.6 2014/11/07 20:51:03 roy Exp $
# Start, reconfigure and stop wpa_supplicant per wireless interface.
# This is needed because wpa_supplicant lacks hotplugging of any kind
# and the user should not be expected to have to wire it into their system
# if the base system doesn't do this itself.
if [ -z "$wpa_supplicant_conf" ]; then
for x in \
/etc/wpa_supplicant/wpa_supplicant-"$interface".conf \
/etc/wpa_supplicant/wpa_supplicant.conf \
/etc/wpa_supplicant-"$interface".conf \
/etc/wpa_supplicant.conf \
; do
if [ -s "$x" ]; then
wpa_supplicant_conf="$x"
break
fi
done
fi
: ${wpa_supplicant_conf:=/etc/wpa_supplicant.conf}
wpa_supplicant_ctrldir()
{
local dir
dir=$(key_get_value "[[:space:]]*ctrl_interface=" \
"$wpa_supplicant_conf")
dir=$(trim "$dir")
case "$dir" in
DIR=*)
dir=${dir##DIR=}
dir=${dir%%[[:space:]]GROUP=*}
dir=$(trim "$dir")
;;
esac
printf %s "$dir"
}
wpa_supplicant_start()
{
local dir err errn
# If the carrier is up, don't bother checking anything
[ "$ifcarrier" = "up" ] && return 0
# Pre flight checks
if [ ! -s "$wpa_supplicant_conf" ]; then
syslog warn \
"$wpa_supplicant_conf does not exist"
syslog warn "not interacting with wpa_supplicant(8)"
return 1
fi
dir=$(wpa_supplicant_ctrldir)
if [ -z "$dir" ]; then
syslog warn \
"ctrl_interface not defined in $wpa_supplicant_conf"
syslog warn "not interacting with wpa_supplicant(8)"
return 1
fi
wpa_cli -p "$dir" -i "$interface" status >/dev/null 2>&1 && return 0
syslog info "starting wpa_supplicant"
driver=${wpa_supplicant_driver:+-D}$wpa_supplicant_driver
err=$(wpa_supplicant -B -c"$wpa_supplicant_conf" -i"$interface" \
"$driver" 2>&1)
errn=$?
if [ $errn != 0 ]; then
syslog err "failed to start wpa_supplicant"
syslog err "$err"
fi
return $errn
}
wpa_supplicant_reconfigure()
{
local dir err errn
dir=$(wpa_supplicant_ctrldir)
[ -z "$dir" ] && return 1
if ! wpa_cli -p "$dir" -i "$interface" status >/dev/null 2>&1; then
wpa_supplicant_start
return $?
fi
syslog info "reconfiguring wpa_supplicant"
err=$(wpa_cli -p "$dir" -i "$interface" reconfigure 2>&1)
errn=$?
if [ $errn != 0 ]; then
syslog err "failed to reconfigure wpa_supplicant"
syslog err "$err"
fi
return $errn
}
wpa_supplicant_stop()
{
local dir err errn
dir=$(wpa_supplicant_ctrldir)
[ -z "$dir" ] && return 1
wpa_cli -p "$dir" -i "$interface" status >/dev/null 2>&1 || return 0
syslog info "stopping wpa_supplicant"
err=$(wpa_cli -i"$interface" terminate 2>&1)
errn=$?
if [ $errn != 0 ]; then
syslog err "failed to start wpa_supplicant"
syslog err "$err"
fi
return $errn
}
if [ "$ifwireless" = "1" ] && \
type wpa_supplicant >/dev/null 2>&1 && \
type wpa_cli >/dev/null 2>&1
then
case "$reason" in
PREINIT) wpa_supplicant_start;;
RECONFIGURE) wpa_supplicant_reconfigure;;
DEPARTED) wpa_supplicant_stop;;
esac
fi

View File

@ -0,0 +1,50 @@
# $NetBSD: 15-timezone,v 1.6 2014/11/07 20:51:03 roy Exp $
# Configure timezone
: ${localtime:=/etc/localtime}
set_zoneinfo()
{
local zoneinfo_dir= zone_file=
[ -z "$new_tzdb_timezone" ] && return 0
for d in \
/usr/share/zoneinfo \
/usr/lib/zoneinfo \
/var/share/zoneinfo \
/var/zoneinfo \
; do
if [ -d "$d" ]; then
zoneinfo_dir="$d"
break
fi
done
if [ -z "$zoneinfo_dir" ]; then
syslog warning "timezone directory not found"
return 1
fi
zone_file="$zoneinfo_dir/$new_tzdb_timezone"
if [ ! -e "$zone_file" ]; then
syslog warning "no timezone definition for $new_tzdb_timezone"
return 1
fi
if copy_file "$zone_file" "$localtime"; then
syslog info "timezone changed to $new_tzdb_timezone"
fi
}
# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
new_tzdb_timezone="$new_dhcp6_tzdb_timezone"
;;
esac
if $if_up; then
set_zoneinfo
fi

View File

@ -0,0 +1,203 @@
# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $
# Generate /etc/resolv.conf
# Support resolvconf(8) if available
# We can merge other dhcpcd resolv.conf files into one like resolvconf,
# but resolvconf is preferred as other applications like VPN clients
# can readily hook into it.
# Also, resolvconf can configure local nameservers such as bind
# or dnsmasq. This is important as the libc resolver isn't that powerful.
resolv_conf_dir="$state_dir/resolv.conf"
NL="
"
build_resolv_conf()
{
local cf="$state_dir/resolv.conf.$ifname"
local interfaces= header= search= srvs= servers= x=
# Build a list of interfaces
interfaces=$(list_interfaces "$resolv_conf_dir")
# Build the resolv.conf
if [ -n "$interfaces" ]; then
# Build the header
for x in ${interfaces}; do
header="$header${header:+, }$x"
done
# Build the search list
domain=$(cd "$resolv_conf_dir"; \
key_get_value "domain " ${interfaces})
search=$(cd "$resolv_conf_dir"; \
key_get_value "search " ${interfaces})
set -- ${domain}
domain="$1"
[ -n "$2" ] && search="$search $*"
[ -n "$search" ] && search="$(uniqify $search)"
[ "$domain" = "$search" ] && search=
[ -n "$domain" ] && domain="domain $domain$NL"
[ -n "$search" ] && search="search $search$NL"
# Build the nameserver list
srvs=$(cd "$resolv_conf_dir"; \
key_get_value "nameserver " ${interfaces})
for x in $(uniqify ${srvs}); do
servers="${servers}nameserver $x$NL"
done
fi
header="$signature_base${header:+ $from }$header"
# Assemble resolv.conf using our head and tail files
[ -f "$cf" ] && rm -f "$cf"
[ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
echo "$header" > "$cf"
if [ -f /etc/resolv.conf.head ]; then
cat /etc/resolv.conf.head >> "$cf"
else
echo "# /etc/resolv.conf.head can replace this line" >> "$cf"
fi
printf %s "$domain$search$servers" >> "$cf"
if [ -f /etc/resolv.conf.tail ]; then
cat /etc/resolv.conf.tail >> "$cf"
else
echo "# /etc/resolv.conf.tail can replace this line" >> "$cf"
fi
if change_file /etc/resolv.conf "$cf"; then
chmod 644 /etc/resolv.conf
fi
rm -f "$cf"
}
# Extract any ND DNS options from the RA
# For now, we ignore the lifetime of the DNS options unless they
# are absent or zero.
# In this case they are removed from consideration.
# See draft-gont-6man-slaac-dns-config-issues-01 for issues
# regarding DNS option lifetime in ND messages.
eval_nd_dns()
{
eval ltime=\$nd${i}_rdnss${j}_lifetime
if [ -z "$ltime" -o "$ltime" = 0 ]; then
rdnss=
else
eval rdnss=\$nd${i}_rdnss${j}_servers
fi
eval ltime=\$nd${i}_dnssl${j}_lifetime
if [ -z "$ltime" -o "$ltime" = 0 ]; then
dnssl=
else
eval dnssl=\$nd${i}_dnssl${j}_search
fi
[ -z "$rdnss" -a -z "$dnssl" ] && return 1
new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss"
new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl"
j=$(($j + 1))
return 0
}
add_resolv_conf()
{
local x= conf="$signature$NL" warn=true
local i j ltime rdnss dnssl new_rdnss new_dnssl
# Loop to extract the ND DNS options using our indexed shell values
i=1
j=1
while true; do
while true; do
eval_nd_dns || break
done
i=$(($i + 1))
j=1
eval_nd_dns || break
done
new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
# Derive a new domain from our various hostname options
if [ -z "$new_domain_name" ]; then
if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then
new_domain_name="${new_dhcp6_fqdn#*.}"
elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then
new_domain_name="${new_fqdn#*.}"
elif [ "$new_host_name" != "${new_host_name#*.}" ]; then
new_domain_name="${new_host_name#*.}"
fi
fi
# If we don't have any configuration, remove it
if [ -z "$new_domain_name_servers" -a \
-z "$new_domain_name" -a \
-z "$new_domain_search" ]; then
remove_resolv_conf
return $?
fi
if [ -n "$new_domain_name" ]; then
set -- $new_domain_name
if valid_domainname "$1"; then
conf="${conf}domain $1$NL"
else
syslog err "Invalid domain name: $1"
fi
# If there is no search this, make this one
if [ -z "$new_domain_search" ]; then
new_domain_search="$new_domain_name"
[ "$new_domain_name" = "$1" ] && warn=true
fi
fi
if [ -n "$new_domain_search" ]; then
if valid_domainname_list $new_domain_search; then
conf="${conf}search $new_domain_search$NL"
elif ! $warn; then
syslog err "Invalid domain name in list:" \
"$new_domain_search"
fi
fi
for x in ${new_domain_name_servers}; do
conf="${conf}nameserver $x$NL"
done
if type resolvconf >/dev/null 2>&1; then
[ -n "$ifmetric" ] && export IF_METRIC="$ifmetric"
printf %s "$conf" | resolvconf -a "$ifname"
return $?
fi
if [ -e "$resolv_conf_dir/$ifname" ]; then
rm -f "$resolv_conf_dir/$ifname"
fi
[ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
printf %s "$conf" > "$resolv_conf_dir/$ifname"
build_resolv_conf
}
remove_resolv_conf()
{
if type resolvconf >/dev/null 2>&1; then
resolvconf -d "$ifname" -f
else
if [ -e "$resolv_conf_dir/$ifname" ]; then
rm -f "$resolv_conf_dir/$ifname"
fi
build_resolv_conf
fi
}
# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
new_domain_name_servers="$new_dhcp6_name_servers"
new_domain_search="$new_dhcp6_domain_search"
;;
esac
if $if_up || [ "$reason" = ROUTERADVERT ]; then
add_resolv_conf
elif $if_down; then
remove_resolv_conf
fi

View File

@ -0,0 +1,42 @@
# $NetBSD: 29-lookup-hostname,v 1.7 2014/12/09 20:21:05 roy Exp $
# Lookup the hostname in DNS if not set
lookup_hostname()
{
[ -z "$new_ip_address" ] && return 1
local h=
# Silly ISC programs love to send error text to stdout
if type dig >/dev/null 2>&1; then
h=$(dig +short -x $new_ip_address)
if [ $? = 0 ]; then
echo "$h" | sed 's/\.$//'
return 0
fi
elif type host >/dev/null 2>&1; then
h=$(host $new_ip_address)
if [ $? = 0 ]; then
echo "$h" \
| sed 's/.* domain name pointer \(.*\)./\1/'
return 0
fi
elif type getent >/dev/null 2>&1; then
h=$(getent hosts $new_ip_address)
if [ $? = 0 ]; then
echo "$h" | sed 's/[^ ]* *\([^ ]*\).*/\1/'
return 0
fi
fi
return 1
}
set_hostname()
{
if [ -z "$new_host_name" -a -z "$new_fqdn_name" ]; then
export new_host_name="$(lookup_hostname)"
fi
}
if $if_up; then
set_hostname
fi

View File

@ -0,0 +1,157 @@
# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $
# Set the hostname from DHCP data if required
# A hostname can either be a short hostname or a FQDN.
# hostname_fqdn=true
# hostname_fqdn=false
# hostname_fqdn=server
# A value of server means just what the server says, don't manipulate it.
# This could lead to an inconsistent hostname on a DHCPv4 and DHCPv6 network
# where the DHCPv4 hostname is short and the DHCPv6 has an FQDN.
# DHCPv6 has no hostname option.
# RFC4702 section 3.1 says FQDN should be prefered over hostname.
#
# As such, the default is hostname_fqdn=true so that a consistent hostname
# is always assigned.
: ${hostname_fqdn:=true}
# Some systems don't have hostname(1)
_hostname()
{
local name=
if [ -z "$1" ]; then
if type hostname >/dev/null 2>&1; then
hostname
elif [ -r /proc/sys/kernel/hostname ]; then
read name </proc/sys/kernel/hostname && echo "$name"
elif sysctl kern.hostname >/dev/null 2>&1; then
sysctl -n kern.hostname
elif sysctl kernel.hostname >/dev/null 2>&1; then
sysctl -n kernel.hostname
else
return 1
fi
return $?
fi
# Always prefer hostname(1) if we have it
if type hostname >/dev/null 2>&1; then
hostname "$1"
elif [ -w /proc/sys/kernel/hostname ]; then
echo "$1" >/proc/sys/kernel/hostname
elif sysctl kern.hostname >/dev/null 2>&1; then
sysctl -w "kern.hostname=$1"
elif sysctl kernel.hostname >/dev/null 2>&1; then
sysctl -w "kernel.hostname=$1"
else
# We know this will fail, but it will now fail
# with an error to stdout
hostname "$1"
fi
}
need_hostname()
{
local hostname hfqdn=false hshort=false
case "$force_hostname" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) return 0;;
esac
hostname="$(_hostname)"
case "$hostname" in
""|"(none)"|localhost|localhost.localdomain) return 0;;
esac
case "$hostname_fqdn" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
[Ss][Ee][Rr][Vv][Ee][Rr]) ;;
*) hshort=true;;
esac
if [ -n "$old_fqdn" ]; then
if ${hfqdn} || ! ${hsort}; then
[ "$hostname" = "$old_fqdn" ]
else
[ "$hostname" = "${old_fqdn%%.*}" ]
fi
elif [ -n "$old_host_name" ]; then
if ${hfqdn}; then
if [ -n "$old_domain_name" -a \
"$old_host_name" = "${old_host_name#*.}" ]
then
[ "$hostname" = \
"$old_host_name.$old_domain_name" ]
else
[ "$hostname" = "$old_host_name" ]
fi
elif ${hshort}; then
[ "$hostname" = "${old_host_name%%.*}" ]
else
[ "$hostname" = "$old_host_name" ]
fi
else
# No old hostname
false
fi
}
try_hostname()
{
if valid_domainname "$1"; then
_hostname "$1"
else
syslog err "Invalid hostname: $1"
fi
}
set_hostname()
{
local hfqdn=false hshort=false
need_hostname || return
case "$hostname_fqdn" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
"") ;;
*) hshort=true;;
esac
if [ -n "$new_fqdn" ]; then
if ${hfqdn} || ! ${hshort}; then
try_hostname "$new_fqdn"
else
try_hostname "${new_fqdn%%.*}"
fi
elif [ -n "$new_host_name" ]; then
if ${hfqdn}; then
if [ -n "$new_domain_name" -a \
"$new_host_name" = "${new_host_name#*.}" ]
then
try_hostname "$new_host_name.$new_domain_name"
else
try_hostname "$new_host_name"
fi
elif ${hshort}; then
try_hostname "${new_host_name%%.*}"
else
try_hostname "$new_host_name"
fi
fi
}
# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
new_fqdn="$new_dhcp6_fqdn"
old_fqdn="$old_dhcp6_fqdn"
;;
esac
if $if_up; then
set_hostname
fi

View File

@ -0,0 +1,120 @@
# $NetBSD: 50-ntp.conf,v 1.6 2014/11/07 20:51:03 roy Exp $
# Sample dhcpcd hook script for ntp
# Like our resolv.conf hook script, we store a database of ntp.conf files
# and merge into /etc/ntp.conf
# You can set the env var NTP_CONF to another file like this
# dhcpcd -e NTP_CONF=/usr/pkg/etc/ntpd.conf
# or by adding this to /etc/dhcpcd.enter-hook
# NTP_CONF=/usr/pkg/etc/ntpd.conf
# to use OpenNTPD instead of the default NTP.
if type invoke-rc.d >/dev/null 2>&1; then
# Debian has a seperate file for DHCP config to avoid stamping on
# the master.
[ -e /var/lib/ntp ] || mkdir /var/lib/ntp
: ${ntp_service:=ntp}
: ${NTP_DHCP_CONF:=/var/lib/ntp/ntp.conf.dhcp}
fi
: ${ntp_service:=ntpd}
: ${ntp_restart_cmd:=service_condcommand $ntp_service restart}
ntp_conf_dir="$state_dir/ntp.conf"
# If we have installed OpenNTPD but not NTP then prefer it
# XXX If both exist then update both?
if [ -z "$NTP_CONF" -a -e /etc/ntpd.conf -a ! -e /etc/ntp.conf ]; then
: ${NTP_CONF:=/etc/ntpd.conf}
else
: ${NTP_CONF:=/etc/ntp.conf}
fi
ntp_conf=${NTP_CONF}
NL="
"
build_ntp_conf()
{
local cf="$state_dir/ntp.conf.$ifname"
local interfaces= header= srvs= servers= x=
# Build a list of interfaces
interfaces=$(list_interfaces "$ntp_conf_dir")
if [ -n "$interfaces" ]; then
# Build the header
for x in ${interfaces}; do
header="$header${header:+, }$x"
done
# Build a server list
srvs=$(cd "$ntp_conf_dir";
key_get_value "server " $interfaces)
if [ -n "$srvs" ]; then
for x in $(uniqify $srvs); do
servers="${servers}server $x$NL"
done
fi
fi
# Merge our config into ntp.conf
[ -e "$cf" ] && rm -f "$cf"
[ -d "$ntp_conf_dir" ] || mkdir -p "$ntp_conf_dir"
if [ -n "$NTP_DHCP_CONF" ]; then
[ -e "$ntp_conf" ] && cp "$ntp_conf" "$cf"
ntp_conf="$NTP_DHCP_CONF"
elif [ -e "$ntp_conf" ]; then
remove_markers "$signature_base" "$signature_base_end" \
"$ntp_conf" > "$cf"
fi
if [ -n "$servers" ]; then
echo "$signature_base${header:+ $from }$header" >> "$cf"
printf %s "$servers" >> "$cf"
echo "$signature_base_end${header:+ $from }$header" >> "$cf"
else
[ -e "$ntp_conf" -a -e "$cf" ] || return
fi
# If we changed anything, restart ntpd
if change_file "$ntp_conf" "$cf"; then
[ -n "$ntp_restart_cmd" ] && eval $ntp_restart_cmd
fi
}
add_ntp_conf()
{
local cf="$ntp_conf_dir/$ifname" x=
[ -e "$cf" ] && rm "$cf"
[ -d "$ntp_conf_dir" ] || mkdir -p "$ntp_conf_dir"
if [ -n "$new_ntp_servers" ]; then
for x in $new_ntp_servers; do
echo "server $x" >> "$cf"
done
fi
build_ntp_conf
}
remove_ntp_conf()
{
if [ -e "$ntp_conf_dir/$ifname" ]; then
rm "$ntp_conf_dir/$ifname"
fi
build_ntp_conf
}
# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
new_ntp_servers="$new_dhcp6_sntp_servers"
;;
esac
if $if_up; then
add_ntp_conf
elif $if_down; then
remove_ntp_conf
fi

View File

@ -0,0 +1,88 @@
# $NetBSD: 50-ypbind,v 1.7 2015/03/26 10:26:37 roy Exp $
# Sample dhcpcd hook for ypbind
# This script is only suitable for the BSD versions.
: ${ypbind_restart_cmd:=service_command ypbind restart}
: ${ypbind_stop_cmd:=service_condcommand ypbind stop}
ypbind_dir="$state_dir/ypbind"
: ${ypdomain_dir:=/var/yp}
: ${ypdomain_suffix:=.ypservers}
best_domain()
{
local i=
for i in "$ypbind_dir/$interface_order".*; do
if [ -f "$i" ]; then
cat "$i"
return 0
fi
done
return 1
}
make_yp_binding()
{
[ -d "$ypbind_dir" ] || mkdir -p "$ypbind_dir"
echo "$new_nis_domain" >"$ypbind_dir/$ifname"
if [ -z "$ypdomain_dir" ]; then
false
else
local cf="$ypdomain_dir/$new_nis_domain$ypdomain_suffix"
if [ -n "$new_nis_servers" ]; then
local ncf="$cf.$ifname" x=
rm -f "$ncf"
for x in $new_nis_servers; do
echo "$x" >>"$ncf"
done
change_file "$cf" "$ncf"
else
[ -e "$cf" ] && rm "$cf"
fi
fi
local nd="$(best_domain)"
if [ $? = 0 -a "$nd" != "$(domainname)" ]; then
domainname "$nd"
if [ -n "$ypbind_restart_cmd" ]; then
eval $ypbind_restart_cmd
fi
fi
}
restore_yp_binding()
{
rm -f "$ypbind_dir/$ifname"
local nd="$(best_domain)"
# We need to stop ypbind if there is no best domain
# otherwise it will just stall as we cannot set domainname
# to blank :/
if [ -z "$nd" ]; then
if [ -n "$ypbind_stop_cmd" ]; then
eval $ypbind_stop_cmd
fi
elif [ "$nd" != "$(domainname)" ]; then
domainname "$nd"
if [ -n "$ypbind_restart_cmd" ]; then
eval $ypbind_restart_cmd
fi
fi
}
if [ "$reason" = PREINIT ]; then
rm -f "$ypbind_dir/$interface".*
elif $if_up || $if_down; then
if [ -n "$new_nis_domain" ]; then
if valid_domainname "$new_nis_domain"; then
make_yp_binding
else
syslog err "Invalid NIS domain name: $new_nis_domain"
fi
elif [ -n "$old_nis_domain" ]; then
restore_yp_binding
fi
fi

View File

@ -0,0 +1,218 @@
.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.15 2015/07/09 10:15:34 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd June 29, 2015
.Dt DHCPCD-RUN-HOOKS 8
.Os
.Sh NAME
.Nm dhcpcd-run-hooks
.Nd DHCP client configuration script
.Sh DESCRIPTION
.Nm
is used by
.Xr dhcpcd 8
to run any system and user defined hook scripts.
System hook scripts are found in
.Pa @HOOKDIR@
and the user defined hooks are
.Pa @SYSCONFDIR@/dhcpcd.enter-hook .
and
.Pa @SYSCONFDIR@/dhcpcd.exit-hook .
The default install supplies hook scripts for configuring
.Pa /etc/resolv.conf
and the hostname.
Your distribution may have included other hook scripts to say configure
ntp or ypbind.
A test hook is also supplied that simply echos the dhcp variables to the
console from DISCOVER message.
.Pp
Each time
.Nm
is invoked,
.Ev $interface
is set to the interface that
.Nm dhcpcd
is run on and
.Ev $reason
is to the reason why
.Nm
was invoked.
DHCP information to be configured is held in variables starting with the word
new_ and old DHCP information to be removed is held in variables starting with
the word old_.
.Nm dhcpcd
can display the full list of variables it knows how about by using the
.Fl V , -variables
argument.
.Pp
Here's a list of reasons why
.Nm
could be invoked:
.Bl -tag -width EXPIREXXXEXPIRE6
.It Dv PREINIT
dhcpcd is starting up and any pre-initialisation should be done.
.It Dv CARRIER
dhcpcd has detected the carrier is up.
This is generally just a notification and no action need be taken.
.It Dv NOCARRIER
dhcpcd lost the carrier.
The cable may have been unplugged or association to the wireless point lost.
.It Dv INFORM | Dv INFORM6
dhcpcd informed a DHCP server about it's address and obtained other
configuration details.
.It Dv BOUND | Dv BOUND6
dhcpcd obtained a new lease from a DHCP server.
.It Dv RENEW | Dv RENEW6
dhcpcd renewed it's lease.
.It Dv REBIND | Dv REBIND6
dhcpcd has rebound to a new DHCP server.
.It Dv REBOOT | Dv REBOOT6
dhcpcd successfully requested a lease from a DHCP server.
.It Dv DELEGATED6
dhcpcd assigned a delegated prefix to the interface.
.It Dv IPV4LL
dhcpcd obtaind an IPV4LL address, or one was removed.
.It Dv STATIC
dhcpcd has been configured with a static configuration which has not been
obtained from a DHCP server.
.It Dv 3RDPARTY
dhcpcd is monitoring the interface for a 3rd party to give it an IP address.
.It Dv TIMEOUT
dhcpcd failed to contact any DHCP servers but was able to use an old lease.
.It Dv EXPIRE | EXPIRE6
dhcpcd's lease or state expired and it failed to obtain a new one.
.It Dv NAK
dhcpcd received a NAK from the DHCP server.
This should be treated as EXPIRE.
.It Dv RECONFIGURE
dhcpcd has been instructed to reconfigure an interface.
.It Dv ROUTERADVERT
dhcpcd has received an IPv6 Router Advertisment, or one has expired.
.It Dv STOP | Dv STOP6
dhcpcd stopped running on the interface.
.It Dv STOPPED
dhcpcd has stopped entirely.
.It Dv DEPARTED
The interface has been removed.
.It Dv FAIL
dhcpcd failed to operate on the interface.
This normally happens when dhcpcd does not support the raw interface, which
means it cannot work as a DHCP or ZeroConf client.
Static configuration and DHCP INFORM is still allowed.
.It Dv DUMP
dhcpcd has been asked to dump the last lease for the interface.
.It Dv TEST
dhcpcd received an OFFER from a DHCP server but will not configure the
interface.
This is primarily used to test the variables are filled correctly for the
script to process them.
.El
.Sh ENVIRONMENT
.Nm dhcpcd
will clear the environment variables aside from
.Ev $PATH
and
.Ev $RC_SVCNAME .
The following variables will then be set, along with any protocol supplied
ones.
.Bl -tag -width xnew_delegated_dhcp6_prefix
.It Ev $interface
the name of the interface.
.It Ev $reason
as described above.
.It Ev $pid
the pid of
.Nm dhcpcd .
.It Ev $ifcarrier
the link status of
.Ev $interface :
.Dv unknown ,
.Dv up
or
.Dv down .
.It Ev $ifmetric
.Ev $interface
preference, lower is better.
.It Ev $ifwireless
.Dv 1 if
.Ev $interface
is wireless, otherwise
.Dv 0 .
.It Ev $ifflags
.Ev $interface
flags.
.It Ev $ifmtu
.Ev $interface
MTU.
.It Ev $ifssid
the name of the SSID the
.Ev interface
is connected to.
.It Ev $interface_order
A list of interfaces, in order of preference.
.It Ev $if_up
.Dv true
if the
.Ev interface
is up, otherwise
.Dv false .
.It Ev $if_down
.Dv true
if the
.Ev interface
is down, otherwise
.Dv false .
.It Ev $af_waiting
Address family waiting for, as defined in
.Xr dhcpcd.conf 5 .
.It Ev $profile
the name of the profile selected from
.Xr dhcpcd.conf 5 .
.It Ev $new_delegated_dhcp6_prefix
space separated list of delegated prefixes.
.El
.Sh FILES
When
.Nm
runs, it loads
.Pa @SYSCONFDIR@/dhcpcd.enter-hook
and any scripts found in
.Pa @HOOKDIR@
in a lexical order and then finally
.Pa @SYSCONFDIR@/dhcpcd.exit-hook
.Sh SEE ALSO
.Xr dhcpcd 8
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd
.Sh SECURITY CONSIDERATIONS
.Nm dhcpcd
will validate the content of each option against its encoding.
For string, ascii, raw or binhex encoding it's up to the user to validate it
for the intended purpose.
.Pp
When used in a shell script, each variable must be quoted correctly.

View File

@ -0,0 +1,384 @@
#!/bin/sh
# $NetBSD: dhcpcd-run-hooks.in,v 1.11 2015/08/21 10:39:00 roy Exp $
# dhcpcd client configuration script
# Handy variables and functions for our hooks to use
case "$reason" in
ROUTERADVERT)
ifsuffix=".ra";;
INFORM6|BOUND6|RENEW6|REBIND6|REBOOT6|EXPIRE6|RELEASE6|STOP6)
ifsuffix=".dhcp6";;
IPV4LL)
ifsuffix=".ipv4ll";;
*)
ifsuffix=".dhcp";;
esac
ifname="$interface$ifsuffix"
from=from
signature_base="# Generated by dhcpcd"
signature="$signature_base $from $ifname"
signature_base_end="# End of dhcpcd"
signature_end="$signature_base_end $from $ifname"
state_dir=@RUNDIR@/dhcpcd
_detected_init=false
: ${if_up:=false}
: ${if_down:=false}
: ${syslog_debug:=false}
# Ensure that all arguments are unique
uniqify()
{
local result= i=
for i do
case " $result " in
*" $i "*);;
*) result="$result $i";;
esac
done
echo "${result# *}"
}
# List interface config files in a directory.
# If dhcpcd is running as a single instance then it will have a list of
# interfaces in the preferred order.
# Otherwise we just use what we have.
list_interfaces()
{
local i= x= ifaces=
for i in $interface_order; do
for x in "$1"/$i.*; do
[ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
done
done
for x in "$1"/*; do
[ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
done
uniqify $ifaces
}
# Trim function
trim()
{
local var="$*"
var=${var#"${var%%[![:space:]]*}"}
var=${var%"${var##*[![:space:]]}"}
if [ -z "$var" ]; then
# So it seems our shell doesn't support wctype(3) patterns
# Fall back to sed
var=$(echo "$*" | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
fi
printf %s "$var"
}
# We normally use sed to extract values using a key from a list of files
# but sed may not always be available at the time.
key_get_value()
{
local key="$1" value= x= line=
shift
if type sed >/dev/null 2>&1; then
sed -n "s/^$key//p" $@
else
for x do
while read line; do
case "$line" in
"$key"*) echo "${line##$key}";;
esac
done < "$x"
done
fi
}
# We normally use sed to remove markers from a configuration file
# but sed may not always be available at the time.
remove_markers()
{
local m1="$1" m2="$2" x= line= in_marker=0
shift; shift
if type sed >/dev/null 2>&1; then
sed "/^$m1/,/^$m2/d" $@
else
for x do
while read line; do
case "$line" in
"$m1"*) in_marker=1;;
"$m2"*) in_marker=0;;
*) [ $in_marker = 0 ] && echo "$line";;
esac
done < "$x"
done
fi
}
# Compare two files.
comp_file()
{
[ -e "$1" -a -e "$2" ] || return 1
if type cmp >/dev/null 2>&1; then
cmp -s "$1" "$2"
elif type diff >/dev/null 2>&1; then
diff -q "$1" "$2" >/dev/null
else
# Hopefully we're only working on small text files ...
[ "$(cat "$1")" = "$(cat "$2")" ]
fi
}
# Compare two files.
# If different, replace first with second otherwise remove second.
change_file()
{
if [ -e "$1" ]; then
if comp_file "$1" "$2"; then
rm -f "$2"
return 1
fi
fi
cat "$2" > "$1"
rm -f "$2"
return 0
}
# Compare two files.
# If different, copy or link depending on target type
copy_file()
{
if [ -h "$2" ]; then
[ "$(readlink "$2")" = "$1" ] && return 1
ln -sf "$1" "$2"
else
comp_file "$1" "$2" && return 1
cat "$1" >"$2"
fi
}
# Save a config file
save_conf()
{
if [ -f "$1" ]; then
rm -f "$1-pre.$interface"
cat "$1" > "$1-pre.$interface"
fi
}
# Restore a config file
restore_conf()
{
[ -f "$1-pre.$interface" ] || return 1
cat "$1-pre.$interface" > "$1"
rm -f "$1-pre.$interface"
}
# Write a syslog entry
syslog()
{
local lvl="$1"
if [ "$lvl" = debug ]; then
${syslog_debug} || return 0
fi
[ -n "$lvl" ] && shift
[ -n "$*" ] || return 0
case "$lvl" in
err|error) echo "$interface: $*" >&2;;
*) echo "$interface: $*";;
esac
if type logger >/dev/null 2>&1; then
logger -i -p daemon."$lvl" -t dhcpcd-run-hooks "$interface: $*"
fi
}
# Check for a valid domain name as per RFC1123 with the exception of
# allowing - and _ as they seem to be widely used.
valid_domainname()
{
local name="$1" label
[ -z "$name" -o ${#name} -gt 255 ] && return 1
while [ -n "$name" ]; do
label="${name%%.*}"
[ -z "$label" -o ${#label} -gt 63 ] && return 1
case "$label" in
-*|_*|*-|*_) return 1;;
# some sh require - as the first or last character in the class
# when matching it
*[![:alnum:]_-]*) return 1;;
esac
[ "$name" = "${name#*.}" ] && break
name="${name#*.}"
done
return 0
}
valid_domainname_list()
{
local name
for name do
valid_domainname "$name" || return $?
done
return 0
}
# Check for a valid path
valid_path()
{
case "$@" in
*[![:alnum:]#%+-_:\.,@~\\/\[\]=\ ]*) return 1;;
esac
return 0
}
# With the advent of alternative init systems, it's possible to have
# more than one installed. So we need to try and guess what one we're
# using unless overriden by configure.
detect_init()
{
_service_exists="@SERVICEEXISTS@"
_service_cmd="@SERVICECMD@"
_service_status="@SERVICESTATUS@"
[ -n "$_service_cmd" ] && return 0
if ${_detected_init}; then
[ -n "$_service_cmd" ]
return $?
fi
# Detect the running init system.
# As systemd and OpenRC can be installed on top of legacy init
# systems we try to detect them first.
_service_status=
if [ -x /bin/systemctl -a -S /run/systemd/private ]; then
_service_exists="/bin/systemctl --quiet is-enabled \$1.service"
_service_status="/bin/systemctl --quiet is-active \$1.service"
_service_cmd="/bin/systemctl \$2 \$1.service"
elif [ -x /usr/bin/systemctl -a -S /run/systemd/private ]; then
_service_exists="/usr/bin/systemctl --quiet is-enabled \$1.service"
_service_status="/usr/bin/systemctl --quiet is-active \$1.service"
_service_cmd="/usr/bin/systemctl \$2 \$1.service"
elif [ -x /sbin/rc-service -a \
-s /libexec/rc/init.d/softlevel -o -s /run/openrc/softlevel ]
then
_service_exists="/sbin/rc-service -e \$1"
_service_cmd="/sbin/rc-service \$1 -- -D \$2"
elif [ -x /usr/sbin/invoke-rc.d ]; then
_service_exists="/usr/sbin/invoke-rc.d --query --quiet \$1 start >/dev/null 2>&1 || [ \$? = 104 ]"
_service_cmd="/usr/sbin/invoke-rc.d \$1 \$2"
elif [ -x /sbin/service ]; then
_service_exists="/sbin/service \$1 >/dev/null 2>&1"
_service_cmd="/sbin/service \$1 \$2"
elif [ -x /bin/sv ]; then
_service_exists="/bin/sv status \1 >/dev/null 2>&1"
_service_cmd="/bin/sv \$1 \$2"
elif [ -x /usr/bin/sv ]; then
_service_exists="/usr/bin/sv status \1 >/dev/null 2>&1"
_service_cmd="/usr/bin/sv \$1 \$2"
elif [ -e /etc/slackware-version -a -d /etc/rc.d ]; then
_service_exists="[ -x /etc/rc.d/rc.\$1 ]"
_service_cmd="/etc/rc.d/rc.\$1 \$2"
_service_status="/etc/rc.d/rc.\$1 status 1>/dev/null 2>&1"
else
for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
if [ -d $x ]; then
_service_exists="[ -x $x/\$1 ]"
_service_cmd="$x/\$1 \$2"
break
fi
done
if [ -e /etc/arch-release ]; then
_service_status="[ -e /var/run/daemons/\$1 ]"
elif [ "$x" = "/etc/rc.d" -a -e /etc/rc.d/rc.subr ]; then
_service_status="$x/\$1 check 1>/dev/null 2>&1"
fi
fi
_detected_init=true
if [ -z "$_service_cmd" ]; then
syslog err "could not detect a useable init system"
return 1
fi
return 0
}
# Check a system service exists
service_exists()
{
if [ -z "$_service_exists" ]; then
detect_init || return 1
fi
eval $_service_exists
}
# Send a command to a system service
service_cmd()
{
if [ -z "$_service_cmd" ]; then
detect_init || return 1
fi
eval $_service_cmd
}
# Send a command to a system service if it is running
service_status()
{
if [ -z "$_service_cmd" ]; then
detect_init || return 1
fi
if [ -n "$_service_status" ]; then
eval $_service_status
else
service_command $1 status >/dev/null 2>&1
fi
}
# Handy macros for our hooks
service_command()
{
service_exists $1 && service_cmd $1 $2
}
service_condcommand()
{
service_exists $1 && service_status $1 && service_cmd $1 $2
}
# We source each script into this one so that scripts run earlier can
# remove variables from the environment so later scripts don't see them.
# Thus, the user can create their dhcpcd.enter/exit-hook script to configure
# /etc/resolv.conf how they want and stop the system scripts ever updating it.
for hook in \
@SYSCONFDIR@/dhcpcd.enter-hook \
@HOOKDIR@/* \
@SYSCONFDIR@/dhcpcd.exit-hook
do
for skip in $skip_hooks; do
case "$hook" in
*/*~) continue 2;;
*/"$skip") continue 2;;
*/[0-9][0-9]"-$skip") continue 2;;
*/[0-9][0-9]"-$skip.sh") continue 2;;
esac
done
if [ -f "$hook" ]; then
. "$hook"
fi
done

745
external/bsd/dhcpcd/dist/dhcpcd.8.in vendored Normal file
View File

@ -0,0 +1,745 @@
.\" $NetBSD: dhcpcd.8.in,v 1.44 2015/08/21 10:39:00 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd August 21, 2015
.Dt DHCPCD 8
.Os
.Sh NAME
.Nm dhcpcd
.Nd a DHCP client
.Sh SYNOPSIS
.Nm
.Op Fl 46ABbDdEGgHJKLMpqTV
.Op Fl C , Fl Fl nohook Ar hook
.Op Fl c , Fl Fl script Ar script
.Op Fl e , Fl Fl env Ar value
.Op Fl F , Fl Fl fqdn Ar FQDN
.Op Fl f , Fl Fl config Ar file
.Op Fl h , Fl Fl hostname Ar hostname
.Op Fl I , Fl Fl clientid Ar clientid
.Op Fl i , Fl Fl vendorclassid Ar vendorclassid
.Op Fl j , Fl Fl logfile Ar logfile
.Op Fl l , Fl Fl leasetime Ar seconds
.Op Fl m , Fl Fl metric Ar metric
.Op Fl O , Fl Fl nooption Ar option
.Op Fl o , Fl Fl option Ar option
.Op Fl Q , Fl Fl require Ar option
.Op Fl r , Fl Fl request Ar address
.Op Fl S , Fl Fl static Ar value
.Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr
.Op Fl t , Fl Fl timeout Ar seconds
.Op Fl u , Fl Fl userclass Ar class
.Op Fl v , Fl Fl vendor Ar code , Ar value
.Op Fl W , Fl Fl whitelist Ar address Ns Op Ar /cidr
.Op Fl w
.Op Fl Fl waitip Op 4 | 6
.Op Fl y , Fl Fl reboot Ar seconds
.Op Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr
.Op Fl Z , Fl Fl denyinterfaces Ar pattern
.Op Fl z , Fl Fl allowinterfaces Ar pattern
.Op interface
.Op ...
.Nm
.Fl n , Fl Fl rebind
.Op interface
.Nm
.Fl k , Fl Fl release
.Op interface
.Nm
.Fl U, Fl Fl dumplease
.Ar interface
.Nm
.Fl Fl version
.Nm
.Fl x , Fl Fl exit
.Op interface
.Sh DESCRIPTION
.Nm
is an implementation of the DHCP client specified in
.Li RFC 2131 .
.Nm
gets the host information
.Po
IP address, routes, etc
.Pc
from a DHCP server and configures the network
.Ar interface
of the
machine on which it is running.
.Nm
then runs the configuration script which writes DNS information to
.Xr resolvconf 8 ,
if available, otherwise directly to
.Pa /etc/resolv.conf .
If the hostname is currently blank, (null) or localhost, or
.Va force_hostname
is YES or TRUE or 1 then
.Nm
sets the hostname to the one supplied by the DHCP server.
.Nm
then daemonises and waits for the lease renewal time to lapse.
It will then attempt to renew its lease and reconfigure if the new lease
changes when the lease beings to expire or the DHCP server sends message
to renew early.
.Pp
If any interface reports a working carrier then
.Nm
will try and obtain a lease before forking to the background,
otherwise it will fork right away.
This behaviour can be modified with the
.Fl b , Fl Fl background
and
.Fl w , Fl Fl waitip
options.
.Pp
.Nm
is also an implementation of the BOOTP client specified in
.Li RFC 951 .
.Pp
.Nm
is also an implementation of the IPv6 Router Solicitor as specified in
.Li RFC 4861
and
.Li RFC 6106 .
.Pp
.Nm
is also an implementation of the IPv6 Privacy Extensions to AutoConf as
specified in
.Li RFC 4941 .
This feature needs to be enabled in the kernel and
.Nm
will start using it.
.Pp
.Nm
is also an implemenation of the DHCPv6 client as specified in
.Li RFC 3315 .
By default,
.Nm
only starts DHCPv6 when instructed to do so by an IPV6 Router Advertisement.
If no Identity Association is configured,
then a Non-temporary Address is requested.
.Ss Local Link configuration
If
.Nm
failed to obtain a lease, it probes for a valid IPv4LL address
.Po
aka ZeroConf, aka APIPA
.Pc .
Once obtained it restarts the process of looking for a DHCP server to get a
proper address.
.Pp
When using IPv4LL,
.Nm
nearly always succeeds and returns an exit code of 0.
In the rare case it fails, it normally means that there is a reverse ARP proxy
installed which always defeats IPv4LL probing.
To disable this behaviour, you can use the
.Fl L , Fl Fl noipv4ll
option.
.Ss Multiple interfaces
If a list of interfaces are given on the command line, then
.Nm
only works with those interfaces, otherwise
.Nm
discovers available Ethernet interfaces that can be configured.
When
.Nm
is operating on more than one interface,
it is called Master mode. and this behaviour can be forced with the
.Fl M , Fl Fl master
option so that an individual interface can start
.Nm
but only one instance is running.
The
.Nm dhcpcd-ui
project expects dhcpcd to be running this way.
.Pp
If a single interface is given then
.Nm
only works for that interface and runs as a separate instance.
The
.Fl w , Fl Fl waitip
option is enabled in this instance to maintain compatibility with older
versions.
.Pp
Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric.
For systems that support route metrics, each route will be tagged with the
metric, otherwise
.Nm
changes the routes to use the interface with the same route and the lowest
metric.
See options below for controlling which interfaces we allow and deny through
the use of patterns.
.Ss Hooking into events
.Nm
runs
.Pa @SCRIPT@ ,
or the script specified by the
.Fl c , Fl Fl script
option.
This script runs each script found in
.Pa @HOOKDIR@
in a lexical order.
The default installation supplies the scripts
.Pa 01-test ,
.Pa 02-dump ,
.Pa 10-wpa_supplicant ,
.Pa 15-timezone ,
.Pa 20-resolv.conf
and
.Pa 30-hostname .
You can disable each script by using the
.Fl C , Fl Fl nohook
option.
See
.Xr dhcpcd-run-hooks 8
for details on how these scripts work.
.Nm
currently ignores the exit code of the script.
.Ss Fine tuning
You can fine-tune the behaviour of
.Nm
with the following options:
.Bl -tag -width indent
.It Fl b , Fl Fl background
Background immediately.
This is useful for startup scripts which don't disable link messages for
carrier status.
.It Fl c , Fl Fl script Ar script
Use this
.Ar script
instead of the default
.Pa @SCRIPT@ .
.It Fl D , Fl Fl duid
Generate an
.Li RFC 4361
compliant clientid.
This requires persistent storage and not all DHCP servers work with it so it
is not enabled by default.
.Nm
generates the DUID and stores it in
.Pa @SYSCONFDIR@/dhcpcd.duid .
This file should not be copied to other hosts.
.It Fl d , Fl Fl debug
Echo debug messages to the stderr and syslog.
.It Fl E , Fl Fl lastlease
If
.Nm
cannot obtain a lease, then try to use the last lease acquired for the
interface.
If the
.Fl p, Fl Fl persistent
option is not given then the lease is used if it hasn't expired.
.It Fl e , Fl Fl env Ar value
Push
.Ar value
to the environment for use in
.Xr dhcpcd-run-hooks 8 .
For example, you can force the hostname hook to always set the hostname with
.Fl e
.Va force_hostname=YES .
.It Fl g , Fl Fl reconfigure
.Nm
will re-apply IP address, routing and run
.Xr dhcpcd-run-hooks 8
for each interface.
This is useful so that a 3rd party such as PPP or VPN can change the routing
table and / or DNS, etc and then instruct
.Nm
to put things back afterwards.
.Nm
does not read a new configuration when this happens - you should rebind if you
need that functionality.
.It Fl F , Fl Fl fqdn Ar fqdn
Requests that the DHCP server updates DNS using FQDN instead of just a
hostname.
Valid values for
.Ar fqdn
are disable, none, ptr and both.
.Nm
itself never does any DNS updates.
.Nm
encodes the FQDN hostname as specified in
.Li RFC1035 .
.It Fl f , Fl Fl config Ar file
Specify a config to load instead of
.Pa @SYSCONFDIR@/dhcpcd.conf .
.Nm
always processes the config file before any command line options.
.It Fl h , Fl Fl hostname Ar hostname
Sends
.Ar hostname
to the DHCP server so it can be registered in DNS.
If
.Ar hostname
is an empty string then the current system hostname is sent.
If
.Ar hostname
is a FQDN (ie, contains a .) then it will be encoded as such.
.It Fl I , Fl Fl clientid Ar clientid
Send the
.Ar clientid .
If the string is of the format 01:02:03 then it is encoded as hex.
For interfaces whose hardware address is longer than 8 bytes, or if the
.Ar clientid
is an empty string then
.Nm
sends a default
.Ar clientid
of the hardware family and the hardware address.
.It Fl i , Fl Fl vendorclassid Ar vendorclassid
Override the DHCPv4
.Ar vendorclassid
field sent.
The default is
dhcpcd-<version>:<os>:<machine>:<platform>.
For example
.D1 dhcpcd-5.5.6:NetBSD-6.99.5:i386:i386
If not set then none is sent.
Some badly configured DHCP servers reject unknown vendorclassids.
To work around it, try and impersonate Windows by using the MSFT vendorclassid.
.It Fl j , Fl Fl logfile Ar logfile
Writes to the specified
.Ar logfile
rather than
.Xr syslog 3 .
The
.Ar logfile
is truncated when opened and is reopened when
.Nm
receives the
.Dv SIGUSR2
signal.
.It Fl k , Fl Fl release Op Ar interface
This causes an existing
.Nm
process running on the
.Ar interface
to release its lease and de-configure the
.Ar interface
regardless of the
.Fl p , Fl Fl persistent
option.
If no
.Ar interface
is specified then this applies to all interfaces.
If no interfaces are left running,
.Nm
will exit.
.It Fl l , Fl Fl leasetime Ar seconds
Request a specific lease time in
.Ar seconds .
By default
.Nm
does not request any lease time and leaves it in the hands of the
DHCP server.
.It Fl M , Fl Fl master
Start
.Nm
in master mode even if only one interface specified on the command line.
See the Multiple Interfaces section above.
.It Fl m , Fl Fl metric Ar metric
Metrics are used to prefer an interface over another one, lowest wins.
.Nm
will supply a default metic of 200 +
.Xr if_nametoindex 3 .
An extra 100 will be added for wireless interfaces.
.It Fl n , Fl Fl rebind Op Ar interface
Notifies
.Nm
to reload its configuration and rebind the specified
.Ar interface .
If no interface is specified then this applies to all interfaces.
If
.Nm
is not running, then it starts up as normal.
This may also cause
.Xr wpa_supplicant 8
to reload its configuration for each interface as well.
.It Fl o , Fl Fl option Ar option
Request the DHCP
.Ar option
variable for use in
.Pa @SCRIPT@ .
.It Fl p , Fl Fl persistent
.Nm
normally de-configures the
.Ar interface
and configuration when it exits.
Sometimes, this isn't desirable if, for example, you have root mounted over
NFS or SSH clients connect to this host and they need to be notified of
the host shutting down.
You can use this option to stop this from happening.
.It Fl r , Fl Fl request Op Ar address
Request the
.Ar address
in the DHCP DISCOVER message.
There is no guarantee this is the address the DHCP server will actually give.
If no
.Ar address
is given then the first address currently assigned to the
.Ar interface
is used.
.It Fl s , Fl Fl inform Op Ar address Ns Op Ar /cidr
Behaves like
.Fl r , Fl Fl request
as above, but sends a DHCP INFORM instead of DISCOVER/REQUEST.
This does not get a lease as such, just notifies the DHCP server of the
.Ar address
in use.
You should also include the optional
.Ar cidr
network number in case the address is not already configured on the interface.
.Nm
remains running and pretends it has an infinite lease.
.Nm
will not de-configure the interface when it exits.
If
.Nm
fails to contact a DHCP server then it returns a failure instead of falling
back on IPv4LL.
.It Fl S, Fl Fl static Ar value
Configures a static DHCP
.Ar value .
If you set
.Ic ip_address
then
.Nm
will not attempt to obtain a lease and just use the value for the address with
an infinite lease time.
.Pp
Here is an example which configures a static address, routes and dns.
.D1 dhcpcd -S ip_address=192.168.0.10/24 \e
.D1 -S routers=192.168.0.1 \e
.D1 -S domain_name_servers=192.168.0.1 \e
.D1 eth0
.Pp
You cannot presently set static DHCPv6 values.
Use the
.Fl e , Fl Fl env
option instead.
.It Fl t , Fl Fl timeout Ar seconds
Timeout after
.Ar seconds ,
instead of the default 30.
A setting of 0
.Ar seconds
causes
.Nm
to wait forever to get a lease.
If
.Nm
is working on a single interface then
.Nm
will exit when a timeout occurs, otherwise
.Nm
will fork into the background.
.It Fl u , Fl Fl userclass Ar class
Tags the DHCPv4 message with the userclass
.Ar class .
DHCP servers use this to give members of the class DHCP options other than the
default, without having to know things like hardware address or hostname.
.It Fl v , Fl Fl vendor Ar code , Ns Ar value
Add an encapsulated vendor option.
.Ar code
should be between 1 and 254 inclusive.
To add a raw vendor string, omit
.Ar code
but keep the comma.
Examples.
.Pp
Set the vendor option 01 with an IP address.
.D1 dhcpcd \-v 01,192.168.0.2 eth0
Set the vendor option 02 with a hex code.
.D1 dhcpcd \-v 02,01:02:03:04:05 eth0
Set the vendor option 03 with an IP address as a string.
.D1 dhcpcd \-v 03,\e"192.168.0.2\e" eth0
Set un-encapsulated vendor option to hello world.
.D1 dhcpcd \-v ,"hello world" eth0
.It Fl Fl version
Display both program version and copyright information.
.Nm
then exits before doing any configuration.
.It Fl w
Wait for an address to be assigned before forking to the background.
Does not take an argument, unlike the below option.
.Fl fl waitip
option.
.It Fl Fl waitip Op 4 | 6
Wait for an address to be assigned before forking to the background.
4 means wait for an IPv4 address to be assigned.
6 means wait for an IPv6 address to be assigned.
If no argument is given,
.Nm
will wait for any address protocol to be assigned.
It is possible to wait for more than one address protocol and
.Nm
will only fork to the background when all waiting conditions are satisfied.
.It Fl x , Fl Fl exit Op Ar interface
This will signal an existing
.Nm
process running on the
.Ar interface
to exit.
If no interface is specified, then the above is applied to all interfaces.
See the
.Fl p , Fl Fl persistent
option to control configuration persistence on exit,
which is enabled by default in
.Xr dhcpcd.conf 5 .
.Nm
then waits until this process has exited.
.It Fl y , Fl Fl reboot Ar seconds
Allow
.Ar reboot
seconds before moving to the discover phase if we have an old lease to use.
Allow
.Ar reboot
seconds before starting fallback states from the discover phase.
IPv4LL is started when the first
.Ar reboot
timeout is reached.
The default is 5 seconds.
A setting of 0 seconds causes
.Nm
to skip the reboot phase and go straight into discover.
This has no effect on DHCPv6 other than skipping the reboot phase.
.El
.Ss Restricting behaviour
.Nm
will try to do as much as it can by default.
However, there are sometimes situations where you don't want the things to be
configured exactly how the the DHCP server wants.
Here are some options that deal with turning these bits off.
.Bl -tag -width indent
.It Fl 4 , Fl Fl ipv4only
Configure IPv4 only.
.It Fl 6 , Fl Fl ipv6only
Configure IPv6 only.
.It Fl A , Fl Fl noarp
Don't request or claim the address by ARP.
This also disables IPv4LL.
.It Fl B , Fl Fl nobackground
Don't run in the background when we acquire a lease.
This is mainly useful for running under the control of another process, such
as a debugger or a network manager.
.It Fl C , Fl Fl nohook Ar script
Don't run this hook script.
Matches full name, or prefixed with 2 numbers optionally ending with
.Pa .sh .
.Pp
So to stop
.Nm
from touching your DNS settings you would do:-
.D1 dhcpcd -C resolv.conf eth0
.It Fl G , Fl Fl nogateway
Don't set any default routes.
.It Fl H , Fl Fl xidhwaddr
Use the last four bytes of the hardware address as the DHCP xid instead
of a randomly generated number.
.It Fl J , Fl Fl broadcast
Instructs the DHCP server to broadcast replies back to the client.
Normally this is only set for non Ethernet interfaces,
such as FireWire and InfiniBand.
In most instances,
.Nm
will set this automatically.
.It Fl K , Fl Fl nolink
Don't receive link messages for carrier status.
You should only have to use this with buggy device drivers or running
.Nm
through a network manager.
.It Fl L , Fl Fl noipv4ll
Don't use IPv4LL (aka APIPA, aka Bonjour, aka ZeroConf).
.It Fl O , Fl Fl nooption Ar option
Don't request the specified option.
If no option given, then don't request any options other than those to
configure the interface and routing.
.It Fl Q , Fl Fl require Ar option
Requires the
.Ar option
to be present in all DHCP messages, otherwise the message is ignored.
To enforce that
.Nm
only responds to DHCP servers and not BOOTP servers, you can
.Fl Q
.Ar dhcp_message_type .
.It Fl q , Fl Fl quiet
Quiet
.Nm
on the command line, only warnings and errors will be displayed.
The messages are still logged though.
.It Fl T, Fl Fl test
On receipt of DHCP messages just call
.Pa @SCRIPT@
with the reason of TEST which echos the DHCP variables found in the message
to the console.
The interface configuration isn't touched and neither are any configuration
files.
The
.Ar rapid_commit
option is not sent in TEST mode so that the server does not lease an address.
To test INFORM the interface needs to be configured with the desired address
before starting
.Nm .
.It Fl U, Fl Fl dumplease Ar interface
Dumps the last lease for the
.Ar interface
to stdout.
.Ar interface
could also be a path to a DHCP wire formatted file.
Use the
.Fl 4
or
.Fl 6
flags to specify an address family.
.It Fl V, Fl Fl variables
Display a list of option codes, the associated variable and encoding for use in
.Xr dhcpcd-run-hooks 8 .
Variables are prefixed with new_ and old_ unless the option number is -.
Variables without an option are part of the DHCP message and cannot be
directly requested.
.It Fl W, Fl Fl whitelist Ar address Ns Op /cidr
Only accept packets from
.Ar address Ns Op /cidr .
.Fl X, Fl Fl blacklist
is ignored if
.Fl W, Fl Fl whitelist
is set.
.It Fl X, Fl Fl blacklist Ar address Ns Op Ar /cidr
Ignore all packets from
.Ar address Ns Op Ar /cidr .
.It Fl Z , Fl Fl denyinterfaces Ar pattern
When discovering interfaces, the interface name must not match
.Ar pattern
which is a space or comma separated list of patterns passed to
.Xr fnmatch 3 .
.It Fl z , Fl Fl allowinterfaces Ar pattern
When discovering interfaces, the interface name must match
.Ar pattern
which is a space or comma separated list of patterns passed to
.Xr fnmatch 3 .
If the same interface is matched in
.Fl Z , Fl Fl denyinterfaces
then it is still denied.
.It Fl Fl nodev
Don't load any
.Pa /dev
management modules.
.El
.Sh 3RDPARTY LINK MANAGEMENT
Some interfaces require configuration by 3rd parties, such as PPP or VPN.
When an interface configuration in
.Nm
is marked as STATIC or INFORM without an address then
.Nm
will monitor the interface until an address is added or removed from it and
act accordingly.
For point to point interfaces (like PPP), a default route to its
destination is automatically added to the configuration.
If the point to point interface is configured for INFORM, then
.Nm
unicasts INFORM to the destination, otherwise it defaults to STATIC.
.Sh NOTES
.Nm
requires a Berkley Packet Filter, or BPF device on BSD based systems and a
Linux Socket Filter, or LPF device on Linux based systems for all IPv4
configuration.
.Pp
If restricting
.Nm
to a single interface and optionally address family via the command-line
then all futher calls to
.Nm
to rebind, reconfigure or exit need to include the same restrictive flags
so that
.Nm
knows which process to signal.
.Sh FILES
.Bl -ohang
.It Pa @SYSCONFDIR@/dhcpcd.conf
Configuration file for dhcpcd.
If you always use the same options, put them here.
.It Pa @SYSCONFDIR@/dhcpcd.duid
Text file that holds the DUID used to identify the host.
.It Pa @SYSCONFDIR@/dhcpcd.secret
Text file that holds a secret key known only to the host.
.It Pa @SCRIPT@
Bourne shell script that is run to configure or de-configure an interface.
.It Pa @LIBDIR@/dhcpcd/dev
.Pa /dev
management modules.
.It Pa @HOOKDIR@
A directory containing bourne shell scripts that are run by the above script.
Each script can be disabled by using the
.Fl C , Fl Fl nohook
option described above.
.It Pa @DBDIR@/dhcpcd\- Ns Ar interface Ns Ar -ssid Ns .lease
The actual DHCP message sent by the server.
We use this when reading the last
lease and use the files mtime as when it was issued.
.It Pa @DBDIR@/dhcpcd\- Ns Ar interface Ns Ar -ssid Ns .lease6
The actual DHCPv6 message sent by the server.
We use this when reading the last
lease and use the files mtime as when it was issued.
.It Pa @DBDIR@/dhcpcd-rdm.monotonic
Stores the monotonic counter used in the
.Ar replay
field in Authentication Options.
.It Pa @RUNDIR@/dhcpcd.pid
Stores the PID of
.Nm
running on all interfaces.
.It Pa @RUNDIR@/dhcpcd\- Ns Ar interface Ns .pid
Stores the PID of
.Nm
running on the
.Ar interface .
.It Pa @RUNDIR@/dhcpcd.sock
Control socket to the master daemon.
.It Pa @RUNDIR@/dhcpcd.unpriv.sock
Unpriviledged socket to the master daemon, only allows state retrieval.
.It Pa @RUNDIR@/dhcpcd\- Ns Ar interface Ns .sock
Control socket to per interface daemon.
.El
.Sh SEE ALSO
.Xr fnmatch 3 ,
.Xr if_nametoindex 3 ,
.Xr dhcpcd.conf 5 ,
.Xr resolv.conf 5 ,
.Xr dhcpcd-run-hooks 8 ,
.Xr resolvconf 8
.Sh STANDARDS
RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855,
RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396,
RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075,
RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833,
RFC\ 4941, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6603,
RFC\ 6704, RFC\ 7217, RFC\ 7550.
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd

1910
external/bsd/dhcpcd/dist/dhcpcd.c vendored Normal file

File diff suppressed because it is too large Load Diff

49
external/bsd/dhcpcd/dist/dhcpcd.conf vendored Normal file
View File

@ -0,0 +1,49 @@
# $NetBSD: dhcpcd.conf,v 1.17 2015/08/21 10:39:00 roy Exp $
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel
# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the hardware address of the interface for the Client ID.
#clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
# Some non-RFC compliant DHCP servers do not reply with this set.
# In this case, comment out duid and enable clientid above.
duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Most distributions have NTP support.
option ntp_servers
# Respect the network MTU. This is applied to DHCP routes.
option interface_mtu
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate Stable Private IPv6 Addresses instead of hardware based ones
slaac private
# A hook script is provided to lookup the hostname if not set by the DHCP
# server, but it should not be run by default.
nohook lookup-hostname
# MINIX 3 only: the LWIP service supports only one IPv4 address per interface.
# The 'noalias' directive tells dhcpcd(8) to remove any previous IPv4 addresses
# before adding a new one. This directive should and does not affect IPv6.
noalias

View File

@ -0,0 +1,857 @@
.\" $NetBSD: dhcpcd.conf.5.in,v 1.23 2015/08/21 10:39:00 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd August 1, 2015
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
.Nm dhcpcd.conf
.Nd dhcpcd configuration file
.Sh DESCRIPTION
Although
.Nm dhcpcd
can do everything from the command line, there are cases where it's just easier
to do it once in a configuration file.
Most of the options found in
.Xr dhcpcd 8
can be used here.
The first word on the line is the option and the rest of the line is the value.
Leading and trailing whitespace for the option and value are trimmed.
You can escape characters in the value using the \\ character.
.Pp
Blank lines and lines starting with # are ignored.
.Pp
Here's a list of available options:
.Bl -tag -width indent
.It Ic allowinterfaces Ar pattern
When discovering interfaces, the interface name must match
.Ar pattern
which is a space or comma separated list of patterns passed to
.Xr fnmatch 3 .
If the same interface is matched in
.Ic denyinterfaces
then it is still denied.
.It Ic denyinterfaces Ar pattern
When discovering interfaces, the interface name must not match
.Ar pattern
which is a space or comma separated list of patterns passed to
.Xr fnmatch 3 .
.It Ic arping Ar address Op address
.Nm dhcpcd
will arping each address in order before attempting DHCP.
If an address is found, we will select the replying hardware address as the
profile, otherwise the ip address.
Example:
.Pp
.D1 interface bge0
.D1 arping 192.168.0.1
.Pp
.D1 profile 192.168.0.1
.D1 static ip_address=192.168.0.10/24
.It Ic authprotocol Ar protocol Ar algorithm Ar rdm
Authenticate DHCP messages.
See the Supported Authentication Protocols section.
.It Ic authtoken Ar secretid Ar realm Ar expire Ar key
Define a shared key for use in authentication.
.Ar realm can be "" to for use with the
.Ar delayed
prptocol.
.Ar expire
is the date the token expires and should be formatted "yyy-mm-dd HH:MM".
You can use the keyword
.Ar forever
or
.Ar 0
which means the token never expires.
For the token protocol,
.Ar secretid
needs to be 0 and
.Ar realm
needs to be "".
If
.Nm dhcpcd
has the error
.D1 dhcp_auth_encode: Invalid argument
then it means that
.Nm dhcpcd
could not find the correct authentication token in your configuration.
.It Ic background
Background immediately.
This is useful for startup scripts which don't disable link messages for
carrier status.
.It Ic blacklist Ar address Ns Op /cidr
Ignores all packets from
.Ar address Ns Op /cidr .
.It Ic whitelist Ar address Ns Op /cidr
Only accept packets from
.Ar address Ns Op /cidr .
.Ic blacklist
is ignored if
.Ic whitelist
is set.
.It Ic bootp
Be a BOOTP client.
Basically, this just doesn't send a DHCP Message Type option and will only
interact with a BOOTP server.
All other DHCP options still work.
.It Ic broadcast
Instructs the DHCP server to broadcast replies back to the client.
Normally this is only set for non Ethernet interfaces,
such as FireWire and InfiniBand.
In most cases,
.Nm dhcpcd
will set this automatically.
.It Ic controlgroup Ar group
Sets the group ownership of
.Pa @RUNDIR@/dhcpcd.sock
so that users other than root can connect to
.Nm dhcpcd .
.It Ic debug
Echo debug messages to the stderr and syslog.
.It Ic dev Ar value
Load the
.Ar value
.Pa /dev
management module.
.Nm dhcpcd
will load the first one found to work, if any.
.It Ic env Ar value
Push
.Ar value
to the environment for use in
.Xr dhcpcd-run-hooks 8 .
For example, you can force the hostname hook to always set the hostname with
.Ic env
.Va force_hostname=YES .
Or set which driver
.Xr wpa_supplicant 8
should use with
.Ic env
.Va wpa_supplicant_driver=nl80211
.Pp
If the hostname is set, will be will set to the FQDN if possible as per
RFC 4702 section 3.1.
If the FQDN option is missing,
.Nm dhcpcd
will still try and set a FQDN from the hostname and domain options for
consistency.
To override this, set
.Ic env
.Va hostname_fqdn=[YES|NO|SERVER] .
A value of server means just what the server says, don't manipulate it.
This could lead to an inconsistent hostname on a DHCPv4 and DHCPv6 network
where the DHCPv4 hostname is short and the DHCPv6 has an FQDN.
DHCPv6 has no hostname option.
.It Ic clientid Ar string
Send the
.Ar clientid .
If the string is of the format 01:02:03 then it is encoded as hex.
For interfaces whose hardware address is longer than 8 bytes, or if the
.Ar clientid
is an empty string then
.Nm dhcpcd
sends a default
.Ar clientid
of the hardware family and the hardware address.
.It Ic duid
Generate an
.Rs
.%T "RFC 4361"
.Re
compliant DHCP Unique Identifier.
If persistent storage is available then a DUID-LLT (link local address + time)
is generated, otherwise DUID-LL is generated (link local address).
This, plus the IAID will be used as the
.Ic clientid .
The DUID-LLT generated will be held in
.Pa @SYSCONFDIR@/dhcpcd.duid
and should not be copied to other hosts.
.It Ic iaid Ar iaid
Set the Interface Association Identifier to
.Ar iaid .
This option must be used in an
.Ic interface
block.
This defaults to the last 4 bytes of the hardware address assigned to the
interface.
Each instance of this should be unique within the scope of the client and
.Nm dhcpcd
warns if a conflict is detected.
If there is a conflict, it is only a problem if the conflicted IAIDs are
used on the same network.
.It Ic dhcp
Enable DHCP on the interface, on by default.
.It Ic dhcp6
Enable DHCPv6 on the interface, on by default.
.It Ic ipv4
Enable IPv4 on the interface, on by default.
.It Ic ipv6
Enable IPv6 on the interface, on by default.
.It Ic persistent
.Nm dhcpcd
normally de-configures the interface and configuration when it exits.
Sometimes, this isn't desirable if, for example, you have root mounted over
NFS or SSH clients connect to this host and they need to be notified of
the host shutting down.
You can use this option to stop this from happening.
.It Ic fallback Ar profile
Fallback to using this profile if DHCP fails.
This allows you to configure a static profile instead of using ZeroConf.
.It Ic hostname Ar name
Sends
.Ar hostname
to the DHCP server so it can be registered in DNS.
If
.Ar hostname
is an empty string then the current system hostname is sent.
If
.Ar hostname
is a FQDN (ie, contains a .) then it will be encoded as such.
.It Ic hostname_short
Sends the short hostname to the DHCP server instead of the FQDN.
This is useful because DHCP servers will not register the FQDN in their
DNS if the domain part does not match theirs.
.Pp
Also, see the
.Ic env
option above to control how the hostname is set on the host.
.It Ic ia_na Op Ar iaid Op / address
Request a DHCPv6 Normal Address for
.Ar iaid .
.Ar iaid
defaults to the
.Ic iaid
option as described above.
You can request more than one ia_na by specifying a unique
.Ar iaid
for each one.
.It Ic ia_ta Op Ar iaid
Request a DHCPv6 Temporary Address for
.Ar iaid .
You can request more than one ia_ta by specifying a unique
.Ar iaid
for each one.
.It Ic ia_pd Op Ar iaid Oo / Ar prefix / Ar prefix_len Oc Op Ar interface Op / Ar sla_id Op / Ar prefix_len
Request a DHCPv6 Delegated Prefix for
.Ar iaid .
This option must be used in an
.Ic interface
block.
Unless a
.Ar sla_id
of 0 is assigned, a reject route is installed for the Delegated Prefix to
stop unallocated addresses being resolved upstream.
This reject route is in essence SLA 0, thus you need space within the prefix
to assign a SLA per interface.
If no
.Ar interface
is given then we will assign a prefix to every other interface with a
.Ar sla_id
equivalent to the interface index assigned by the OS.
Otherwise addresses are only assigned for each
.Ar interface
and
.Ar sla_id .
Each assigned address will have a suffix of 1.
You cannot assign a prefix to the requesting interface unless the
DHCPv6 server supports
.Li RFC6603
Prefix Exclude Option.
.Nm dhcpcd
has to be running for all the interfaces it is delegating to.
A default
.Ar prefix_len
of 64 is assumed, unless the maximum
.Ar sla_id
does not fit.
In this case
.Ar prefix_len
is increased to the highest multiple of 8 that can accommodate the
.Ar sla_id .
.Ar sla_id
is an integer and is added to the prefix which must fit inside
.Ar prefix_len
less the length of the delegated prefix.
.Ar sla_id can be 0 only if the Delegated Prefix is assigned to one interface.
You can specify multiple
.Ar interface /
.Ar sla_id /
.Ar prefix_len
per
.Ic ia_pd ,
space separated.
IPv6RS should be disabled globally when requesting a Prefix Delegation.
.Pp
In the following example eth0 is the externally facing interface to be
configured for both IPv4 and IPv6.
The DHCPv4 server will provide us with an IPv4 address and a default route.
The DHCPv6 server is going to provide us with an IPv6 address, a default
route and a /64 subnet to be delegated to the internal interface.
The eth1 interface will be automatically configured
for IPv6 using the first address (::1) from the delegated prefix.
A second prefix is requested and assigned to two other interfaces.
.Xr rtadvd 8
can be used with an empty configuration file on eth1, eth2 and eth3,
to provide automatic
IPv6 address configuration for the internal network.
.Bd -literal -indent
noipv6rs # disable routing solicitation
denyinterfaces eth2 # Don't touch eth2 at all
interface eth0
ipv6rs # enable routing solicitation get the
# default IPv6 route
ia_na 1 # request an IPv6 address
ia_pd 2 eth1/0 # request a PD and assign it to eth1
ia_pd 3 eth2/1 eth3/2 # req a PD and assign it to eth2 and eth3
# we cannot use SLA 0 above because we are
# assinging the PD to more than one interface
.Ed
.It Ic ipv4only
Only configure IPv4.
.It Ic ipv6only
Only confgiure IPv6.
.It Ic fqdn Op disable | ptr | both
ptr just asks the DHCP server to update the PTR
record of the host in DNS whereas both also updates the A record.
disable will disable the FQDN option.
The default is both.
.Nm dhcpcd
itself never does any DNS updates.
.Nm dhcpcd
encodes the FQDN hostname as specified in
.Li RFC1035 .
.It Ic interface Ar interface
Subsequent options are only parsed for this
.Ar interface .
.It Ic ipv6ra_autoconf
Generate SLAAC addresses for each Prefix advertised by a
Router Advertisement message with the Auto flag set.
On by default.
.It Ic ipv6ra_noautoconf
Disables the above option.
.It Ic ipv6ra_fork
By default, when
.Nm dhcpcd
receives an IPv6 RA,
.Nm dhcpcd
will only fork to the background if the RA contains at least one unexpired
RDNSS option and a valid prefix or no DHCPv6 instruction.
Set this option so to make
.Nm dhcpcd
always fork on an RA.
.It Ic ipv6ra_own
Disables kernel IPv6 Router Advertisment processing so dhcpcd can manage
addresses and routes.
.It Ic ipv6ra_own_default
Each time dhcpcd receives an IPv6 Router Adveristment, dhcpcd will manage
the default route only.
This allows dhcpcd to prefer an interface for outbound traffic based on metric
and/or user selection rather than the kernel.
.It Ic ipv6ra_accept_nopublic
Some IPv6 routers advertise themselves as a default router without any
public prefixes or managed addresses.
Generally, this is incorrect behaviour and
.Nm dhcpcd
will ignore the advertisement unless this option is turned on.
.It Ic ipv6rs
Enables IPv6 Router Advertisment solicitation.
This is on by default, but is documented here in the case where it is disabled
globally but needs to be enabled for one interface.
.It Ic leasetime Ar seconds
Request a leasetime of
.Ar seconds .
.It Ic logfile Ar logfile
Writes to the specified
.Ar logfile
rather than
.Xr syslog 3 .
The
.Ar logfile
is truncated when opened and is reopened when
.Nm dhcpcd
receives the
.Dv SIGUSR2
signal.
.It Ic metric Ar metric
Metrics are used to prefer an interface over another one, lowest wins.
.Nm dhcpcd
will supply a default metric of 200 +
.Xr if_nametoindex 3 .
An extra 100 will be added for wireless interfaces.
.It Ic noalias
Any pre-existing IPv4 addresses existing address will be removed from the
interface when adding a new IPv4 address.
.It Ic noarp
Don't send any ARP requests.
This also disables IPv4LL.
.It Ic noauthrequired
Don't require authentication even though we requested it.
Also allows FORCERENEW and RECONFIGURE messages without authentication.
.It Ic nodelay
Don't delay for an initial randomised time when starting protocols.
.It Ic nodev
Don't load
.Pa /dev
management modules.
.It Ic nodhcp
Don't start DHCP or listen to DHCP messages.
This is only useful when allowing IPv4LL.
.It Ic nodhcp6
Don't start DHCPv6 or listen to DHCPv6 messages.
Normally DHCPv6 is started by a RA instruction or configuration.
.It Ic nogateway
Don't install any default routes.
.It Ic gateway
Install a default route if available (default).
.It Ic nohook Ar script
Don't run this hook script.
Matches full name, or prefixed with 2 numbers optionally ending with
.Pa .sh .
.Pp
So to stop
.Nm dhcpcd
from touching your DNS settings or starting wpa_supplicant you would do:-
.D1 nohook resolv.conf, wpa_supplicant
.It Ic noipv4
Don't attempt to configure an IPv4 address.
.It Ic noipv4ll
Don't attempt to obtain an IPv4LL address if we failed to get one via DHCP.
See
.Rs
.%T "RFC 3927"
.Re
.It Ic noipv6
Don't attmept to configure an IPv6 address.
.It Ic noipv6rs
Disable solicitation and receipt of IPv6 Router Advertisements.
.It Ic nolink
Don't receive link messages about carrier status.
You should only set this for buggy interface drivers.
.It Ic noup
Don't bring the interface up when in master mode.
If
.Nm
cannot determine the carrier state,
.Nm
will enter a tight polling loop until the interface is marked up and running
or a valid carrier state is reported.
.It Ic option Ar option
Requests the
.Ar option
from the server.
It can be a variable to be used in
.Xr dhcpcd-run-hooks 8
or the numerical value.
You can specify more
.Ar option Ns s
separated by commas, spaces or more
.Ic option
lines.
.Ar option
Prepend dhcp6_ to
.Ar option
to request a DHCPv6 option.
If no DHCPv6 options are configured,
then DHCPv4 options are mapped to equivalent DHCPv6 options.
.Pp
Prepend nd_ to
.Ar option
to handle ND options, but this only works for the
.Ic nooption ,
.Ic reject
and
.Ic require
options.
.It Ic nooption Ar option
Remove the option from the message before it's processed.
.It Ic require Ar option
Requires the
.Ar option
to be present in all messages, otherwise the message is ignored.
To enforce that
.Nm dhcpcd
only responds to DHCP servers and not BOOTP servers, you can
.Ic require
.Ar dhcp_message_type .
This isn't an exact science though because a BOOTP server can send DHCP like
options.
.It Ic reject Ar option
Reject a message that contains the
.Ar option .
This is useful when you cannot use
.Ic require
to select / de-select BOOTP messages.
.It Ic destination Ar option
If
.Nm
detects an address added to a point to point interface (PPP, TUN, etc) then
it will set the listed DHCP options to the destination address of the
interface.
.It Ic profile Ar name
Subsequent options are only parsed for this profile
.Ar name .
.It Ic quiet
Suppress any dhcpcd output to the console, except for errors.
.It Ic reboot Ar seconds
Allow
.Ar reboot
seconds before moving to the DISCOVER phase if we have an old lease to use
and moving from DISCOVER to IPv4LL if no reply.
The default is 5 seconds.
A setting of 0 seconds causes
.Nm dhcpcd
to skip the REBOOT phase and go straight into DISCOVER.
This is desirable for mobile users because if you change from network A to
network B and they use the same subnet and the address from network A isn't
in use on network B, then the DHCP server will remain silent even if authorative
which means
.Nm dhcpcd
will timeout before moving back to the DISCOVER phase.
.It Ic release
.Nm dhcpcd
will release the lease prior to stopping the interface.
.It Ic script Ar script
Use
.Ar script
instead of the default
.Pa @SCRIPT@ .
.It Ic ssid Ar ssid
Subsequent options are only parsed for this wireless
.Ar ssid .
.It Ic slaac Op Ar hwaddr | Ar private
Selects the interface identifier used for SLAAC generated IPv6 addresses.
If
.Ar private
is used, a RFC7217 address is generated.
.It Ic static Ar value
Configures a static
.Ar value .
If you set
.Ic ip_address
then
.Nm dhcpcd
will not attempt to obtain a lease and just use the value for the address with
an infinite lease time.
.Pp
Here is an example which configures a static address, routes and dns.
.D1 interface eth0
.D1 static ip_address=192.168.0.10/24
.D1 static routers=192.168.0.1
.D1 static domain_name_servers=192.168.0.1
.Pp
Here is an example for PPP which gives the destination a default route.
It uses the special destination keyword to insert the destination address
into the value.
.D1 interface ppp0
.D1 static ip_address=
.D1 destination routers
.It Ic timeout Ar seconds
Timeout after
.Ar seconds ,
instead of the default 30.
A setting of 0
.Ar seconds
causes
.Nm dhcpcd
to wait forever to get a lease.
If
.Nm dhcpcd
is working on a single interface then
.Nm dhcpcd
will exit when a timeout occurs, otherwise
.Nm dhcpcd
will fork into the background.
If using IPv4LL then
.Nm dhcpcd
start the IPv4LL process after the timeout and then wait a little longer
before really timing out.
.It Ic userclass Ar string
Tag the DHCPv4 messages with the userclass.
You can specify more than one.
.It Ic vendor Ar code , Ns Ar value
Add an encapsulated vendor option.
.Ar code
should be between 1 and 254 inclusive.
To add a raw vendor string, omit
.Ar code
but keep the comma.
Examples.
.Pp
Set the vendor option 01 with an IP address.
.D1 vendor 01,192.168.0.2
Set the vendor option 02 with a hex code.
.D1 vendor 02,01:02:03:04:05
Set the vendor option 03 with an IP address as a string.
.D1 vendor 03,\e"192.168.0.2\e"
Set un-encapsulated vendor option to hello world.
.D1 vendor ,"hello world"
.It Ic vendorclassid Ar string
Set the DHCP Vendor Class.
DHCPv6 has it's own option as shown below.
The default is
dhcpcd-<version>:<os>:<machine>:<platform>.
For example
.D1 dhcpcd-5.5.6:NetBSD-6.99.5:i386:i386
If not set then none is sent.
Some badly configured DHCP servers reject unknown vendorclassids.
To work around it, try and impersonate Windows by using the MSFT vendorclassid.
.It Ic vendclass Ar en Ar data
Add the DHCPv6 Vendor Indetifying Vendor Class with the IANA assigned Enterprise
Number
.Ar en
with the
.Ar data .
This option can be set more than once to add more data, but the behaviour,
as per
.Xr RFC 3925
is undefined if the Enterprise Number differs.
.It Ic waitip Op 4 | 6
Wait for an address to be assigned before forking to the background.
4 means wait for an IPv4 address to be assigned.
6 means wait for an IPv6 address to be assigned.
If no argument is given,
.Nm
will wait for any address protocol to be assigned.
It is possible to wait for more than one address protocol and
.Nm
will only fork to the background when all waiting conditions are satisfied.
.It Ic xidhwaddr
Use the last four bytes of the hardware address as the DHCP xid instead
of a randomly generated number.
.El
.Ss Defining new options
DHCP, ND and DHCPv6 allow for the use of custom options.
Each option needs to be started with the
.Ic define ,
.If definend
or
.Ic define6
directive.
This can optionally be followed by both
.Ic embed
or
.Ic encap
options.
Both can be specified more than once and
.Ic embed
must come before
.Ic encap .
.Bl -tag -width indent
.It Ic define Ar code Ar type Ar variable
Defines the DHCP option
.Ar code
of
.Ar type
with a name of
.Ar variable
exported to
.Xr dhcpcd-run-hooks 8 .
.It Ic definend Ar code Ar type Ar variable
Defines the ND option
.Ar code
of
.Ar type
with a name of
.Ar variable
exported to
.Xr dhcpcd-run-hooks 8 ,
with a prefix of
.Va _nd .
.It Ic define6 Ar code Ar type Ar variable
Defines the DHCPv6 option
.Ar code
of
.Ar type
with a name of
.Ar variable
exported to
.Xr dhcpcd-run-hooks 8 ,
with a prefix of
.Va _dhcp6 .
.It Ic vendopt Ar code Ar type Ar variable
Defines the Vendor-Identifying Vendor Options.
The
.Ar code
is the IANA Enterprise Number which will unqiuely describe the encapsulated
options.
.Ar type
is normally
.Ar encap .
.Ar variable
names the Vendor option to be exported.
.It Ic embed Ar type Ar variable
Defines an embedded variable within the defined option.
The length is determined by the
.Ar type .
If the
.Ar variable
is not the same as defined in the parent option,
it is prefixed with the parent
.Ar variable
first with an underscore.
If the
.Ar variable
has the name of
.Ar reserved
then it is not processed.
.It Ic encap Ar code Ar type Ar variable
Defines an encapsulated variable within the defined option.
The length is determined by the
.Ar type .
If the
.Ar variable
is not the same as defined in the parent option,
it is prefixed with the parent
.Ar variable
first with an underscore.
.El
.Ss Type prefix
These keywords come before the type itself, to describe it more fully.
You can use more than one, but they must appear in the order listed below.
.Bl -tag -width -indent
.It Ic request
Requests the option by default without having to be specified in user
configuration
.It Ic norequest
This option cannot be requested, regardless of user configuration
.It Ic index
The option can appear more than once and will be indexed.
.It Ic array
The option data is split into a space separated array, each element being
the same type.
.El
.Ss Types to define
The type directly affects the length of data consumed inside the option.
Any remaining data is normally discarded.
Lengths can be specified for string and binhex types, but this is generally
with other data embedded afterwards in the same option.
.Bl -tag -width indent
.It Ic ipaddress
An IPv4 address, 4 bytes.
.It Ic ip6address
An IPv6 address, 16 bytes.
.It Ic string Op : Ic length
A NVT ASCII string of printable characters.
.It Ic byte
A byte.
.It Ic bitflags : Ic flags
A byte represented as a string of flags, most significant bit first.
For example, using ABCDEFGH then A would equal 10000000, B 01000000,
C 00100000, etc.
If the bit is not set, the flag is not printed.
A flag of 0 is not printed even if the bit postition is set.
This is to allow reservation of the first bits while assinging the last bits.
.It Ic int16
A signed 16bit integer, 2 bytes.
.It Ic uint16
An unsigned 16bit integer, 2 bytes.
.It Ic int32
A signed 32bit integer, 4 bytes.
.It Ic uint32
An unsigned 32bit integer, 4 bytes.
.It Ic flag
A fixed value (1) to indicate that the option is present, 0 bytes.
.It Ic domain
A RFC 3397 encoded string.
.It Ic dname
A RFC 1035 validated string.
.It Ic binhex Op : Ic length
Binary data expressed as hexadecimal.
.It Ic embed
Contains embedded options (implies encap as well).
.It Ic encap
Contains encapsulated options (implies embed as well).
.It Ic option
References an option from the global definition.
.El
.Ss Example definition
.D1 # DHCP option 81, Fully Qualified Domain Name, RFC4702
.D1 define 81 embed fqdn
.D1 embed byte flags
.D1 embed byte rcode1
.D1 embed byte rcode2
.D1 embed domain fqdn
.Pp
.D1 # DHCP option 125, Vendor Specific Information Option, RFC3925
.D1 define 125 encap vsio
.D1 embed uint32 enterprise_number
.D1 # Options defined for the enterprise number
.D1 encap 1 ipaddress ipaddress
.Ss Supported Authentication Protocols
.Bl -tag -width -indent
.It Ic token
Sends and expects the token with the secretid 0 and realm of "" in each message.
.It Ic delayedrealm
Delayed Authentication.
.Nm dhcpcd
will send an authentication option with no key or MAC.
The server will see this option, and select a key for
.Nm , writing the
.Ar realm
and
.Ar secretid
in it.
.Nm dhcpcd
will then look for a non-expired token with a matching realm and secretid.
This token is used to authenicate all other messages.
.It Ic delayed
Same as above, but without a realm.
.El
.Ss Supported Authentication Algorithms
If none specified,
.Ic hmac-md5
is the default.
.Bl -tag -width -indent
.It Ic hmac-md5
.El
.Ss Supported Replay Detection Mechanisms
If none specified,
.Ic monotonic
is the default.
If this is changed from what was previously used,
or the means of calculating or storing it is broken then the DHCP server
will probably have to have its notion of the clients Replay Detection Value
reset.
.Bl -tag -width -indent
.It Ic monocounter
Read the number in the file
.Pa @DBDIR@/dhcpcd-rdm.monotonic
and add one to it.
.It Ic monotime
Create a NTP timestamp from the system time.
.It Ic monotonic
Same as
.Ic monotime .
.El
.Sh SEE ALSO
.Xr fnmatch 3 ,
.Xr if_nametoindex 3 ,
.Xr dhcpcd 8 ,
.Xr dhcpcd-run-hooks 8
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd

199
external/bsd/dhcpcd/dist/dhcpcd.h vendored Normal file
View File

@ -0,0 +1,199 @@
/* $NetBSD: dhcpcd.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DHCPCD_H
#define DHCPCD_H
#include <sys/socket.h>
#include <net/if.h>
#include "config.h"
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h>
#endif
#include "defs.h"
#include "control.h"
#include "if-options.h"
#define HWADDR_LEN 20
#define IF_SSIDSIZE 33
#define PROFILE_LEN 64
#define SECRET_LEN 64
#define LINK_UP 1
#define LINK_UNKNOWN 0
#define LINK_DOWN -1
#define IF_DATA_IPV4 0
#define IF_DATA_ARP 1
#define IF_DATA_IPV4LL 2
#define IF_DATA_DHCP 3
#define IF_DATA_IPV6 4
#define IF_DATA_IPV6ND 5
#define IF_DATA_DHCP6 6
#define IF_DATA_MAX 7
/* If the interface does not support carrier status (ie PPP),
* dhcpcd can poll it for the relevant flags periodically */
#define IF_POLL_UP 100 /* milliseconds */
#ifdef __QNX__
/* QNX carries defines for, but does not actually support PF_LINK */
#undef IFLR_ACTIVE
#endif
struct interface {
struct dhcpcd_ctx *ctx;
TAILQ_ENTRY(interface) next;
char name[IF_NAMESIZE];
#ifdef __linux__
char alias[IF_NAMESIZE];
#endif
unsigned int index;
unsigned int flags;
sa_family_t family;
unsigned char hwaddr[HWADDR_LEN];
uint8_t hwlen;
unsigned int metric;
int carrier;
int wireless;
uint8_t ssid[IF_SSIDSIZE];
unsigned int ssid_len;
char profile[PROFILE_LEN];
struct if_options *options;
void *if_data[IF_DATA_MAX];
};
TAILQ_HEAD(if_head, interface);
struct dhcpcd_ctx {
int pid_fd;
char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1];
const char *cffile;
unsigned long long options;
char *logfile;
int log_fd;
int argc;
char **argv;
int ifac; /* allowed interfaces */
char **ifav; /* allowed interfaces */
int ifdc; /* denied interfaces */
char **ifdv; /* denied interfaces */
int ifc; /* listed interfaces */
char **ifv; /* listed interfaces */
int ifcc; /* configured interfaces */
char **ifcv; /* configured interfaces */
unsigned char *duid;
size_t duid_len;
struct if_head *ifaces;
int pf_inet_fd;
#if defined(INET6) && defined(BSD)
int pf_inet6_fd;
#endif
#ifdef IFLR_ACTIVE
int pf_link_fd;
#endif
int link_fd;
#ifdef USE_SIGNALS
sigset_t sigset;
#endif
struct eloop *eloop;
int control_fd;
int control_unpriv_fd;
struct fd_list_head control_fds;
char control_sock[sizeof(CONTROLSOCKET) + IF_NAMESIZE];
gid_t control_group;
/* DHCP Enterprise options, RFC3925 */
struct dhcp_opt *vivso;
size_t vivso_len;
char *randomstate; /* original state */
#ifdef INET
struct dhcp_opt *dhcp_opts;
size_t dhcp_opts_len;
struct rt_head *ipv4_routes;
struct rt_head *ipv4_kroutes;
int udp_fd;
uint8_t *packet;
/* Our aggregate option buffer.
* We ONLY use this when options are split, which for most purposes is
* practically never. See RFC3396 for details. */
uint8_t *opt_buffer;
#endif
#ifdef INET6
unsigned char secret[SECRET_LEN];
size_t secret_len;
struct dhcp_opt *nd_opts;
size_t nd_opts_len;
struct dhcp_opt *dhcp6_opts;
size_t dhcp6_opts_len;
struct ipv6_ctx *ipv6;
#ifndef __linux__
int ra_global;
#endif
#endif /* INET6 */
#ifdef PLUGIN_DEV
char *dev_load;
int dev_fd;
struct dev *dev;
void *dev_handle;
#endif
};
#ifdef USE_SIGNALS
extern const int dhcpcd_signals[];
extern const size_t dhcpcd_signals_len;
#endif
int dhcpcd_ifafwaiting(const struct interface *);
int dhcpcd_afwaiting(const struct dhcpcd_ctx *);
pid_t dhcpcd_daemonise(struct dhcpcd_ctx *);
int dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **);
void dhcpcd_handlecarrier(struct dhcpcd_ctx *, int, unsigned int, const char *);
int dhcpcd_handleinterface(void *, int, const char *);
void dhcpcd_handlehwaddr(struct dhcpcd_ctx *, const char *,
const unsigned char *, uint8_t);
void dhcpcd_dropinterface(struct interface *, const char *);
int dhcpcd_selectprofile(struct interface *, const char *);
void dhcpcd_startinterface(void *);
void dhcpcd_initstate(struct interface *, unsigned long long);
#endif

169
external/bsd/dhcpcd/dist/duid.c vendored Normal file
View File

@ -0,0 +1,169 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: duid.c,v 1.9 2015/07/09 10:15:34 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define DUID_TIME_EPOCH 946684800
#define DUID_LLT 1
#define DUID_LL 3
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifndef ARPHRD_NETROM
# define ARPHRD_NETROM 0
#endif
#include "common.h"
#include "dhcpcd.h"
#include "duid.h"
static size_t
duid_make(unsigned char *d, const struct interface *ifp, uint16_t type)
{
unsigned char *p;
uint16_t u16;
time_t t;
uint32_t u32;
p = d;
u16 = htons(type);
memcpy(p, &u16, 2);
p += 2;
u16 = htons(ifp->family);
memcpy(p, &u16, 2);
p += 2;
if (type == DUID_LLT) {
/* time returns seconds from jan 1 1970, but DUID-LLT is
* seconds from jan 1 2000 modulo 2^32 */
t = time(NULL) - DUID_TIME_EPOCH;
u32 = htonl((uint32_t)t & 0xffffffff);
memcpy(p, &u32, 4);
p += 4;
}
/* Finally, add the MAC address of the interface */
memcpy(p, ifp->hwaddr, ifp->hwlen);
p += ifp->hwlen;
return (size_t)(p - d);
}
#define DUID_STRLEN DUID_LEN * 3
static size_t
duid_get(unsigned char *d, const struct interface *ifp)
{
FILE *fp;
int x = 0;
size_t len = 0;
char line[DUID_STRLEN];
const struct interface *ifp2;
/* If we already have a DUID then use it as it's never supposed
* to change once we have one even if the interfaces do */
if ((fp = fopen(DUID, "r"))) {
while (fgets(line, DUID_STRLEN, fp)) {
len = strlen(line);
if (len) {
if (line[len - 1] == '\n')
line[len - 1] = '\0';
}
len = hwaddr_aton(NULL, line);
if (len && len <= DUID_LEN) {
hwaddr_aton(d, line);
break;
}
len = 0;
}
fclose(fp);
if (len)
return len;
} else {
if (errno != ENOENT)
logger(ifp->ctx, LOG_ERR,
"error reading DUID: %s: %m", DUID);
}
/* No file? OK, lets make one based on our interface */
if (ifp->family == ARPHRD_NETROM) {
logger(ifp->ctx, LOG_WARNING,
"%s: is a NET/ROM psuedo interface", ifp->name);
TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
if (ifp2->family != ARPHRD_NETROM)
break;
}
if (ifp2) {
ifp = ifp2;
logger(ifp->ctx, LOG_WARNING,
"picked interface %s to generate a DUID",
ifp->name);
} else {
logger(ifp->ctx, LOG_WARNING,
"no interfaces have a fixed hardware address");
return duid_make(d, ifp, DUID_LL);
}
}
if (!(fp = fopen(DUID, "w"))) {
logger(ifp->ctx, LOG_ERR, "error writing DUID: %s: %m", DUID);
return duid_make(d, ifp, DUID_LL);
}
len = duid_make(d, ifp, DUID_LLT);
x = fprintf(fp, "%s\n", hwaddr_ntoa(d, len, line, sizeof(line)));
if (fclose(fp) == EOF)
x = -1;
/* Failed to write the duid? scrub it, we cannot use it */
if (x < 1) {
logger(ifp->ctx, LOG_ERR, "error writing DUID: %s: %m", DUID);
unlink(DUID);
return duid_make(d, ifp, DUID_LL);
}
return len;
}
size_t duid_init(const struct interface *ifp)
{
if (ifp->ctx->duid == NULL) {
ifp->ctx->duid = malloc(DUID_LEN);
if (ifp->ctx->duid == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return 0;
}
ifp->ctx->duid_len = duid_get(ifp->ctx->duid, ifp);
}
return ifp->ctx->duid_len;
}

37
external/bsd/dhcpcd/dist/duid.h vendored Normal file
View File

@ -0,0 +1,37 @@
/* $NetBSD: duid.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef DUID_H
#define DUID_H
#define DUID_LEN 128 + 2
size_t duid_init(const struct interface *);
#endif

829
external/bsd/dhcpcd/dist/eloop.c vendored Normal file
View File

@ -0,0 +1,829 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: eloop.c,v 1.11 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/time.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* config.h should define HAVE_KQUEUE, HAVE_EPOLL, etc */
#include "config.h"
#include "eloop.h"
#ifndef UNUSED
#define UNUSED(a) (void)((a))
#endif
#ifndef __unused
#ifdef __GNUC__
#define __unused __attribute__((__unused__))
#else
#define __unused
#endif
#endif
#ifndef MSEC_PER_SEC
#define MSEC_PER_SEC 1000L
#define NSEC_PER_MSEC 1000000L
#endif
#if defined(HAVE_KQUEUE)
#include <sys/event.h>
#include <fcntl.h>
#ifdef __NetBSD__
/* udata is void * except on NetBSD
* lengths are int except on NetBSD */
#define UPTR(x) ((intptr_t)(x))
#define LENC(x) (x)
#else
#define UPTR(x) (x)
#define LENC(x) ((int)(x))
#endif
#define eloop_event_setup_fds(eloop)
#elif defined(HAVE_EPOLL)
#include <sys/epoll.h>
#define eloop_event_setup_fds(eloop)
#else
#include <poll.h>
static void
eloop_event_setup_fds(struct eloop *eloop)
{
struct eloop_event *e;
size_t i;
i = 0;
TAILQ_FOREACH(e, &eloop->events, next) {
eloop->fds[i].fd = e->fd;
eloop->fds[i].events = 0;
if (e->read_cb)
eloop->fds[i].events |= POLLIN;
if (e->write_cb)
eloop->fds[i].events |= POLLOUT;
eloop->fds[i].revents = 0;
e->pollfd = &eloop->fds[i];
i++;
}
}
#ifndef pollts
/* Wrapper around pselect, to imitate the NetBSD pollts call. */
#if !defined(__minix)
static int
#else /* defined(__minix) */
int
#endif /* defined(__minix) */
pollts(struct pollfd * fds, nfds_t nfds,
const struct timespec *ts, const sigset_t *sigmask)
{
fd_set read_fds;
nfds_t n;
int maxfd, r;
#if defined(__minix)
sigset_t omask;
struct timeval tv, *tvp;
#endif /* defined(__minix) */
FD_ZERO(&read_fds);
maxfd = 0;
for (n = 0; n < nfds; n++) {
if (fds[n].events & POLLIN) {
FD_SET(fds[n].fd, &read_fds);
if (fds[n].fd > maxfd)
maxfd = fds[n].fd;
}
}
#if !defined(__minix)
r = pselect(maxfd + 1, &read_fds, NULL, NULL, ts, sigmask);
#else /* defined(__minix) */
/* XXX FIXME - horrible hack with race condition */
sigprocmask(SIG_SETMASK, sigmask, &omask);
if (ts != NULL) {
tv.tv_sec = ts->tv_sec;
tv.tv_usec = ts->tv_nsec / 1000;
tvp = &tv;
} else
tvp = NULL;
r = select(maxfd + 1, &read_fds, NULL, NULL, tvp);
sigprocmask(SIG_SETMASK, &omask, NULL);
#endif /* defined(__minix) */
if (r > 0) {
for (n = 0; n < nfds; n++) {
fds[n].revents =
FD_ISSET(fds[n].fd, &read_fds) ? POLLIN : 0;
}
}
return r;
}
#endif
#endif
int
eloop_event_add(struct eloop *eloop, int fd,
void (*read_cb)(void *), void *read_cb_arg,
void (*write_cb)(void *), void *write_cb_arg)
{
struct eloop_event *e;
#if defined(HAVE_KQUEUE)
struct kevent ke[2];
#elif defined(HAVE_EPOLL)
struct epoll_event epe;
#else
struct pollfd *nfds;
#endif
assert(eloop != NULL);
assert(read_cb != NULL || write_cb != NULL);
if (fd == -1) {
errno = EINVAL;
return -1;
}
#ifdef HAVE_EPOLL
memset(&epe, 0, sizeof(epe));
epe.data.fd = fd;
epe.events = EPOLLIN;
if (write_cb)
epe.events |= EPOLLOUT;
#endif
/* We should only have one callback monitoring the fd */
TAILQ_FOREACH(e, &eloop->events, next) {
if (e->fd == fd) {
int error;
#if defined(HAVE_KQUEUE)
EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ, EV_ADD,
0, 0, UPTR(e));
if (write_cb)
EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
EV_ADD, 0, 0, UPTR(e));
else if (e->write_cb)
EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
EV_DELETE, 0, 0, UPTR(e));
error = kevent(eloop->poll_fd, ke,
e->write_cb || write_cb ? 2 : 1, NULL, 0, NULL);
#elif defined(HAVE_EPOLL)
epe.data.ptr = e;
error = epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD,
fd, &epe);
#else
error = 0;
#endif
if (read_cb) {
e->read_cb = read_cb;
e->read_cb_arg = read_cb_arg;
}
if (write_cb) {
e->write_cb = write_cb;
e->write_cb_arg = write_cb_arg;
}
eloop_event_setup_fds(eloop);
return error;
}
}
/* Allocate a new event if no free ones already allocated */
if ((e = TAILQ_FIRST(&eloop->free_events))) {
TAILQ_REMOVE(&eloop->free_events, e, next);
} else {
e = malloc(sizeof(*e));
if (e == NULL)
goto err;
}
/* Ensure we can actually listen to it */
eloop->events_len++;
#if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL)
if (eloop->events_len > eloop->fds_len) {
nfds = realloc(eloop->fds,
sizeof(*eloop->fds) * (eloop->fds_len + 5));
if (nfds == NULL)
goto err;
eloop->fds_len += 5;
eloop->fds = nfds;
}
#endif
/* Now populate the structure and add it to the list */
e->fd = fd;
e->read_cb = read_cb;
e->read_cb_arg = read_cb_arg;
e->write_cb = write_cb;
e->write_cb_arg = write_cb_arg;
#if defined(HAVE_KQUEUE)
if (read_cb != NULL)
EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
EV_ADD, 0, 0, UPTR(e));
if (write_cb != NULL)
EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
EV_ADD, 0, 0, UPTR(e));
if (kevent(eloop->poll_fd, ke, write_cb ? 2 : 1, NULL, 0, NULL) == -1)
goto err;
#elif defined(HAVE_EPOLL)
epe.data.ptr = e;
if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, fd, &epe) == -1)
goto err;
#endif
/* The order of events should not matter.
* However, some PPP servers love to close the link right after
* sending their final message. So to ensure dhcpcd processes this
* message (which is likely to be that the DHCP addresses are wrong)
* we insert new events at the queue head as the link fd will be
* the first event added. */
TAILQ_INSERT_HEAD(&eloop->events, e, next);
eloop_event_setup_fds(eloop);
return 0;
err:
if (e) {
eloop->events_len--;
TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
}
return -1;
}
void
eloop_event_delete_write(struct eloop *eloop, int fd, int write_only)
{
struct eloop_event *e;
#if defined(HAVE_KQUEUE)
struct kevent ke[2];
#elif defined(HAVE_EPOLL)
struct epoll_event epe;
#endif
assert(eloop != NULL);
TAILQ_FOREACH(e, &eloop->events, next) {
if (e->fd == fd) {
if (write_only && e->read_cb != NULL) {
if (e->write_cb != NULL) {
e->write_cb = NULL;
e->write_cb_arg = NULL;
#if defined(HAVE_KQUEUE)
EV_SET(&ke[0], (uintptr_t)fd,
EVFILT_WRITE, EV_DELETE,
0, 0, UPTR(NULL));
kevent(eloop->poll_fd, ke, 1, NULL, 0,
NULL);
#elif defined(HAVE_EPOLL)
memset(&epe, 0, sizeof(epe));
epe.data.fd = e->fd;
epe.data.ptr = e;
epe.events = EPOLLIN;
epoll_ctl(eloop->poll_fd,
EPOLL_CTL_MOD, fd, &epe);
#endif
}
} else {
TAILQ_REMOVE(&eloop->events, e, next);
#if defined(HAVE_KQUEUE)
EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
EV_DELETE, 0, 0, UPTR(NULL));
if (e->write_cb)
EV_SET(&ke[1], (uintptr_t)fd,
EVFILT_WRITE, EV_DELETE,
0, 0, UPTR(NULL));
kevent(eloop->poll_fd, ke, e->write_cb ? 2 : 1,
NULL, 0, NULL);
#elif defined(HAVE_EPOLL)
/* NULL event is safe because we
* rely on epoll_pwait which as added
* after the delete without event was fixed. */
epoll_ctl(eloop->poll_fd, EPOLL_CTL_DEL,
fd, NULL);
#endif
TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
eloop->events_len--;
}
eloop_event_setup_fds(eloop);
break;
}
}
}
int
eloop_q_timeout_add_tv(struct eloop *eloop, int queue,
const struct timespec *when, void (*callback)(void *), void *arg)
{
struct timespec now, w;
struct eloop_timeout *t, *tt = NULL;
assert(eloop != NULL);
assert(when != NULL);
assert(callback != NULL);
clock_gettime(CLOCK_MONOTONIC, &now);
timespecadd(&now, when, &w);
/* Check for time_t overflow. */
if (timespeccmp(&w, &now, <)) {
errno = ERANGE;
return -1;
}
/* Remove existing timeout if present */
TAILQ_FOREACH(t, &eloop->timeouts, next) {
if (t->callback == callback && t->arg == arg) {
TAILQ_REMOVE(&eloop->timeouts, t, next);
break;
}
}
if (t == NULL) {
/* No existing, so allocate or grab one from the free pool */
if ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
TAILQ_REMOVE(&eloop->free_timeouts, t, next);
} else {
if ((t = malloc(sizeof(*t))) == NULL)
return -1;
}
}
t->when = w;
t->callback = callback;
t->arg = arg;
t->queue = queue;
/* The timeout list should be in chronological order,
* soonest first. */
TAILQ_FOREACH(tt, &eloop->timeouts, next) {
if (timespeccmp(&t->when, &tt->when, <)) {
TAILQ_INSERT_BEFORE(tt, t, next);
return 0;
}
}
TAILQ_INSERT_TAIL(&eloop->timeouts, t, next);
return 0;
}
int
eloop_q_timeout_add_sec(struct eloop *eloop, int queue, time_t when,
void (*callback)(void *), void *arg)
{
struct timespec tv;
tv.tv_sec = when;
tv.tv_nsec = 0;
return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
}
int
eloop_q_timeout_add_msec(struct eloop *eloop, int queue, long when,
void (*callback)(void *), void *arg)
{
struct timespec tv;
tv.tv_sec = when / MSEC_PER_SEC;
tv.tv_nsec = (when % MSEC_PER_SEC) * NSEC_PER_MSEC;
return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
}
#if !defined(HAVE_KQUEUE)
static int
eloop_timeout_add_now(struct eloop *eloop,
void (*callback)(void *), void *arg)
{
assert(eloop->timeout0 == NULL);
eloop->timeout0 = callback;
eloop->timeout0_arg = arg;
return 0;
}
#endif
void
eloop_q_timeout_delete(struct eloop *eloop, int queue,
void (*callback)(void *), void *arg)
{
struct eloop_timeout *t, *tt;
assert(eloop != NULL);
TAILQ_FOREACH_SAFE(t, &eloop->timeouts, next, tt) {
if ((queue == 0 || t->queue == queue) &&
t->arg == arg &&
(!callback || t->callback == callback))
{
TAILQ_REMOVE(&eloop->timeouts, t, next);
TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
}
}
}
void
eloop_exit(struct eloop *eloop, int code)
{
assert(eloop != NULL);
eloop->exitcode = code;
eloop->exitnow = 1;
}
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
static int
eloop_open(struct eloop *eloop)
{
#if defined(HAVE_KQUEUE1)
return (eloop->poll_fd = kqueue1(O_CLOEXEC));
#elif defined(HAVE_KQUEUE)
int i;
if ((eloop->poll_fd = kqueue()) == -1)
return -1;
if ((i = fcntl(eloop->poll_fd, F_GETFD, 0)) == -1 ||
fcntl(eloop->poll_fd, F_SETFD, i | FD_CLOEXEC) == -1)
{
close(eloop->poll_fd);
eloop->poll_fd = -1;
return -1;
}
return eloop->poll_fd;
#elif defined (HAVE_EPOLL)
return (eloop->poll_fd = epoll_create1(EPOLL_CLOEXEC));
#endif
}
int
eloop_requeue(struct eloop *eloop)
{
struct eloop_event *e;
int error;
#if defined(HAVE_KQUEUE)
size_t i;
struct kevent *ke;
#elif defined(HAVE_EPOLL)
struct epoll_event epe;
#endif
assert(eloop != NULL);
if (eloop->poll_fd != -1)
close(eloop->poll_fd);
if (eloop_open(eloop) == -1)
return -1;
#if defined (HAVE_KQUEUE)
i = eloop->signals_len;
TAILQ_FOREACH(e, &eloop->events, next) {
i++;
if (e->write_cb)
i++;
}
if ((ke = malloc(sizeof(*ke) * i)) == NULL)
return -1;
for (i = 0; i < eloop->signals_len; i++)
EV_SET(&ke[i], (uintptr_t)eloop->signals[i],
EVFILT_SIGNAL, EV_ADD, 0, 0, UPTR(NULL));
TAILQ_FOREACH(e, &eloop->events, next) {
EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_READ,
EV_ADD, 0, 0, UPTR(e));
i++;
if (e->write_cb) {
EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_WRITE,
EV_ADD, 0, 0, UPTR(e));
i++;
}
}
error = kevent(eloop->poll_fd, ke, LENC(i), NULL, 0, NULL);
free(ke);
#elif defined(HAVE_EPOLL)
error = 0;
TAILQ_FOREACH(e, &eloop->events, next) {
memset(&epe, 0, sizeof(epe));
epe.data.fd = e->fd;
epe.events = EPOLLIN;
if (e->write_cb)
epe.events |= EPOLLOUT;
epe.data.ptr = e;
if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, e->fd, &epe) == -1)
error = -1;
}
#endif
return error;
}
#endif
int
eloop_signal_set_cb(struct eloop *eloop,
const int *signals, size_t signals_len,
void (*signal_cb)(int, void *), void *signal_cb_ctx)
{
assert(eloop != NULL);
eloop->signals = signals;
eloop->signals_len = signals_len;
eloop->signal_cb = signal_cb;
eloop->signal_cb_ctx = signal_cb_ctx;
return eloop_requeue(eloop);
}
#ifndef HAVE_KQUEUE
struct eloop_siginfo {
int sig;
struct eloop *eloop;
};
static struct eloop_siginfo _eloop_siginfo;
static struct eloop *_eloop;
static void
eloop_signal1(void *arg)
{
struct eloop_siginfo *si = arg;
si->eloop->signal_cb(si->sig, si->eloop->signal_cb_ctx);
}
static void
#if !defined(__minix)
eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
#else /* defined(__minix) */
eloop_signal3(int sig)
#endif /* defined(__minix) */
{
/* So that we can operate safely under a signal we instruct
* eloop to pass a copy of the siginfo structure to handle_signal1
* as the very first thing to do. */
_eloop_siginfo.eloop = _eloop;
_eloop_siginfo.sig = sig;
eloop_timeout_add_now(_eloop_siginfo.eloop,
eloop_signal1, &_eloop_siginfo);
}
#endif
int
eloop_signal_mask(struct eloop *eloop, sigset_t *oldset)
{
sigset_t newset;
#ifndef HAVE_KQUEUE
size_t i;
struct sigaction sa;
#endif
assert(eloop != NULL);
sigfillset(&newset);
if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
return -1;
#ifdef HAVE_KQUEUE
UNUSED(eloop);
#else
memset(&sa, 0, sizeof(sa));
#if !defined(__minix)
sa.sa_sigaction = eloop_signal3;
sa.sa_flags = SA_SIGINFO;
#else /* defined(__minix) */
sa.sa_handler = eloop_signal3;
#endif /* defined(__minix) */
sigemptyset(&sa.sa_mask);
for (i = 0; i < eloop->signals_len; i++) {
if (sigaction(eloop->signals[i], &sa, NULL) == -1)
return -1;
}
#endif
return 0;
}
struct eloop *
eloop_new(void)
{
struct eloop *eloop;
struct timespec now;
/* Check we have a working monotonic clock. */
if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
return NULL;
eloop = calloc(1, sizeof(*eloop));
if (eloop) {
TAILQ_INIT(&eloop->events);
TAILQ_INIT(&eloop->free_events);
TAILQ_INIT(&eloop->timeouts);
TAILQ_INIT(&eloop->free_timeouts);
eloop->exitcode = EXIT_FAILURE;
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
eloop->poll_fd = -1;
eloop_open(eloop);
#endif
}
return eloop;
}
void eloop_free(struct eloop *eloop)
{
struct eloop_event *e;
struct eloop_timeout *t;
if (eloop == NULL)
return;
while ((e = TAILQ_FIRST(&eloop->events))) {
TAILQ_REMOVE(&eloop->events, e, next);
free(e);
}
while ((e = TAILQ_FIRST(&eloop->free_events))) {
TAILQ_REMOVE(&eloop->free_events, e, next);
free(e);
}
while ((t = TAILQ_FIRST(&eloop->timeouts))) {
TAILQ_REMOVE(&eloop->timeouts, t, next);
free(t);
}
while ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
TAILQ_REMOVE(&eloop->free_timeouts, t, next);
free(t);
}
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
close(eloop->poll_fd);
#else
free(eloop->fds);
#endif
free(eloop);
}
int
eloop_start(struct eloop *eloop, sigset_t *signals)
{
int n;
struct eloop_event *e;
struct eloop_timeout *t;
struct timespec now, ts, *tsp;
void (*t0)(void *);
#if defined(HAVE_KQUEUE)
struct kevent ke;
UNUSED(signals);
#elif defined(HAVE_EPOLL)
struct epoll_event epe;
#endif
#ifndef HAVE_KQUEUE
int timeout;
_eloop = eloop;
#endif
assert(eloop != NULL);
for (;;) {
if (eloop->exitnow)
break;
/* Run all timeouts first */
if (eloop->timeout0) {
t0 = eloop->timeout0;
eloop->timeout0 = NULL;
t0(eloop->timeout0_arg);
continue;
}
if ((t = TAILQ_FIRST(&eloop->timeouts))) {
clock_gettime(CLOCK_MONOTONIC, &now);
if (timespeccmp(&now, &t->when, >)) {
TAILQ_REMOVE(&eloop->timeouts, t, next);
t->callback(t->arg);
TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
continue;
}
timespecsub(&t->when, &now, &ts);
tsp = &ts;
} else
/* No timeouts, so wait forever */
tsp = NULL;
if (tsp == NULL && eloop->events_len == 0)
break;
#ifndef HAVE_KQUEUE
if (tsp == NULL)
timeout = -1;
else if (tsp->tv_sec > INT_MAX / 1000 ||
(tsp->tv_sec == INT_MAX / 1000 &&
(tsp->tv_nsec + 999999) / 1000000 > INT_MAX % 1000000))
timeout = INT_MAX;
else
timeout = (int)(tsp->tv_sec * 1000 +
(tsp->tv_nsec + 999999) / 1000000);
#endif
#if defined(HAVE_KQUEUE)
n = kevent(eloop->poll_fd, NULL, 0, &ke, 1, tsp);
#elif defined(HAVE_EPOLL)
if (signals)
n = epoll_pwait(eloop->poll_fd, &epe, 1,
timeout, signals);
else
n = epoll_wait(eloop->poll_fd, &epe, 1, timeout);
#else
if (signals)
n = pollts(eloop->fds, (nfds_t)eloop->events_len,
tsp, signals);
else
n = poll(eloop->fds, (nfds_t)eloop->events_len,
timeout);
#endif
if (n == -1) {
if (errno == EINTR)
continue;
return -errno;
}
/* Process any triggered events.
* We go back to the start after calling each callback incase
* the current event or next event is removed. */
#if defined(HAVE_KQUEUE)
if (n) {
if (ke.filter == EVFILT_SIGNAL) {
eloop->signal_cb((int)ke.ident,
eloop->signal_cb_ctx);
continue;
}
e = (struct eloop_event *)ke.udata;
if (ke.filter == EVFILT_WRITE) {
e->write_cb(e->write_cb_arg);
continue;
} else if (ke.filter == EVFILT_READ) {
e->read_cb(e->read_cb_arg);
continue;
}
}
#elif defined(HAVE_EPOLL)
if (n) {
e = (struct eloop_event *)epe.data.ptr;
if (epe.events & EPOLLOUT && e->write_cb != NULL) {
e->write_cb(e->write_cb_arg);
continue;
}
if (epe.events &
(EPOLLIN | EPOLLERR | EPOLLHUP) &&
e->read_cb != NULL)
{
e->read_cb(e->read_cb_arg);
continue;
}
}
#else
if (n > 0) {
TAILQ_FOREACH(e, &eloop->events, next) {
if (e->pollfd->revents & POLLOUT &&
e->write_cb != NULL)
{
e->write_cb(e->write_cb_arg);
break;
}
if (e->pollfd->revents && e->read_cb != NULL) {
e->read_cb(e->read_cb_arg);
break;
}
}
}
#endif
}
return eloop->exitcode;
}

193
external/bsd/dhcpcd/dist/eloop.h vendored Normal file
View File

@ -0,0 +1,193 @@
/* $NetBSD: eloop.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ELOOP_H
#define ELOOP_H
#include <time.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
/* Attempt to autodetect kqueue or epoll.
* If we can't, the system has to support pselect, which is a POSIX call. */
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
#if defined(BSD)
/* Assume BSD has a working sys/queue.h and kqueue(2) interface */
#define HAVE_SYS_QUEUE_H
#define HAVE_KQUEUE
#elif defined(__linux__)
/* Assume Linux has a working epoll(3) interface */
#define HAVE_EPOLL
#endif
#endif
/* Our structures require TAILQ macros, which really every libc should
* ship as they are useful beyond belief.
* Sadly some libc's don't have sys/queue.h and some that do don't have
* the TAILQ_FOREACH macro. For those that don't, the application using
* this implementation will need to ship a working queue.h somewhere.
* If we don't have sys/queue.h found in config.h, then
* allow QUEUE_H to override loading queue.h in the current directory. */
#ifndef TAILQ_FOREACH
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h>
#elif defined(QUEUE_H)
#define __QUEUE_HEADER(x) #x
#define _QUEUE_HEADER(x) __QUEUE_HEADER(x)
#include _QUEUE_HEADER(QUEUE_H)
#else
#include "queue.h"
#endif
#endif
/* Some systems don't define timespec macros */
#ifndef timespecclear
#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
#define timespeccmp(tsp, usp, cmp) \
(((tsp)->tv_sec == (usp)->tv_sec) ? \
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
((tsp)->tv_sec cmp (usp)->tv_sec))
#define timespecadd(tsp, usp, vsp) \
do { \
(vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
(vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
if ((vsp)->tv_nsec >= 1000000000L) { \
(vsp)->tv_sec++; \
(vsp)->tv_nsec -= 1000000000L; \
} \
} while (/* CONSTCOND */ 0)
#define timespecsub(tsp, usp, vsp) \
do { \
(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
if ((vsp)->tv_nsec < 0) { \
(vsp)->tv_sec--; \
(vsp)->tv_nsec += 1000000000L; \
} \
} while (/* CONSTCOND */ 0)
#endif
/* eloop queues are really only for deleting timeouts registered
* for a function or object.
* The idea being that one interface as different timeouts for
* say DHCP and DHCPv6. */
#ifndef ELOOP_QUEUE
#define ELOOP_QUEUE 1
#endif
struct eloop_event {
TAILQ_ENTRY(eloop_event) next;
int fd;
void (*read_cb)(void *);
void *read_cb_arg;
void (*write_cb)(void *);
void *write_cb_arg;
#if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL)
struct pollfd *pollfd;
#endif
};
struct eloop_timeout {
TAILQ_ENTRY(eloop_timeout) next;
struct timespec when;
void (*callback)(void *);
void *arg;
int queue;
};
struct eloop {
size_t events_len;
TAILQ_HEAD (event_head, eloop_event) events;
struct event_head free_events;
TAILQ_HEAD (timeout_head, eloop_timeout) timeouts;
struct timeout_head free_timeouts;
void (*timeout0)(void *);
void *timeout0_arg;
const int *signals;
size_t signals_len;
void (*signal_cb)(int, void *);
void *signal_cb_ctx;
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
int poll_fd;
#else
struct pollfd *fds;
size_t fds_len;
#endif
int exitnow;
int exitcode;
};
int eloop_event_add(struct eloop *, int,
void (*)(void *), void *,
void (*)(void *), void *);
#define eloop_event_delete(eloop, fd) \
eloop_event_delete_write((eloop), (fd), 0)
#define eloop_event_remove_writecb(eloop, fd) \
eloop_event_delete_write((eloop), (fd), 1)
void eloop_event_delete_write(struct eloop *, int, int);
#define eloop_timeout_add_tv(eloop, tv, cb, ctx) \
eloop_q_timeout_add_tv((eloop), ELOOP_QUEUE, (tv), (cb), (ctx))
#define eloop_timeout_add_sec(eloop, tv, cb, ctx) \
eloop_q_timeout_add_sec((eloop), ELOOP_QUEUE, (tv), (cb), (ctx))
#define eloop_timeout_add_msec(eloop, ms, cb, ctx) \
eloop_q_timeout_add_msec((eloop), ELOOP_QUEUE, (ms), (cb), (ctx))
#define eloop_timeout_delete(eloop, cb, ctx) \
eloop_q_timeout_delete((eloop), ELOOP_QUEUE, (cb), (ctx))
int eloop_q_timeout_add_tv(struct eloop *, int,
const struct timespec *, void (*)(void *), void *);
int eloop_q_timeout_add_sec(struct eloop *, int,
time_t, void (*)(void *), void *);
int eloop_q_timeout_add_msec(struct eloop *, int,
long, void (*)(void *), void *);
void eloop_q_timeout_delete(struct eloop *, int, void (*)(void *), void *);
int eloop_signal_set_cb(struct eloop *, const int *, size_t,
void (*)(int, void *), void *);
int eloop_signal_mask(struct eloop *, sigset_t *oldset);
struct eloop * eloop_new(void);
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
int eloop_requeue(struct eloop *);
#else
#define eloop_requeue(eloop) (0)
#endif
void eloop_free(struct eloop *);
void eloop_exit(struct eloop *, int);
int eloop_start(struct eloop *, sigset_t *);
#endif

1664
external/bsd/dhcpcd/dist/if-bsd.c vendored Normal file

File diff suppressed because it is too large Load Diff

2483
external/bsd/dhcpcd/dist/if-options.c vendored Normal file

File diff suppressed because it is too large Load Diff

223
external/bsd/dhcpcd/dist/if-options.h vendored Normal file
View File

@ -0,0 +1,223 @@
/* $NetBSD: if-options.h,v 1.14 2015/09/04 12:25:01 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef IF_OPTIONS_H
#define IF_OPTIONS_H
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <getopt.h>
#include <limits.h>
#include <stdint.h>
#include "auth.h"
/* Don't set any optional arguments here so we retain POSIX
* compatibility with getopt */
#define IF_OPTS "46bc:de:f:gh:i:j:kl:m:no:pqr:s:t:u:v:wxy:z:" \
"ABC:DEF:GHI:JKLMO:Q:S:TUVW:X:Z:"
#define DEFAULT_TIMEOUT 30
#define DEFAULT_REBOOT 5
#ifndef HOSTNAME_MAX_LEN
#define HOSTNAME_MAX_LEN 250 /* 255 - 3 (FQDN) - 2 (DNS enc) */
#endif
#define VENDORCLASSID_MAX_LEN 255
#define CLIENTID_MAX_LEN 48
#define USERCLASS_MAX_LEN 255
#define VENDOR_MAX_LEN 255
#define DHCPCD_ARP (1ULL << 0)
#define DHCPCD_RELEASE (1ULL << 1)
#define DHCPCD_DOMAIN (1ULL << 2)
#define DHCPCD_GATEWAY (1ULL << 3)
#define DHCPCD_STATIC (1ULL << 4)
#define DHCPCD_DEBUG (1ULL << 5)
#define DHCPCD_LASTLEASE (1ULL << 7)
#define DHCPCD_INFORM (1ULL << 8)
#define DHCPCD_REQUEST (1ULL << 9)
#define DHCPCD_IPV4LL (1ULL << 10)
#define DHCPCD_DUID (1ULL << 11)
#define DHCPCD_PERSISTENT (1ULL << 12)
#define DHCPCD_DAEMONISE (1ULL << 14)
#define DHCPCD_DAEMONISED (1ULL << 15)
#define DHCPCD_TEST (1ULL << 16)
#define DHCPCD_MASTER (1ULL << 17)
#define DHCPCD_HOSTNAME (1ULL << 18)
#define DHCPCD_CLIENTID (1ULL << 19)
#define DHCPCD_LINK (1ULL << 20)
#define DHCPCD_QUIET (1ULL << 21)
#define DHCPCD_BACKGROUND (1ULL << 22)
#define DHCPCD_VENDORRAW (1ULL << 23)
#define DHCPCD_NOWAITIP (1ULL << 24) /* To force daemonise */
#define DHCPCD_WAITIP (1ULL << 25)
#define DHCPCD_SLAACPRIVATE (1ULL << 26)
#define DHCPCD_CSR_WARNED (1ULL << 27)
#define DHCPCD_XID_HWADDR (1ULL << 28)
#define DHCPCD_BROADCAST (1ULL << 29)
#define DHCPCD_DUMPLEASE (1ULL << 30)
#define DHCPCD_IPV6RS (1ULL << 31)
#define DHCPCD_IPV6RA_REQRDNSS (1ULL << 32)
#define DHCPCD_IPV6RA_OWN (1ULL << 33)
#define DHCPCD_IPV6RA_OWN_DEFAULT (1ULL << 34)
#define DHCPCD_IPV4 (1ULL << 35)
#define DHCPCD_FORKED (1ULL << 36)
#define DHCPCD_IPV6 (1ULL << 37)
#define DHCPCD_STARTED (1ULL << 38)
#define DHCPCD_NOALIAS (1ULL << 39)
#define DHCPCD_IA_FORCED (1ULL << 40)
#define DHCPCD_STOPPING (1ULL << 41)
#define DHCPCD_DEPARTED (1ULL << 42)
#define DHCPCD_HOSTNAME_SHORT (1ULL << 43)
#define DHCPCD_EXITING (1ULL << 44)
#define DHCPCD_WAITIP4 (1ULL << 45)
#define DHCPCD_WAITIP6 (1ULL << 46)
#define DHCPCD_DEV (1ULL << 47)
#define DHCPCD_IAID (1ULL << 48)
#define DHCPCD_DHCP (1ULL << 49)
#define DHCPCD_DHCP6 (1ULL << 50)
#define DHCPCD_IF_UP (1ULL << 51)
// unassigned (1ULL << 52)
// unassinged (1ULL << 53)
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
#define DHCPCD_ROUTER_HOST_ROUTE_WARNED (1ULL << 55)
#define DHCPCD_IPV6RA_ACCEPT_NOPUBLIC (1ULL << 56)
#define DHCPCD_BOOTP (1ULL << 57)
#define DHCPCD_INITIAL_DELAY (1ULL << 58)
#define DHCPCD_NODROP (DHCPCD_EXITING | DHCPCD_PERSISTENT)
#define DHCPCD_WAITOPTS (DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6)
#define DHCPCD_WARNINGS (DHCPCD_CSR_WARNED | \
DHCPCD_ROUTER_HOST_ROUTE_WARNED)
extern const struct option cf_options[];
struct if_sla {
char ifname[IF_NAMESIZE];
uint32_t sla;
uint8_t prefix_len;
int8_t sla_set;
};
struct if_ia {
uint8_t iaid[4];
#ifdef INET6
uint16_t ia_type;
uint8_t iaid_set;
struct in6_addr addr;
uint8_t prefix_len;
uint32_t sla_max;
size_t sla_len;
struct if_sla *sla;
#endif
};
struct vivco {
size_t len;
uint8_t *data;
};
struct if_options {
time_t mtime;
uint8_t iaid[4];
int metric;
uint8_t requestmask[256 / NBBY];
uint8_t requiremask[256 / NBBY];
uint8_t nomask[256 / NBBY];
uint8_t rejectmask[256 / NBBY];
uint8_t dstmask[256 / NBBY];
uint8_t requestmasknd[(UINT16_MAX + 1) / NBBY];
uint8_t requiremasknd[(UINT16_MAX + 1) / NBBY];
uint8_t nomasknd[(UINT16_MAX + 1) / NBBY];
uint8_t rejectmasknd[(UINT16_MAX + 1) / NBBY];
uint8_t requestmask6[(UINT16_MAX + 1) / NBBY];
uint8_t requiremask6[(UINT16_MAX + 1) / NBBY];
uint8_t nomask6[(UINT16_MAX + 1) / NBBY];
uint8_t rejectmask6[(UINT16_MAX + 1) / NBBY];
uint32_t leasetime;
time_t timeout;
time_t reboot;
unsigned long long options;
struct in_addr req_addr;
struct in_addr req_mask;
struct rt_head *routes;
unsigned int mtu;
char **config;
char **environ;
char *script;
char hostname[HOSTNAME_MAX_LEN + 1]; /* We don't store the length */
uint8_t fqdn;
uint8_t vendorclassid[VENDORCLASSID_MAX_LEN + 2];
uint8_t clientid[CLIENTID_MAX_LEN + 2];
uint8_t userclass[USERCLASS_MAX_LEN + 2];
uint8_t vendor[VENDOR_MAX_LEN + 2];
size_t blacklist_len;
in_addr_t *blacklist;
size_t whitelist_len;
in_addr_t *whitelist;
size_t arping_len;
in_addr_t *arping;
char *fallback;
struct if_ia *ia;
size_t ia_len;
struct dhcp_opt *dhcp_override;
size_t dhcp_override_len;
struct dhcp_opt *nd_override;
size_t nd_override_len;
struct dhcp_opt *dhcp6_override;
size_t dhcp6_override_len;
uint32_t vivco_en;
struct vivco *vivco;
size_t vivco_len;
struct dhcp_opt *vivso_override;
size_t vivso_override_len;
struct auth auth;
};
struct if_options *read_config(struct dhcpcd_ctx *,
const char *, const char *, const char *);
int add_options(struct dhcpcd_ctx *, const char *,
struct if_options *, int, char **);
void free_dhcp_opt_embenc(struct dhcp_opt *);
void free_options(struct if_options *);
#endif

692
external/bsd/dhcpcd/dist/if.c vendored Normal file
View File

@ -0,0 +1,692 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: if.c,v 1.16 2015/09/04 12:25:01 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
# include <net/if_var.h>
#endif
#ifdef AF_LINK
# include <net/if_dl.h>
# include <net/if_types.h>
# include <netinet/in_var.h>
#endif
#ifdef AF_PACKET
# include <netpacket/packet.h>
#endif
#ifdef SIOCGIFMEDIA
# include <net/if_media.h>
#endif
#include <net/route.h>
#include <ctype.h>
#include <errno.h>
#include <ifaddrs.h>
#include <fnmatch.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "config.h"
#include "common.h"
#include "dev.h"
#include "dhcp.h"
#include "dhcp6.h"
#include "if.h"
#include "if-options.h"
#include "ipv4.h"
#include "ipv4ll.h"
#include "ipv6nd.h"
void
if_free(struct interface *ifp)
{
if (ifp == NULL)
return;
ipv4ll_free(ifp);
dhcp_free(ifp);
ipv4_free(ifp);
dhcp6_free(ifp);
ipv6nd_free(ifp);
ipv6_free(ifp);
free_options(ifp->options);
free(ifp);
}
int
if_opensockets(struct dhcpcd_ctx *ctx)
{
if ((ctx->link_fd = if_openlinksocket()) == -1)
return -1;
ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC);
if (ctx->pf_inet_fd == -1)
return -1;
#if defined(INET6) && defined(BSD)
ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC);
if (ctx->pf_inet6_fd == -1)
return -1;
#endif
#ifdef IFLR_ACTIVE
ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC);
if (ctx->pf_link_fd == -1)
return -1;
#endif
return 0;
}
int
if_carrier(struct interface *ifp)
{
int r;
struct ifreq ifr;
#ifdef SIOCGIFMEDIA
struct ifmediareq ifmr;
#endif
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1)
return LINK_UNKNOWN;
ifp->flags = (unsigned int)ifr.ifr_flags;
#ifdef SIOCGIFMEDIA
memset(&ifmr, 0, sizeof(ifmr));
strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) != -1 &&
ifmr.ifm_status & IFM_AVALID)
r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
else
r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_UNKNOWN;
#else
r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
#endif
return r;
}
int
if_setflag(struct interface *ifp, short flag)
{
struct ifreq ifr;
int r;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
r = -1;
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == 0) {
if (flag == 0 || (ifr.ifr_flags & flag) == flag)
r = 0;
else {
ifr.ifr_flags |= flag;
if (ioctl(ifp->ctx->pf_inet_fd, SIOCSIFFLAGS, &ifr) ==0)
r = 0;
}
ifp->flags = (unsigned int)ifr.ifr_flags;
}
return r;
}
static int
if_hasconf(struct dhcpcd_ctx *ctx, const char *ifname)
{
int i;
for (i = 0; i < ctx->ifcc; i++) {
if (strcmp(ctx->ifcv[i], ifname) == 0)
return 1;
}
return 0;
}
static void if_learnaddrs1(struct dhcpcd_ctx *ctx, struct if_head *ifs,
struct ifaddrs *ifaddrs)
{
struct ifaddrs *ifa;
struct interface *ifp;
#ifdef INET
const struct sockaddr_in *addr, *net, *dst;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6, *net6;
#endif
int ifa_flags;
for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL)
continue;
switch(ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
addr = (const struct sockaddr_in *)
(void *)ifa->ifa_addr;
net = (const struct sockaddr_in *)
(void *)ifa->ifa_netmask;
if (ifa->ifa_flags & IFF_POINTOPOINT)
dst = (const struct sockaddr_in *)
(void *)ifa->ifa_dstaddr;
else
dst = NULL;
ifa_flags = if_addrflags(&addr->sin_addr, ifp);
ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
&addr->sin_addr,
&net->sin_addr,
dst ? &dst->sin_addr : NULL, ifa_flags);
break;
#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;
net6 = (struct sockaddr_in6 *)(void *)ifa->ifa_netmask;
#ifdef __KAME__
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
/* Remove the scope from the address */
sin6->sin6_addr.s6_addr[2] =
sin6->sin6_addr.s6_addr[3] = '\0';
#endif
ifa_flags = if_addrflags6(&sin6->sin6_addr, ifp);
if (ifa_flags != -1)
ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
ifa->ifa_name,
&sin6->sin6_addr,
ipv6_prefixlen(&net6->sin6_addr),
ifa_flags);
break;
#endif
}
}
}
struct if_head *
if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
{
struct ifaddrs *ifaddrs, *ifa;
char *p;
int i;
struct if_head *ifs;
struct interface *ifp;
#ifdef __linux__
char ifn[IF_NAMESIZE];
#endif
#ifdef AF_LINK
const struct sockaddr_dl *sdl;
#ifdef SIOCGIFPRIORITY
struct ifreq ifr;
#endif
#ifdef IFLR_ACTIVE
struct if_laddrreq iflr;
#endif
#ifdef IFLR_ACTIVE
memset(&iflr, 0, sizeof(iflr));
#endif
#elif AF_PACKET
const struct sockaddr_ll *sll;
#endif
if (getifaddrs(&ifaddrs) == -1)
return NULL;
ifs = malloc(sizeof(*ifs));
if (ifs == NULL)
return NULL;
TAILQ_INIT(ifs);
for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr != NULL) {
#ifdef AF_LINK
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
#elif AF_PACKET
if (ifa->ifa_addr->sa_family != AF_PACKET)
continue;
#endif
}
/* It's possible for an interface to have >1 AF_LINK.
* For our purposes, we use the first one. */
TAILQ_FOREACH(ifp, ifs, next) {
if (strcmp(ifp->name, ifa->ifa_name) == 0)
break;
}
if (ifp)
continue;
if (argc > 0) {
for (i = 0; i < argc; i++) {
#ifdef __linux__
/* Check the real interface name */
strlcpy(ifn, argv[i], sizeof(ifn));
p = strchr(ifn, ':');
if (p)
*p = '\0';
if (strcmp(ifn, ifa->ifa_name) == 0)
break;
#else
if (strcmp(argv[i], ifa->ifa_name) == 0)
break;
#endif
}
if (i == argc)
continue;
p = argv[i];
} else {
p = ifa->ifa_name;
#ifdef __linux__
strlcpy(ifn, ifa->ifa_name, sizeof(ifn));
#endif
/* -1 means we're discovering against a specific
* interface, but we still need the below rules
* to apply. */
if (argc == -1 && strcmp(argv[0], ifa->ifa_name) != 0)
continue;
}
for (i = 0; i < ctx->ifdc; i++)
if (!fnmatch(ctx->ifdv[i], p, 0))
break;
if (i < ctx->ifdc)
continue;
for (i = 0; i < ctx->ifac; i++)
if (!fnmatch(ctx->ifav[i], p, 0))
break;
if (ctx->ifac && i == ctx->ifac)
continue;
/* Ensure that the interface name has settled */
if (!dev_initialized(ctx, p))
continue;
/* Don't allow loopback or pointopoint unless explicit */
if (ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
if ((argc == 0 || argc == -1) &&
ctx->ifac == 0 && !if_hasconf(ctx, p))
continue;
}
if (if_vimaster(ctx, p) == 1) {
logger(ctx, argc ? LOG_ERR : LOG_DEBUG,
"%s: is a Virtual Interface Master, skipping", p);
continue;
}
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
break;
}
ifp->ctx = ctx;
#ifdef __linux__
strlcpy(ifp->name, ifn, sizeof(ifp->name));
strlcpy(ifp->alias, p, sizeof(ifp->alias));
#else
strlcpy(ifp->name, p, sizeof(ifp->name));
#endif
ifp->flags = ifa->ifa_flags;
ifp->carrier = if_carrier(ifp);
if (ifa->ifa_addr != NULL) {
#ifdef AF_LINK
sdl = (const struct sockaddr_dl *)(void *)ifa->ifa_addr;
#ifdef IFLR_ACTIVE
/* We need to check for active address */
strlcpy(iflr.iflr_name, ifp->name,
sizeof(iflr.iflr_name));
memcpy(&iflr.addr, ifa->ifa_addr,
MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
iflr.flags = IFLR_PREFIX;
iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY;
if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 ||
!(iflr.flags & IFLR_ACTIVE))
{
if_free(ifp);
continue;
}
#endif
ifp->index = sdl->sdl_index;
switch(sdl->sdl_type) {
#ifdef IFT_BRIDGE
case IFT_BRIDGE: /* FALLTHROUGH */
#endif
#ifdef IFT_PPP
case IFT_PPP: /* FALLTHROUGH */
#endif
#ifdef IFT_PROPVIRTUAL
case IFT_PROPVIRTUAL: /* FALLTHROUGH */
#endif
#if defined(IFT_BRIDGE) || defined(IFT_PPP) || defined(IFT_PROPVIRTUAL)
/* Don't allow unless explicit */
if ((argc == 0 || argc == -1) &&
ctx->ifac == 0 &&
!if_hasconf(ctx, ifp->name))
{
logger(ifp->ctx, LOG_DEBUG,
"%s: ignoring due to"
" interface type and"
" no config",
ifp->name);
if_free(ifp);
continue;
}
/* FALLTHROUGH */
#endif
#ifdef IFT_L2VLAN
case IFT_L2VLAN: /* FALLTHROUGH */
#endif
#ifdef IFT_L3IPVLAN
case IFT_L3IPVLAN: /* FALLTHROUGH */
#endif
case IFT_ETHER:
ifp->family = ARPHRD_ETHER;
break;
#ifdef IFT_IEEE1394
case IFT_IEEE1394:
ifp->family = ARPHRD_IEEE1394;
break;
#endif
#ifdef IFT_INFINIBAND
case IFT_INFINIBAND:
ifp->family = ARPHRD_INFINIBAND;
break;
#endif
default:
/* Don't allow unless explicit */
if ((argc == 0 || argc == -1) &&
ctx->ifac == 0 &&
!if_hasconf(ctx, ifp->name))
{
if_free(ifp);
continue;
}
logger(ifp->ctx, LOG_WARNING,
"%s: unsupported interface type %.2x",
ifp->name, sdl->sdl_type);
/* Pretend it's ethernet */
ifp->family = ARPHRD_ETHER;
break;
}
ifp->hwlen = sdl->sdl_alen;
#ifndef CLLADDR
# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
#endif
memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen);
#elif AF_PACKET
sll = (const struct sockaddr_ll *)(void *)ifa->ifa_addr;
ifp->index = (unsigned int)sll->sll_ifindex;
ifp->family = sll->sll_hatype;
ifp->hwlen = sll->sll_halen;
if (ifp->hwlen != 0)
memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen);
#endif
}
#ifdef __linux__
/* PPP addresses on Linux don't have hardware addresses */
else
ifp->index = if_nametoindex(ifp->name);
#endif
/* We only work on ethernet by default */
if (ifp->family != ARPHRD_ETHER) {
if ((argc == 0 || argc == -1) &&
ctx->ifac == 0 && !if_hasconf(ctx, ifp->name))
{
if_free(ifp);
continue;
}
switch (ifp->family) {
case ARPHRD_IEEE1394:
case ARPHRD_INFINIBAND:
#ifdef ARPHRD_LOOPBACK
case ARPHRD_LOOPBACK:
#endif
#ifdef ARPHRD_PPP
case ARPHRD_PPP:
#endif
/* We don't warn for supported families */
break;
/* IFT already checked */
#ifndef AF_LINK
default:
logger(ifp->ctx, LOG_WARNING,
"%s: unsupported interface family %.2x",
ifp->name, ifp->family);
break;
#endif
}
}
if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) {
/* Handle any platform init for the interface */
if (if_init(ifp) == -1) {
logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
if_free(ifp);
continue;
}
/* Ensure that the MTU is big enough for DHCP */
if (if_getmtu(ifp) < MTU_MIN &&
if_setmtu(ifp, MTU_MIN) == -1)
{
logger(ifp->ctx, LOG_ERR,
"%s: if_setmtu: %m", p);
if_free(ifp);
continue;
}
}
#ifdef SIOCGIFPRIORITY
/* Respect the interface priority */
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0)
ifp->metric = ifr.ifr_metric;
#else
/* We reserve the 100 range for virtual interfaces, if and when
* we can work them out. */
ifp->metric = 200 + ifp->index;
if (if_getssid(ifp) != -1) {
ifp->wireless = 1;
ifp->metric += 100;
}
#endif
TAILQ_INSERT_TAIL(ifs, ifp, next);
}
if_learnaddrs1(ctx, ifs, ifaddrs);
freeifaddrs(ifaddrs);
return ifs;
}
static struct interface *
if_findindexname(struct if_head *ifaces, unsigned int idx, const char *name)
{
if (ifaces != NULL) {
struct interface *ifp;
TAILQ_FOREACH(ifp, ifaces, next) {
if ((name && strcmp(ifp->name, name) == 0) ||
#ifdef __linux__
(name && strcmp(ifp->alias, name) == 0) ||
#endif
(!name && ifp->index == idx))
return ifp;
}
}
errno = ESRCH;
return NULL;
}
struct interface *
if_find(struct if_head *ifaces, const char *name)
{
return if_findindexname(ifaces, 0, name);
}
struct interface *
if_findindex(struct if_head *ifaces, unsigned int idx)
{
return if_findindexname(ifaces, idx, NULL);
}
int
if_domtu(const struct interface *ifp, short int mtu)
{
int r;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
ifr.ifr_mtu = mtu;
r = ioctl(ifp->ctx->pf_inet_fd, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
if (r == -1)
return -1;
return ifr.ifr_mtu;
}
/* Interface comparer for working out ordering. */
static int
if_cmp(const struct interface *si, const struct interface *ti)
{
#ifdef INET
int r;
#endif
/* Check carrier status first */
if (si->carrier > ti->carrier)
return -1;
if (si->carrier < ti->carrier)
return 1;
if (D_STATE_RUNNING(si) && !D_STATE_RUNNING(ti))
return -1;
if (!D_STATE_RUNNING(si) && D_STATE_RUNNING(ti))
return 1;
if (RS_STATE_RUNNING(si) && !RS_STATE_RUNNING(ti))
return -1;
if (!RS_STATE_RUNNING(si) && RS_STATE_RUNNING(ti))
return 1;
if (D6_STATE_RUNNING(si) && !D6_STATE_RUNNING(ti))
return -1;
if (!D6_STATE_RUNNING(si) && D6_STATE_RUNNING(ti))
return 1;
#ifdef INET
/* Special attention needed here due to states and IPv4LL. */
if ((r = ipv4_ifcmp(si, ti)) != 0)
return r;
#endif
/* Finally, metric */
if (si->metric < ti->metric)
return -1;
if (si->metric > ti->metric)
return 1;
return 0;
}
/* Sort the interfaces into a preferred order - best first, worst last. */
void
if_sortinterfaces(struct dhcpcd_ctx *ctx)
{
struct if_head sorted;
struct interface *ifp, *ift;
if (ctx->ifaces == NULL ||
(ifp = TAILQ_FIRST(ctx->ifaces)) == NULL ||
TAILQ_NEXT(ifp, next) == NULL)
return;
TAILQ_INIT(&sorted);
TAILQ_REMOVE(ctx->ifaces, ifp, next);
TAILQ_INSERT_HEAD(&sorted, ifp, next);
while ((ifp = TAILQ_FIRST(ctx->ifaces))) {
TAILQ_REMOVE(ctx->ifaces, ifp, next);
TAILQ_FOREACH(ift, &sorted, next) {
if (if_cmp(ifp, ift) == -1) {
TAILQ_INSERT_BEFORE(ift, ifp, next);
break;
}
}
if (ift == NULL)
TAILQ_INSERT_TAIL(&sorted, ifp, next);
}
TAILQ_CONCAT(ctx->ifaces, &sorted, next);
}
int
xsocket(int domain, int type, int protocol, int flags)
{
#ifdef SOCK_CLOEXEC
if (flags & O_CLOEXEC)
type |= SOCK_CLOEXEC;
if (flags & O_NONBLOCK)
type |= SOCK_NONBLOCK;
return socket(domain, type, protocol);
#else
int s, xflags;
if ((s = socket(domain, type, protocol)) == -1)
return -1;
if ((flags & O_CLOEXEC) && (xflags = fcntl(s, F_GETFD, 0)) == -1 ||
fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1)
goto out;
if ((flags & O_NONBLOCK) && (xflags = fcntl(s, F_GETFL, 0)) == -1 ||
fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)
goto out;
return s;
out:
close(s);
return -1;
#endif
}

186
external/bsd/dhcpcd/dist/if.h vendored Normal file
View File

@ -0,0 +1,186 @@
/* $NetBSD: if.h,v 1.12 2015/08/21 10:39:00 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef INTERFACE_H
#define INTERFACE_H
#include <net/if.h>
#ifdef __FreeBSD__
#include <net/if_var.h>
#endif
#include <net/route.h> /* for RTM_ADD et all */
#include <netinet/in.h>
#ifdef BSD
#include <netinet/in_var.h> /* for IN_IFF_TENTATIVE et all */
#endif
#if defined(__minix)
/*
* These flags are used for IPv4 autoconfiguration (RFC 3927). The MINIX 3
* TCP/IP service does not support IPv4 autoconfiguration, because lwIP's
* AUTOIP implementation is all-or-nothing by nature: either it implements the
* whole thing fully itself, or no support is present at all. dhcpcd(8) needs
* a more hybrid implementation if at all. It appears that by undefining the
* following flags, dhcpcd(8) will assume that no support is present for them
* in the operating system, and do everything itself instead, which is exactly
* what we want.
*/
#undef IN_IFF_TENTATIVE
#undef IN_IFF_DUPLICATED
#undef IN_IFF_DETACHED
#undef IN_IFF_TRYTENTATIVE
#undef IN_IFF_NOTREADY
#endif /* defined(__minix) */
/* Some systems have route metrics.
* OpenBSD route priority is not this. */
#ifndef HAVE_ROUTE_METRIC
# if defined(__linux__)
# define HAVE_ROUTE_METRIC 1
# endif
#endif
/* Some systems have in-built IPv4 DAD.
* However, we need them to do DAD at carrier up as well. */
#ifdef IN_IFF_TENTATIVE
# ifdef __NetBSD__
# define NOCARRIER_PRESERVE_IP
# endif
#endif
#include "config.h"
#include "dhcpcd.h"
#include "ipv4.h"
#include "ipv6.h"
#define EUI64_ADDR_LEN 8
#define INFINIBAND_ADDR_LEN 20
/* Linux 2.4 doesn't define this */
#ifndef ARPHRD_IEEE1394
# define ARPHRD_IEEE1394 24
#endif
/* The BSD's don't define this yet */
#ifndef ARPHRD_INFINIBAND
# define ARPHRD_INFINIBAND 32
#endif
/* Work out if we have a private address or not
* 10/8
* 172.16/12
* 192.168/16
*/
#ifndef IN_PRIVATE
# define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) || \
((addr & 0xfff00000) == 0xac100000) || \
((addr & IN_CLASSB_NET) == 0xc0a80000))
#endif
#define RAW_EOF 1 << 0
#define RAW_PARTIALCSUM 2 << 0
int if_setflag(struct interface *ifp, short flag);
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING))
struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *);
struct interface *if_find(struct if_head *, const char *);
struct interface *if_findindex(struct if_head *, unsigned int);
void if_sortinterfaces(struct dhcpcd_ctx *);
void if_free(struct interface *);
int if_domtu(const struct interface *, short int);
#define if_getmtu(ifp) if_domtu((ifp), 0)
#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
int if_carrier(struct interface *);
/* The below functions are provided by if-KERNEL.c */
int if_conf(struct interface *);
int if_init(struct interface *);
int if_getssid(struct interface *);
int if_vimaster(const struct dhcpcd_ctx *ctx, const char *);
int if_opensockets(struct dhcpcd_ctx *);
int if_openlinksocket(void);
int if_managelink(struct dhcpcd_ctx *);
/* dhcpcd uses the same routing flags as BSD.
* If the platform doesn't use these flags,
* map them in the platform interace file. */
#ifndef RTM_ADD
#define RTM_ADD 0x1 /* Add Route */
#define RTM_DELETE 0x2 /* Delete Route */
#define RTM_CHANGE 0x3 /* Change Metrics or flags */
#define RTM_GET 0x4 /* Report Metrics */
#endif
#ifdef INET
extern const char *if_pfname;
int if_openrawsocket(struct interface *, uint16_t);
ssize_t if_sendrawpacket(const struct interface *,
uint16_t, const void *, size_t);
ssize_t if_readrawpacket(struct interface *, uint16_t, void *, size_t, int *);
int if_address(const struct interface *,
const struct in_addr *, const struct in_addr *,
const struct in_addr *, int);
#define if_addaddress(ifp, addr, net, brd) \
if_address(ifp, addr, net, brd, 1)
#define if_deladdress(ifp, addr, net) \
if_address(ifp, addr, net, NULL, -1)
int if_addrflags(const struct in_addr *, const struct interface *);
int if_route(unsigned char, const struct rt *rt);
int if_initrt(struct interface *);
#endif
#ifdef INET6
int if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *, int);
#ifdef IPV6_MANAGETEMPADDR
int ip6_use_tempaddr(const char *ifname);
int ip6_temp_preferred_lifetime(const char *ifname);
int ip6_temp_valid_lifetime(const char *ifname);
#else
#define ip6_use_tempaddr(a) (0)
#endif
int if_address6(const struct ipv6_addr *, int);
#define if_addaddress6(a) if_address6(a, 1)
#define if_deladdress6(a) if_address6(a, -1)
int if_addrflags6(const struct in6_addr *, const struct interface *);
int if_getlifetime6(struct ipv6_addr *);
int if_route6(unsigned char, const struct rt6 *rt);
int if_initrt6(struct interface *);
#else
#define if_checkipv6(a, b, c) (-1)
#endif
int if_machinearch(char *, size_t);
int xsocket(int, int, int, int);
#endif

1210
external/bsd/dhcpcd/dist/ipv4.c vendored Normal file

File diff suppressed because it is too large Load Diff

145
external/bsd/dhcpcd/dist/ipv4.h vendored Normal file
View File

@ -0,0 +1,145 @@
/* $NetBSD: ipv4.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef IPV4_H
#define IPV4_H
#include "dhcpcd.h"
#ifdef IN_IFF_TENTATIVE
#define IN_IFF_NOTUSEABLE \
(IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED)
#endif
/* Prefer our macro */
#ifdef HTONL
#undef HTONL
#endif
#if BYTE_ORDER == BIG_ENDIAN
#define HTONL(A) (A)
#elif BYTE_ORDER == LITTLE_ENDIAN
#define HTONL(A) \
((((uint32_t)(A) & 0xff000000) >> 24) | \
(((uint32_t)(A) & 0x00ff0000) >> 8) | \
(((uint32_t)(A) & 0x0000ff00) << 8) | \
(((uint32_t)(A) & 0x000000ff) << 24))
#else
#error Endian unknown
#endif /* BYTE_ORDER */
struct rt {
TAILQ_ENTRY(rt) next;
struct in_addr dest;
struct in_addr net;
struct in_addr gate;
const struct interface *iface;
#ifdef HAVE_ROUTE_METRIC
unsigned int metric;
#endif
unsigned int mtu;
struct in_addr src;
unsigned int flags;
unsigned int state;
};
TAILQ_HEAD(rt_head, rt);
struct ipv4_addr {
TAILQ_ENTRY(ipv4_addr) next;
struct in_addr addr;
struct in_addr net;
struct in_addr dst;
struct interface *iface;
int addr_flags;
};
TAILQ_HEAD(ipv4_addrhead, ipv4_addr);
struct ipv4_state {
struct ipv4_addrhead addrs;
struct rt_head routes;
#ifdef BSD
/* Buffer for BPF */
size_t buffer_size, buffer_len, buffer_pos;
unsigned char *buffer;
#endif
};
#define IPV4_STATE(ifp) \
((struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4])
#define IPV4_CSTATE(ifp) \
((const struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4])
#ifdef INET
struct ipv4_state *ipv4_getstate(struct interface *);
int ipv4_init(struct dhcpcd_ctx *);
int ipv4_protocol_fd(const struct interface *, uint16_t);
int ipv4_ifcmp(const struct interface *, const struct interface *);
uint8_t inet_ntocidr(struct in_addr);
int inet_cidrtoaddr(int, struct in_addr *);
uint32_t ipv4_getnetmask(uint32_t);
int ipv4_hasaddr(const struct interface *);
#define STATE_ADDED 0x01
#define STATE_FAKE 0x02
void ipv4_buildroutes(struct dhcpcd_ctx *);
int ipv4_deladdr(struct interface *, const struct in_addr *,
const struct in_addr *, int);
int ipv4_preferanother(struct interface *);
struct ipv4_addr *ipv4_addaddr(struct interface *,
const struct in_addr *, const struct in_addr *, const struct in_addr *);
void ipv4_applyaddr(void *);
int ipv4_handlert(struct dhcpcd_ctx *, int, struct rt *);
void ipv4_freerts(struct rt_head *);
struct ipv4_addr *ipv4_iffindaddr(struct interface *,
const struct in_addr *, const struct in_addr *);
struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
const struct in_addr *, const struct in_addr *, const struct in_addr *,
int);
void ipv4_freeroutes(struct rt_head *);
void ipv4_free(struct interface *);
void ipv4_ctxfree(struct dhcpcd_ctx *);
#else
#define ipv4_init(a) (-1)
#define ipv4_sortinterfaces(a) {}
#define ipv4_applyaddr(a) {}
#define ipv4_freeroutes(a) {}
#define ipv4_free(a) {}
#define ipv4_ctxfree(a) {}
#define ipv4_hasaddr(a) (0)
#define ipv4_preferanother(a) (0)
#endif
#endif

440
external/bsd/dhcpcd/dist/ipv4ll.c vendored Normal file
View File

@ -0,0 +1,440 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ELOOP_QUEUE 6
#include "config.h"
#include "arp.h"
#include "common.h"
#include "eloop.h"
#include "if.h"
#include "if-options.h"
#include "ipv4.h"
#include "ipv4ll.h"
#include "script.h"
const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
static in_addr_t
ipv4ll_pick_addr(const struct arp_state *astate)
{
struct in_addr addr;
struct ipv4ll_state *istate;
istate = IPV4LL_STATE(astate->iface);
setstate(istate->randomstate);
do {
/* RFC 3927 Section 2.1 states that the first 256 and
* last 256 addresses are reserved for future use.
* See ipv4ll_start for why we don't use arc4_random. */
addr.s_addr = ntohl(LINKLOCAL_ADDR |
((uint32_t)(random() % 0xFD00) + 0x0100));
/* No point using a failed address */
if (addr.s_addr == astate->failed.s_addr)
continue;
/* Ensure we don't have the address on another interface */
} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
/* Restore the original random state */
setstate(astate->iface->ctx->randomstate);
return addr.s_addr;
}
struct rt *
ipv4ll_subnet_route(const struct interface *ifp)
{
const struct ipv4ll_state *state;
struct rt *rt;
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
state->addr.s_addr == INADDR_ANY)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
return NULL;
}
rt->iface = ifp;
rt->dest.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
rt->net = inaddr_llmask;
rt->gate.s_addr = INADDR_ANY;
rt->src = state->addr;
return rt;
}
struct rt *
ipv4ll_default_route(const struct interface *ifp)
{
const struct ipv4ll_state *state;
struct rt *rt;
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
state->addr.s_addr == INADDR_ANY)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
return NULL;
}
rt->iface = ifp;
rt->dest.s_addr = INADDR_ANY;
rt->net.s_addr = INADDR_ANY;
rt->gate.s_addr = INADDR_ANY;
rt->src = state->addr;
return rt;
}
ssize_t
ipv4ll_env(char **env, const char *prefix, const struct interface *ifp)
{
const struct ipv4ll_state *state;
const char *pf = prefix == NULL ? "" : "_";
struct in_addr netnum;
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL)
return 0;
if (env == NULL)
return 5;
/* Emulate a DHCP environment */
if (asprintf(&env[0], "%s%sip_address=%s",
prefix, pf, inet_ntoa(state->addr)) == -1)
return -1;
if (asprintf(&env[1], "%s%ssubnet_mask=%s",
prefix, pf, inet_ntoa(inaddr_llmask)) == -1)
return -1;
if (asprintf(&env[2], "%s%ssubnet_cidr=%d",
prefix, pf, inet_ntocidr(inaddr_llmask)) == -1)
return -1;
if (asprintf(&env[3], "%s%sbroadcast_address=%s",
prefix, pf, inet_ntoa(inaddr_llbcast)) == -1)
return -1;
netnum.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
if (asprintf(&env[4], "%s%snetwork_number=%s",
prefix, pf, inet_ntoa(netnum)) == -1)
return -1;
return 5;
}
static void
ipv4ll_probed(struct arp_state *astate)
{
struct interface *ifp;
struct ipv4ll_state *state;
struct ipv4_addr *ia;
assert(astate != NULL);
assert(astate->iface != NULL);
ifp = astate->iface;
state = IPV4LL_STATE(ifp);
assert(state != NULL);
ia = ipv4_iffindaddr(ifp, &astate->addr, &inaddr_llmask);
#ifdef IN_IFF_NOTREADY
if (ia == NULL || ia->addr_flags & IN_IFF_NOTREADY)
#endif
logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
ifp->name, inet_ntoa(astate->addr));
if (ia == NULL)
ia = ipv4_addaddr(ifp, &astate->addr,
&inaddr_llmask, &inaddr_llbcast);
if (ia == NULL)
return;
#ifdef IN_IFF_NOTREADY
if (ia->addr_flags & IN_IFF_NOTREADY)
return;
logger(ifp->ctx, LOG_DEBUG, "%s: DAD completed for %s",
ifp->name, inet_ntoa(astate->addr));
#endif
state->addr = astate->addr;
timespecclear(&state->defend);
if_initrt(ifp);
ipv4_buildroutes(ifp->ctx);
arp_announce(astate);
script_runreason(ifp, "IPV4LL");
dhcpcd_daemonise(ifp->ctx);
}
static void
ipv4ll_announced(struct arp_state *astate)
{
struct ipv4ll_state *state = IPV4LL_STATE(astate->iface);
state->conflicts = 0;
/* Need to keep the arp state so we can defend our IP. */
}
static void
ipv4ll_probe(void *arg)
{
#ifdef IN_IFF_TENTATIVE
ipv4ll_probed(arg);
#else
arp_probe(arg);
#endif
}
static void
ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
{
struct interface *ifp;
struct ipv4ll_state *state;
in_addr_t fail;
assert(astate != NULL);
assert(astate->iface != NULL);
ifp = astate->iface;
state = IPV4LL_STATE(ifp);
assert(state != NULL);
fail = 0;
/* RFC 3927 2.2.1, Probe Conflict Detection */
if (amsg == NULL ||
(amsg->sip.s_addr == astate->addr.s_addr ||
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr)))
fail = astate->addr.s_addr;
/* RFC 3927 2.5, Conflict Defense */
if (IN_LINKLOCAL(ntohl(state->addr.s_addr)) &&
amsg && amsg->sip.s_addr == state->addr.s_addr)
fail = state->addr.s_addr;
if (fail == 0)
return;
astate->failed.s_addr = fail;
arp_report_conflicted(astate, amsg);
if (astate->failed.s_addr == state->addr.s_addr) {
struct timespec now, defend;
/* RFC 3927 Section 2.5 */
defend.tv_sec = state->defend.tv_sec + DEFEND_INTERVAL;
defend.tv_nsec = state->defend.tv_nsec;
clock_gettime(CLOCK_MONOTONIC, &now);
if (timespeccmp(&defend, &now, >)) {
logger(ifp->ctx, LOG_WARNING,
"%s: IPv4LL %d second defence failed for %s",
ifp->name, DEFEND_INTERVAL,
inet_ntoa(state->addr));
ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
state->down = 1;
script_runreason(ifp, "IPV4LL");
state->addr.s_addr = INADDR_ANY;
} else {
logger(ifp->ctx, LOG_DEBUG,
"%s: defended IPv4LL address %s",
ifp->name, inet_ntoa(state->addr));
state->defend = now;
return;
}
}
arp_cancel(astate);
if (++state->conflicts == MAX_CONFLICTS)
logger(ifp->ctx, LOG_ERR,
"%s: failed to acquire an IPv4LL address",
ifp->name);
astate->addr.s_addr = ipv4ll_pick_addr(astate);
eloop_timeout_add_sec(ifp->ctx->eloop,
state->conflicts >= MAX_CONFLICTS ?
RATE_LIMIT_INTERVAL : PROBE_WAIT,
ipv4ll_probe, astate);
}
static void
ipv4ll_arpfree(struct arp_state *astate)
{
struct ipv4ll_state *state;
state = IPV4LL_STATE(astate->iface);
if (state->arp == astate)
state->arp = NULL;
}
void
ipv4ll_start(void *arg)
{
struct interface *ifp;
struct ipv4ll_state *state;
struct arp_state *astate;
struct ipv4_addr *ia;
assert(arg != NULL);
ifp = arg;
if ((state = IPV4LL_STATE(ifp)) == NULL) {
ifp->if_data[IF_DATA_IPV4LL] = calloc(1, sizeof(*state));
if ((state = IPV4LL_STATE(ifp)) == NULL) {
syslog(LOG_ERR, "%s: calloc %m", __func__);
return;
}
state->addr.s_addr = INADDR_ANY;
}
if (state->arp != NULL)
return;
/* RFC 3927 Section 2.1 states that the random number generator
* SHOULD be seeded with a value derived from persistent information
* such as the IEEE 802 MAC address so that it usually picks
* the same address without persistent storage. */
if (state->conflicts == 0) {
unsigned int seed;
char *orig;
if (sizeof(seed) > ifp->hwlen) {
seed = 0;
memcpy(&seed, ifp->hwaddr, ifp->hwlen);
} else
memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
sizeof(seed));
orig = initstate(seed,
state->randomstate, sizeof(state->randomstate));
/* Save the original state. */
if (ifp->ctx->randomstate == NULL)
ifp->ctx->randomstate = orig;
/* Set back the original state until we need the seeded one. */
setstate(ifp->ctx->randomstate);
}
if ((astate = arp_new(ifp, NULL)) == NULL)
return;
state->arp = astate;
astate->probed_cb = ipv4ll_probed;
astate->announced_cb = ipv4ll_announced;
astate->conflicted_cb = ipv4ll_conflicted;
astate->free_cb = ipv4ll_arpfree;
/* Find an existing IPv4LL address and ensure we can work with it. */
ia = ipv4_iffindlladdr(ifp);
#ifdef IN_IFF_TENTATIVE
if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
ipv4_deladdr(ifp, &ia->addr, &ia->net, 0);
ia = NULL;
}
#endif
if (ia != NULL) {
astate->addr = ia->addr;
#ifdef IN_IFF_TENTATIVE
if (ia->addr_flags & (IN_IFF_TENTATIVE | IN_IFF_DETACHED)) {
logger(ifp->ctx, LOG_INFO,
"%s: waiting for DAD to complete on %s",
ifp->name, inet_ntoa(ia->addr));
return;
}
logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
ifp->name, inet_ntoa(astate->addr));
#endif
ipv4ll_probed(astate);
return;
}
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
ifp->name);
astate->addr.s_addr = ipv4ll_pick_addr(astate);
#ifdef IN_IFF_TENTATIVE
ipv4ll_probed(astate);
#else
arp_probe(astate);
#endif
}
void
ipv4ll_freedrop(struct interface *ifp, int drop)
{
struct ipv4ll_state *state;
int dropped;
assert(ifp != NULL);
state = IPV4LL_STATE(ifp);
dropped = 0;
/* Free ARP state first because ipv4_deladdr might also ... */
if (state && state->arp) {
eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp);
arp_free(state->arp);
state->arp = NULL;
}
if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) {
struct ipv4_state *istate;
if (state && state->addr.s_addr != INADDR_ANY) {
ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
state->addr.s_addr = INADDR_ANY;
dropped = 1;
}
/* Free any other link local addresses that might exist. */
if ((istate = IPV4_STATE(ifp)) != NULL) {
struct ipv4_addr *ia, *ian;
TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
ipv4_deladdr(ifp, &ia->addr,
&ia->net, 0);
dropped = 1;
}
}
}
}
if (state) {
free(state);
ifp->if_data[IF_DATA_IPV4LL] = NULL;
if (dropped) {
ipv4_buildroutes(ifp->ctx);
script_runreason(ifp, "IPV4LL");
}
}
}

74
external/bsd/dhcpcd/dist/ipv4ll.h vendored Normal file
View File

@ -0,0 +1,74 @@
/* $NetBSD: ipv4ll.h,v 1.10 2015/08/21 10:39:00 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef IPV4LL_H
#define IPV4LL_H
#include "arp.h"
extern const struct in_addr inaddr_llmask;
extern const struct in_addr inaddr_llbcast;
#define LINKLOCAL_ADDR 0xa9fe0000
#define LINKLOCAL_MASK IN_CLASSB_NET
#define LINKLOCAL_BRDC (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
#ifndef IN_LINKLOCAL
# define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR)
#endif
struct ipv4ll_state {
struct in_addr addr;
struct arp_state *arp;
unsigned int conflicts;
struct timespec defend;
char randomstate[128];
uint8_t down;
};
#define IPV4LL_STATE(ifp) \
((struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
#define IPV4LL_CSTATE(ifp) \
((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
#define IPV4LL_STATE_RUNNING(ifp) \
(IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \
IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr)))
struct rt* ipv4ll_subnet_route(const struct interface *);
struct rt* ipv4ll_default_route(const struct interface *);
ssize_t ipv4ll_env(char **, const char *, const struct interface *);
void ipv4ll_start(void *);
void ipv4ll_claimed(void *);
void ipv4ll_handle_failure(void *);
#define ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0);
#define ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1);
void ipv4ll_freedrop(struct interface *, int);
#endif

2178
external/bsd/dhcpcd/dist/ipv6.c vendored Normal file

File diff suppressed because it is too large Load Diff

295
external/bsd/dhcpcd/dist/ipv6.h vendored Normal file
View File

@ -0,0 +1,295 @@
/* $NetBSD: ipv6.h,v 1.14 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef IPV6_H
#define IPV6_H
#include <sys/uio.h>
#include <netinet/in.h>
#ifndef __linux__
# ifndef __QNX__
# include <sys/endian.h>
# endif
# include <net/if.h>
# ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
# include <net/if_var.h>
# endif
# ifndef __sun
# include <netinet6/in6_var.h>
# endif
#endif
#include "config.h"
#include "dhcpcd.h"
#define ALLROUTERS "ff02::2"
#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
#define ROUNDUP16(a) (1 + (((a) - 1) | 16))
#define EUI64_GBIT 0x01
#define EUI64_UBIT 0x02
#define EUI64_TO_IFID(in6) do {(in6)->s6_addr[8] ^= EUI64_UBIT; } while (0)
#define EUI64_GROUP(in6) ((in6)->s6_addr[8] & EUI64_GBIT)
#ifndef ND6_INFINITE_LIFETIME
# define ND6_INFINITE_LIFETIME ((uint32_t)~0)
#endif
/* RFC4941 constants */
#define TEMP_VALID_LIFETIME 604800 /* 1 week */
#define TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
#define REGEN_ADVANCE 5 /* seconds */
#define MAX_DESYNC_FACTOR 600 /* 10 minutes */
#define TEMP_IDGEN_RETRIES 3
#define GEN_TEMPID_RETRY_MAX 5
/* RFC7217 constants */
#define IDGEN_RETRIES 3
#define IDGEN_DELAY 1 /* second */
/*
* BSD kernels don't inform userland of DAD results.
* See the discussion here:
* http://mail-index.netbsd.org/tech-net/2013/03/15/msg004019.html
*/
#ifndef __linux__
/* We guard here to avoid breaking a compile on linux ppc-64 headers */
# include <sys/param.h>
#endif
#ifdef BSD
# define IPV6_POLLADDRFLAG
#endif
/* This was fixed in NetBSD */
#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000
# undef IPV6_POLLADDRFLAG
#endif
/* Linux-3.18 can manage temporary addresses even with RA
* processing disabled. */
//#undef IFA_F_MANAGETEMPADDR
#if defined(__linux__) && defined(IFA_F_MANAGETEMPADDR)
#define IPV6_MANAGETEMPADDR
#endif
/* Some BSDs do not allow userland to set temporary addresses. */
#if defined(BSD) && defined(IN6_IFF_TEMPORARY)
#define IPV6_MANAGETEMPADDR
#endif
struct ipv6_addr {
TAILQ_ENTRY(ipv6_addr) next;
struct interface *iface;
struct in6_addr prefix;
uint8_t prefix_len;
uint32_t prefix_vltime;
uint32_t prefix_pltime;
struct timespec created;
struct timespec acquired;
struct in6_addr addr;
int addr_flags;
short flags;
char saddr[INET6_ADDRSTRLEN];
uint8_t iaid[4];
uint16_t ia_type;
struct interface *delegating_iface;
uint8_t prefix_exclude_len;
struct in6_addr prefix_exclude;
void (*dadcallback)(void *);
int dadcounter;
uint8_t *ns;
size_t nslen;
int nsprobes;
};
TAILQ_HEAD(ipv6_addrhead, ipv6_addr);
#define IPV6_AF_ONLINK 0x0001
#define IPV6_AF_NEW 0x0002
#define IPV6_AF_STALE 0x0004
#define IPV6_AF_ADDED 0x0008
#define IPV6_AF_AUTOCONF 0x0010
#define IPV6_AF_DUPLICATED 0x0020
#define IPV6_AF_DADCOMPLETED 0x0040
#define IPV6_AF_DELEGATED 0x0080
#define IPV6_AF_DELEGATEDPFX 0x0100
#define IPV6_AF_DELEGATEDZERO 0x0200
#define IPV6_AF_REQUEST 0x0400
#ifdef IPV6_MANAGETEMPADDR
#define IPV6_AF_TEMPORARY 0X0800
#endif
struct rt6 {
TAILQ_ENTRY(rt6) next;
struct in6_addr dest;
struct in6_addr net;
struct in6_addr gate;
const struct interface *iface;
unsigned int flags;
#ifdef HAVE_ROUTE_METRIC
unsigned int metric;
#endif
unsigned int mtu;
};
TAILQ_HEAD(rt6_head, rt6);
struct ll_callback {
TAILQ_ENTRY(ll_callback) next;
void (*callback)(void *);
void *arg;
};
TAILQ_HEAD(ll_callback_head, ll_callback);
struct ipv6_state {
struct ipv6_addrhead addrs;
struct ll_callback_head ll_callbacks;
#ifdef IPV6_MANAGETEMPADDR
time_t desync_factor;
uint8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
uint8_t randomseed1[8]; /* lower 64 bits */
uint8_t randomid[8];
#endif
};
#define IPV6_STATE(ifp) \
((struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6])
#define IPV6_CSTATE(ifp) \
((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6])
/* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */
#ifdef __QNX__
#undef CMSG_SPACE
#endif
#ifndef ALIGNBYTES
#define ALIGNBYTES (sizeof(int) - 1)
#endif
#ifndef ALIGN
#define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
#endif
#ifndef CMSG_SPACE
#define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len))
#endif
#define IP6BUFLEN (CMSG_SPACE(sizeof(struct in6_pktinfo)) + \
CMSG_SPACE(sizeof(int)))
#ifdef INET6
struct ipv6_ctx {
struct sockaddr_in6 from;
struct msghdr sndhdr;
struct iovec sndiov[2];
unsigned char sndbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
struct msghdr rcvhdr;
struct iovec rcviov[2];
unsigned char rcvbuf[IP6BUFLEN];
unsigned char ansbuf[1500];
char ntopbuf[INET6_ADDRSTRLEN];
const char *sfrom;
int nd_fd;
struct ra_head *ra_routers;
struct rt6_head *routes;
struct rt6_head kroutes;
int dhcp_fd;
};
struct ipv6_ctx *ipv6_init(struct dhcpcd_ctx *);
ssize_t ipv6_printaddr(char *, size_t, const uint8_t *, const char *);
int ipv6_makestableprivate(struct in6_addr *addr,
const struct in6_addr *prefix, int prefix_len,
const struct interface *ifp, int *dad_counter);
int ipv6_makeaddr(struct in6_addr *, const struct interface *,
const struct in6_addr *, int);
int ipv6_makeprefix(struct in6_addr *, const struct in6_addr *, int);
int ipv6_mask(struct in6_addr *, int);
uint8_t ipv6_prefixlen(const struct in6_addr *);
int ipv6_userprefix( const struct in6_addr *, short prefix_len,
uint64_t user_number, struct in6_addr *result, short result_len);
void ipv6_checkaddrflags(void *);
int ipv6_addaddr(struct ipv6_addr *, const struct timespec *);
ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
const struct interface *);
void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
const char *, const struct in6_addr *, uint8_t, int);
int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
const struct in6_addr *, int);
int ipv6_publicaddr(const struct ipv6_addr *);
const struct ipv6_addr *ipv6_iffindaddr(const struct interface *,
const struct in6_addr *);
int ipv6_hasaddr(const struct interface *);
int ipv6_findaddrmatch(const struct ipv6_addr *, const struct in6_addr *,
short);
struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
const struct in6_addr *, short);
#define ipv6_linklocal(ifp) ipv6_iffindaddr((ifp), NULL)
int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
void ipv6_freeaddr(struct ipv6_addr *);
void ipv6_freedrop(struct interface *, int);
#define ipv6_free(ifp) ipv6_freedrop((ifp), 0)
#define ipv6_drop(ifp) ipv6_freedrop((ifp), 2)
#ifdef IPV6_MANAGETEMPADDR
void ipv6_gentempifid(struct interface *);
void ipv6_settempstale(struct interface *);
struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *,
const struct timespec *);
struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int);
void ipv6_addtempaddrs(struct interface *, const struct timespec *);
#else
#define ipv6_gentempifid(a) {}
#define ipv6_settempstale(a) {}
#endif
int ipv6_start(struct interface *);
void ipv6_ctxfree(struct dhcpcd_ctx *);
int ipv6_handlert(struct dhcpcd_ctx *, int cmd, struct rt6 *);
void ipv6_freerts(struct rt6_head *);
void ipv6_buildroutes(struct dhcpcd_ctx *);
#else
#define ipv6_init(a) (NULL)
#define ipv6_start(a) (-1)
#define ipv6_hasaddr(a) (0)
#define ipv6_free_ll_callbacks(a) {}
#define ipv6_free(a) {}
#define ipv6_drop(a) {}
#define ipv6_ctxfree(a) {}
#define ipv6_gentempifid(a) {}
#endif
#endif

1700
external/bsd/dhcpcd/dist/ipv6nd.c vendored Normal file

File diff suppressed because it is too large Load Diff

131
external/bsd/dhcpcd/dist/ipv6nd.h vendored Normal file
View File

@ -0,0 +1,131 @@
/* $NetBSD: ipv6nd.h,v 1.13 2015/07/09 10:15:34 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef IPV6ND_H
#define IPV6ND_H
#include <time.h>
#include "config.h"
#include "dhcpcd.h"
#include "ipv6.h"
struct ra {
TAILQ_ENTRY(ra) next;
struct interface *iface;
struct in6_addr from;
char sfrom[INET6_ADDRSTRLEN];
unsigned char *data;
size_t data_len;
struct timespec acquired;
unsigned char flags;
uint32_t lifetime;
uint32_t reachable;
uint32_t retrans;
uint32_t mtu;
struct ipv6_addrhead addrs;
uint8_t hasdns;
uint8_t expired;
uint8_t no_public_warned;
};
TAILQ_HEAD(ra_head, ra);
struct rs_state {
unsigned char *rs;
size_t rslen;
int rsprobes;
};
#define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6ND])
#define RS_STATE_RUNNING(a) (ipv6nd_hasra((a)) && ipv6nd_dadcompleted((a)))
#define ND_CFIRST_OPTION(m) \
((const struct nd_opt_hdr *) \
((const uint8_t *)(m)->data + sizeof(struct nd_router_advert)))
#define ND_OPTION_LEN(o) ((size_t)((o)->nd_opt_len * 8) - \
sizeof(struct nd_opt_hdr))
#define ND_CNEXT_OPTION(o) \
((const struct nd_opt_hdr *)((const uint8_t *)(o) + \
(size_t)((o)->nd_opt_len * 8)))
#define ND_COPTION_DATA(o) \
((const uint8_t *)(o) + sizeof(struct nd_opt_hdr))
#define MAX_RTR_SOLICITATION_DELAY 1 /* seconds */
#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */
#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
#define MAX_RTR_SOLICITATIONS 3 /* times */
/* On carrier up, expire known routers after RTR_CARRIER_EXPIRE seconds. */
#define RTR_CARRIER_EXPIRE \
(MAX_RTR_SOLICITATION_DELAY + \
(MAX_RTR_SOLICITATIONS + 1) * \
RTR_SOLICITATION_INTERVAL)
#define MAX_REACHABLE_TIME 3600000 /* milliseconds */
#define REACHABLE_TIME 30000 /* milliseconds */
#define RETRANS_TIMER 1000 /* milliseconds */
#define DELAY_FIRST_PROBE_TIME 5 /* seconds */
#define IPV6ND_REACHABLE (1 << 0)
#define IPV6ND_ROUTER (1 << 1)
#ifdef INET6
void ipv6nd_printoptions(const struct dhcpcd_ctx *,
const struct dhcp_opt *, size_t);
void ipv6nd_startrs(struct interface *);
ssize_t ipv6nd_env(char **, const char *, const struct interface *);
const struct ipv6_addr *ipv6nd_iffindaddr(const struct interface *ifp,
const struct in6_addr *addr, short flags);
struct ipv6_addr *ipv6nd_findaddr(struct dhcpcd_ctx *,
const struct in6_addr *, short);
void ipv6nd_freedrop_ra(struct ra *, int);
#define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra), 0)
#define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1)
ssize_t ipv6nd_free(struct interface *);
void ipv6nd_expirera(void *arg);
int ipv6nd_hasra(const struct interface *);
int ipv6nd_hasradhcp(const struct interface *);
void ipv6nd_runignoredra(struct interface *);
void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
const char *, const struct in6_addr *, int);
int ipv6nd_dadcompleted(const struct interface *);
void ipv6nd_expire(struct interface *, uint32_t);
void ipv6nd_drop(struct interface *);
void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
#else
#define ipv6nd_startrs(a) {}
#define ipv6nd_free(a) {}
#define ipv6nd_hasra(a) (0)
#define ipv6nd_dadcompleted(a) (0)
#define ipv6nd_drop(a) {}
#define ipv6nd_expire(a, b) {}
#endif
#endif

766
external/bsd/dhcpcd/dist/script.c vendored Normal file
View File

@ -0,0 +1,766 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: script.c,v 1.23 2015/09/04 12:25:01 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
/* We can't include spawn.h here because it may not exist.
* config.h will pull it in, or our compat one. */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "common.h"
#include "dhcp.h"
#include "dhcp6.h"
#include "if.h"
#include "if-options.h"
#include "ipv4ll.h"
#include "ipv6nd.h"
#include "script.h"
#ifdef HAVE_SPAWN_H
#include <spawn.h>
#else
#include "compat/posix_spawn.h"
#endif
/* Allow the OS to define another script env var name */
#ifndef RC_SVCNAME
#define RC_SVCNAME "RC_SVCNAME"
#endif
#define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
static const char * const if_params[] = {
"interface",
"reason",
"pid",
"ifcarrier",
"ifmetric",
"ifwireless",
"ifflags",
"ssid",
"profile",
"interface_order",
NULL
};
void
if_printoptions(void)
{
const char * const *p;
for (p = if_params; *p; p++)
printf(" - %s\n", *p);
}
static int
exec_script(const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env)
{
pid_t pid;
posix_spawnattr_t attr;
int r;
#ifdef USE_SIGNALS
size_t i;
short flags;
sigset_t defsigs;
#else
UNUSED(ctx);
#endif
/* posix_spawn is a safe way of executing another image
* and changing signals back to how they should be. */
if (posix_spawnattr_init(&attr) == -1)
return -1;
#ifdef USE_SIGNALS
flags = POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF;
posix_spawnattr_setflags(&attr, flags);
sigemptyset(&defsigs);
for (i = 0; i < dhcpcd_signals_len; i++)
sigaddset(&defsigs, dhcpcd_signals[i]);
posix_spawnattr_setsigdefault(&attr, &defsigs);
posix_spawnattr_setsigmask(&attr, &ctx->sigset);
#endif
errno = 0;
r = posix_spawn(&pid, argv[0], NULL, &attr, argv, env);
if (r) {
errno = r;
return -1;
}
return pid;
}
#ifdef INET
static char *
make_var(struct dhcpcd_ctx *ctx, const char *prefix, const char *var)
{
size_t len;
char *v;
len = strlen(prefix) + strlen(var) + 2;
if ((v = malloc(len)) == NULL) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
snprintf(v, len, "%s_%s", prefix, var);
return v;
}
static int
append_config(struct dhcpcd_ctx *ctx, char ***env, size_t *len,
const char *prefix, const char *const *config)
{
size_t i, j, e1;
char **ne, *eq, **nep, *p;
int ret;
if (config == NULL)
return 0;
ne = *env;
ret = 0;
for (i = 0; config[i] != NULL; i++) {
eq = strchr(config[i], '=');
e1 = (size_t)(eq - config[i] + 1);
for (j = 0; j < *len; j++) {
if (strncmp(ne[j], prefix, strlen(prefix)) == 0 &&
ne[j][strlen(prefix)] == '_' &&
strncmp(ne[j] + strlen(prefix) + 1,
config[i], e1) == 0)
{
p = make_var(ctx, prefix, config[i]);
if (p == NULL) {
ret = -1;
break;
}
free(ne[j]);
ne[j] = p;
break;
}
}
if (j == *len) {
j++;
p = make_var(ctx, prefix, config[i]);
if (p == NULL) {
ret = -1;
break;
}
nep = realloc(ne, sizeof(char *) * (j + 1));
if (nep == NULL) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
free(p);
ret = -1;
break;
}
ne = nep;
ne[j - 1] = p;
*len = j;
}
}
*env = ne;
return ret;
}
#endif
static ssize_t
arraytostr(const char *const *argv, char **s)
{
const char *const *ap;
char *p;
size_t len, l;
if (*argv == NULL)
return 0;
len = 0;
ap = argv;
while (*ap)
len += strlen(*ap++) + 1;
*s = p = malloc(len);
if (p == NULL)
return -1;
ap = argv;
while (*ap) {
l = strlen(*ap) + 1;
memcpy(p, *ap, l);
p += l;
ap++;
}
return (ssize_t)len;
}
static ssize_t
make_env(const struct interface *ifp, const char *reason, char ***argv)
{
char **env, **nenv, *p;
size_t e, elen, l;
#if defined(INET) || defined(INET6)
ssize_t n;
#endif
const struct if_options *ifo = ifp->options;
const struct interface *ifp2;
int af;
#ifdef INET
int dhcp, ipv4ll;
const struct dhcp_state *state;
const struct ipv4ll_state *istate;
#endif
#ifdef INET6
const struct dhcp6_state *d6_state;
int dhcp6, ra;
#endif
#ifdef INET
dhcp = ipv4ll = 0;
state = D_STATE(ifp);
istate = IPV4LL_CSTATE(ifp);
#endif
#ifdef INET6
dhcp6 = ra = 0;
d6_state = D6_CSTATE(ifp);
#endif
if (strcmp(reason, "TEST") == 0) {
if (1 == 2) {}
#ifdef INET6
else if (d6_state && d6_state->new)
dhcp6 = 1;
else if (ipv6nd_hasra(ifp))
ra = 1;
#endif
#ifdef INET
else if (state->added)
dhcp = 1;
else
ipv4ll = 1;
#endif
}
#ifdef INET6
else if (reason[strlen(reason) - 1] == '6')
dhcp6 = 1;
else if (strcmp(reason, "ROUTERADVERT") == 0)
ra = 1;
#endif
else if (strcmp(reason, "PREINIT") == 0 ||
strcmp(reason, "CARRIER") == 0 ||
strcmp(reason, "NOCARRIER") == 0 ||
strcmp(reason, "UNKNOWN") == 0 ||
strcmp(reason, "DEPARTED") == 0 ||
strcmp(reason, "STOPPED") == 0)
{
/* This space left intentionally blank */
}
#ifdef INET
else if (strcmp(reason, "IPV4LL") == 0)
ipv4ll = 1;
else
dhcp = 1;
#endif
/* When dumping the lease, we only want to report interface and
reason - the other interface variables are meaningless */
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
elen = 2;
else
elen = 11;
#define EMALLOC(i, l) if ((env[(i)] = malloc((l))) == NULL) goto eexit;
/* Make our env + space for profile, wireless and debug */
env = calloc(1, sizeof(char *) * (elen + 4 + 1));
if (env == NULL)
goto eexit;
e = strlen("interface") + strlen(ifp->name) + 2;
EMALLOC(0, e);
snprintf(env[0], e, "interface=%s", ifp->name);
e = strlen("reason") + strlen(reason) + 2;
EMALLOC(1, e);
snprintf(env[1], e, "reason=%s", reason);
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
goto dumplease;
e = 20;
EMALLOC(2, e);
snprintf(env[2], e, "pid=%d", getpid());
EMALLOC(3, e);
snprintf(env[3], e, "ifcarrier=%s",
ifp->carrier == LINK_UNKNOWN ? "unknown" :
ifp->carrier == LINK_UP ? "up" : "down");
EMALLOC(4, e);
snprintf(env[4], e, "ifmetric=%d", ifp->metric);
EMALLOC(5, e);
snprintf(env[5], e, "ifwireless=%d", ifp->wireless);
EMALLOC(6, e);
snprintf(env[6], e, "ifflags=%u", ifp->flags);
EMALLOC(7, e);
snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp));
l = e = strlen("interface_order=");
TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
e += strlen(ifp2->name) + 1;
}
EMALLOC(8, e);
p = env[8];
strlcpy(p, "interface_order=", e);
e -= l;
p += l;
TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
l = strlcpy(p, ifp2->name, e);
p += l;
e -= l;
*p++ = ' ';
e--;
}
*--p = '\0';
if (strcmp(reason, "STOPPED") == 0) {
env[9] = strdup("if_up=false");
if (ifo->options & DHCPCD_RELEASE)
env[10] = strdup("if_down=true");
else
env[10] = strdup("if_down=false");
} else if (strcmp(reason, "TEST") == 0 ||
strcmp(reason, "PREINIT") == 0 ||
strcmp(reason, "CARRIER") == 0 ||
strcmp(reason, "UNKNOWN") == 0)
{
env[9] = strdup("if_up=false");
env[10] = strdup("if_down=false");
} else if (1 == 2 /* appease ifdefs */
#ifdef INET
|| (dhcp && state && state->new)
|| (ipv4ll && IPV4LL_STATE_RUNNING(ifp))
#endif
#ifdef INET6
|| (dhcp6 && d6_state && d6_state->new)
|| (ra && ipv6nd_hasra(ifp))
#endif
)
{
env[9] = strdup("if_up=true");
env[10] = strdup("if_down=false");
} else {
env[9] = strdup("if_up=false");
env[10] = strdup("if_down=true");
}
if (env[9] == NULL || env[10] == NULL)
goto eexit;
if ((af = dhcpcd_ifafwaiting(ifp)) != AF_MAX) {
e = 20;
EMALLOC(elen, e);
snprintf(env[elen++], e, "if_afwaiting=%d", af);
}
if ((af = dhcpcd_afwaiting(ifp->ctx)) != AF_MAX) {
TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
if ((af = dhcpcd_ifafwaiting(ifp2)) != AF_MAX)
break;
}
}
if (af != AF_MAX) {
e = 20;
EMALLOC(elen, e);
snprintf(env[elen++], e, "af_waiting=%d", af);
}
if (ifo->options & DHCPCD_DEBUG) {
e = strlen("syslog_debug=true") + 1;
EMALLOC(elen, e);
snprintf(env[elen++], e, "syslog_debug=true");
}
if (*ifp->profile) {
e = strlen("profile=") + strlen(ifp->profile) + 1;
EMALLOC(elen, e);
snprintf(env[elen++], e, "profile=%s", ifp->profile);
}
if (ifp->wireless) {
static const char *pfx = "ifssid=";
size_t pfx_len;
ssize_t psl;
pfx_len = strlen(pfx);
psl = print_string(NULL, 0, ESCSTRING,
(const uint8_t *)ifp->ssid, ifp->ssid_len);
if (psl != -1) {
EMALLOC(elen, pfx_len + (size_t)psl + 1);
memcpy(env[elen], pfx, pfx_len);
print_string(env[elen] + pfx_len, (size_t)psl + 1,
ESCSTRING,
(const uint8_t *)ifp->ssid, ifp->ssid_len);
elen++;
}
}
#ifdef INET
if (dhcp && state && state->old) {
n = dhcp_env(NULL, NULL, state->old, ifp);
if (n == -1)
goto eexit;
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
n = dhcp_env(env + elen, "old", state->old, ifp);
if (n == -1)
goto eexit;
elen += (size_t)n;
}
if (append_config(ifp->ctx, &env, &elen, "old",
(const char *const *)ifo->config) == -1)
goto eexit;
}
#endif
#ifdef INET6
if (dhcp6 && d6_state && d6_state->old) {
n = dhcp6_env(NULL, NULL, ifp,
d6_state->old, d6_state->old_len);
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
n = dhcp6_env(env + elen, "old", ifp,
d6_state->old, d6_state->old_len);
if (n == -1)
goto eexit;
elen += (size_t)n;
}
}
#endif
dumplease:
#ifdef INET
if (ipv4ll) {
n = ipv4ll_env(NULL, NULL, ifp);
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
if ((n = ipv4ll_env(env + elen,
istate->down ? "old" : "new", ifp)) == -1)
goto eexit;
elen += (size_t)n;
}
}
if (dhcp && state && state->new) {
n = dhcp_env(NULL, NULL, state->new, ifp);
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
n = dhcp_env(env + elen, "new",
state->new, ifp);
if (n == -1)
goto eexit;
elen += (size_t)n;
}
if (append_config(ifp->ctx, &env, &elen, "new",
(const char *const *)ifo->config) == -1)
goto eexit;
}
#endif
#ifdef INET6
if (dhcp6 && D6_STATE_RUNNING(ifp)) {
n = dhcp6_env(NULL, NULL, ifp,
d6_state->new, d6_state->new_len);
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
n = dhcp6_env(env + elen, "new", ifp,
d6_state->new, d6_state->new_len);
if (n == -1)
goto eexit;
elen += (size_t)n;
}
}
if (ra) {
n = ipv6nd_env(NULL, NULL, ifp);
if (n > 0) {
nenv = realloc(env, sizeof(char *) *
(elen + (size_t)n + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
n = ipv6nd_env(env + elen, NULL, ifp);
if (n == -1)
goto eexit;
elen += (size_t)n;
}
}
#endif
/* Add our base environment */
if (ifo->environ) {
e = 0;
while (ifo->environ[e++])
;
nenv = realloc(env, sizeof(char *) * (elen + e + 1));
if (nenv == NULL)
goto eexit;
env = nenv;
e = 0;
while (ifo->environ[e]) {
env[elen + e] = strdup(ifo->environ[e]);
if (env[elen + e] == NULL)
goto eexit;
e++;
}
elen += e;
}
env[elen] = NULL;
*argv = env;
return (ssize_t)elen;
eexit:
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
if (env) {
nenv = env;
while (*nenv)
free(*nenv++);
free(env);
}
return -1;
}
static int
send_interface1(struct fd_list *fd, const struct interface *iface,
const char *reason)
{
char **env, **ep, *s;
size_t elen;
int retval;
if (make_env(iface, reason, &env) == -1)
return -1;
s = NULL;
elen = (size_t)arraytostr((const char *const *)env, &s);
if ((ssize_t)elen == -1) {
free(s);
return -1;
}
retval = control_queue(fd, s, elen, 1);
ep = env;
while (*ep)
free(*ep++);
free(env);
return retval;
}
int
send_interface(struct fd_list *fd, const struct interface *ifp)
{
const char *reason;
int retval = 0;
#ifdef INET
const struct dhcp_state *d;
#endif
#ifdef INET6
const struct dhcp6_state *d6;
#endif
switch (ifp->carrier) {
case LINK_UP:
reason = "CARRIER";
break;
case LINK_DOWN:
reason = "NOCARRIER";
break;
default:
reason = "UNKNOWN";
break;
}
if (send_interface1(fd, ifp, reason) == -1)
retval = -1;
#ifdef INET
if (D_STATE_RUNNING(ifp)) {
d = D_CSTATE(ifp);
if (send_interface1(fd, ifp, d->reason) == -1)
retval = -1;
}
if (IPV4LL_STATE_RUNNING(ifp)) {
if (send_interface1(fd, ifp, "IPV4LL") == -1)
retval = -1;
}
#endif
#ifdef INET6
if (RS_STATE_RUNNING(ifp)) {
if (send_interface1(fd, ifp, "ROUTERADVERT") == -1)
retval = -1;
}
if (D6_STATE_RUNNING(ifp)) {
d6 = D6_CSTATE(ifp);
if (send_interface1(fd, ifp, d6->reason) == -1)
retval = -1;
}
#endif
return retval;
}
int
script_runreason(const struct interface *ifp, const char *reason)
{
char *argv[2];
char **env = NULL, **ep;
char *svcname, *path, *bigenv;
size_t e, elen = 0;
pid_t pid;
int status = 0;
struct fd_list *fd;
if (ifp->options->script &&
(ifp->options->script[0] == '\0' ||
strcmp(ifp->options->script, "/dev/null") == 0) &&
TAILQ_FIRST(&ifp->ctx->control_fds) == NULL)
return 0;
/* Make our env */
elen = (size_t)make_env(ifp, reason, &env);
if (elen == (size_t)-1) {
logger(ifp->ctx, LOG_ERR, "%s: make_env: %m", ifp->name);
return -1;
}
if (ifp->options->script &&
(ifp->options->script[0] == '\0' ||
strcmp(ifp->options->script, "/dev/null") == 0))
goto send_listeners;
argv[0] = ifp->options->script ? ifp->options->script : UNCONST(SCRIPT);
argv[1] = NULL;
logger(ifp->ctx, LOG_DEBUG, "%s: executing `%s' %s",
ifp->name, argv[0], reason);
/* Resize for PATH and RC_SVCNAME */
svcname = getenv(RC_SVCNAME);
ep = realloc(env, sizeof(char *) * (elen + 2 + (svcname ? 1 : 0)));
if (ep == NULL) {
elen = 0;
goto out;
}
env = ep;
/* Add path to it */
path = getenv("PATH");
if (path) {
e = strlen("PATH") + strlen(path) + 2;
env[elen] = malloc(e);
if (env[elen] == NULL) {
elen = 0;
goto out;
}
snprintf(env[elen], e, "PATH=%s", path);
} else {
env[elen] = strdup(DEFAULT_PATH);
if (env[elen] == NULL) {
elen = 0;
goto out;
}
}
if (svcname) {
e = strlen(RC_SVCNAME) + strlen(svcname) + 2;
env[++elen] = malloc(e);
if (env[elen] == NULL) {
elen = 0;
goto out;
}
snprintf(env[elen], e, "%s=%s", RC_SVCNAME, svcname);
}
env[++elen] = NULL;
pid = exec_script(ifp->ctx, argv, env);
if (pid == -1)
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", __func__, argv[0]);
else if (pid != 0) {
/* Wait for the script to finish */
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
logger(ifp->ctx, LOG_ERR, "waitpid: %m");
status = 0;
break;
}
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status))
logger(ifp->ctx, LOG_ERR,
"%s: %s: WEXITSTATUS %d",
__func__, argv[0], WEXITSTATUS(status));
} else if (WIFSIGNALED(status))
logger(ifp->ctx, LOG_ERR, "%s: %s: %s",
__func__, argv[0], strsignal(WTERMSIG(status)));
}
send_listeners:
/* Send to our listeners */
bigenv = NULL;
status = 0;
TAILQ_FOREACH(fd, &ifp->ctx->control_fds, next) {
if (!(fd->flags & FD_LISTEN))
continue;
if (bigenv == NULL) {
elen = (size_t)arraytostr((const char *const *)env,
&bigenv);
if ((ssize_t)elen == -1) {
logger(ifp->ctx, LOG_ERR, "%s: arraytostr: %m",
ifp->name);
break;
}
}
if (control_queue(fd, bigenv, elen, 1) == -1)
logger(ifp->ctx, LOG_ERR,
"%s: control_queue: %m", __func__);
else
status = 1;
}
if (!status)
free(bigenv);
out:
/* Cleanup */
ep = env;
while (*ep)
free(*ep++);
free(env);
if (elen == 0)
return -1;
return WEXITSTATUS(status);
}

39
external/bsd/dhcpcd/dist/script.h vendored Normal file
View File

@ -0,0 +1,39 @@
/* $NetBSD: script.h,v 1.7 2015/03/26 10:26:37 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef SCRIPT_H
#define SCRIPT_H
#include "control.h"
void if_printoptions(void);
int send_interface(struct fd_list *, const struct interface *);
int script_runreason(const struct interface *, const char *);
#endif

5
external/bsd/dhcpcd/sbin/Makefile vendored Normal file
View File

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2008/07/27 19:31:03 joerg Exp $
SUBDIR= dhcpcd
.include <bsd.subdir.mk>

11
external/bsd/dhcpcd/sbin/Makefile.inc vendored Normal file
View File

@ -0,0 +1,11 @@
# $NetBSD: Makefile.inc,v 1.2 2008/09/19 23:00:49 joerg Exp $
.include <bsd.own.mk>
WARNS?= 4
BINDIR= /sbin
.if (${MKDYNAMICROOT} == "no")
LDSTATIC?= -static
.endif

View File

@ -0,0 +1,66 @@
# $NetBSD: Makefile,v 1.26 2015/08/21 10:44:43 roy Exp $
#
PROG= dhcpcd
SRCS= common.c control.c dhcpcd.c duid.c eloop.c
SRCS+= if.c if-options.c script.c
SRCS+= dhcp-common.c dhcpcd-embedded.c
SRCS+= if-bsd.c
WARNS?= 6
USE_FORT?= yes # network client (local server)
CPPFLAGS+= -DHAVE_CONFIG_H
.include <bsd.own.mk>
SRCS+= auth.c hmac_md5.c
USE_INET?= yes
.if (${USE_INET} != "no")
CPPFLAGS+= -DINET
SRCS+= arp.c dhcp.c ipv4.c ipv4ll.c
.endif
.if (${USE_INET6} != "no")
CPPFLAGS+= -DINET6
SRCS+= ipv6.c ipv6nd.c dhcp6.c
.endif
DIST= ${NETBSDSRCDIR}/external/bsd/dhcpcd/dist
CPPFLAGS+= -I${DIST}
.PATH: ${DIST} ${DIST}/crypt ${LIBC_NET}
SCRIPTS= dhcpcd-run-hooks
SCRIPTSDIR_dhcpcd-run-hooks= /libexec
CONFIGFILES= dhcpcd.conf
FILESDIR_dhcpcd.conf= /etc
HOOKS= 01-test 02-dump 10-wpa_supplicant 15-timezone
HOOKS+= 20-resolv.conf 29-lookup-hostname 30-hostname
HOOKS+= 50-ntp.conf
FILES= ${HOOKS:C,^,${DIST}/dhcpcd-hooks/,}
FILESDIR= /libexec/dhcpcd-hooks
MAN= dhcpcd.conf.5 dhcpcd.8 dhcpcd-run-hooks.8
CLEANFILES= dhcpcd.conf.5 dhcpcd.8 \
dhcpcd-run-hooks dhcpcd-run-hooks.8
.for f in dhcpcd-run-hooks dhcpcd.conf.5 dhcpcd.8 dhcpcd-run-hooks.8
${f}: ${f}.in
${TOOL_SED} -e 's:@SYSCONFDIR@:/etc:g' -e 's:@DBDIR@:/var/db:g' \
-e 's:@LIBDIR@:/lib:g' \
-e 's:@RUNDIR@:/var/run:g' \
-e 's:@HOOKDIR@:/libexec/dhcpcd-hooks:g' \
-e 's:@SCRIPT@:/libexec/dhcpcd-run-hooks:g' \
-e 's:@SERVICEEXISTS@::g' \
-e 's:@SERVICECMD@::g' \
-e 's:@SERVICESTATUS@::g' \
${DIST}/${f}.in > $@
.endfor
.include <bsd.prog.mk>