#include <resolv.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include "config.h"
#include "odhcp6c.h"
}
void config_dhcp_reset(void) {
+ config_dhcp.log_level = LOG_WARNING;
config_dhcp.release = true;
config_dhcp.dscp = 0;
config_dhcp.sk_prio = 0;
bool config_set_dscp(unsigned int value) {
if (value > 63) {
- syslog(LOG_ERR, "Invalid DSCP value");
+ error("Invalid DSCP value");
return false;
}
config_dhcp.dscp = value;
bool config_set_sk_priority(unsigned int priority) {
if (priority > 6) {
- syslog(LOG_ERR, "Invalid SK priority value");
+ error("Invalid SK priority value");
return false;
}
config_dhcp.sk_prio = priority;
} else if (!strcmp(mode, "try")) {
config_dhcp.ia_na_mode = IA_MODE_TRY;
} else {
- syslog(LOG_ERR, "Invalid IA_NA Request Addresses mode");
+ error("Invalid IA_NA Request Addresses mode");
return false;
}
prefix.iaid = htonl(id);
if (odhcp6c_add_state(STATE_IA_PD_INIT, &prefix, sizeof(prefix))) {
- syslog(LOG_ERR, "Failed to set request IPv6-Prefix");
+ error("Failed to set request IPv6-Prefix");
return false;
}
}
bool config_add_requested_options(unsigned int option) {
if (option > UINT16_MAX) {
- syslog(LOG_ERR, "Invalid requested option");
+ error("Invalid requested option");
return false;
}
option = htons(option);
if (odhcp6c_insert_state(STATE_ORO, 0, &option, 2)) {
- syslog(LOG_ERR, "Failed to set requested option");
+ error("Failed to set requested option");
return false;
}
config_dhcp.oro_user_cnt++;
bool config_set_rtx_delay_max(enum config_dhcp_msg msg, unsigned int value)
{
if (msg >= CONFIG_DHCP_MAX || value > UINT8_MAX) {
- syslog(LOG_ERR, "Invalid retransmission Maximum Delay value");
+ error("Invalid retransmission Maximum Delay value");
return false;
}
config_dhcp.message_rtx[msg].delay_max = value;
bool config_set_rtx_timeout_init(enum config_dhcp_msg msg, unsigned int value)
{
if (msg >= CONFIG_DHCP_MAX || value > UINT8_MAX || value == 0) {
- syslog(LOG_ERR, "Invalid retransmission Initial Timeout value");
+ error("Invalid retransmission Initial Timeout value");
return false;
}
config_dhcp.message_rtx[msg].timeout_init = value;
bool config_set_rtx_timeout_max(enum config_dhcp_msg msg, unsigned int value)
{
if (msg >= CONFIG_DHCP_MAX || value > UINT16_MAX) {
- syslog(LOG_ERR, "Invalid retransmission Maximum Timeout value");
+ error("Invalid retransmission Maximum Timeout value");
return false;
}
config_dhcp.message_rtx[msg].timeout_max = value;
bool config_set_rtx_rc_max(enum config_dhcp_msg msg, unsigned int value)
{
if (msg >= CONFIG_DHCP_MAX || value > UINT8_MAX) {
- syslog(LOG_ERR, "Invalid retransmission Retry Attempt value");
+ error("Invalid retransmission Retry Attempt value");
return false;
}
config_dhcp.message_rtx[msg].rc_max = value;
bool config_set_irt_default(unsigned int value)
{
if (value == 0) {
- syslog(LOG_ERR, "Invalid Default Information Refresh Time value");
+ error("Invalid Default Information Refresh Time value");
return false;
}
config_dhcp.irt_default = value;
bool config_set_irt_min(unsigned int value)
{
if (value == 0) {
- syslog(LOG_ERR, "Invalid Minimum Information Refresh Time value");
+ error("Invalid Minimum Information Refresh Time value");
return false;
}
config_dhcp.irt_min = value;
bool config_set_rand_factor(unsigned int value)
{
if (value > 999 || value < 10) {
- syslog(LOG_ERR, "Invalid Random Factor value");
+ error("Invalid Random Factor value");
return false;
}
config_dhcp.rand_factor = value;
} else if (!strcmp(protocol, "ReconfigureKeyAuthentication")) {
config_dhcp.auth_protocol = AUTH_PROT_RKAP;
} else {
- syslog(LOG_ERR, "Invalid Authentication protocol");
+ error("Invalid Authentication protocol");
return false;
}
if (odhcp6c_add_state(STATE_OPTS, &opt_hdr, sizeof(opt_hdr)) ||
odhcp6c_add_state(STATE_OPTS, data, len)) {
- syslog(LOG_ERR, "Failed to add option %hu", code);
+ error("Failed to add option %hu", code);
return 1;
}
};
struct config_dhcp {
+ bool log_syslog;
bool release;
+ int log_level;
int dscp;
int sk_prio;
bool stateful_only_mode;
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
{
int flags = fcntl(sockfd, F_GETFL, 0);
if (flags == -1) {
- syslog(LOG_ERR,
+ error(
"Failed to get the dhcpv6 socket flags: fcntl F_GETFL failed (%s)",
strerror(errno));
return -1;
// Set the socket to non-blocking
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
- syslog(LOG_ERR,
+ error(
"Failed to set the dhcpv6 socket to non-blocking: fcntl F_SETFL failed (%s)",
strerror(errno));
return -1;
if (sendmsg(sock, &msg, 0) < 0) {
char in6_str[INET6_ADDRSTRLEN];
- syslog(LOG_ERR, "Failed to send %s message to %s (%s)",
+ error("Failed to send %s message to %s (%s)",
dhcpv6_msg_to_str(req_msg_type),
inet_ntop(AF_INET6, (const void *)&srv.sin6_addr,
in6_str, sizeof(in6_str)), strerror(errno));
_o_fallthrough;
case DHCPV6_MSG_INFO_REQ:
msg = odata[0];
- syslog(LOG_NOTICE, "Need to respond with %s in reply to %s",
+ notice("Need to respond with %s in reply to %s",
dhcpv6_msg_to_str(msg), dhcpv6_msg_to_str(DHCPV6_MSG_RECONF));
break;
if (t1 > t2 && t1 > 0 && t2 > 0)
return 0;
- syslog(LOG_INFO, "%s %04x T1 %d T2 %d", ntohs(ia_hdr->type) == DHCPV6_OPT_IA_PD ? "IA_PD" : "IA_NA", ntohl(ia_hdr->iaid), t1, t2);
+ info("%s %04x T1 %d T2 %d", ntohs(ia_hdr->type) == DHCPV6_OPT_IA_PD ? "IA_PD" : "IA_NA", ntohl(ia_hdr->iaid), t1, t2);
// Update address IA
dhcpv6_for_each_option(&ia_hdr[1], end, otype, olen, odata) {
if (odhcp6c_update_entry(STATE_IA_PD, &entry, 0))
updated_IAs++;
- syslog(LOG_INFO, "%s/%d preferred %d valid %d",
+ info("%s/%d preferred %d valid %d",
inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)),
entry.length, entry.preferred , entry.valid);
}
if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0))
updated_IAs++;
- syslog(LOG_INFO, "%s preferred %d valid %d",
+ info("%s preferred %d valid %d",
inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)),
entry.preferred , entry.valid);
}
t2 = l_t2;
t3 = l_t3;
- syslog(LOG_INFO, "T1 %"PRId64"s, T2 %"PRId64"s, T3 %"PRId64"s", t1, t2, t3);
+ info("T1 %"PRId64"s, T2 %"PRId64"s, T3 %"PRId64"s", t1, t2, t3);
}
return (unsigned int)(ia_pd_entry_cnt + ia_na_entry_cnt);
*dst = 0;
- syslog(LOG_WARNING, "Server returned %s status '%s %s'",
+ warn("Server returned %s status '%s %s'",
scope, dhcpv6_status_code_to_str(code), buf);
}
if (retx->timeout == 0)
return -1;
- syslog(LOG_NOTICE, "Starting %s transaction (timeout %"PRIu64"s, max rc %d)",
+ notice("Starting %s transaction (timeout %"PRIu64"s, max rc %d)",
retx->name, retx->timeout, retx->max_rc);
// Generate transaction ID
case DHCPV6_MSG_UNKNOWN:
break;
default:
- syslog(LOG_NOTICE, "Send %s message (elapsed %"PRIu64"ms, rc %d)",
+ notice("Send %s message (elapsed %"PRIu64"ms, rc %d)",
retx->name, elapsed, retx->rc);
_o_fallthrough;
case DHCPV6_MSG_SOLICIT:
// Receive cycle
len = recvmsg(sock, &msg, 0);
if (len < 0) {
- syslog(LOG_ERR, "Error occurred when reading the response of (%s) error(%s)",
+ error("Error occurred when reading the response of (%s) error(%s)",
retx->name, strerror(errno));
return -1;
}
retx->round_start = odhcp6c_get_milli_time();
uint64_t elapsed = retx->round_start - retx->start;
- syslog(LOG_NOTICE, "Got a valid %s after %"PRIu64"ms",
+ notice("Got a valid %s after %"PRIu64"ms",
dhcpv6_msg_to_str(hdr->msg_type), elapsed);
if (retx->handler_reply) {
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
-#include <syslog.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>
static char *ifname = NULL;
struct config_dhcp *config_dhcp = NULL;
+void __iflog(int lvl, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (lvl > config_dhcp->log_level)
+ return;
+
+ va_start(ap, fmt);
+
+ if (config_dhcp->log_syslog) {
+ vsyslog(lvl, fmt, ap);
+ } else {
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ }
+
+ va_end(ap);
+}
+
static unsigned int script_sync_delay = 10;
static unsigned int script_accu_delay = 1;
uint16_t opttype;
struct odhcp6c_opt *opt;
int ia_pd_iaid_index = 0;
- int verbosity = 0;
bool help = false, daemonize = false;
int logopt = LOG_PID;
int c;
unsigned int ra_holdoff_interval = RA_MIN_ADV_INTERVAL;
ra_ifid_mode_t ra_ifid_mode = RA_IFID_LLA;
bool terminate = false;
+ bool deprecated_opt = false;
config_dhcp = config_dhcp_get();
config_dhcp_reset();
- while ((c = getopt(argc, argv, "SDN:V:P:FB:c:i:r:Ru:Ux:s:EkK:t:C:m:Lhedp:fav")) != -1) {
+ while ((c = getopt(argc, argv, "SDN:V:P:FB:c:i:r:Ru:Ux:s:EkK:t:C:m:Lhedp:favl:")) != -1) {
switch (c) {
case 'S':
config_set_allow_slaac_only(false);
case 'V':
opt = odhcp6c_find_opt(DHCPV6_OPT_VENDOR_CLASS);
if (!opt) {
- syslog(LOG_ERR, "Failed to set vendor-class option");
+ error("Failed to set vendor-class option");
return 1;
}
strncpy((char *)buf, optarg, optpos - optarg);
buf[optpos - optarg] = '\0';
if (inet_pton(AF_INET6, (char *)buf, &prefix.addr) <= 0) {
- syslog(LOG_ERR, "invalid argument: '%s'", optarg);
+ error("invalid argument: '%s'", optarg);
return 1;
}
optpos++;
prefix.length = strtoul(optpos, &iaid_begin, 10);
if (*iaid_begin != '\0' && *iaid_begin != ',' && *iaid_begin != ':') {
- syslog(LOG_ERR, "invalid argument: '%s'", optarg);
+ error("invalid argument: '%s'", optarg);
return 1;
}
prefix.iaid = htonl(++ia_pd_iaid_index);
if (odhcp6c_add_state(STATE_IA_PD_INIT, &prefix, sizeof(prefix))) {
- syslog(LOG_ERR, "Failed to set request IPv6-Prefix");
+ error("Failed to set request IPv6-Prefix");
return 1;
}
break;
buf[2] = 0;
buf[3] = l;
if (odhcp6c_add_state(STATE_CLIENT_ID, buf, l + 4)) {
- syslog(LOG_ERR, "Failed to override client-ID");
+ error("Failed to override client-ID");
return 1;
} else {
client_id_param = true;
ifid.s6_addr[1] = 0x80;
} else {
/* Do not error on bad values; fall back to default */
- syslog(LOG_ERR, "Invalid interface-ID: %s", optarg);
+ error("Invalid interface-ID: %s", optarg);
}
break;
optarg = &optpos[1];
if (odhcp6c_add_state(STATE_ORO, &opttype, 2)) {
- syslog(LOG_ERR, "Failed to add requested option");
+ error("Failed to add requested option");
return 1;
}
}
case 'u':
opt = odhcp6c_find_opt(DHCPV6_OPT_USER_CLASS);
if (!opt) {
- syslog(LOG_ERR, "Failed to set user-class option");
+ error("Failed to set user-class option");
return 1;
}
case 'E':
#ifndef WITH_UBUS
- syslog(LOG_ERR, "Failed to use ubus event: ENABLE_UBUS compilation flag missing");
+ error("Failed to use ubus event: ENABLE_UBUS compilation flag missing");
return 1;
#endif /* WITH_UBUS */
script = NULL;
break;
case 'v':
- ++verbosity;
+ /* deprecated - remove -v options from start scripts first */
+ deprecated_opt = true;
+ break;
+
+ case 'l':
+ config_dhcp->log_level = (atoi(optarg) & LOG_PRIMASK);
break;
case 'x':
}
openlog("odhcp6c", logopt, LOG_DAEMON);
- if (!verbosity)
- setlogmask(LOG_UPTO(LOG_WARNING));
+ setlogmask(LOG_UPTO(config_dhcp->log_level));
ifname = argv[optind];
if (daemonize) {
openlog("odhcp6c", LOG_PID, LOG_DAEMON); // Disable LOG_PERROR
if (daemon(0, 0)) {
- syslog(LOG_ERR, "Failed to daemonize: %s",
+ error("Failed to daemonize: %s",
strerror(errno));
return 3;
}
fprintf(fp, "%i\n", getpid());
fclose(fp);
}
+ } else {
+ config_dhcp->log_syslog = false;
}
+ if (deprecated_opt)
+ warn("The -v flag is deprecated and will be removed. Use -l[0-7].");
+
if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 ||
ra_init(ifname, &ifid, ra_ifid_mode, ra_options, ra_holdoff_interval) ||
script_init(script, ifname)) {
- syslog(LOG_ERR, "failed to initialize: %s", strerror(errno));
+ error("failed to initialize: %s", strerror(errno));
return 4;
}
#ifdef WITH_UBUS
char *err = ubus_init(ifname);
if (err) {
- syslog(LOG_ERR, "ubus error: %s", err);
+ error("ubus error: %s", err);
return 1;
}
struct ubus_context *ubus = ubus_get_ctx();
int ubus_socket = ubus->sock.fd;
if (ubus_socket < 0) {
- syslog(LOG_ERR, "Invalid ubus file descriptor");
+ error("Invalid ubus file descriptor");
return 1;
}
fds[UBUS_FD_INDEX].fd = ubus_socket;
config_dhcp->oro_user_cnt = oro_len / sizeof(uint16_t);
if (init_dhcpv6(ifname)) {
- syslog(LOG_ERR, "failed to initialize: %s", strerror(errno));
+ error("failed to initialize: %s", strerror(errno));
return 1;
}
fds[DHCPV6_FD_INDEX].fd = dhcpv6_get_socket();
- syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);
+ notice("(re)starting transaction on %s", ifname);
signal_usr1 = signal_usr2 = false;
if (!bound) {
bound = true;
if (mode == DHCPV6_STATELESS) {
- syslog(LOG_NOTICE, "entering stateless-mode on %s", ifname);
+ notice("entering stateless-mode on %s", ifname);
signal_usr1 = false;
notify_state_change("informed", script_sync_delay, true);
} else {
notify_state_change("bound", script_sync_delay, true);
- syslog(LOG_NOTICE, "entering stateful-mode on %s", ifname);
+ notice("entering stateful-mode on %s", ifname);
}
}
" -p <pidfile> Set pidfile (/var/run/odhcp6c.pid)\n"
" -d Daemonize\n"
" -e Write logmessages to stderr\n"
- " -v Increase logging verbosity\n"
+ " -l <level> Set logging level (0-7)\n"
" -h Show this help\n\n";
fputs(buf, stderr);
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
+#include <syslog.h>
#ifndef _o_aligned
#define _o_aligned(n) __attribute__((aligned(n)))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+void __iflog(int lvl, const char *fmt, ...);
+#define debug(fmt, ...) __iflog(LOG_DEBUG, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define info(fmt, ...) __iflog(LOG_INFO, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define notice(fmt, ...) __iflog(LOG_NOTICE, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define warn(fmt, ...) __iflog(LOG_WARNING, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define error(fmt, ...) __iflog(LOG_ERR, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define critical(fmt, ...) __iflog(LOG_CRIT, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define alert(fmt, ...) __iflog(LOG_ALERT, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define emergency(fmt, ...) __iflog(LOG_EMERG, fmt __VA_OPT__(, ) __VA_ARGS__)
+
#define ND_OPT_RECURSIVE_DNS 25
#define ND_OPT_DNSSL 31
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
len = sizeof(struct icmp6_hdr);
if (sendto(sock, &rs, len, MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)
- syslog(LOG_ERR, "Failed to send RS (%s)", strerror(errno));
+ error("Failed to send RS (%s)", strerror(errno));
if (++rs_attempt <= 3)
alarm(4);
} while (read > 0);
if (ret) {
- syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);
+ notice("carrier => %i event on %s", (int)!nocarrier, if_name);
rs_attempt = 0;
ra_send_rs(SIGALRM);
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
- syslog(LOG_ERR,
+ error(
"%s: error creating EUI64 socket",
if_name);
return false;
strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);
if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
- syslog(LOG_ERR,
+ error(
"%s: error getting EUI64 HW address",
if_name);
close(sock);
close(sock);
if (!odhcp6c_is_valid_ether_addr((uint8_t *) ifr.ifr_hwaddr.sa_data)) {
- syslog(LOG_ERR,
+ error(
"%s: invalid EUI64 HW address",
if_name);
return false;
sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if (sock < 0) {
- syslog(LOG_ERR,
+ error(
"%s: error creating LLA socket",
if_name);
return false;
}
if (connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) {
- syslog(LOG_ERR,
+ error(
"%s: error connecting LLA socket",
if_name);
close(sock);
}
if (getsockname(sock, (struct sockaddr*) &addr, &alen) != 0) {
- syslog(LOG_ERR,
+ error(
"%s: error getting address from LLA socket",
if_name);
close(sock);
if (odhcp6c_random(&ra_addr.s6_addr[8], 8) != 8) {
ra_addr.s6_addr32[2] = 0;
ra_addr.s6_addr32[3] = 0;
- syslog(LOG_ERR,
+ error(
"%s: error generating random interface address",
if_name);
return false;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <sys/wait.h>
#include <unistd.h>
if (capt_port_ra_len > 0 && capt_port_dhcpv6_len > 0) {
if (capt_port_ra_len != capt_port_dhcpv6_len ||
!memcmp(capt_port_dhcpv6, capt_port_ra, capt_port_dhcpv6_len))
- syslog(LOG_ERR,
+ error(
"%s received via different vectors differ: preferring URI from DHCPv6",
CAPT_PORT_URI_STR);
}
#include <resolv.h>
#include <stdio.h>
#include <sys/types.h>
-#include <syslog.h>
#include "config.h"
#include "odhcp6c.h"
int ret = (stmt); \
if (ret != UBUS_STATUS_OK) \
{ \
- syslog(LOG_ERR, "%s failed: %s (%d)", #stmt, ubus_strerror(ret), ret); \
+ error("%s failed: %s (%d)", #stmt, ubus_strerror(ret), ret); \
return ret; \
} \
} while (0)
ret = ubus_reconnect(ubus, NULL);
if (ret) {
- syslog(LOG_ERR, "Cannot reconnect to ubus: %s", ubus_strerror(ret));
+ error("Cannot reconnect to ubus: %s", ubus_strerror(ret));
ubus_destroy(ubus);
}
}
void ubus_destroy(struct ubus_context *ubus)
{
- syslog(LOG_NOTICE, "Disconnecting from ubus");
+ notice("Disconnecting from ubus");
if (ubus != NULL)
ubus_free(ubus);
if (capt_port_ra_len > 0 && capt_port_dhcpv6_len > 0) {
if (capt_port_ra_len != capt_port_dhcpv6_len ||
!memcmp(capt_port_dhcpv6, capt_port_ra, capt_port_dhcpv6_len))
- syslog(LOG_ERR,
+ error(
"%s received via different vectors differ: preferring URI from DHCPv6",
CAPT_PORT_URI_STR);
}