syslogd(8) may not always be running before dhcpcd so any startup errors are

lost. Also, it's output with LOG_PERROR is ugly and LOG_PERROR isn't portable.

logger is a new function to solve the above which is identical to syslog(3)
but takes a dhcpcd_ctx for context so it functions in the RTEMS OS.
When writing to stdout/stderr or a given logfile, logger will convert %m
into the error string based on errno, just like syslog(3) does.
If your libc supports %m via printf, then define HAVE_PRINTF_M to remove
a fair chunk of code. There is no way of working out if your libc supports
this, especially in cross-compiled environment.
If the logfile is rotated, send dhcpcd a SIGUSR2 and the logfile will be
re-opened.

This does add about an exta 4K on 64-bit platforms so for size constraints
this can be compiled out by defining USE_LOGFILE to 0.
This commit is contained in:
Roy Marples 2015-03-17 23:46:38 +00:00
parent 30d2a5f522
commit 069e2f284f
32 changed files with 1242 additions and 953 deletions

25
arp.c
View File

@ -36,7 +36,6 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 5
@ -99,7 +98,7 @@ arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg
{
char buf[HWADDR_LEN * 3];
syslog(LOG_ERR, "%s: hardware address %s claims %s",
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));
@ -125,8 +124,8 @@ arp_packet(void *arg)
bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
arp_buffer, sizeof(arp_buffer), &flags);
if (bytes == -1) {
syslog(LOG_ERR, "%s: arp if_readrawpacket: %m",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: arp if_readrawpacket: %m", ifp->name);
dhcp_close(ifp);
return;
}
@ -184,7 +183,8 @@ arp_open(struct interface *ifp)
if (state->arp_fd == -1) {
state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
if (state->arp_fd == -1) {
syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
__func__, ifp->name);
return;
}
eloop_event_add(ifp->ctx->eloop, state->arp_fd,
@ -213,19 +213,19 @@ arp_announce1(void *arg)
struct interface *ifp = astate->iface;
if (++astate->claims < ANNOUNCE_NUM)
syslog(LOG_DEBUG,
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
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: ARP announcing %s (%d of %d)",
ifp->name, inet_ntoa(astate->addr),
astate->claims, ANNOUNCE_NUM);
if (arp_send(ifp, ARPOP_REQUEST,
astate->addr.s_addr, astate->addr.s_addr) == -1)
syslog(LOG_ERR, "send_arp: %m");
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);
@ -266,13 +266,13 @@ arp_probe1(void *arg)
tv.tv_nsec = 0;
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
}
syslog(LOG_DEBUG,
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_send(ifp, ARPOP_REQUEST, 0, astate->addr.s_addr) == -1)
syslog(LOG_ERR, "send_arp: %m");
logger(ifp->ctx, LOG_ERR, "send_arp: %m");
}
void
@ -281,12 +281,11 @@ arp_probe(struct arp_state *astate)
arp_open(astate->iface);
astate->probes = 0;
syslog(LOG_DEBUG, "%s: probing for %s",
logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s",
astate->iface->name, inet_ntoa(astate->addr));
arp_probe1(astate);
}
struct arp_state *
arp_new(struct interface *ifp) {
struct arp_state *astate;
@ -294,7 +293,7 @@ arp_new(struct interface *ifp) {
astate = calloc(1, sizeof(*astate));
if (astate == NULL) {
syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
return NULL;
}

1
auth.c
View File

@ -32,7 +32,6 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>

142
common.c
View File

@ -39,12 +39,14 @@
#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>
@ -54,6 +56,8 @@
#include <unistd.h>
#include "common.h"
#include "dhcpcd.h"
#include "if-options.h"
#ifndef _PATH_DEVNULL
# define _PATH_DEVNULL "/dev/null"
@ -94,7 +98,6 @@ get_monotonic(struct timespec *ts)
#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, ts);
return 0;
#elif defined(__APPLE__)
/* We can use mach kernel functions here.
* This is crap though - why can't they implement clock_gettime?*/
@ -126,7 +129,7 @@ get_monotonic(struct timespec *ts)
#if 0
/* Something above failed, so fall back to gettimeofday */
if (!posix_clock_set) {
syslog(LOG_WARNING, NO_MONOTONIC);
logger(NULL, LOG_WARNING, NO_MONOTONIC);
posix_clock_set = 1;
}
#endif
@ -141,8 +144,134 @@ get_monotonic(struct timespec *ts)
return -1;
}
#if USE_LOGFILE
void
logger_open(struct dhcpcd_ctx *ctx)
{
if (ctx->logfile) {
int f = O_CREAT | O_APPEND;
#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
serrno = errno;
va_start(va, fmt);
if (pri >= LOG_DEBUG && ctx && !(ctx->options & DHCPCD_DEBUG))
return;
#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(char ***e, const char *prefix, const char *var, const char *value)
setvar(struct dhcpcd_ctx *ctx,
char ***e, const char *prefix, const char *var, const char *value)
{
size_t len = strlen(var) + strlen(value) + 3;
@ -150,7 +279,7 @@ setvar(char ***e, const char *prefix, const char *var, const char *value)
len += strlen(prefix) + 1;
**e = malloc(len);
if (**e == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
if (prefix)
@ -162,12 +291,13 @@ setvar(char ***e, const char *prefix, const char *var, const char *value)
}
ssize_t
setvard(char ***e, const char *prefix, const char *var, size_t value)
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(e, prefix, var, buffer);
return setvar(ctx, e, prefix, var, buffer);
}

View File

@ -31,9 +31,11 @@
#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) */
@ -47,6 +49,7 @@
#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
@ -114,6 +117,9 @@
# 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
@ -124,6 +130,9 @@
# ifndef __packed
# define __packed
# endif
# ifndef __printflike
# define __printflike
# endif
# ifndef __unused
# define __unused
# endif
@ -145,8 +154,35 @@ void get_line_free(void);
const char *get_hostname(char *, size_t, int);
extern int clock_monotonic;
int get_monotonic(struct timespec *);
ssize_t setvar(char ***, const char *, const char *, const char *);
ssize_t setvard(char ***, const char *, const char *, size_t);
/* 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);
time_t uptime(void);
char *hwaddr_ntoa(const unsigned char *, size_t, char *, size_t);

View File

@ -33,7 +33,7 @@
#include "dprintf.h"
int
dprintf(int fd, const char *fmt, ...)
vdprintf(int fd, const char *fmt, va_list va)
{
int e;
FILE *fp;
@ -47,9 +47,19 @@ dprintf(int fd, const char *fmt, ...)
return -1;
}
va_start(va, fmt);
e = vfprintf(fp, fmt, va);
va_end(va);
fclose(fp);
return e;
}
int
dprintf(int fd, const char *fmt, ...)
{
int e;
va_start(va, fmt);
e = vdprintf(fd, fmt, va);
va_end(va);
return e;
}

View File

@ -28,5 +28,6 @@
#ifndef DPRINTF_H
#define DPRINTF_H
int dprintf(int, const char *, va_list);
int dprintf(int, const char *, ...);
#endif

23
configure vendored
View File

@ -916,29 +916,6 @@ pselect)
;;
esac
if [ -z "$LOG_PERROR" ]; then
printf "Testing for LOG_PERROR ... "
cat <<EOF >_log_perror.c
#include <syslog.h>
int main(void) {
openlog("test", LOG_PERROR, LOG_DAEMON);
return 0;
}
EOF
if $XCC _log_perror.c -o _log_perror 2>&3; then
LOG_PERROR=yes
else
LOG_PERROR=no
fi
echo "$LOG_PERROR"
rm -f _log_perror.c _log_perror
fi
if [ "$LOG_PERROR" = no ]; then
echo "COMPAT_SRCS+= compat/psyslog.c" >>$CONFIG_MK
echo "#include \"compat/psyslog.h\"" >>$CONFIG_H
echo "#define syslog psyslog" >>$CONFIG_H
fi
if [ -z "$BE64ENC" ]; then
printf "Testing for be64enc ... "
cat <<EOF >_be64enc.c

View File

@ -35,7 +35,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
@ -140,7 +139,8 @@ control_handle_data(void *arg)
}
*ap = NULL;
if (dhcpcd_handleargs(fd->ctx, fd, argc, argvp) == -1) {
syslog(LOG_ERR, "%s: dhcpcd_handleargs: %m", __func__);
logger(fd->ctx, LOG_ERR,
"%s: dhcpcd_handleargs: %m", __func__);
if (errno != EINTR && errno != EAGAIN) {
control_delete(fd);
return;
@ -384,7 +384,8 @@ control_writeone(void *arg)
iov[1].iov_base = data->data;
iov[1].iov_len = data->data_len;
if (writev(fd->fd, iov, 2) == -1) {
syslog(LOG_ERR, "%s: writev fd %d: %m", __func__, fd->fd);
logger(fd->ctx, LOG_ERR,
"%s: writev fd %d: %m", __func__, fd->fd);
if (errno != EINTR && errno != EAGAIN)
control_delete(fd);
return;

2
defs.h
View File

@ -28,7 +28,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "6.7.99.4"
#define VERSION "6.7.99.5"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"

19
dev.c
View File

@ -29,7 +29,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#define _INDEV
#include "common.h"
@ -61,7 +60,8 @@ dev_stop1(struct dhcpcd_ctx *ctx, int stop)
if (ctx->dev) {
if (stop)
syslog(LOG_DEBUG, "dev: unloaded %s", ctx->dev->name);
logger(ctx, LOG_DEBUG,
"dev: unloaded %s", ctx->dev->name);
eloop_event_delete(ctx->eloop, ctx->dev_fd, 0);
ctx->dev->stop();
free(ctx->dev);
@ -93,13 +93,13 @@ dev_start2(struct dhcpcd_ctx *ctx, const char *name)
snprintf(file, sizeof(file), DEVDIR "/%s", name);
h = dlopen(file, RTLD_LAZY);
if (h == NULL) {
syslog(LOG_ERR, "dlopen: %s", dlerror());
logger(ctx, LOG_ERR, "dlopen: %s", dlerror());
return -1;
}
fptr = (void (*)(struct dev *, const struct dev_dhcpcd *))
dlsym(h, "dev_init");
if (fptr == NULL) {
syslog(LOG_ERR, "dlsym: %s", dlerror());
logger(ctx, LOG_ERR, "dlsym: %s", dlerror());
dlclose(h);
return -1;
}
@ -112,7 +112,7 @@ dev_start2(struct dhcpcd_ctx *ctx, const char *name)
dlclose(h);
return -1;
}
syslog(LOG_INFO, "dev: loaded %s", ctx->dev->name);
logger(ctx, LOG_INFO, "dev: loaded %s", ctx->dev->name);
ctx->dev_handle = h;
return r;
}
@ -125,7 +125,7 @@ dev_start1(struct dhcpcd_ctx *ctx)
int r;
if (ctx->dev) {
syslog(LOG_ERR, "dev: already started %s", ctx->dev->name);
logger(ctx, LOG_ERR, "dev: already started %s", ctx->dev->name);
return -1;
}
@ -134,7 +134,7 @@ dev_start1(struct dhcpcd_ctx *ctx)
dp = opendir(DEVDIR);
if (dp == NULL) {
syslog(LOG_DEBUG, "dev: %s: %m", DEVDIR);
logger(ctx, LOG_DEBUG, "dev: %s: %m", DEVDIR);
return 0;
}
@ -167,7 +167,7 @@ dev_start(struct dhcpcd_ctx *ctx)
{
if (ctx->dev_fd != -1) {
syslog(LOG_ERR, "%s: already started on fd %d", __func__,
logger(ctx, LOG_ERR, "%s: already started on fd %d", __func__,
ctx->dev_fd);
return ctx->dev_fd;
}
@ -177,7 +177,8 @@ dev_start(struct dhcpcd_ctx *ctx)
if (eloop_event_add(ctx->eloop,
ctx->dev_fd, dev_handle_data, ctx, NULL, NULL) == -1)
{
syslog(LOG_ERR, "%s: eloop_event_add: %m", __func__);
logger(ctx, LOG_ERR,
"%s: eloop_event_add: %m", __func__);
dev_stop1(ctx, 1);
return -1;
}

View File

@ -33,7 +33,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
@ -764,7 +763,7 @@ dhcp_set_leasefile(char *leasefile, size_t len, int family,
}
static size_t
dhcp_envoption1(char **env, const char *prefix,
dhcp_envoption1(struct dhcpcd_ctx *ctx, char **env, const char *prefix,
const struct dhcp_opt *opt, int vname, const uint8_t *od, size_t ol,
const char *ifname)
{
@ -788,7 +787,7 @@ dhcp_envoption1(char **env, const char *prefix,
return e;
v = val = *env = malloc(e);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return 0;
}
if (vname)
@ -817,7 +816,7 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, char **env, const char *prefix,
/* If no embedded or encapsulated options, it's easy */
if (opt->embopts_len == 0 && opt->encopts_len == 0) {
if (dhcp_envoption1(env == NULL ? NULL : &env[0],
if (dhcp_envoption1(ctx, env == NULL ? NULL : &env[0],
prefix, opt, 1, od, ol, ifname))
return 1;
return 0;
@ -828,7 +827,7 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, char **env, const char *prefix,
if (opt->type & INDEX) {
if (opt->index > 999) {
errno = ENOBUFS;
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return 0;
}
}
@ -836,7 +835,7 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, char **env, const char *prefix,
(opt->type & INDEX ? 3 : 0);
pfx = malloc(e);
if (pfx == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return 0;
}
if (opt->type & INDEX)
@ -859,7 +858,7 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, char **env, const char *prefix,
* name is different.
* This avoids new_fqdn_fqdn which would be silly. */
ov = strcmp(opt->var, eopt->var);
if (dhcp_envoption1(env == NULL ? NULL : &env[n],
if (dhcp_envoption1(ctx, env == NULL ? NULL : &env[n],
pfx, eopt, ov, od, e, ifname))
n++;
od += e;

441
dhcp.c

File diff suppressed because it is too large Load Diff

353
dhcp6.c
View File

@ -38,7 +38,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 4
@ -182,7 +181,8 @@ dhcp6_makevendor(struct dhcp6_option *o, const struct interface *ifp)
}
if (len > UINT16_MAX) {
syslog(LOG_ERR, "%s: DHCPv6 Vendor Class too big", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: DHCPv6 Vendor Class too big", ifp->name);
return 0;
}
@ -401,7 +401,7 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
state = D6_STATE(ifp);
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
@ -466,9 +466,10 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
{
sa = inet_ntop(AF_INET6, &prefix->prefix,
sabuf, sizeof(sabuf));
syslog(LOG_ERR, "%s: invalid prefix %s/%d + %d/%d: %m",
ifp->name, sa, prefix->prefix_len,
sla->sla, sla->prefix_len);
logger(ifp->ctx, LOG_ERR,
"%s: invalid prefix %s/%d + %d/%d: %m",
ifp->name, sa, prefix->prefix_len,
sla->sla, sla->prefix_len);
return -1;
}
@ -477,7 +478,8 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
{
sa = inet_ntop(AF_INET6, &prefix->prefix_exclude,
sabuf, sizeof(sabuf));
syslog(LOG_ERR, "%s: cannot delegate excluded prefix %s/%d",
logger(ifp->ctx, LOG_ERR,
"%s: cannot delegate excluded prefix %s/%d",
ifp->name, sa, prefix->prefix_exclude_len);
return -1;
}
@ -703,8 +705,8 @@ dhcp6_makemessage(struct interface *ifp)
auth_len = (size_t)dhcp_auth_encode(&ifo->auth,
state->auth.token, NULL, 0, 6, type, NULL, 0);
if ((ssize_t)auth_len == -1) {
syslog(LOG_ERR, "%s: dhcp_auth_encode: %m",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp_auth_encode: %m", ifp->name);
auth_len = 0;
} else if (auth_len != 0)
len += sizeof(*o) + auth_len;
@ -1020,7 +1022,8 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
}
if (!callback)
syslog(LOG_DEBUG, "%s: %s %s with xid 0x%02x%02x%02x",
logger(ifp->ctx, LOG_DEBUG,
"%s: %s %s with xid 0x%02x%02x%02x",
ifp->name,
broad_uni,
dhcp6_get_op(state->send->type),
@ -1083,7 +1086,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
}
logsend:
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: %s %s (xid 0x%02x%02x%02x),"
" next in %0.1f seconds",
ifp->name,
@ -1108,7 +1111,8 @@ logsend:
if (ifp->options->auth.options & DHCPCD_AUTH_SEND &&
dhcp6_update_auth(ifp, state->send, state->send_len) == -1)
{
syslog(LOG_ERR, "%s: dhcp6_updateauth: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_updateauth: %m", ifp->name);
if (errno != ESRCH)
return -1;
}
@ -1131,7 +1135,8 @@ logsend:
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
if (sendmsg(ctx->dhcp_fd, &ctx->sndhdr, 0) == -1) {
syslog(LOG_ERR, "%s: %s: sendmsg: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR,
"%s: %s: sendmsg: %m", ifp->name, __func__);
ifp->options->options &= ~DHCPCD_IPV6;
dhcp6_drop(ifp, "EXPIRE6");
return -1;
@ -1146,7 +1151,8 @@ logsend:
eloop_timeout_add_tv(ifp->ctx->eloop,
&state->RT, state->MRCcallback, ifp);
else
syslog(LOG_WARNING, "%s: sent %d times with no reply",
logger(ifp->ctx, LOG_WARNING,
"%s: sent %d times with no reply",
ifp->name, state->RTC);
}
return 0;
@ -1219,7 +1225,8 @@ dhcp6_startrenew(void *arg)
state->MRC = 0;
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
else
dhcp6_sendrenew(ifp);
}
@ -1255,7 +1262,7 @@ dhcp6_dadcallback(void *arg)
if (ap->flags & IPV6_AF_DUPLICATED)
/* XXX FIXME
* We should decline the address */
syslog(LOG_WARNING, "%s: DAD detected %s",
logger(ap->iface->ctx, LOG_WARNING, "%s: DAD detected %s",
ap->iface->name, ap->saddr);
if (!wascompleted) {
@ -1276,8 +1283,8 @@ dhcp6_dadcallback(void *arg)
}
}
if (!wascompleted) {
syslog(LOG_DEBUG, "%s: DHCPv6 DAD completed",
ifp->name);
logger(ap->iface->ctx, LOG_DEBUG,
"%s: DHCPv6 DAD completed", ifp->name);
script_runreason(ifp,
ap->delegating_iface ?
"DELEGATED6" : state->reason);
@ -1307,7 +1314,7 @@ dhcp6_addrequestedaddrs(struct interface *ifp)
continue;
a = calloc(1, sizeof(*a));
if (a == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
a->flags = IPV6_AF_REQUEST;
@ -1351,7 +1358,7 @@ dhcp6_startdiscover(void *arg)
ifp = arg;
dhcp6_delete_delegates(ifp);
syslog(LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name);
logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name);
state = D6_STATE(ifp);
state->state = DH6S_DISCOVER;
state->start_uptime = uptime();
@ -1372,7 +1379,8 @@ dhcp6_startdiscover(void *arg)
dhcp6_addrequestedaddrs(ifp);
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
else
dhcp6_senddiscover(ifp);
}
@ -1383,7 +1391,8 @@ dhcp6_failconfirm(void *arg)
struct interface *ifp;
ifp = arg;
syslog(LOG_ERR, "%s: failed to confirm prior address", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: failed to confirm prior address", ifp->name);
/* Section 18.1.2 says that we SHOULD use the last known
* IP address(s) and lifetimes if we didn't get a reply.
* I disagree with this. */
@ -1396,7 +1405,7 @@ dhcp6_failrequest(void *arg)
struct interface *ifp;
ifp = arg;
syslog(LOG_ERR, "%s: failed to request address", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: failed to request address", ifp->name);
/* Section 18.1.1 says that client local policy dictates
* what happens if a REQUEST fails.
* Of the possible scenarios listed, moving back to the
@ -1410,7 +1419,8 @@ dhcp6_failrebind(void *arg)
struct interface *ifp;
ifp = arg;
syslog(LOG_ERR, "%s: failed to rebind prior delegation", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: failed to rebind prior delegation", ifp->name);
dhcp6_delete_delegates(ifp);
/* Section 18.1.2 says that we SHOULD use the last known
* IP address(s) and lifetimes if we didn't get a reply.
@ -1451,11 +1461,11 @@ dhcp6_startrebind(void *arg)
eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrenew, ifp);
state = D6_STATE(ifp);
if (state->state == DH6S_RENEW)
syslog(LOG_WARNING, "%s: failed to renew DHCPv6, rebinding",
ifp->name);
logger(ifp->ctx, LOG_WARNING,
"%s: failed to renew DHCPv6, rebinding", ifp->name);
else
syslog(LOG_INFO, "%s: rebinding prior DHCPv6 lease",
ifp->name);
logger(ifp->ctx, LOG_INFO,
"%s: rebinding prior DHCPv6 lease", ifp->name);
state->state = DH6S_REBIND;
state->RTC = 0;
state->MRC = 0;
@ -1472,7 +1482,8 @@ dhcp6_startrebind(void *arg)
}
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
else
dhcp6_sendrebind(ifp);
@ -1498,7 +1509,8 @@ dhcp6_startrequest(struct interface *ifp)
state->MRCcallback = dhcp6_failrequest;
if (dhcp6_makemessage(ifp) == -1) {
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
return;
}
@ -1519,9 +1531,11 @@ dhcp6_startconfirm(struct interface *ifp)
state->MRT = CNF_MAX_RT;
state->MRC = 0;
syslog(LOG_INFO, "%s: confirming prior DHCPv6 lease", ifp->name);
logger(ifp->ctx, LOG_INFO,
"%s: confirming prior DHCPv6 lease", ifp->name);
if (dhcp6_makemessage(ifp) == -1) {
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
return;
}
dhcp6_sendconfirm(ifp);
@ -1538,8 +1552,8 @@ dhcp6_startinform(void *arg)
ifp = arg;
state = D6_STATE(ifp);
if (state->new == NULL || ifp->options->options & DHCPCD_DEBUG)
syslog(LOG_INFO, "%s: requesting DHCPv6 information",
ifp->name);
logger(ifp->ctx, LOG_INFO,
"%s: requesting DHCPv6 information", ifp->name);
state->state = DH6S_INFORM;
state->start_uptime = uptime();
state->RTC = 0;
@ -1549,7 +1563,8 @@ dhcp6_startinform(void *arg)
state->MRC = 0;
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
else
dhcp6_sendinform(ifp);
}
@ -1562,16 +1577,15 @@ dhcp6_startexpire(void *arg)
ifp = arg;
eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrebind, ifp);
syslog(LOG_ERR, "%s: DHCPv6 lease expired", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 lease expired", ifp->name);
dhcp6_freedrop_addrs(ifp, 1, NULL);
dhcp6_delete_delegates(ifp);
script_runreason(ifp, "EXPIRE6");
if (ipv6nd_hasradhcp(ifp) || dhcp6_hasprefixdelegation(ifp))
dhcp6_startdiscover(ifp);
else
syslog(LOG_WARNING,
"%s: no advertising IPv6 router wants DHCP",
ifp->name);
logger(ifp->ctx, LOG_WARNING,
"%s: no advertising IPv6 router wants DHCP", ifp->name);
}
static void
@ -1593,7 +1607,8 @@ dhcp6_startrelease(struct interface *ifp)
state->MRCcallback = NULL;
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_makemessage: %m", ifp->name);
else
/* XXX: We should loop a few times
* Luckily RFC3315 section 18.1.6 says this is optional */
@ -1614,13 +1629,13 @@ dhcp6_checkstatusok(const struct interface *ifp,
else
o = dhcp6_getmoption(D6_OPTION_STATUS_CODE, m, len);
if (o == NULL) {
//syslog(LOG_DEBUG, "%s: no status", ifp->name);
//logger(ifp->ctx, LOG_DEBUG, "%s: no status", ifp->name);
return 0;
}
len = ntohs(o->len);
if (len < sizeof(code)) {
syslog(LOG_ERR, "%s: status truncated", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: status truncated", ifp->name);
return -1;
}
@ -1643,13 +1658,13 @@ dhcp6_checkstatusok(const struct interface *ifp,
status = malloc(len + 1);
if (status == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
if (p)
memcpy(status, p, len);
status[len] = '\0';
syslog(LOG_ERR, "%s: DHCPv6 REPLY: %s", ifp->name, status);
logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 REPLY: %s", ifp->name, status);
free(status);
return -1;
}
@ -1718,8 +1733,8 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
d += sizeof(*o) + u32;
if (u32 < 24) {
errno = EINVAL;
syslog(LOG_ERR, "%s: IA Address option truncated",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: IA Address option truncated", ifp->name);
continue;
}
iap = (const struct dhcp6_ia_addr *)D6_COPTION_DATA(o);
@ -1727,7 +1742,7 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
if (a == NULL) {
a = calloc(1, sizeof(*a));
if (a == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
break;
}
a->iface = ifp;
@ -1801,8 +1816,8 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
d += sizeof(*o) + ol;
if (ol < sizeof(*pdp)) {
errno = EINVAL;
syslog(LOG_ERR, "%s: IA Prefix option truncated",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: IA Prefix option truncated", ifp->name);
continue;
}
@ -1814,7 +1829,7 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
if (a == NULL) {
a = calloc(1, sizeof(*a));
if (a == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
break;
}
a->iface = ifp;
@ -1870,8 +1885,8 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
continue;
ol = ntohs(ex->len);
if (ol < 2) {
syslog(LOG_ERR, "%s: truncated PD Exclude",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: truncated PD Exclude", ifp->name);
continue;
}
op = D6_COPTION_DATA(ex);
@ -1880,8 +1895,8 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
if (((a->prefix_exclude_len - a->prefix_len - 1) / NBBY) + 1
!= ol)
{
syslog(LOG_ERR, "%s: PD Exclude length mismatch",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: PD Exclude length mismatch", ifp->name);
a->prefix_exclude_len = 0;
continue;
}
@ -1934,7 +1949,8 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
ol = ntohs(o->len);
if (sizeof(*o) + ol > l) {
errno = EINVAL;
syslog(LOG_ERR, "%s: option overflow", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: option overflow", ifp->name);
break;
}
l -= sizeof(*o) + ol;
@ -1953,7 +1969,8 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
}
if (ol < u32) {
errno = EINVAL;
syslog(LOG_ERR, "%s: IA option truncated", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: IA option truncated", ifp->name);
continue;
}
@ -1969,13 +1986,15 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
if (j == ifo->ia_len &&
!(ifo->ia_len == 0 && ifp->ctx->options & DHCPCD_DUMPLEASE))
{
syslog(LOG_DEBUG, "%s: ignoring unrequested IAID %s",
logger(ifp->ctx, LOG_DEBUG,
"%s: ignoring unrequested IAID %s",
ifp->name,
hwaddr_ntoa(iaid, sizeof(iaid), buf, sizeof(buf)));
continue;
}
if ( j < ifo->ia_len && ifo->ia[j].ia_type != code) {
syslog(LOG_ERR, "%s: IAID %s: option type mismatch",
logger(ifp->ctx, LOG_ERR,
"%s: IAID %s: option type mismatch",
ifp->name,
hwaddr_ntoa(iaid, sizeof(iaid), buf, sizeof(buf)));
continue;
@ -2000,7 +2019,7 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
if (!(ifo->options & DHCPCD_NOPFXDLG) &&
dhcp6_findpd(ifp, iaid, p, ol, acquired) == 0)
{
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: %s: DHCPv6 REPLY missing Prefix",
ifp->name, sfrom);
continue;
@ -2008,7 +2027,7 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
} else if (!(ifo->options & DHCPCD_PFXDLGONLY)) {
if (dhcp6_findna(ifp, code, iaid, p, ol, acquired) == 0)
{
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: %s: DHCPv6 REPLY missing IA Address",
ifp->name, sfrom);
continue;
@ -2017,7 +2036,7 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
if (code != D6_OPTION_IA_TA) {
if (renew > rebind && rebind > 0) {
if (sfrom)
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: T1 (%d) > T2 (%d) from %s",
ifp->name, renew, rebind, sfrom);
renew = 0;
@ -2058,7 +2077,8 @@ dhcp6_validatelease(struct interface *ifp,
struct timespec aq;
if (len <= sizeof(*m)) {
syslog(LOG_ERR, "%s: DHCPv6 lease truncated", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: DHCPv6 lease truncated", ifp->name);
return -1;
}
@ -2074,8 +2094,8 @@ dhcp6_validatelease(struct interface *ifp,
}
nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
if (nia == 0) {
syslog(LOG_ERR, "%s: no useable IA found in lease",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: no useable IA found in lease", ifp->name);
return -1;
}
return nia;
@ -2089,12 +2109,12 @@ dhcp6_writelease(const struct interface *ifp)
ssize_t bytes;
state = D6_CSTATE(ifp);
syslog(LOG_DEBUG, "%s: writing lease `%s'",
ifp->name, state->leasefile);
logger(ifp->ctx, LOG_DEBUG,
"%s: writing lease `%s'", ifp->name, state->leasefile);
fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
syslog(LOG_ERR, "%s: dhcp6_writelease: %m", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: dhcp6_writelease: %m", ifp->name);
return -1;
}
bytes = write(fd, state->new, state->new_len);
@ -2117,36 +2137,36 @@ dhcp6_readlease(struct interface *ifp)
if (stat(state->leasefile, &st) == -1) {
if (errno == ENOENT)
return 0;
syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
return -1;
}
syslog(LOG_DEBUG, "%s: reading lease `%s'",
logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
ifp->name, state->leasefile);
if (st.st_size > UINT32_MAX) {
syslog(LOG_ERR, "%s: file too big", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: file too big", ifp->name);
return -1;
}
state->new = malloc((size_t)st.st_size);
if (state->new == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
state->new_len = (size_t)st.st_size;
fd = open(state->leasefile, O_RDONLY);
if (fd == -1) {
syslog(LOG_ERR, "%s: %s: %s: %m", ifp->name, __func__,
state->leasefile);
logger(ifp->ctx, LOG_ERR, "%s: %s: %s: %m",
ifp->name, __func__, state->leasefile);
return -1;
}
bytes = read(fd, state->new, state->new_len);
close(fd);
if (bytes != (ssize_t)state->new_len) {
syslog(LOG_ERR, "%s: read: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: read: %m", __func__);
goto ex;
}
if ((now = time(NULL)) == -1) {
syslog(LOG_ERR, "%s: time: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: time: %m", __func__);
goto ex;
}
@ -2163,7 +2183,8 @@ dhcp6_readlease(struct interface *ifp)
state->expire != ND6_INFINITE_LIFETIME)
{
if ((time_t)state->expire < now - st.st_mtime) {
syslog(LOG_DEBUG,"%s: discarding expired lease",
logger(ifp->ctx,
LOG_DEBUG,"%s: discarding expired lease",
ifp->name);
goto ex;
}
@ -2176,20 +2197,22 @@ dhcp6_readlease(struct interface *ifp)
(uint8_t *)state->new, state->new_len, 6, state->new->type,
D6_COPTION_DATA(o), ntohs(o->len)) == NULL)
{
syslog(LOG_DEBUG, "%s: dhcp_auth_validate: %m",
ifp->name);
syslog(LOG_ERR, "%s: authentication failed",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: dhcp_auth_validate: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: authentication failed", ifp->name);
goto ex;
}
if (state->auth.token)
syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
logger(ifp->ctx, LOG_DEBUG,
"%s: validated using 0x%08" PRIu32,
ifp->name, state->auth.token->secretid);
else
syslog(LOG_DEBUG, "%s: accepted reconfigure key",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: accepted reconfigure key", ifp->name);
} else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) {
syslog(LOG_ERR, "%s: authentication now required", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: authentication now required", ifp->name);
goto ex;
}
@ -2237,8 +2260,8 @@ dhcp6_startinit(struct interface *ifp)
{
r = dhcp6_readlease(ifp);
if (r == -1)
syslog(LOG_ERR, "%s: dhcp6_readlease: %s: %m",
ifp->name, state->leasefile);
logger(ifp->ctx, LOG_ERR, "%s: dhcp6_readlease: %s: %m",
ifp->name, state->leasefile);
else if (r != 0) {
/* RFC 3633 section 12.1 */
if (dhcp6_hasprefixdelegation(ifp))
@ -2267,7 +2290,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
if (prefix->prefix_exclude_len == 0) {
/* Don't spam the log automatically */
if (sla)
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: DHCPv6 server does not support "
"OPTION_PD_EXCLUDE",
ifp->name);
@ -2282,7 +2305,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
a = calloc(1, sizeof(*a));
if (a == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
a->iface = ifp;
@ -2355,9 +2378,8 @@ dhcp6_script_try_run(struct interface *ifp, int delegated)
if (!delegated)
dhcpcd_daemonise(ifp->ctx);
} else
syslog(LOG_DEBUG,
"%s: waiting for DHCPv6 DAD to complete",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: waiting for DHCPv6 DAD to complete", ifp->name);
}
static void
@ -2386,11 +2408,11 @@ dhcp6_delegate_prefix(struct interface *ifp)
if (j >= i &&
if_find(ifp->ctx, sla->ifname) == NULL)
{
syslog(LOG_INFO,
logger(ifp->ctx, LOG_INFO,
"%s: loading for delegation", sla->ifname);
if (dhcpcd_handleinterface(ifp->ctx, 2,
sla->ifname) == -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: interface does not exist"
" for delegation",
sla->ifname);
@ -2408,7 +2430,8 @@ dhcp6_delegate_prefix(struct interface *ifp)
continue;
if (ap->flags & IPV6_AF_NEW) {
ap->flags &= ~IPV6_AF_NEW;
syslog(LOG_DEBUG, "%s: delegated prefix %s",
logger(ifp->ctx, LOG_DEBUG,
"%s: delegated prefix %s",
ifp->name, ap->saddr);
}
for (i = 0; i < ifo->ia_len; i++) {
@ -2420,7 +2443,7 @@ dhcp6_delegate_prefix(struct interface *ifp)
/* no SLA configured, so lets
* automate it */
if (ifd->carrier != LINK_UP) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: has no carrier, cannot"
" delegate addresses",
ifd->name);
@ -2439,7 +2462,7 @@ dhcp6_delegate_prefix(struct interface *ifp)
if (strcmp(ifd->name, sla->ifname))
continue;
if (ifd->carrier != LINK_UP) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: has no carrier, cannot"
" delegate addresses",
ifd->name);
@ -2501,7 +2524,7 @@ dhcp6_find_delegates(struct interface *ifp)
if (strcmp(ifp->name, sla->ifname))
continue;
if (ipv6_linklocal(ifp) == NULL) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: delaying adding"
" delegated addresses for"
" LL address",
@ -2519,7 +2542,8 @@ dhcp6_find_delegates(struct interface *ifp)
}
if (k) {
syslog(LOG_INFO, "%s: adding delegated prefixes", ifp->name);
logger(ifp->ctx, LOG_INFO,
"%s: adding delegated prefixes", ifp->name);
state = D6_STATE(ifp);
state->state = DH6S_DELEGATED;
ipv6_addaddrs(&state->addrs);
@ -2551,7 +2575,7 @@ dhcp6_findpfxdlgif(struct interface *ifp)
static void
dhcp6_handledata(void *arg)
{
struct dhcpcd_ctx *dhcpcd_ctx;
struct dhcpcd_ctx *dctx;
struct ipv6_ctx *ctx;
size_t i, len;
ssize_t bytes;
@ -2569,14 +2593,14 @@ dhcp6_handledata(void *arg)
int error;
uint32_t u32;
dhcpcd_ctx = arg;
ctx = dhcpcd_ctx->ipv6;
dctx = arg;
ctx = dctx->ipv6;
ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
bytes = recvmsg(ctx->dhcp_fd, &ctx->rcvhdr, 0);
if (bytes == -1) {
syslog(LOG_ERR, "recvmsg: %m");
logger(dctx, LOG_ERR, "%s: recvmsg: %m", __func__);
close(ctx->dhcp_fd);
eloop_event_delete(dhcpcd_ctx->eloop, ctx->dhcp_fd, 0);
eloop_event_delete(dctx->eloop, ctx->dhcp_fd, 0);
ctx->dhcp_fd = -1;
return;
}
@ -2584,8 +2608,8 @@ dhcp6_handledata(void *arg)
ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
ctx->ntopbuf, sizeof(ctx->ntopbuf));
if (len < sizeof(struct dhcp6_message)) {
syslog(LOG_ERR, "DHCPv6 packet too short from %s",
ctx->sfrom);
logger(dctx, LOG_ERR,
"DHCPv6 packet too short from %s", ctx->sfrom);
return;
}
@ -2605,18 +2629,17 @@ dhcp6_handledata(void *arg)
}
if (pkt.ipi6_ifindex == 0) {
syslog(LOG_ERR,
"DHCPv6 reply did not contain index from %s",
ctx->sfrom);
logger(dctx, LOG_ERR,
"DHCPv6 reply did not contain index from %s", ctx->sfrom);
return;
}
TAILQ_FOREACH(ifp, dhcpcd_ctx->ifaces, next) {
TAILQ_FOREACH(ifp, dctx->ifaces, next) {
if (ifp->index == (unsigned int)pkt.ipi6_ifindex)
break;
}
if (ifp == NULL) {
syslog(LOG_DEBUG,
logger(dctx, LOG_DEBUG,
"DHCPv6 reply for unexpected interface from %s",
ctx->sfrom);
return;
@ -2636,8 +2659,8 @@ dhcp6_handledata(void *arg)
state = D6_STATE(ifp);
if (state == NULL || state->send == NULL) {
syslog(LOG_DEBUG, "%s: DHCPv6 reply received but not running",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: DHCPv6 reply received but not running", ifp->name);
return;
}
/* We're already bound and this message is for another machine */
@ -2651,7 +2674,7 @@ dhcp6_handledata(void *arg)
r->xid[1] != state->send->xid[1] ||
r->xid[2] != state->send->xid[2]))
{
syslog(LOG_DEBUG,
logger(dctx, LOG_DEBUG,
"%s: wrong xid 0x%02x%02x%02x"
" (expecting 0x%02x%02x%02x) from %s",
ifp->name,
@ -2663,30 +2686,29 @@ dhcp6_handledata(void *arg)
}
if (dhcp6_getmoption(D6_OPTION_SERVERID, r, len) == NULL) {
syslog(LOG_DEBUG, "%s: no DHCPv6 server ID from %s",
logger(ifp->ctx, LOG_DEBUG, "%s: no DHCPv6 server ID from %s",
ifp->name, ctx->sfrom);
return;
}
o = dhcp6_getmoption(D6_OPTION_CLIENTID, r, len);
if (o == NULL || ntohs(o->len) != dhcpcd_ctx->duid_len ||
memcmp(D6_COPTION_DATA(o),
dhcpcd_ctx->duid, dhcpcd_ctx->duid_len) != 0)
if (o == NULL || ntohs(o->len) != dctx->duid_len ||
memcmp(D6_COPTION_DATA(o), dctx->duid, dctx->duid_len) != 0)
{
syslog(LOG_DEBUG, "%s: incorrect client ID from %s",
logger(ifp->ctx, LOG_DEBUG, "%s: incorrect client ID from %s",
ifp->name, ctx->sfrom);
return;
}
ifo = ifp->options;
for (i = 0, opt = dhcpcd_ctx->dhcp6_opts;
i < dhcpcd_ctx->dhcp6_opts_len;
for (i = 0, opt = dctx->dhcp6_opts;
i < dctx->dhcp6_opts_len;
i++, opt++)
{
if (has_option_mask(ifo->requiremask6, opt->option) &&
dhcp6_getmoption(opt->option, r, len) == NULL)
{
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: reject DHCPv6 (no option %s) from %s",
ifp->name, opt->var, ctx->sfrom);
return;
@ -2694,7 +2716,7 @@ dhcp6_handledata(void *arg)
if (has_option_mask(ifo->rejectmask6, opt->option) &&
dhcp6_getmoption(opt->option, r, len))
{
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: reject DHCPv6 (option %s) from %s",
ifp->name, opt->var, ctx->sfrom);
return;
@ -2708,25 +2730,26 @@ dhcp6_handledata(void *arg)
(uint8_t *)r, len, 6, r->type,
D6_COPTION_DATA(auth), ntohs(auth->len)) == NULL)
{
syslog(LOG_DEBUG, "dhcp_auth_validate: %m");
syslog(LOG_ERR, "%s: authentication failed from %s",
logger(ifp->ctx, LOG_DEBUG, "dhcp_auth_validate: %m");
logger(ifp->ctx, LOG_ERR,
"%s: authentication failed from %s",
ifp->name, ctx->sfrom);
return;
}
if (state->auth.token)
syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
logger(ifp->ctx, LOG_DEBUG,
"%s: validated using 0x%08" PRIu32,
ifp->name, state->auth.token->secretid);
else
syslog(LOG_DEBUG, "%s: accepted reconfigure key",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: accepted reconfigure key", ifp->name);
} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
syslog(LOG_ERR, "%s: no authentication from %s",
ifp->name, ctx->sfrom);
logger(ifp->ctx, LOG_ERR,
"%s: no authentication from %s", ifp->name, ctx->sfrom);
return;
} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
syslog(LOG_WARNING,
"%s: no authentication from %s",
ifp->name, ctx->sfrom);
logger(ifp->ctx, LOG_WARNING,
"%s: no authentication from %s", ifp->name, ctx->sfrom);
op = dhcp6_get_op(r->type);
switch(r->type) {
@ -2796,12 +2819,13 @@ dhcp6_handledata(void *arg)
memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32));
u32 = ntohl(u32);
if (u32 >= 60 && u32 <= 86400) {
syslog(LOG_DEBUG, "%s: SOL_MAX_RT %llu -> %d",
ifp->name,
logger(ifp->ctx, LOG_DEBUG,
"%s: SOL_MAX_RT %llu -> %d", ifp->name,
(unsigned long long)state->sol_max_rt, u32);
state->sol_max_rt = (time_t)u32;
} else
syslog(LOG_ERR, "%s: invalid SOL_MAX_RT %d",
logger(ifp->ctx, LOG_ERR,
"%s: invalid SOL_MAX_RT %d",
ifp->name, u32);
}
o = dhcp6_getmoption(D6_OPTION_INF_MAX_RT, r, len);
@ -2809,12 +2833,14 @@ dhcp6_handledata(void *arg)
memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32));
u32 = ntohl(u32);
if (u32 >= 60 && u32 <= 86400) {
syslog(LOG_DEBUG, "%s: INF_MAX_RT %llu -> %d",
logger(ifp->ctx, LOG_DEBUG,
"%s: INF_MAX_RT %llu -> %d",
ifp->name,
(unsigned long long)state->inf_max_rt, u32);
state->inf_max_rt = (time_t)u32;
} else
syslog(LOG_ERR, "%s: invalid INF_MAX_RT %d",
logger(ifp->ctx, LOG_ERR,
"%s: invalid INF_MAX_RT %d",
ifp->name, u32);
}
if (dhcp6_validatelease(ifp, r, len, ctx->sfrom, NULL) == -1)
@ -2822,30 +2848,29 @@ dhcp6_handledata(void *arg)
break;
case DHCP6_RECONFIGURE:
if (auth == NULL) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: unauthenticated %s from %s",
ifp->name, op, ctx->sfrom);
return;
}
syslog(LOG_INFO, "%s: %s from %s",
logger(ifp->ctx, LOG_INFO, "%s: %s from %s",
ifp->name, op, ctx->sfrom);
o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len);
if (o == NULL) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: missing Reconfigure Message option",
ifp->name);
return;
}
if (ntohs(o->len) != 1) {
syslog(LOG_ERR,
"%s: missing Reconfigure Message type",
ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: missing Reconfigure Message type", ifp->name);
return;
}
switch(*D6_COPTION_DATA(o)) {
case DHCP6_RENEW:
if (state->state != DH6S_BOUND) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: not bound, ignoring %s",
ifp->name, op);
return;
@ -2856,7 +2881,7 @@ dhcp6_handledata(void *arg)
break;
case DHCP6_INFORMATION_REQ:
if (state->state != DH6S_INFORMED) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: not informed, ignoring %s",
ifp->name, op);
return;
@ -2866,19 +2891,20 @@ dhcp6_handledata(void *arg)
dhcp6_startinform(ifp);
break;
default:
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: unsupported %s type %d",
ifp->name, op, *D6_COPTION_DATA(o));
break;
}
return;
default:
syslog(LOG_ERR, "%s: invalid DHCP6 type %s (%d)",
logger(ifp->ctx, LOG_ERR, "%s: invalid DHCP6 type %s (%d)",
ifp->name, op, r->type);
return;
}
if (op == NULL) {
syslog(LOG_WARNING, "%s: invalid state for DHCP6 type %s (%d)",
logger(ifp->ctx, LOG_WARNING,
"%s: invalid state for DHCP6 type %s (%d)",
ifp->name, op, r->type);
return;
}
@ -2887,7 +2913,8 @@ dhcp6_handledata(void *arg)
free(state->recv);
state->recv = malloc(len);
if (state->recv == NULL) {
syslog(LOG_ERR, "%s: malloc recv: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: malloc recv: %m", ifp->name);
return;
}
}
@ -2899,7 +2926,7 @@ dhcp6_handledata(void *arg)
if (state->state == DH6S_REQUEST) /* rapid commit */
break;
ap = TAILQ_FIRST(&state->addrs);
syslog(LOG_INFO, "%s: ADV %s from %s",
logger(ifp->ctx, LOG_INFO, "%s: ADV %s from %s",
ifp->name, ap->saddr, ctx->sfrom);
if (ifp->ctx->options & DHCPCD_TEST)
break;
@ -2915,7 +2942,7 @@ recv:
break;
}
}
syslog(has_new ? LOG_INFO : LOG_DEBUG,
logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
"%s: %s received from %s", ifp->name, op, ctx->sfrom);
state->reason = NULL;
@ -2993,16 +3020,16 @@ recv:
dhcp6_delegate_prefix(ifp);
if (state->state == DH6S_INFORMED)
syslog(has_new ? LOG_INFO : LOG_DEBUG,
logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
"%s: refresh in %"PRIu32" seconds",
ifp->name, state->renew);
else if (state->renew || state->rebind)
syslog(has_new ? LOG_INFO : LOG_DEBUG,
logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
"%s: renew in %"PRIu32" seconds,"
" rebind in %"PRIu32" seconds",
ifp->name, state->renew, state->rebind);
else if (state->expire == 0)
syslog(has_new ? LOG_INFO : LOG_DEBUG,
logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
"%s: will expire", ifp->name);
ipv6_buildroutes(ifp->ctx);
dhcp6_writelease(ifp);
@ -3071,7 +3098,7 @@ dhcp6_open(struct dhcpcd_ctx *dctx)
n = 1;
if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEPORT,
&n, sizeof(n)) == -1)
syslog(LOG_WARNING, "setsockopt: SO_REUSEPORT: %m");
logger(dctx, LOG_WARNING, "setsockopt: SO_REUSEPORT: %m");
#endif
if (bind(ctx->dhcp_fd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
@ -3137,7 +3164,7 @@ dhcp6_start1(void *arg)
if (ifs) {
ifn = TAILQ_FIRST(ifs);
if (ifn) {
syslog(LOG_INFO,
logger(ifp->ctx, LOG_INFO,
"%s: creating pseudo interface"
" to handle Prefix Delegation",
ifp->name);
@ -3217,7 +3244,7 @@ gogogo:
AF_INET6, ifp,
ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
if (ipv6_linklocal(ifp) == NULL) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: delaying DHCPv6 soliciation for LL address",
ifp->name);
ipv6_addlinklocalcallback(ifp, dhcp6_start1, ifp);
@ -3426,7 +3453,7 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp,
i = strlen(prefix) + strlen("_dhcp6") + 1;
pfx = malloc(i);
if (pfx == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
snprintf(pfx, i, "%s_dhcp6", prefix);
@ -3501,7 +3528,7 @@ delegated:
i += strlen(prefix) + strlen("_delegated_dhcp6_prefix=");
v = val = env[n] = malloc(i);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
v += snprintf(val, i, "%s_delegated_dhcp6_prefix=", prefix);
@ -3532,7 +3559,7 @@ dhcp6_dump(struct interface *ifp)
ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
TAILQ_INIT(&state->addrs);
@ -3542,9 +3569,11 @@ dhcp6_dump(struct interface *ifp)
r = dhcp6_readlease(ifp);
if (r == -1) {
if (errno == ENOENT)
syslog(LOG_ERR, "%s: no lease to dump", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: no lease to dump", ifp->name);
else
syslog(LOG_ERR, "%s: dhcp6_readlease: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_readlease: %m", ifp->name);
return -1;
}
state->reason = "DUMP6";

View File

@ -188,8 +188,12 @@ syslog()
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" -s -t dhcpcd "$interface: $*"
logger -i -p daemon."$lvl" -t dhcpcd-run-hooks "$interface: $*"
fi
}

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 16, 2015
.Dd March 17, 2015
.Dt DHCPCD 8
.Os
.Sh NAME
@ -39,6 +39,7 @@
.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
@ -318,6 +319,18 @@ For example
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 reopened when
.Nm
receives the
.Dv SIGUSR2
signal.
.It Fl k , Fl Fl release Op Ar interface
This causes an existing
.Nm

240
dhcpcd.c
View File

@ -46,7 +46,6 @@ const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
@ -73,6 +72,7 @@ const int dhcpcd_handlesigs[] = {
SIGALRM,
SIGHUP,
SIGUSR1,
SIGUSR2,
SIGPIPE,
0
};
@ -192,7 +192,7 @@ handle_exit_timeout(void *arg)
struct dhcpcd_ctx *ctx;
ctx = arg;
syslog(LOG_ERR, "timed out");
logger(ctx, LOG_ERR, "timed out");
if (!(ctx->options & DHCPCD_MASTER)) {
eloop_exit(ctx->eloop, EXIT_FAILURE);
return;
@ -261,26 +261,26 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
return 0;
/* Setup a signal pipe so parent knows when to exit. */
if (pipe(sidpipe) == -1) {
syslog(LOG_ERR, "pipe: %m");
logger(ctx, LOG_ERR, "pipe: %m");
return 0;
}
syslog(LOG_DEBUG, "forking to background");
logger(ctx, LOG_DEBUG, "forking to background");
switch (pid = fork()) {
case -1:
syslog(LOG_ERR, "fork: %m");
logger(ctx, LOG_ERR, "fork: %m");
return 0;
case 0:
setsid();
/* Some polling methods don't survive after forking,
* so ensure we can requeue all our events. */
if (eloop_requeue(ctx->eloop) == -1) {
syslog(LOG_ERR, "eloop_requeue: %m");
logger(ctx, LOG_ERR, "eloop_requeue: %m");
eloop_exit(ctx->eloop, EXIT_FAILURE);
}
/* Notify parent it's safe to exit as we've detached. */
close(sidpipe[0]);
if (write(sidpipe[1], &buf, 1) == -1)
syslog(LOG_ERR, "failed to notify parent: %m");
logger(ctx, LOG_ERR, "failed to notify parent: %m");
close(sidpipe[1]);
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
dup2(fd, STDIN_FILENO);
@ -293,13 +293,13 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
/* Wait for child to detach */
close(sidpipe[1]);
if (read(sidpipe[0], &buf, 1) == -1)
syslog(LOG_ERR, "failed to read child: %m");
logger(ctx, LOG_ERR, "failed to read child: %m");
close(sidpipe[0]);
break;
}
/* Done with the fd now */
if (pid != 0) {
syslog(LOG_INFO, "forked to background, child pid %d", pid);
logger(ctx, LOG_INFO, "forked to background, child pid %d", pid);
write_pid(ctx->pid_fd, pid);
close(ctx->pid_fd);
ctx->pid_fd = -1;
@ -318,7 +318,7 @@ stop_interface(struct interface *ifp)
struct dhcpcd_ctx *ctx;
ctx = ifp->ctx;
syslog(LOG_INFO, "%s: removing interface", ifp->name);
logger(ctx, LOG_INFO, "%s: removing interface", ifp->name);
ifp->options->options |= DHCPCD_STOPPING;
dhcp6_drop(ifp, NULL);
@ -483,7 +483,7 @@ configure_interface1(struct interface *ifp)
{
ifo->ia = malloc(sizeof(*ifo->ia));
if (ifo->ia == NULL)
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
else {
ifo->ia_len = 1;
ifo->ia->ia_type = D6_OPTION_IA_NA;
@ -520,19 +520,21 @@ dhcpcd_selectprofile(struct interface *ifp, const char *profile)
r = print_string(pssid, sizeof(pssid), ESCSTRING,
ifp->ssid, ifp->ssid_len);
if (r == -1) {
syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR,
"%s: %s: %m", ifp->name, __func__);
pssid[0] = '\0';
}
} else
pssid[0] = '\0';
ifo = read_config(ifp->ctx, ifp->name, pssid, profile);
if (ifo == NULL) {
syslog(LOG_DEBUG, "%s: no profile %s", ifp->name, profile);
logger(ifp->ctx, LOG_DEBUG, "%s: no profile %s",
ifp->name, profile);
return -1;
}
if (profile != NULL) {
strlcpy(ifp->profile, profile, sizeof(ifp->profile));
syslog(LOG_INFO, "%s: selected profile %s",
logger(ifp->ctx, LOG_INFO, "%s: selected profile %s",
ifp->name, profile);
} else
*ifp->profile = '\0';
@ -608,11 +610,11 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
if (carrier == LINK_UNKNOWN) {
if (errno != ENOTTY) /* For example a PPP link on BSD */
syslog(LOG_ERR, "%s: carrier_status: %m", ifname);
logger(ctx, LOG_ERR, "%s: carrier_status: %m", ifname);
} else if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
if (ifp->carrier != LINK_DOWN) {
if (ifp->carrier == LINK_UP)
syslog(LOG_INFO, "%s: carrier lost", ifp->name);
logger(ctx, LOG_INFO, "%s: carrier lost", ifp->name);
ifp->carrier = LINK_DOWN;
script_runreason(ifp, "NOCARRIER");
dhcp6_drop(ifp, "EXPIRE6");
@ -623,7 +625,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
}
} else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
if (ifp->carrier != LINK_UP) {
syslog(LOG_INFO, "%s: carrier acquired", ifp->name);
logger(ctx, LOG_INFO, "%s: carrier acquired", ifp->name);
ifp->carrier = LINK_UP;
#if !defined(__linux__) && !defined(__NetBSD__)
/* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
@ -666,7 +668,7 @@ warn_iaid_conflict(struct interface *ifp, uint8_t *iaid)
/* This is only a problem if the interfaces are on the same network. */
if (ifn && strcmp(ifp->name, ifn->name))
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: IAID conflicts with one assigned to %s",
ifp->name, ifn->name);
}
@ -680,7 +682,7 @@ pre_start(struct interface *ifp)
* This is also a safety check incase it was ripped out
* from under us. */
if (ifp->options->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
syslog(LOG_ERR, "%s: ipv6_start: %m", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name);
ifp->options->options &= ~DHCPCD_IPV6;
}
}
@ -700,7 +702,8 @@ dhcpcd_startinterface(void *arg)
case LINK_UP:
break;
case LINK_DOWN:
syslog(LOG_INFO, "%s: waiting for carrier", ifp->name);
logger(ifp->ctx, LOG_INFO, "%s: waiting for carrier",
ifp->name);
return;
case LINK_UNKNOWN:
/* No media state available.
@ -723,7 +726,7 @@ dhcpcd_startinterface(void *arg)
if (duid_init(ifp) == 0)
return;
if (!(ifo->options & DHCPCD_PFXDLGONLY))
syslog(LOG_INFO, "DUID %s",
logger(ifp->ctx, LOG_INFO, "DUID %s",
hwaddr_ntoa(ifp->ctx->duid,
ifp->ctx->duid_len,
buf, sizeof(buf)));
@ -734,7 +737,7 @@ dhcpcd_startinterface(void *arg)
!(ifo->options & DHCPCD_PFXDLGONLY))
{
/* Report IAIDs */
syslog(LOG_INFO, "%s: IAID %s", ifp->name,
logger(ifp->ctx, LOG_INFO, "%s: IAID %s", ifp->name,
hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid),
buf, sizeof(buf)));
warn_iaid_conflict(ifp, ifo->iaid);
@ -742,8 +745,8 @@ dhcpcd_startinterface(void *arg)
if (memcmp(ifo->iaid, ifo->ia[i].iaid,
sizeof(ifo->iaid)))
{
syslog(LOG_INFO, "%s: IAID %s", ifp->name,
hwaddr_ntoa(ifo->ia[i].iaid,
logger(ifp->ctx, LOG_INFO, "%s: IAID %s",
ifp->name, hwaddr_ntoa(ifo->ia[i].iaid,
sizeof(ifo->ia[i].iaid),
buf, sizeof(buf)));
warn_iaid_conflict(ifp, ifo->ia[i].iaid);
@ -783,7 +786,7 @@ dhcpcd_startinterface(void *arg)
#endif
}
if (nolease == -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: dhcp6_start: %m", ifp->name);
}
}
@ -799,7 +802,7 @@ dhcpcd_prestartinterface(void *arg)
pre_start(ifp);
if (if_up(ifp) == -1)
syslog(LOG_ERR, "%s: if_up: %m", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: if_up: %m", ifp->name);
if (ifp->options->options & DHCPCD_LINK &&
ifp->carrier == LINK_UNKNOWN)
@ -811,7 +814,7 @@ dhcpcd_prestartinterface(void *arg)
ifp->flags, ifp->name);
return;
}
syslog(LOG_INFO,
logger(ifp->ctx, LOG_INFO,
"%s: unknown carrier, waiting for interface flags",
ifp->name);
}
@ -826,7 +829,7 @@ handle_link(void *arg)
ctx = arg;
if (if_managelink(ctx) == -1) {
syslog(LOG_ERR, "if_managelink: %m");
logger(ctx, LOG_ERR, "if_managelink: %m");
eloop_event_delete(ctx->eloop, ctx->link_fd, 0);
close(ctx->link_fd);
ctx->link_fd = -1;
@ -843,11 +846,11 @@ dhcpcd_initstate1(struct interface *ifp, int argc, char **argv,
ifo = ifp->options;
if (ifo->options & DHCPCD_IPV4 && ipv4_init(ifp->ctx) == -1) {
syslog(LOG_ERR, "ipv4_init: %m");
logger(ifp->ctx, LOG_ERR, "ipv4_init: %m");
ifo->options &= ~DHCPCD_IPV4;
}
if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == NULL) {
syslog(LOG_ERR, "ipv6_init: %m");
logger(ifp->ctx, LOG_ERR, "ipv6_init: %m");
ifo->options &= ~DHCPCD_IPV6RS;
}
@ -856,7 +859,7 @@ dhcpcd_initstate1(struct interface *ifp, int argc, char **argv,
* This needs to happen before PREINIT incase a hook script
* inadvertently ups the interface. */
if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
syslog(LOG_ERR, "%s: ipv6_start: %m", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name);
ifo->options &= ~DHCPCD_IPV6;
}
}
@ -899,7 +902,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
errno = ESRCH;
return -1;
}
syslog(LOG_DEBUG, "%s: interface departed", ifp->name);
logger(ctx, LOG_DEBUG, "%s: interface departed", ifp->name);
ifp->options->options |= DHCPCD_DEPARTED;
stop_interface(ifp);
return 0;
@ -917,7 +920,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
i = -1;
ifs = if_discover(ctx, -1, UNCONST(argv));
if (ifs == NULL) {
syslog(LOG_ERR, "%s: if_discover: %m", __func__);
logger(ctx, LOG_ERR, "%s: if_discover: %m", __func__);
return -1;
}
TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) {
@ -927,14 +930,14 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
/* Check if we already have the interface */
iff = if_find(ctx, ifp->name);
if (iff) {
syslog(LOG_DEBUG, "%s: interface updated", iff->name);
logger(ctx, LOG_DEBUG, "%s: interface updated", iff->name);
/* The flags and hwaddr could have changed */
iff->flags = ifp->flags;
iff->hwlen = ifp->hwlen;
if (ifp->hwlen != 0)
memcpy(iff->hwaddr, ifp->hwaddr, iff->hwlen);
} else {
syslog(LOG_DEBUG, "%s: interface added", ifp->name);
logger(ctx, LOG_DEBUG, "%s: interface added", ifp->name);
TAILQ_REMOVE(ifs, ifp, next);
TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
dhcpcd_initstate(ifp, 0);
@ -970,14 +973,14 @@ dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname,
if (hwlen > sizeof(ifp->hwaddr)) {
errno = ENOBUFS;
syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
logger(ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
return;
}
if (ifp->hwlen == hwlen && memcmp(ifp->hwaddr, hwaddr, hwlen) == 0)
return;
syslog(LOG_INFO, "%s: new hardware address: %s", ifp->name,
logger(ctx, LOG_INFO, "%s: new hardware address: %s", ifp->name,
hwaddr_ntoa(hwaddr, hwlen, buf, sizeof(buf)));
ifp->hwlen = hwlen;
memcpy(ifp->hwaddr, hwaddr, hwlen);
@ -1021,7 +1024,7 @@ reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi)
ifs = if_discover(ctx, argc - oi, argv + oi);
if (ifs == NULL) {
syslog(LOG_ERR, "%s: if_discover: %m", __func__);
logger(ctx, LOG_ERR, "%s: if_discover: %m", __func__);
return;
}
@ -1070,7 +1073,7 @@ stop_all_interfaces(struct dhcpcd_ctx *ctx, int do_release)
#ifdef USE_SIGNALS
struct dhcpcd_siginfo dhcpcd_siginfo;
#define sigmsg "received signal %s, %s"
#define sigmsg "received %s, %s"
void
dhcpcd_handle_signal(void *arg)
{
@ -1085,19 +1088,19 @@ dhcpcd_handle_signal(void *arg)
exit_code = EXIT_FAILURE;
switch (si->signo) {
case SIGINT:
syslog(LOG_INFO, sigmsg, "INT", "stopping");
logger(ctx, LOG_INFO, sigmsg, "SIGINT", "stopping");
break;
case SIGTERM:
syslog(LOG_INFO, sigmsg, "TERM", "stopping");
logger(ctx, LOG_INFO, sigmsg, "SIGTERM", "stopping");
exit_code = EXIT_SUCCESS;
break;
case SIGALRM:
syslog(LOG_INFO, sigmsg, "ALRM", "releasing");
logger(ctx, LOG_INFO, sigmsg, "SIGALRM", "releasing");
do_release = 1;
exit_code = EXIT_SUCCESS;
break;
case SIGHUP:
syslog(LOG_INFO, sigmsg, "HUP", "rebinding");
logger(ctx, LOG_INFO, sigmsg, "SIGHUP", "rebinding");
reload_config(ctx);
/* Preserve any options passed on the commandline
* when we were started. */
@ -1105,16 +1108,21 @@ dhcpcd_handle_signal(void *arg)
ctx->argc - ctx->ifc);
return;
case SIGUSR1:
syslog(LOG_INFO, sigmsg, "USR1", "reconfiguring");
logger(ctx, LOG_INFO, sigmsg, "SIGUSR1", "reconfiguring");
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
ipv4_applyaddr(ifp);
}
return;
case SIGUSR2:
logger_close(ctx);
logger_open(ctx);
logger(ctx, LOG_INFO, sigmsg, "SIGUSR2", "reopened logfile");
return;
case SIGPIPE:
syslog(LOG_WARNING, "received signal PIPE");
logger(ctx, LOG_WARNING, "received SIGPIPE");
return;
default:
syslog(LOG_ERR,
logger(ctx, LOG_ERR,
"received signal %d, "
"but don't know what to do with it",
si->signo);
@ -1190,7 +1198,8 @@ dhcpcd_getinterfaces(void *arg)
eloop_event_delete(fd->ctx->eloop, fd->fd, 1);
TAILQ_FOREACH(ifp, fd->ctx->ifaces, next) {
if (send_interface(fd, ifp) == -1)
syslog(LOG_ERR, "send_interface %d: %m", fd->fd);
logger(ifp->ctx, LOG_ERR,
"send_interface %d: %m", fd->fd);
}
}
@ -1245,7 +1254,7 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
*p++ = ' ';
}
*--p = '\0';
syslog(LOG_INFO, "control command: %s", tmp);
logger(ctx, LOG_INFO, "control command: %s", tmp);
free(tmp);
optind = 0;
@ -1310,23 +1319,6 @@ main(int argc, char **argv)
const char *siga;
#endif
memset(&ctx, 0, sizeof(ctx));
#ifdef USE_SIGNALS
dhcpcd_ctx = &ctx;
sig = 0;
siga = NULL;
#endif
closefrom(3);
#ifdef LOG_PERROR
openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON);
#else
openlog(PACKAGE, LOG_PID, LOG_DAEMON);
#endif
setlogmask(LOG_UPTO(LOG_INFO));
#ifndef LOG_PERROR
psyslog_prio = LOG_UPTO(LOG_INFO);
#endif
/* Test for --help and --version */
if (argc > 1) {
if (strcmp(argv[1], "--help") == 0) {
@ -1338,6 +1330,18 @@ main(int argc, char **argv)
}
}
memset(&ctx, 0, sizeof(ctx));
#ifdef USE_SIGNALS
dhcpcd_ctx = &ctx;
sig = 0;
siga = NULL;
#endif
closefrom(3);
ctx.log_fd = -1;
logger_open(&ctx);
logger_mask(&ctx, LOG_UPTO(LOG_INFO));
ifo = NULL;
ctx.cffile = CONFIG;
ctx.pid_fd = ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1;
@ -1353,19 +1357,9 @@ main(int argc, char **argv)
{
switch (opt) {
case '4':
if (family) {
syslog(LOG_ERR, "cannot specify more than one"
" address family");
goto exit_failure;
}
family = AF_INET;
break;
case '6':
if (family) {
syslog(LOG_ERR, "cannot specify more than one"
" address family");
goto exit_failure;
}
family = AF_INET6;
break;
case 'f':
@ -1376,6 +1370,11 @@ main(int argc, char **argv)
sig = SIGUSR1;
siga = "USR1";
break;
case 'j':
ctx.logfile = strdup(optarg);
logger_close(&ctx);
logger_open(&ctx);
break;
case 'k':
sig = SIGALRM;
siga = "ARLM";
@ -1463,16 +1462,12 @@ main(int argc, char **argv)
ctx.options &= ~DHCPCD_DAEMONISE;
#endif
if (ctx.options & DHCPCD_DEBUG) {
setlogmask(LOG_UPTO(LOG_DEBUG));
#ifndef LOG_PERROR
psyslog_prio = LOG_UPTO(LOG_DEBUG);
#endif
}
if (ctx.options & DHCPCD_DEBUG)
logger_mask(&ctx, LOG_UPTO(LOG_DEBUG));
if (ctx.options & DHCPCD_QUIET) {
i = open(_PATH_DEVNULL, O_RDWR);
if (i == -1)
syslog(LOG_ERR, "%s: open: %m", __func__);
logger(&ctx, LOG_ERR, "%s: open: %m", __func__);
else {
dup2(i, STDERR_FILENO);
close(i);
@ -1486,7 +1481,8 @@ main(int argc, char **argv)
const char *per;
if (strlen(argv[optind]) > IF_NAMESIZE) {
syslog(LOG_ERR, "%s: interface name too long",
logger(&ctx, LOG_ERR,
"%s: interface name too long",
argv[optind]);
goto exit_failure;
}
@ -1511,19 +1507,20 @@ main(int argc, char **argv)
}
if (chdir("/") == -1)
syslog(LOG_ERR, "chdir `/': %m");
logger(&ctx, LOG_ERR, "chdir `/': %m");
/* Freeing allocated addresses from dumping leases can trigger
* eloop removals as well, so init here. */
ctx.eloop = eloop_init();
ctx.eloop = eloop_init(&ctx);
if (ctx.eloop == NULL) {
syslog(LOG_ERR, "%s: eloop_init: %m", __func__);
logger(&ctx, LOG_ERR, "%s: eloop_init: %m", __func__);
goto exit_failure;
}
if (ctx.options & DHCPCD_DUMPLEASE) {
if (optind != argc - 1) {
syslog(LOG_ERR, "dumplease requires an interface");
logger(&ctx, LOG_ERR,
"dumplease requires an interface");
goto exit_failure;
}
i = 0;
@ -1531,14 +1528,14 @@ main(int argc, char **argv)
* load the hardware address to compare automated IAID */
ctx.ifaces = if_discover(&ctx, 1, argv + optind);
if (ctx.ifaces == NULL) {
syslog(LOG_ERR, "if_discover: %m");
logger(&ctx, LOG_ERR, "if_discover: %m");
goto exit_failure;
}
ifp = TAILQ_FIRST(ctx.ifaces);
if (ifp == NULL) {
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(&ctx, LOG_ERR, "%s: %m", __func__);
goto exit_failure;
}
strlcpy(ctx.pidfile, argv[optind], sizeof(ctx.pidfile));
@ -1579,40 +1576,41 @@ main(int argc, char **argv)
if (i == -1)
i = control_open(&ctx, NULL);
if (i != -1) {
syslog(LOG_INFO,
logger(&ctx, LOG_INFO,
"sending commands to master dhcpcd process");
len = control_send(&ctx, argc, argv);
control_close(&ctx);
if (len > 0) {
syslog(LOG_DEBUG, "send OK");
logger(&ctx, LOG_DEBUG, "send OK");
goto exit_success;
} else {
syslog(LOG_ERR, "failed to send commands");
logger(&ctx, LOG_ERR,
"failed to send commands");
goto exit_failure;
}
} else {
if (errno != ENOENT)
syslog(LOG_ERR, "control_open: %m");
logger(&ctx, LOG_ERR, "control_open: %m");
}
#ifdef USE_SIGNALS
}
#endif
if (geteuid())
syslog(LOG_WARNING,
logger(&ctx, LOG_WARNING,
PACKAGE " will not work correctly unless run as root");
#ifdef USE_SIGNALS
if (sig != 0) {
pid = read_pid(ctx.pidfile);
if (pid != 0)
syslog(LOG_INFO, "sending signal %s to pid %d",
logger(&ctx, LOG_INFO, "sending signal %s to pid %d",
siga, pid);
if (pid == 0 || kill(pid, sig) != 0) {
if (sig != SIGHUP && errno != EPERM)
syslog(LOG_ERR, ""PACKAGE" not running");
logger(&ctx, LOG_ERR, ""PACKAGE" not running");
if (pid != 0 && errno != ESRCH) {
syslog(LOG_ERR, "kill: %m");
logger(&ctx, LOG_ERR, "kill: %m");
goto exit_failure;
}
unlink(ctx.pidfile);
@ -1624,7 +1622,8 @@ main(int argc, char **argv)
if (sig == SIGHUP || sig == SIGUSR1)
goto exit_success;
/* Spin until it exits */
syslog(LOG_INFO, "waiting for pid %d to exit", pid);
logger(&ctx, LOG_INFO,
"waiting for pid %d to exit", pid);
ts.tv_sec = 0;
ts.tv_nsec = 100000000; /* 10th of a second */
for(i = 0; i < 100; i++) {
@ -1632,7 +1631,7 @@ main(int argc, char **argv)
if (read_pid(ctx.pidfile) == 0)
goto exit_success;
}
syslog(LOG_ERR, "pid %d failed to exit", pid);
logger(&ctx, LOG_ERR, "pid %d failed to exit", pid);
goto exit_failure;
}
}
@ -1641,7 +1640,7 @@ main(int argc, char **argv)
if ((pid = read_pid(ctx.pidfile)) > 0 &&
kill(pid, 0) == 0)
{
syslog(LOG_ERR, ""PACKAGE
logger(&ctx, LOG_ERR, ""PACKAGE
" already running on pid %d (%s)",
pid, ctx.pidfile);
goto exit_failure;
@ -1649,9 +1648,9 @@ main(int argc, char **argv)
/* Ensure we have the needed directories */
if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
syslog(LOG_ERR, "mkdir `%s': %m", RUNDIR);
logger(&ctx, LOG_ERR, "mkdir `%s': %m", RUNDIR);
if (mkdir(DBDIR, 0755) == -1 && errno != EEXIST)
syslog(LOG_ERR, "mkdir `%s': %m", DBDIR);
logger(&ctx, LOG_ERR, "mkdir `%s': %m", DBDIR);
opt = O_WRONLY | O_CREAT | O_NONBLOCK;
#ifdef O_CLOEXEC
@ -1659,13 +1658,13 @@ main(int argc, char **argv)
#endif
ctx.pid_fd = open(ctx.pidfile, opt, 0664);
if (ctx.pid_fd == -1)
syslog(LOG_ERR, "open `%s': %m", ctx.pidfile);
logger(&ctx, LOG_ERR, "open `%s': %m", ctx.pidfile);
else {
#ifdef LOCK_EX
/* Lock the file so that only one instance of dhcpcd
* runs on an interface */
if (flock(ctx.pid_fd, LOCK_EX | LOCK_NB) == -1) {
syslog(LOG_ERR, "flock `%s': %m", ctx.pidfile);
logger(&ctx, LOG_ERR, "flock `%s': %m", ctx.pidfile);
close(ctx.pid_fd);
ctx.pid_fd = -1;
goto exit_failure;
@ -1675,7 +1674,7 @@ main(int argc, char **argv)
if (fcntl(ctx.pid_fd, F_GETFD, &opt) == -1 ||
fcntl(ctx.pid_fd, F_SETFD, opt | FD_CLOEXEC) == -1)
{
syslog(LOG_ERR, "fcntl: %m");
logger(&ctx, LOG_ERR, "fcntl: %m");
close(ctx.pid_fd);
ctx.pid_fd = -1;
goto exit_failure;
@ -1688,23 +1687,23 @@ main(int argc, char **argv)
if (ctx.options & DHCPCD_MASTER) {
if (control_start(&ctx, NULL) == -1)
syslog(LOG_ERR, "control_start: %m");
logger(&ctx, LOG_ERR, "control_start: %m");
}
#else
if (control_start(&ctx,
ctx.options & DHCPCD_MASTER ? NULL : argv[optind]) == -1)
{
syslog(LOG_ERR, "control_start: %m");
logger(&ctx, LOG_ERR, "control_start: %m");
goto exit_failure;
}
#endif
syslog(LOG_INFO, "version " VERSION " starting");
logger(&ctx, LOG_DEBUG, PACKAGE "-" VERSION " starting");
ctx.options |= DHCPCD_STARTED;
#ifdef USE_SIGNALS
/* Save signal mask, block and redirect signals to our handler */
if (signal_init(&ctx.sigset) == -1) {
syslog(LOG_ERR, "signal_setup: %m");
logger(&ctx, LOG_ERR, "signal_setup: %m");
goto exit_failure;
}
#endif
@ -1721,7 +1720,7 @@ main(int argc, char **argv)
* so that we pickup any new addresses during the discover phase. */
ctx.link_fd = if_openlinksocket();
if (ctx.link_fd == -1)
syslog(LOG_ERR, "open_link_socket: %m");
logger(&ctx, LOG_ERR, "open_link_socket: %m");
else
eloop_event_add(ctx.eloop, ctx.link_fd,
handle_link, &ctx, NULL, NULL);
@ -1734,21 +1733,22 @@ main(int argc, char **argv)
ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv);
if (ctx.ifaces == NULL) {
syslog(LOG_ERR, "if_discover: %m");
logger(&ctx, LOG_ERR, "if_discover: %m");
goto exit_failure;
}
for (i = 0; i < ctx.ifc; i++) {
if (if_find(&ctx, ctx.ifv[i]) == NULL)
syslog(LOG_ERR, "%s: interface not found or invalid",
logger(&ctx, LOG_ERR,
"%s: interface not found or invalid",
ctx.ifv[i]);
}
if (TAILQ_FIRST(ctx.ifaces) == NULL) {
if (ctx.ifc == 0)
syslog(LOG_ERR, "no valid interfaces found");
logger(&ctx, LOG_ERR, "no valid interfaces found");
else
goto exit_failure;
if (!(ctx.options & DHCPCD_LINK)) {
syslog(LOG_ERR,
logger(&ctx, LOG_ERR,
"aborting as link detection is disabled");
goto exit_failure;
}
@ -1779,7 +1779,8 @@ main(int argc, char **argv)
ctx.options & DHCPCD_LINK &&
!(ctx.options & DHCPCD_WAITIP))
{
syslog(LOG_WARNING, "no interfaces have a carrier");
logger(&ctx, LOG_WARNING,
"no interfaces have a carrier");
if (dhcpcd_daemonise(&ctx))
goto exit_success;
} else if (t > 0 &&
@ -1799,7 +1800,7 @@ main(int argc, char **argv)
dhcpcd_prestartinterface, ifp);
}
i = eloop_start(&ctx);
i = eloop_start(ctx.eloop);
goto exit1;
exit_success:
@ -1830,7 +1831,7 @@ exit1:
ipv6_ctxfree(&ctx);
dev_stop(&ctx);
if (control_stop(&ctx) == -1)
syslog(LOG_ERR, "control_stop: %m:");
logger(&ctx, LOG_ERR, "control_stop: %m:");
if (ctx.pid_fd != -1) {
close(ctx.pid_fd);
unlink(ctx.pidfile);
@ -1838,7 +1839,8 @@ exit1:
eloop_free(ctx.eloop);
if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
syslog(LOG_INFO, "exited");
closelog();
logger(&ctx, LOG_INFO, PACKAGE " exited");
logger_close(&ctx);
free(ctx.logfile);
return i;
}

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd January 20, 2015
.Dd March 17, 2015
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@ -375,6 +375,18 @@ 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 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

View File

@ -85,6 +85,8 @@ struct dhcpcd_ctx {
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 */

18
duid.c
View File

@ -39,7 +39,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
@ -111,31 +110,32 @@ duid_get(unsigned char *d, const struct interface *ifp)
return len;
} else {
if (errno != ENOENT)
syslog(LOG_ERR, "error reading DUID: %s: %m", DUID);
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) {
syslog(LOG_WARNING, "%s: is a NET/ROM psuedo interface",
ifp->name);
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;
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"picked interface %s to generate a DUID",
ifp->name);
} else {
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"no interfaces have a fixed hardware address");
return duid_make(d, ifp, DUID_LL);
}
}
if (!(fp = fopen(DUID, "w"))) {
syslog(LOG_ERR, "error writing DUID: %s: %m", DUID);
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);
@ -143,7 +143,7 @@ duid_get(unsigned char *d, const struct interface *ifp)
fclose(fp);
/* Failed to write the duid? scrub it, we cannot use it */
if (x < 1) {
syslog(LOG_ERR, "error writing DUID: %s: %m", DUID);
logger(ifp->ctx, LOG_ERR, "error writing DUID: %s: %m", DUID);
unlink(DUID);
return duid_make(d, ifp, DUID_LL);
}
@ -156,7 +156,7 @@ size_t duid_init(const struct interface *ifp)
if (ifp->ctx->duid == NULL) {
ifp->ctx->duid = malloc(DUID_LEN);
if (ifp->ctx->duid == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return 0;
}
ifp->ctx->duid_len = duid_get(ifp->ctx->duid, ifp);

28
eloop.c
View File

@ -35,7 +35,6 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
@ -192,7 +191,7 @@ eloop_event_add(struct eloop_ctx *ctx, int fd,
return 0;
err:
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx->ctx, LOG_ERR, "%s: %m", __func__);
if (e) {
ctx->events_len--;
TAILQ_INSERT_TAIL(&ctx->free_events, e, next);
@ -289,7 +288,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
} else {
t = malloc(sizeof(*t));
if (t == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
}
@ -323,13 +322,15 @@ eloop_q_timeout_add_sec(struct eloop_ctx *ctx, int queue, time_t when,
return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
}
#if !defined(HAVE_KQUEUE)
int
eloop_timeout_add_now(struct eloop_ctx *ctx,
void (*callback)(void *), void *arg)
{
if (ctx->timeout0 != NULL) {
syslog(LOG_WARNING, "%s: timeout0 already set", __func__);
logger(ctx->ctx, LOG_WARNING,
"%s: timeout0 already set", __func__);
return eloop_q_timeout_add_sec(ctx, 0, 0, callback, arg);
}
@ -337,6 +338,7 @@ eloop_timeout_add_now(struct eloop_ctx *ctx,
ctx->timeout0_arg = arg;
return 0;
}
#endif
void
eloop_q_timeout_delete(struct eloop_ctx *ctx, int queue,
@ -455,7 +457,7 @@ eloop_requeue(struct eloop_ctx *ctx)
#endif
struct eloop_ctx *
eloop_init(void)
eloop_init(struct dhcpcd_ctx *dctx)
{
struct eloop_ctx *ctx;
struct timespec now;
@ -466,6 +468,7 @@ eloop_init(void)
ctx = calloc(1, sizeof(*ctx));
if (ctx) {
ctx->ctx = dctx;
TAILQ_INIT(&ctx->events);
TAILQ_INIT(&ctx->free_events);
TAILQ_INIT(&ctx->timeouts);
@ -516,9 +519,8 @@ void eloop_free(struct eloop_ctx *ctx)
}
int
eloop_start(struct dhcpcd_ctx *dctx)
eloop_start(struct eloop_ctx *ctx)
{
struct eloop_ctx *ctx;
int n;
struct eloop_event *e;
struct eloop_timeout *t;
@ -533,7 +535,6 @@ eloop_start(struct dhcpcd_ctx *dctx)
struct epoll_event epe;
#endif
ctx = dctx->eloop;
for (;;) {
if (ctx->exitnow)
break;
@ -560,7 +561,7 @@ eloop_start(struct dhcpcd_ctx *dctx)
tsp = NULL;
if (tsp == NULL && ctx->events_len == 0) {
syslog(LOG_ERR, "nothing to do");
logger(ctx->ctx, LOG_ERR, "nothing to do");
break;
}
@ -580,14 +581,15 @@ eloop_start(struct dhcpcd_ctx *dctx)
n = kevent(ctx->poll_fd, NULL, 0, &ke, 1, tsp);
#elif defined(HAVE_EPOLL)
#ifdef USE_SIGNALS
n = epoll_pwait(ctx->poll_fd, &epe, 1, timeout, &dctx->sigset);
n = epoll_pwait(ctx->poll_fd, &epe, 1, timeout,
&ctx->ctx->sigset);
#else
n = epoll_wait(ctx->poll_fd, &epe, 1, timeout);
#endif
#else
#ifdef USE_SIGNALS
n = pollts(ctx->fds, (nfds_t)ctx->events_len,
tsp, &dctx->sigset);
n = pollts(ctx->fds, (nfds_t)ctx->events_len, tsp,
&ctx->ctx->sigset);
#else
n = poll(ctx->fds, (nfds_t)ctx->events_len, timeout);
#endif
@ -595,7 +597,7 @@ eloop_start(struct dhcpcd_ctx *dctx)
if (n == -1) {
if (errno == EINTR)
continue;
syslog(LOG_ERR, "poll: %m");
logger(ctx->ctx, LOG_ERR, "poll: %m");
break;
}

View File

@ -61,6 +61,8 @@ struct eloop_timeout {
};
struct eloop_ctx {
struct dhcpcd_ctx *ctx;
size_t events_len;
TAILQ_HEAD (event_head, eloop_event) events;
struct event_head free_events;
@ -97,9 +99,11 @@ int eloop_q_timeout_add_sec(struct eloop_ctx *, int queue,
time_t, void (*)(void *), void *);
int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue,
const struct timespec *, void (*)(void *), void *);
#if !defined(HAVE_KQUEUE)
int eloop_timeout_add_now(struct eloop_ctx *, void (*)(void *), void *);
#endif
void eloop_q_timeout_delete(struct eloop_ctx *, int, void (*)(void *), void *);
struct eloop_ctx * eloop_init(void);
struct eloop_ctx * eloop_init(struct dhcpcd_ctx *);
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
int eloop_requeue(struct eloop_ctx *);
#else
@ -107,6 +111,6 @@ int eloop_requeue(struct eloop_ctx *);
#endif
void eloop_free(struct eloop_ctx *);
void eloop_exit(struct eloop_ctx *, int);
int eloop_start(struct dhcpcd_ctx *);
int eloop_start(struct eloop_ctx *);
#endif

View File

@ -66,7 +66,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#if defined(OpenBSD) && OpenBSD >= 201411
@ -326,7 +325,7 @@ if_openrawsocket(struct interface *ifp, int protocol)
goto eexit;
if (pv.bv_major != BPF_MAJOR_VERSION ||
pv.bv_minor < BPF_MINOR_VERSION) {
syslog(LOG_ERR, "BPF version mismatch - recompile");
logger(ifp->ctx, LOG_ERR, "BPF version mismatch - recompile");
goto eexit;
}
@ -1438,7 +1437,7 @@ eexit:
}
static int
if_raflush(void)
if_raflush(struct dhcpcd_ctx *ctx)
{
int s;
char dummy[IFNAMSIZ + 8];
@ -1448,9 +1447,9 @@ if_raflush(void)
return -1;
strlcpy(dummy, "lo0", sizeof(dummy));
if (ioctl(s, SIOCSRTRFLUSH_IN6, (void *)&dummy) == -1)
syslog(LOG_ERR, "SIOSRTRFLUSH_IN6: %m");
logger(ctx, LOG_ERR, "SIOSRTRFLUSH_IN6: %m");
if (ioctl(s, SIOCSPFXFLUSH_IN6, (void *)&dummy) == -1)
syslog(LOG_ERR, "SIOSPFXFLUSH_IN6: %m");
logger(ctx, LOG_ERR, "SIOSPFXFLUSH_IN6: %m");
close(s);
return 0;
}
@ -1498,7 +1497,7 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
#ifdef ND6_IFF_IFDISABLED
if (del_if_nd6_flag(ifp->name, ND6_IFF_IFDISABLED) == -1) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: del_if_nd6_flag: ND6_IFF_IFDISABLED: %m",
ifp->name);
return -1;
@ -1507,7 +1506,7 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
#ifdef ND6_IFF_PERFORMNUD
if (set_if_nd6_flag(ifp->name, ND6_IFF_PERFORMNUD) == -1) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: set_if_nd6_flag: ND6_IFF_PERFORMNUD: %m",
ifp->name);
return -1;
@ -1520,19 +1519,19 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
all = get_if_nd6_flag(ifp->name,ND6_IFF_AUTO_LINKLOCAL);
if (all == -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: get_if_nd6_flag: "
"ND6_IFF_AUTO_LINKLOCAL: %m",
ifp->name);
else if (all != 0) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: disabling Kernel IPv6 "
"auto link-local support",
ifp->name);
if (del_if_nd6_flag(ifp->name,
ND6_IFF_AUTO_LINKLOCAL) == -1)
{
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: del_if_nd6_flag: "
"ND6_IFF_AUTO_LINKLOCAL: %m",
ifp->name);
@ -1549,13 +1548,13 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
#ifdef ND6_IFF_OVERRIDE_RTADV
override = get_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV);
if (override == -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m",
ifp->name);
else if (override == 0 && own) {
if (set_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV)
== -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: set_if_nd6_flag: "
"ND6_IFF_OVERRIDE_RTADV: %m",
ifp->name);
@ -1567,23 +1566,23 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
#ifdef ND6_IFF_ACCEPT_RTADV
ra = get_if_nd6_flag(ifp->name, ND6_IFF_ACCEPT_RTADV);
if (ra == -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: get_if_nd6_flag: ND6_IFF_ACCEPT_RTADV: %m",
ifp->name);
else if (ra != 0 && own) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: disabling Kernel IPv6 RA support",
ifp->name);
if (del_if_nd6_flag(ifp->name, ND6_IFF_ACCEPT_RTADV)
== -1)
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: del_if_nd6_flag: "
"ND6_IFF_ACCEPT_RTADV: %m",
ifp->name);
else
ra = 0;
} else if (ra == 0 && !own)
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: IPv6 kernel autoconf disabled", ifp->name);
#ifdef ND6_IFF_OVERRIDE_RTADV
if (override == 0 && ra)
@ -1600,12 +1599,12 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
if (ra == -1)
/* The sysctl probably doesn't exist, but this isn't an
* error as such so just log it and continue */
syslog(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
logger(ifp->ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
"IPV6CTL_ACCEPT_RTADV: %m");
else if (ra != 0 && own) {
syslog(LOG_DEBUG, "disabling Kernel IPv6 RA support");
logger(ifp->ctx, LOG_DEBUG, "disabling Kernel IPv6 RA support");
if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1) {
syslog(LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
logger(ifp->ctx, LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
return ra;
}
ra = 0;
@ -1616,7 +1615,7 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
/* Flush the kernel knowledge of advertised routers
* and prefixes so the kernel does not expire prefixes
* and default routes we are trying to own. */
if_raflush();
if_raflush(ctx);
}
ctx->ra_global = ra;

View File

@ -54,7 +54,6 @@
#include <string.h>
#include <unistd.h>
#include "common.h"
#include "config.h"
/* We can't include if.h or dhcpcd.h because

View File

@ -71,7 +71,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
@ -1717,8 +1716,8 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
ifname = "all";
else if (own) {
if (if_disable_autolinklocal(ctx, (int)ifp->index) == -1)
syslog(LOG_DEBUG, "%s: if_disable_autolinklocal: %m",
ifp->name);
logger(ctx, LOG_DEBUG,
"%s: if_disable_autolinklocal: %m", ifp->name);
}
if (ifp)
ifname = ifp->name;
@ -1727,11 +1726,11 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
ra = check_proc_int(path);
if (ra != 1) {
if (!own)
syslog(LOG_WARNING,
logger(ctx, LOG_WARNING,
"%s: IPv6 kernel autoconf disabled", ifname);
} else if (ra != -1 && own) {
if (write_path(path, "0") == -1) {
syslog(LOG_ERR, "write_path: %s: %m", path);
logger(ctx, LOG_ERR, "write_path: %s: %m", path);
return -1;
}
}
@ -1741,13 +1740,13 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
if (ra == -1)
/* The sysctl probably doesn't exist, but this isn't an
* error as such so just log it and continue */
syslog(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
logger(ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
"%s: %m", path);
else if (ra != 0 && own) {
syslog(LOG_DEBUG, "%s: disabling kernel IPv6 RA support",
logger(ctx, LOG_DEBUG, "%s: disabling kernel IPv6 RA support",
ifname);
if (write_path(path, "0") == -1) {
syslog(LOG_ERR, "write_path: %s: %m", path);
logger(ctx, LOG_ERR, "write_path: %s: %m", path);
return ra;
}
return 0;

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@
/* Don't set any optional arguments here so we retain POSIX
* compatibility with getopt */
#define IF_OPTS "46bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GHI:JKLMO:Q:S:TUVW:X:Z:"
#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

15
if.c
View File

@ -57,7 +57,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
@ -288,14 +287,14 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
}
if (if_vimaster(p) == 1) {
syslog(argc ? LOG_ERR : LOG_DEBUG,
logger(ctx, argc ? LOG_ERR : LOG_DEBUG,
"%s: is a Virtual Interface Master, skipping", p);
continue;
}
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
break;
}
ifp->ctx = ctx;
@ -345,7 +344,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
ctx->ifac == 0 &&
!if_hasconf(ctx, ifp->name))
{
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: ignoring due to"
" interface type and"
" no config",
@ -383,7 +382,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if_free(ifp);
continue;
}
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: unsupported interface type %.2x",
ifp->name, sdl->sdl_type);
/* Pretend it's ethernet */
@ -433,7 +432,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
/* IFT already checked */
#ifndef AF_LINK
default:
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: unsupported interface family %.2x",
ifp->name, ifp->family);
break;
@ -443,7 +442,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
/* Handle any platform init for the interface */
if (if_init(ifp) == -1) {
syslog(LOG_ERR, "%s: if_init: %m", p);
logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
if_free(ifp);
continue;
}
@ -452,7 +451,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if (if_getmtu(ifp->name) < MTU_MIN &&
if_setmtu(ifp->name, MTU_MIN) == -1)
{
syslog(LOG_ERR, "%s: set_mtu: %m", p);
logger(ifp->ctx, LOG_ERR, "%s: set_mtu: %m", p);
if_free(ifp);
continue;
}

80
ipv4.c
View File

@ -36,7 +36,6 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
@ -267,26 +266,28 @@ static void
desc_route(const char *cmd, const struct rt *rt)
{
char addr[sizeof("000.000.000.000") + 1];
const char *ifname = rt->iface->name;
struct dhcpcd_ctx *ctx = rt->iface ? rt->iface->ctx : NULL;
const char *ifname = rt->iface ? rt->iface->name : NULL;
strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
if (rt->gate.s_addr == INADDR_ANY)
syslog(LOG_INFO, "%s: %s route to %s/%d", ifname, cmd,
addr, inet_ntocidr(rt->net));
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
ifname, cmd, addr, inet_ntocidr(rt->net));
else if (rt->gate.s_addr == rt->dest.s_addr &&
rt->net.s_addr == INADDR_BROADCAST)
syslog(LOG_INFO, "%s: %s host route to %s", ifname, cmd,
addr);
logger(ctx, LOG_INFO, "%s: %s host route to %s",
ifname, cmd, addr);
else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) &&
rt->net.s_addr == INADDR_BROADCAST)
syslog(LOG_INFO, "%s: %s host route to %s via %s", ifname, cmd,
addr, inet_ntoa(rt->gate));
logger(ctx, LOG_INFO, "%s: %s host route to %s via %s",
ifname, cmd, addr, inet_ntoa(rt->gate));
else if (rt->dest.s_addr == INADDR_ANY && rt->net.s_addr == INADDR_ANY)
syslog(LOG_INFO, "%s: %s default route via %s", ifname, cmd,
inet_ntoa(rt->gate));
logger(ctx, LOG_INFO, "%s: %s default route via %s",
ifname, cmd, inet_ntoa(rt->gate));
else
syslog(LOG_INFO, "%s: %s route to %s/%d via %s", ifname, cmd,
addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate));
logger(ctx, LOG_INFO, "%s: %s route to %s/%d via %s",
ifname, cmd, addr, inet_ntocidr(rt->net),
inet_ntoa(rt->gate));
}
static struct rt *
@ -399,18 +400,18 @@ nc_route(struct rt *ort, struct rt *nrt)
/* With route metrics, we can safely add the new route before
* deleting the old route. */
if ((retval = if_route(RTM_ADD, nrt)) == -1)
syslog(LOG_ERR, "if_route (ADD): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route (ADD): %m");
if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
syslog(LOG_ERR, "if_route (DEL): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
return retval;
#else
/* No route metrics, we need to delete the old route before
* adding the new one. */
if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
syslog(LOG_ERR, "if_route (DEL): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
if (if_route(RTM_ADD, nrt) == 0)
return 0;
syslog(LOG_ERR, "if_route (ADD): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route (ADD): %m");
return -1;
#endif
}
@ -423,7 +424,8 @@ d_route(struct rt *rt)
desc_route("deleting", rt);
retval = if_route(RTM_DELETE, rt);
if (retval != 0 && errno != ENOENT && errno != ESRCH)
syslog(LOG_ERR,"%s: if_delroute: %m", rt->iface->name);
logger(rt->iface->ctx, LOG_ERR,
"%s: if_delroute: %m", rt->iface->name);
return retval;
}
@ -440,7 +442,7 @@ make_subnet_route(const struct interface *ifp)
r = malloc(sizeof(*r));
if (r == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
@ -479,7 +481,7 @@ add_loopback_route(struct rt_head *rt, const struct interface *ifp)
r = malloc(sizeof(*r));
if (r == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
ipv4_freeroutes(rt);
return NULL;
}
@ -505,7 +507,7 @@ get_routes(struct interface *ifp)
break;
r = malloc(sizeof(*r));
if (r == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
ipv4_freeroutes(nrt);
return NULL;
}
@ -537,24 +539,24 @@ massage_host_routes(struct rt_head *rt, const struct interface *ifp)
}
static struct rt_head *
add_destination_route(struct rt_head *rt, const struct interface *iface)
add_destination_route(struct rt_head *rt, const struct interface *ifp)
{
struct rt *r;
if (rt == NULL || /* failed a malloc earlier probably */
!(iface->flags & IFF_POINTOPOINT) ||
!has_option_mask(iface->options->dstmask, DHO_ROUTER))
!(ifp->flags & IFF_POINTOPOINT) ||
!has_option_mask(ifp->options->dstmask, DHO_ROUTER))
return rt;
r = malloc(sizeof(*r));
if (r == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
ipv4_freeroutes(rt);
return NULL;
}
r->dest.s_addr = INADDR_ANY;
r->net.s_addr = INADDR_ANY;
r->gate.s_addr = D_CSTATE(iface)->dst.s_addr;
r->gate.s_addr = D_CSTATE(ifp)->dst.s_addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
}
@ -603,7 +605,7 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp)
!(state->added & STATE_FAKE))
{
ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: forcing router %s through interface",
ifp->name, inet_ntoa(rtp->gate));
}
@ -614,13 +616,13 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp)
!(state->added & STATE_FAKE))
{
ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: router %s requires a host route",
ifp->name, inet_ntoa(rtp->gate));
}
rtn = malloc(sizeof(*rtn));
if (rtn == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
ipv4_freeroutes(rt);
return NULL;
}
@ -646,7 +648,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
nrs = malloc(sizeof(*nrs));
if (nrs == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return;
}
TAILQ_INIT(nrs);
@ -730,12 +732,12 @@ delete_address1(struct interface *ifp,
struct ipv4_state *state;
struct ipv4_addr *ap;
syslog(LOG_DEBUG, "%s: deleting IP address %s/%d",
logger(ifp->ctx, LOG_DEBUG, "%s: deleting IP address %s/%d",
ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
r = if_deladdress(ifp, addr, net);
if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
errno != ENODEV)
syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
state = IPV4_STATE(ifp);
TAILQ_FOREACH(ap, &state->addrs, next) {
@ -779,7 +781,7 @@ ipv4_getstate(struct interface *ifp)
ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
state = IPV4_STATE(ifp);
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
TAILQ_INIT(&state->addrs);
@ -804,12 +806,12 @@ ipv4_addaddr(struct interface *ifp, const struct dhcp_lease *lease)
}
}
syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d",
ifp->name, inet_ntoa(lease->addr),
inet_ntocidr(lease->net));
r = if_addaddress(ifp, &lease->addr, &lease->net, &lease->brd);
if (r == -1 && errno != EEXIST)
syslog(LOG_ERR, "%s: if_addaddress: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m", __func__);
return r;
}
@ -877,7 +879,8 @@ ipv4_applyaddr(void *arg)
nstate->addr.s_addr == lease->addr.s_addr)
{
if (ifn->metric <= ifp->metric) {
syslog(LOG_INFO, "%s: preferring %s on %s",
logger(ifp->ctx, LOG_INFO,
"%s: preferring %s on %s",
ifp->name,
inet_ntoa(lease->addr),
ifn->name);
@ -885,7 +888,7 @@ ipv4_applyaddr(void *arg)
state->net.s_addr = lease->net.s_addr;
goto routes;
}
syslog(LOG_INFO, "%s: preferring %s on %s",
logger(ifp->ctx, LOG_INFO, "%s: preferring %s on %s",
ifn->name,
inet_ntoa(lease->addr),
ifp->name);
@ -912,7 +915,8 @@ ipv4_applyaddr(void *arg)
delete_address1(ifp, &ap->addr, &ap->net);
if (ipv4_iffindaddr(ifp, &lease->addr, &lease->net))
syslog(LOG_DEBUG, "%s: IP address %s/%d already exists",
logger(ifp->ctx, LOG_DEBUG,
"%s: IP address %s/%d already exists",
ifp->name, inet_ntoa(lease->addr),
inet_ntocidr(lease->net));
else {
@ -987,7 +991,7 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
if (type == RTM_NEWADDR && ap == NULL) {
ap = malloc(sizeof(*ap));
if (ap == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
ap->iface = ifp;

View File

@ -29,7 +29,6 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 6
@ -114,7 +113,7 @@ ipv4ll_probed(struct arp_state *astate)
offer = state->offer;
state->offer = ipv4ll_make_lease(astate->addr.s_addr);
if (state->offer == NULL)
syslog(LOG_ERR, "%s: %m", __func__);
logger(astate->iface->ctx, LOG_ERR, "%s: %m", __func__);
else
dhcp_bind(astate->iface, astate);
state->offer = offer;
@ -166,13 +165,14 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
/* RFC 3927 Section 2.5 */
up = uptime();
if (state->defend + DEFEND_INTERVAL > up) {
syslog(LOG_WARNING,
logger(astate->iface->ctx, LOG_WARNING,
"%s: IPv4LL %d second defence failed for %s",
astate->iface->name, DEFEND_INTERVAL,
inet_ntoa(state->addr));
dhcp_drop(astate->iface, "EXPIRE");
} else {
syslog(LOG_DEBUG, "%s: defended IPv4LL address %s",
logger(astate->iface->ctx, LOG_DEBUG,
"%s: defended IPv4LL address %s",
astate->iface->name, inet_ntoa(state->addr));
state->defend = up;
return;
@ -181,7 +181,8 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
arp_cancel(astate);
if (++state->conflicts == MAX_CONFLICTS)
syslog(LOG_ERR, "%s: failed to acquire an IPv4LL address",
logger(astate->iface->ctx, LOG_ERR,
"%s: failed to acquire an IPv4LL address",
astate->iface->name);
astate->addr.s_addr = ipv4ll_pick_addr(astate);
eloop_timeout_add_sec(astate->iface->ctx->eloop,
@ -247,7 +248,7 @@ ipv4ll_start(void *arg)
setstate(state->randomstate);
/* We maybe rebooting an IPv4LL address. */
if (!IN_LINKLOCAL(htonl(astate->addr.s_addr))) {
syslog(LOG_INFO, "%s: probing for an IPv4LL address",
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
ifp->name);
astate->addr.s_addr = INADDR_ANY;
}

93
ipv6.c
View File

@ -53,7 +53,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 7
@ -239,7 +238,8 @@ ipv6_readsecret(struct dhcpcd_ctx *ctx)
return (ssize_t)len;
} else {
if (errno != ENOENT)
syslog(LOG_ERR, "error reading secret: %s: %m", SECRET);
logger(ctx, LOG_ERR,
"error reading secret: %s: %m", SECRET);
}
/* Chaining arc4random should be good enough.
@ -269,7 +269,7 @@ ipv6_readsecret(struct dhcpcd_ctx *ctx)
return (ssize_t)ctx->secret_len;
eexit:
syslog(LOG_ERR, "error writing secret: %s: %m", SECRET);
logger(ctx, LOG_ERR, "error writing secret: %s: %m", SECRET);
unlink(SECRET);
ctx->secret_len = 0;
return -1;
@ -589,7 +589,8 @@ ipv6_checkaddrflags(void *arg)
ap = arg;
ifa_flags = if_addrflags6(&ap->addr, ap->iface);
if (ifa_flags == -1)
syslog(LOG_ERR, "%s: if_addrflags6: %m", ap->iface->name);
logger(ap->iface->ctx, LOG_ERR,
"%s: if_addrflags6: %m", ap->iface->name);
else if (!(ifa_flags & IN6_IFF_TENTATIVE)) {
ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR,
ap->iface->ctx->ifaces, ap->iface->name,
@ -606,20 +607,20 @@ ipv6_checkaddrflags(void *arg)
static void
ipv6_deleteaddr(struct ipv6_addr *addr)
ipv6_deleteaddr(struct ipv6_addr *ia)
{
struct ipv6_state *state;
struct ipv6_addr *ap;
syslog(LOG_INFO, "%s: deleting address %s",
addr->iface->name, addr->saddr);
if (if_deladdress6(addr) == -1 &&
logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s",
ia->iface->name, ia->saddr);
if (if_deladdress6(ia) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
syslog(LOG_ERR, "if_deladdress6: :%m");
logger(ia->iface->ctx, LOG_ERR, "if_deladdress6: :%m");
state = IPV6_STATE(addr->iface);
state = IPV6_STATE(ia->iface);
TAILQ_FOREACH(ap, &state->addrs, next) {
if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr->addr)) {
if (IN6_ARE_ADDR_EQUAL(&ap->addr, &ia->addr)) {
TAILQ_REMOVE(&state->addrs, ap, next);
ipv6_freeaddr(ap);
break;
@ -654,23 +655,23 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
ipv6_iffindaddr(ap->iface, &ap->addr))
ap->flags |= IPV6_AF_DADCOMPLETED;
syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
logger(ap->iface->ctx, ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
"%s: adding address %s", ap->iface->name, ap->saddr);
if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: pltime infinity, vltime infinity",
ap->iface->name);
else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: pltime infinity, vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_vltime);
else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: pltime %"PRIu32"seconds, vltime infinity",
ap->iface->name, ap->prefix_pltime);
else
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: pltime %"PRIu32" seconds, vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
@ -695,9 +696,9 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
}
if (if_addaddress6(ap) == -1) {
syslog(LOG_ERR, "if_addaddress6: %m");
logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
#if 0
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: adj pltime %"PRIu32" seconds, "
"vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
@ -794,21 +795,22 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
strcmp(apf->iface->name, ap->iface->name))
{
if (apf->iface->metric <= ap->iface->metric) {
syslog(LOG_INFO,
logger(apf->iface->ctx, LOG_INFO,
"%s: preferring %s on %s",
ap->iface->name,
ap->saddr,
apf->iface->name);
continue;
}
syslog(LOG_INFO,
logger(apf->iface->ctx, LOG_INFO,
"%s: preferring %s on %s",
apf->iface->name,
ap->saddr,
ap->iface->name);
if (if_deladdress6(apf) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
syslog(LOG_ERR, "if_deladdress6: %m");
logger(apf->iface->ctx, LOG_ERR,
"if_deladdress6: %m");
apf->flags &=
~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
} else if (apf)
@ -883,7 +885,7 @@ ipv6_getstate(struct interface *ifp)
ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state));
state = IPV6_STATE(ifp);
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
TAILQ_INIT(&state->addrs);
@ -912,7 +914,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &addr->s6_addr,
buf, INET6_ADDRSTRLEN);
syslog(LOG_DEBUG, "%s: cmd %d addr %s flags %d",
logger(ctx, LOG_DEBUG, "%s: cmd %d addr %s flags %d",
ifname, cmd, buf, flags);
#endif
@ -1065,7 +1067,7 @@ ipv6_addlinklocalcallback(struct interface *ifp,
if (cb == NULL) {
cb = malloc(sizeof(*cb));
if (cb == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
cb->callback = callback;
@ -1188,7 +1190,8 @@ nextslaacprivate:
return -1;
}
syslog(LOG_WARNING, "%s: waiting for %s to complete",
logger(ap2->iface->ctx, LOG_WARNING,
"%s: waiting for %s to complete",
ap2->iface->name, ap2->saddr);
free(ap);
errno = EEXIST;
@ -1296,7 +1299,8 @@ ipv6_handleifa_addrs(int cmd,
switch (cmd) {
case RTM_DELADDR:
if (ap->flags & IPV6_AF_ADDED) {
syslog(LOG_INFO, "%s: deleted address %s",
logger(ap->iface->ctx, LOG_INFO,
"%s: deleted address %s",
ap->iface->name, ap->saddr);
ap->flags &= ~IPV6_AF_ADDED;
}
@ -1441,14 +1445,15 @@ ipv6_tempdadcallback(void *arg)
struct timespec tv;
if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
syslog(LOG_ERR,
logger(ia->iface->ctx, LOG_ERR,
"%s: too many duplicate temporary addresses",
ia->iface->name);
return;
}
get_monotonic(&tv);
if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
syslog(LOG_ERR, "ipv6_createtempaddr: %m");
logger(ia->iface->ctx, LOG_ERR,
"ipv6_createtempaddr: %m");
else
ia1->dadcounter = ia->dadcounter;
ipv6_deleteaddr(ia);
@ -1669,14 +1674,14 @@ ipv6_regentempaddr(void *arg)
struct ipv6_addr *ia = arg, *ia1;
struct timespec tv;
syslog(LOG_DEBUG, "%s: regen temp addr %s",
logger(ia->iface->ctx, LOG_DEBUG, "%s: regen temp addr %s",
ia->iface->name, ia->saddr);
get_monotonic(&tv);
ia1 = ipv6_createtempaddr(ia, &tv);
if (ia1)
ipv6_addaddr(ia1, &tv);
else
syslog(LOG_ERR, "ipv6_createtempaddr: %m");
logger(ia->iface->ctx, LOG_ERR, "ipv6_createtempaddr: %m");
}
static void
@ -1716,19 +1721,22 @@ desc_route(const char *cmd, const struct rt6 *rt)
char destbuf[INET6_ADDRSTRLEN];
char gatebuf[INET6_ADDRSTRLEN];
const char *ifname, *dest, *gate;
struct dhcpcd_ctx *ctx;
ctx = rt->iface ? rt->iface->ctx : NULL;
ifname = rt->iface ? rt->iface->name : "(no iface)";
dest = inet_ntop(AF_INET6, &rt->dest, destbuf, INET6_ADDRSTRLEN);
gate = inet_ntop(AF_INET6, &rt->gate, gatebuf, INET6_ADDRSTRLEN);
if (IN6_ARE_ADDR_EQUAL(&rt->gate, &in6addr_any))
syslog(LOG_INFO, "%s: %s route to %s/%d", ifname, cmd,
dest, ipv6_prefixlen(&rt->net));
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
ifname, cmd, dest, ipv6_prefixlen(&rt->net));
else if (IN6_ARE_ADDR_EQUAL(&rt->dest, &in6addr_any) &&
IN6_ARE_ADDR_EQUAL(&rt->net, &in6addr_any))
syslog(LOG_INFO, "%s: %s default route via %s", ifname, cmd,
gate);
logger(ctx, LOG_INFO, "%s: %s default route via %s",
ifname, cmd, gate);
else
syslog(LOG_INFO, "%s: %s%s route to %s/%d via %s", ifname, cmd,
logger(ctx, LOG_INFO, "%s: %s%s route to %s/%d via %s",
ifname, cmd,
rt->flags & RTF_REJECT ? " reject" : "",
dest, ipv6_prefixlen(&rt->net), gate);
}
@ -1834,19 +1842,19 @@ nc_route(struct rt6 *ort, struct rt6 *nrt)
/* With route metrics, we can safely add the new route before
* deleting the old route. */
if ((retval = if_route6(RTM_ADD, nrt)) == -1)
syslog(LOG_ERR, "if_route6 (ADD): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route6 (ADD): %m");
if (ort && if_route6(RTM_DELETE, ort) == -1 &&
errno != ESRCH)
syslog(LOG_ERR, "if_route6 (DEL): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route6 (DEL): %m");
return retval;
#else
/* No route metrics, we need to delete the old route before
* adding the new one. */
if (ort && if_route6(RTM_DELETE, ort) == -1 && errno != ESRCH)
syslog(LOG_ERR, "if_route6: %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route6: %m");
if (if_route6(RTM_ADD, nrt) == 0)
return 0;
syslog(LOG_ERR, "if_route6 (ADD): %m");
logger(nrt->iface->ctx, LOG_ERR, "if_route6 (ADD): %m");
return -1;
#endif
}
@ -1859,7 +1867,8 @@ d_route(struct rt6 *rt)
desc_route("deleting", rt);
retval = if_route6(RTM_DELETE, rt);
if (retval != 0 && errno != ENOENT && errno != ESRCH)
syslog(LOG_ERR,"%s: if_delroute6: %m", rt->iface->name);
logger(rt->iface->ctx, LOG_ERR,
"%s: if_delroute6: %m", rt->iface->name);
return retval;
}
@ -1870,7 +1879,7 @@ make_route(const struct interface *ifp, const struct ra *rap)
r = calloc(1, sizeof(*r));
if (r == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
r->iface = ifp;
@ -2025,7 +2034,7 @@ ipv6_buildroutes(struct dhcpcd_ctx *ctx)
nrs = malloc(sizeof(*nrs));
if (nrs == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return;
}
TAILQ_INIT(nrs);

180
ipv6nd.c
View File

@ -39,7 +39,6 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 3
@ -264,7 +263,7 @@ ipv6nd_sendrsprobe(void *arg)
struct in6_pktinfo pi;
if (ipv6_linklocal(ifp) == NULL) {
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: delaying Router Solicitation for LL address",
ifp->name);
ipv6_addlinklocalcallback(ifp, ipv6nd_sendrsprobe, ifp);
@ -278,7 +277,7 @@ ipv6nd_sendrsprobe(void *arg)
#endif
dst.sin6_scope_id = ifp->index;
if (inet_pton(AF_INET6, ALLROUTERS, &dst.sin6_addr) != 1) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
@ -299,9 +298,11 @@ ipv6nd_sendrsprobe(void *arg)
pi.ipi6_ifindex = CAST_IPI6_IFINDEX(ifp->index);
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
syslog(LOG_DEBUG, "%s: sending Router Solicitation", ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: sending Router Solicitation", ifp->name);
if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) {
syslog(LOG_ERR, "%s: %s: sendmsg: %m", ifp->name, __func__);
logger(ifp->ctx, LOG_ERR,
"%s: %s: sendmsg: %m", ifp->name, __func__);
ipv6nd_drop(ifp);
ifp->options->options &= ~(DHCPCD_IPV6 | DHCPCD_IPV6RS);
return;
@ -311,7 +312,8 @@ ipv6nd_sendrsprobe(void *arg)
eloop_timeout_add_sec(ifp->ctx->eloop,
RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
else
syslog(LOG_WARNING, "%s: no IPv6 Routers available", ifp->name);
logger(ifp->ctx, LOG_WARNING,
"%s: no IPv6 Routers available", ifp->name);
}
static void
@ -320,7 +322,8 @@ ipv6nd_reachable(struct ra *rap, int flags)
if (flags & IPV6ND_REACHABLE) {
if (rap->lifetime && rap->expired) {
syslog(LOG_INFO, "%s: %s is reachable again",
logger(rap->iface->ctx, LOG_INFO,
"%s: %s is reachable again",
rap->iface->name, rap->sfrom);
rap->expired = 0;
ipv6_buildroutes(rap->iface->ctx);
@ -329,7 +332,7 @@ ipv6nd_reachable(struct ra *rap, int flags)
}
} else {
if (rap->lifetime && !rap->expired) {
syslog(LOG_WARNING,
logger(rap->iface->ctx, LOG_WARNING,
"%s: %s is unreachable, expiring it",
rap->iface->name, rap->sfrom);
rap->expired = 1;
@ -461,7 +464,8 @@ rtpref(struct ra *rap)
case ND_RA_FLAG_RTPREF_LOW:
return (RTPREF_LOW);
default:
syslog(LOG_ERR, "rtpref: impossible RA flag %x", rap->flags);
logger(rap->iface->ctx, LOG_ERR,
"rtpref: impossible RA flag %x", rap->flags);
return (RTPREF_INVALID);
}
/* NOTREACHED */
@ -502,7 +506,7 @@ ipv6nd_scriptrun(struct ra *rap)
ipv6_iffindaddr(ap->iface, &ap->addr))
ap->flags |= IPV6_AF_DADCOMPLETED;
if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
syslog(LOG_DEBUG,
logger(ap->iface->ctx, LOG_DEBUG,
"%s: waiting for Router Advertisement"
" DAD to complete",
rap->iface->name);
@ -535,7 +539,7 @@ ipv6nd_scriptrun(struct ra *rap)
#if 0
else if (options & DHCPCD_DAEMONISE &&
!(options & DHCPCD_DAEMONISED) && new_data)
syslog(LOG_WARNING,
logger(rap->iface->ctx, LOG_WARNING,
"%s: did not fork due to an absent"
" RDNSS option in the RA",
ifp->name);
@ -588,8 +592,8 @@ ipv6nd_dadcallback(void *arg)
ap->flags |= IPV6_AF_DADCOMPLETED;
if (ap->flags & IPV6_AF_DUPLICATED) {
ap->dadcounter++;
syslog(LOG_WARNING, "%s: DAD detected %s",
ap->iface->name, ap->saddr);
logger(ifp->ctx, LOG_WARNING, "%s: DAD detected %s",
ifp->name, ap->saddr);
/* Try and make another stable private address.
* Because ap->dadcounter is always increamented,
@ -597,23 +601,23 @@ ipv6nd_dadcallback(void *arg)
/* XXX Cache DAD counter per prefix/id/ssid? */
if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
if (ap->dadcounter >= IDGEN_RETRIES) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: unable to obtain a"
" stable private address",
ifp->name);
goto try_script;
}
syslog(LOG_INFO, "%s: deleting address %s",
logger(ifp->ctx, LOG_INFO, "%s: deleting address %s",
ifp->name, ap->saddr);
if (if_deladdress6(ap) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
syslog(LOG_ERR, "if_deladdress6: %m");
logger(ifp->ctx, LOG_ERR, "if_deladdress6: %m");
dadcounter = ap->dadcounter;
if (ipv6_makestableprivate(&ap->addr,
&ap->prefix, ap->prefix_len,
ifp, &dadcounter) == -1)
{
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: ipv6_makestableprivate: %m",
ifp->name);
return;
@ -659,7 +663,7 @@ try_script:
}
if (wascompleted && found) {
syslog(LOG_DEBUG,
logger(rap->iface->ctx, LOG_DEBUG,
"%s: Router Advertisement DAD completed",
rap->iface->name);
if (ipv6nd_scriptrun(rap))
@ -670,9 +674,10 @@ try_script:
}
static void
ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
struct icmp6_hdr *icp, size_t len)
{
struct ipv6_ctx *ctx = dctx->ipv6;
size_t olen, l, n;
ssize_t r;
struct nd_router_advert *nd_ra;
@ -697,25 +702,27 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
#endif
if (len < sizeof(struct nd_router_advert)) {
syslog(LOG_ERR, "IPv6 RA packet too short from %s", ctx->sfrom);
logger(dctx, LOG_ERR,
"IPv6 RA packet too short from %s", ctx->sfrom);
return;
}
if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
syslog(LOG_ERR, "RA from non local address %s", ctx->sfrom);
logger(dctx, LOG_ERR,
"RA from non local address %s", ctx->sfrom);
return;
}
if (ifp == NULL) {
#ifdef DEBUG_RS
syslog(LOG_DEBUG, "RA for unexpected interface from %s",
ctx->sfrom);
logger(dctx, LOG_DEBUG,
"RA for unexpected interface from %s", ctx->sfrom);
#endif
return;
}
if (!(ifp->options->options & DHCPCD_IPV6RS)) {
#ifdef DEBUG_RS
syslog(LOG_DEBUG, "%s: unexpected RA from %s",
logger(ifp->ctx, LOG_DEBUG, "%s: unexpected RA from %s",
ifp->name, ctx->sfrom);
#endif
return;
@ -724,15 +731,16 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
/* We could receive a RA before we sent a RS*/
if (ipv6_linklocal(ifp) == NULL) {
#ifdef DEBUG_RS
syslog(LOG_DEBUG, "%s: received RA from %s (no link-local)",
logger(ifp->ctx, LOG_DEBUG,
"%s: received RA from %s (no link-local)",
ifp->name, ctx->sfrom);
#endif
return;
}
if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr)) {
syslog(LOG_DEBUG, "%s: ignoring RA from ourself %s",
ifp->name, ctx->sfrom);
logger(ifp->ctx, LOG_DEBUG,
"%s: ignoring RA from ourself %s", ifp->name, ctx->sfrom);
return;
}
@ -757,13 +765,13 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
} else
new_data = 0;
if (new_data || ifp->options->options & DHCPCD_DEBUG)
syslog(LOG_INFO, "%s: Router Advertisement from %s",
logger(ifp->ctx, LOG_INFO, "%s: Router Advertisement from %s",
ifp->name, ctx->sfrom);
if (rap == NULL) {
rap = calloc(1, sizeof(*rap));
if (rap == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
rap->iface = ifp;
@ -777,7 +785,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
if (rap->data_len == 0) {
rap->data = malloc(len);
if (rap->data == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
if (new_rap)
free(rap);
return;
@ -789,7 +797,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
get_monotonic(&rap->received);
rap->flags = nd_ra->nd_ra_flags_reserved;
if (new_rap == 0 && rap->lifetime == 0)
syslog(LOG_WARNING, "%s: %s router available",
logger(ifp->ctx, LOG_WARNING, "%s: %s router available",
ifp->name, rap->sfrom);
rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
if (nd_ra->nd_ra_reachable) {
@ -812,17 +820,19 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
lifetime = ~0U;
for (; len > 0; p += olen, len -= olen) {
if (len < sizeof(struct nd_opt_hdr)) {
syslog(LOG_ERR, "%s: short option", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: short option", ifp->name);
break;
}
ndo = (struct nd_opt_hdr *)p;
olen = (size_t)ndo->nd_opt_len * 8;
if (olen == 0) {
syslog(LOG_ERR, "%s: zero length option", ifp->name);
logger(ifp->ctx, LOG_ERR,
"%s: zero length option", ifp->name);
break;
}
if (olen > len) {
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: Option length exceeds message", ifp->name);
break;
}
@ -832,13 +842,13 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
case ND_OPT_PREFIX_INFORMATION:
pi = (struct nd_opt_prefix_info *)(void *)ndo;
if (pi->nd_opt_pi_len != 4) {
syslog(new_data ? LOG_ERR : LOG_DEBUG,
logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
"%s: invalid option len for prefix",
ifp->name);
continue;
}
if (pi->nd_opt_pi_prefix_len > 128) {
syslog(new_data ? LOG_ERR : LOG_DEBUG,
logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
"%s: invalid prefix len",
ifp->name);
continue;
@ -846,14 +856,14 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) ||
IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix))
{
syslog(new_data ? LOG_ERR : LOG_DEBUG,
logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
"%s: invalid prefix in RA", ifp->name);
continue;
}
if (ntohl(pi->nd_opt_pi_preferred_time) >
ntohl(pi->nd_opt_pi_valid_time))
{
syslog(new_data ? LOG_ERR : LOG_DEBUG,
logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
"%s: pltime > vltime", ifp->name);
continue;
}
@ -958,7 +968,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
if (new_ap && ap->prefix_pltime) {
if (ipv6_createtempaddr(ap,
&ap->acquired) == NULL)
syslog(LOG_ERR,
logger(ap->iface->ctx, LOG_ERR,
"ipv6_createtempaddr: %m");
}
}
@ -971,7 +981,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
mtu = (struct nd_opt_mtu *)(void *)p;
mtuv = ntohl(mtu->nd_opt_mtu_mtu);
if (mtuv < IPV6_MMTU) {
syslog(LOG_ERR, "%s: invalid MTU %d",
logger(ifp->ctx, LOG_ERR, "%s: invalid MTU %d",
ifp->name, mtuv);
break;
}
@ -1028,7 +1038,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
n = (size_t)(dnssl->nd_opt_dnssl_len - 1) * 8;
r = decode_rfc3397(NULL, 0, op, n);
if (r < 1) {
syslog(new_data ? LOG_ERR : LOG_DEBUG,
logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
"%s: invalid DNSSL option",
ifp->name);
continue;
@ -1048,7 +1058,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
STRING | ARRAY | DOMAIN,
(const uint8_t *)tmp, l);
} else
syslog(LOG_ERR, "%s: %m",
logger(ifp->ctx, LOG_ERR, "%s: %m",
__func__);
free(tmp);
}
@ -1060,7 +1070,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
}
if (opt == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
continue;
}
@ -1085,7 +1095,7 @@ extra_opt:
if (rao == NULL) {
rao = malloc(sizeof(*rao));
if (rao == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
continue;
}
rao->type = (uint16_t)n;
@ -1136,14 +1146,16 @@ handle_flag:
goto nodhcp6;
if (rap->flags & ND_RA_FLAG_MANAGED) {
if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1)
syslog(LOG_ERR, "dhcp6_start: %s: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"dhcp6_start: %s: %m", ifp->name);
} else if (rap->flags & ND_RA_FLAG_OTHER) {
if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)
syslog(LOG_ERR, "dhcp6_start: %s: %m", ifp->name);
logger(ifp->ctx, LOG_ERR,
"dhcp6_start: %s: %m", ifp->name);
} else {
if (new_data)
syslog(LOG_DEBUG, "%s: No DHCPv6 instruction in RA",
ifp->name);
logger(ifp->ctx, LOG_DEBUG,
"%s: No DHCPv6 instruction in RA", ifp->name);
nodhcp6:
if (ifp->ctx->options & DHCPCD_TEST) {
eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
@ -1202,7 +1214,7 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
if (env) {
snprintf(buffer, sizeof(buffer),
"ra%zu_from", i);
setvar(&env, prefix, buffer, rap->sfrom);
setvar(ifp->ctx, &env, prefix, buffer, rap->sfrom);
}
l++;
@ -1244,7 +1256,8 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
if (rao->type == ND_OPT_MTU) {
new = strchr(**var, '=');
if (new == NULL) {
syslog(LOG_ERR, "new is null");
logger(ifp->ctx, LOG_ERR,
"new is null");
continue;
} else
new++;
@ -1265,7 +1278,8 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
rao->option,
len - 1);
} else
syslog(LOG_ERR,
logger(ifp->ctx,
LOG_ERR,
"new is null");
}
continue;
@ -1278,19 +1292,21 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
*new++ = ' ';
strlcpy(new, rao->option, len);
} else
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR,
"%s: %m", __func__);
continue;
}
if (env) {
snprintf(buffer, sizeof(buffer),
"ra%zu_%s", i, optn);
setvar(&env, prefix, buffer, rao->option);
setvar(ifp->ctx, &env,
prefix, buffer, rao->option);
}
}
}
if (env)
setvard(&env, prefix, "ra_count", i);
setvard(ifp->ctx, &env, prefix, "ra_count", i);
l++;
return (ssize_t)l;
}
@ -1335,7 +1351,7 @@ ipv6nd_expirera(void *arg)
if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
{
if (!rap->expired) {
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: %s: router expired",
ifp->name, rap->sfrom);
rap->expired = expired = 1;
@ -1372,7 +1388,7 @@ ipv6nd_expirera(void *arg)
if (timespeccmp(&now, &rao->expire, >)) {
/* Expired prefixes are logged above */
if (rao->type != ND_OPT_PREFIX_INFORMATION)
syslog(LOG_WARNING,
logger(ifp->ctx, LOG_WARNING,
"%s: %s: expired option %d",
ifp->name, rap->sfrom, rao->type);
TAILQ_REMOVE(&rap->options, rao, next);
@ -1435,9 +1451,10 @@ ipv6nd_drop(struct interface *ifp)
}
static void
ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
ipv6nd_handlena(struct dhcpcd_ctx *dctx, struct interface *ifp,
struct icmp6_hdr *icp, size_t len)
{
struct ipv6_ctx *ctx = dctx->ipv6;
struct nd_neighbor_advert *nd_na;
struct ra *rap;
int is_router, is_solicited;
@ -1446,14 +1463,14 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
if (ifp == NULL) {
#ifdef DEBUG_NS
syslog(LOG_DEBUG, "NA for unexpected interface from %s",
ctx->sfrom);
logger(ctx, LOG_DEBUG, "NA for unexpected interface from %s",
dctx->sfrom);
#endif
return;
}
if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
syslog(LOG_ERR, "%s: IPv6 NA too short from %s",
logger(ifp->ctx, LOG_ERR, "%s: IPv6 NA too short from %s",
ifp->name, ctx->sfrom);
return;
}
@ -1465,7 +1482,7 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
buf, INET6_ADDRSTRLEN);
if (IN6_IS_ADDR_MULTICAST(&nd_na->nd_na_target)) {
syslog(LOG_ERR, "%s: NA multicast address %s (%s)",
logger(ifp->ctx, LOG_ERR, "%s: NA multicast address %s (%s)",
ifp->name, taddr, ctx->sfrom);
return;
}
@ -1477,20 +1494,20 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
}
if (rap == NULL) {
#ifdef DEBUG_NS
syslog(LOG_DEBUG, "%s: unexpected NA from %s for %s",
logger(ifp->ctx, LOG_DEBUG, "%s: unexpected NA from %s for %s",
ifp->name, ctx->sfrom, taddr);
#endif
return;
}
#ifdef DEBUG_NS
syslog(LOG_DEBUG, "%s: %sNA for %s from %s",
logger(ifp->ctx, LOG_DEBUG, "%s: %sNA for %s from %s",
ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom);
#endif
/* Node is no longer a router, so remove it from consideration */
if (!is_router && !rap->expired) {
syslog(LOG_INFO, "%s: %s not a router (%s)",
logger(ifp->ctx, LOG_INFO, "%s: %s not a router (%s)",
ifp->name, taddr, ctx->sfrom);
rap->expired = 1;
ipv6_buildroutes(ifp->ctx);
@ -1501,7 +1518,7 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
if (is_solicited && is_router && rap->lifetime) {
if (rap->expired) {
rap->expired = 0;
syslog(LOG_INFO, "%s: %s reachable (%s)",
logger(ifp->ctx, LOG_INFO, "%s: %s reachable (%s)",
ifp->name, taddr, ctx->sfrom);
ipv6_buildroutes(ifp->ctx);
script_runreason(rap->iface, "ROUTERADVERT"); /* XXX */
@ -1512,7 +1529,7 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, struct interface *ifp,
static void
ipv6nd_handledata(void *arg)
{
struct dhcpcd_ctx *dhcpcd_ctx;
struct dhcpcd_ctx *dctx;
struct ipv6_ctx *ctx;
ssize_t len;
struct cmsghdr *cm;
@ -1521,14 +1538,14 @@ ipv6nd_handledata(void *arg)
struct icmp6_hdr *icp;
struct interface *ifp;
dhcpcd_ctx = arg;
ctx = dhcpcd_ctx->ipv6;
dctx = arg;
ctx = dctx->ipv6;
ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int));
len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
if (len == -1) {
syslog(LOG_ERR, "recvmsg: %m");
eloop_event_delete(dhcpcd_ctx->eloop, ctx->nd_fd, 0);
logger(dctx, LOG_ERR, "recvmsg: %m");
eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
close(ctx->nd_fd);
ctx->nd_fd = -1;
return;
@ -1536,7 +1553,7 @@ ipv6nd_handledata(void *arg)
ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
ctx->ntopbuf, INET6_ADDRSTRLEN);
if ((size_t)len < sizeof(struct icmp6_hdr)) {
syslog(LOG_ERR, "IPv6 ICMP packet too short from %s",
logger(dctx, LOG_ERR, "IPv6 ICMP packet too short from %s",
ctx->sfrom);
return;
}
@ -1562,13 +1579,13 @@ ipv6nd_handledata(void *arg)
}
if (pkt.ipi6_ifindex == 0 || hoplimit == 0) {
syslog(LOG_ERR,
logger(dctx, LOG_ERR,
"IPv6 RA/NA did not contain index or hop limit from %s",
ctx->sfrom);
return;
}
TAILQ_FOREACH(ifp, dhcpcd_ctx->ifaces, next) {
TAILQ_FOREACH(ifp, dctx->ifaces, next) {
if (ifp->index == (unsigned int)pkt.ipi6_ifindex) {
if (!(ifp->options->options & DHCPCD_IPV6) ||
ifp->options->options & DHCPCD_PFXDLGONLY)
@ -1581,15 +1598,15 @@ ipv6nd_handledata(void *arg)
if (icp->icmp6_code == 0) {
switch(icp->icmp6_type) {
case ND_NEIGHBOR_ADVERT:
ipv6nd_handlena(ctx, ifp, icp, (size_t)len);
ipv6nd_handlena(dctx, ifp, icp, (size_t)len);
return;
case ND_ROUTER_ADVERT:
ipv6nd_handlera(ctx, ifp, icp, (size_t)len);
ipv6nd_handlera(dctx, ifp, icp, (size_t)len);
return;
}
}
syslog(LOG_ERR, "invalid IPv6 type %d or code %d from %s",
logger(dctx, LOG_ERR, "invalid IPv6 type %d or code %d from %s",
icp->icmp6_type, icp->icmp6_code, ctx->sfrom);
}
@ -1599,9 +1616,9 @@ ipv6nd_startrs1(void *arg)
struct interface *ifp = arg;
struct rs_state *state;
syslog(LOG_INFO, "%s: soliciting an IPv6 router", ifp->name);
logger(ifp->ctx, LOG_INFO, "%s: soliciting an IPv6 router", ifp->name);
if (ipv6nd_open(ifp->ctx) == -1) {
syslog(LOG_ERR, "%s: ipv6nd_open: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: ipv6nd_open: %m", __func__);
return;
}
@ -1610,7 +1627,7 @@ ipv6nd_startrs1(void *arg)
ifp->if_data[IF_DATA_IPV6ND] = calloc(1, sizeof(*state));
state = RS_STATE(ifp);
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
}
@ -1619,7 +1636,8 @@ ipv6nd_startrs1(void *arg)
* address could have changed. */
ipv6nd_makersprobe(ifp);
if (state->rs == NULL) {
syslog(LOG_ERR, "%s: ipv6ns_makersprobe: %m", __func__);
logger(ifp->ctx, LOG_ERR,
"%s: ipv6ns_makersprobe: %m", __func__);
return;
}
@ -1637,7 +1655,7 @@ ipv6nd_startrs(struct interface *ifp)
tv.tv_nsec = (suseconds_t)arc4random_uniform(
MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
timespecnorm(&tv);
syslog(LOG_DEBUG,
logger(ifp->ctx, LOG_DEBUG,
"%s: delaying IPv6 router solicitation for %0.1f seconds",
ifp->name, timespec_to_double(&tv));
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);

View File

@ -39,7 +39,6 @@
* config.h will pull it in, or our compat one. */
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
@ -128,7 +127,7 @@ exec_script(U const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env)
#ifdef INET
static char *
make_var(const char *prefix, const char *var)
make_var(struct dhcpcd_ctx *ctx, const char *prefix, const char *var)
{
size_t len;
char *v;
@ -136,7 +135,7 @@ make_var(const char *prefix, const char *var)
len = strlen(prefix) + strlen(var) + 2;
v = malloc(len);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
snprintf(v, len, "%s_%s", prefix, var);
@ -145,7 +144,7 @@ make_var(const char *prefix, const char *var)
static int
append_config(char ***env, size_t *len,
append_config(struct dhcpcd_ctx *ctx, char ***env, size_t *len,
const char *prefix, const char *const *config)
{
size_t i, j, e1;
@ -164,7 +163,7 @@ append_config(char ***env, size_t *len,
if (strncmp(ne[j] + strlen(prefix) + 1,
config[i], e1) == 0)
{
p = make_var(prefix, config[i]);
p = make_var(ctx, prefix, config[i]);
if (p == NULL) {
ret = -1;
break;
@ -176,14 +175,14 @@ append_config(char ***env, size_t *len,
}
if (j == *len) {
j++;
p = make_var(prefix, config[i]);
p = make_var(ctx, prefix, config[i]);
if (p == NULL) {
ret = -1;
break;
}
nep = realloc(ne, sizeof(char *) * (j + 1));
if (nep == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
logger(ctx, LOG_ERR, "%s: %m", __func__);
free(p);
ret = -1;
break;
@ -425,7 +424,7 @@ make_env(const struct interface *ifp, const char *reason, char ***argv)
goto eexit;
elen += (size_t)n;
}
if (append_config(&env, &elen, "old",
if (append_config(ifp->ctx, &env, &elen, "old",
(const char *const *)ifo->config) == -1)
goto eexit;
}
@ -475,7 +474,7 @@ dumplease:
goto eexit;
elen += (size_t)n;
}
if (append_config(&env, &elen, "new",
if (append_config(ifp->ctx, &env, &elen, "new",
(const char *const *)ifo->config) == -1)
goto eexit;
}
@ -537,7 +536,7 @@ dumplease:
return (ssize_t)elen;
eexit:
syslog(LOG_ERR, "%s: %m", __func__);
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
if (env) {
nenv = env;
while (*nenv)
@ -637,13 +636,13 @@ script_runreason(const struct interface *ifp, const char *reason)
argv[0] = ifp->options->script ? ifp->options->script : UNCONST(SCRIPT);
argv[1] = NULL;
syslog(LOG_DEBUG, "%s: executing `%s' %s",
logger(ifp->ctx, LOG_DEBUG, "%s: executing `%s' %s",
ifp->name, argv[0], reason);
/* Make our env */
elen = (size_t)make_env(ifp, reason, &env);
if (elen == (size_t)-1) {
syslog(LOG_ERR, "%s: make_env: %m", ifp->name);
logger(ifp->ctx, LOG_ERR, "%s: make_env: %m", ifp->name);
return -1;
}
/* Resize for PATH and RC_SVCNAME */
@ -684,23 +683,23 @@ script_runreason(const struct interface *ifp, const char *reason)
pid = exec_script(ifp->ctx, argv, env);
if (pid == -1)
syslog(LOG_ERR, "%s: %s: %m", __func__, argv[0]);
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) {
syslog(LOG_ERR, "waitpid: %m");
logger(ifp->ctx, LOG_ERR, "waitpid: %m");
status = 0;
break;
}
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status))
syslog(LOG_ERR,
logger(ifp->ctx, LOG_ERR,
"%s: %s: WEXITSTATUS %d",
__func__, argv[0], WEXITSTATUS(status));
} else if (WIFSIGNALED(status))
syslog(LOG_ERR, "%s: %s: %s",
logger(ifp->ctx, LOG_ERR, "%s: %s: %s",
__func__, argv[0], strsignal(WTERMSIG(status)));
}
@ -714,13 +713,14 @@ script_runreason(const struct interface *ifp, const char *reason)
elen = (size_t)arraytostr((const char *const *)env,
&bigenv);
if ((ssize_t)elen == -1) {
syslog(LOG_ERR, "%s: arraytostr: %m",
logger(ifp->ctx, LOG_ERR, "%s: arraytostr: %m",
ifp->name);
break;
}
}
if (control_queue(fd, bigenv, elen, 1) == -1)
syslog(LOG_ERR, "%s: control_queue: %m", __func__);
logger(ifp->ctx, LOG_ERR,
"%s: control_queue: %m", __func__);
else
status = 1;
}