mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-24 10:35:03 +08:00
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:
parent
30d2a5f522
commit
069e2f284f
25
arp.c
25
arp.c
@ -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
1
auth.c
@ -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
142
common.c
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
40
common.h
40
common.h
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
23
configure
vendored
@ -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
|
||||
|
@ -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
2
defs.h
@ -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
19
dev.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
353
dhcp6.c
353
dhcp6.c
@ -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";
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
15
dhcpcd.8.in
15
dhcpcd.8.in
@ -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
240
dhcpcd.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
2
dhcpcd.h
2
dhcpcd.h
@ -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
18
duid.c
@ -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
28
eloop.c
@ -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;
|
||||
}
|
||||
|
||||
|
8
eloop.h
8
eloop.h
@ -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
|
||||
|
39
if-bsd.c
39
if-bsd.c
@ -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;
|
||||
|
@ -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
|
||||
|
15
if-linux.c
15
if-linux.c
@ -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;
|
||||
|
306
if-options.c
306
if-options.c
File diff suppressed because it is too large
Load Diff
@ -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
15
if.c
@ -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
80
ipv4.c
@ -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;
|
||||
|
13
ipv4ll.c
13
ipv4ll.c
@ -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
93
ipv6.c
@ -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
180
ipv6nd.c
@ -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);
|
||||
|
36
script.c
36
script.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user