diff --git a/subsys/logging/backends/Kconfig.net b/subsys/logging/backends/Kconfig.net index 36a5096235b3f03..91de90743243913 100644 --- a/subsys/logging/backends/Kconfig.net +++ b/subsys/logging/backends/Kconfig.net @@ -49,6 +49,13 @@ config LOG_BACKEND_NET_AUTOSTART started by the application later on. Otherwise the logging thread might block. +config LOG_BACKEND_NET_USE_DHCPV4_OPTION + bool "Use DHCPv4 Log Server Option to configure syslog server" + depends on NET_DHCPV4 + help + When enabled the syslog server IP address is read from the DHCPv4 + Log Server Option (7). + backend = NET backend-str = net source "subsys/logging/Kconfig.template.log_format_config" diff --git a/subsys/net/lib/dhcpv4/dhcpv4.c b/subsys/net/lib/dhcpv4/dhcpv4.c index d055a58928b05d7..d25c8f6072697b2 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4.c +++ b/subsys/net/lib/dhcpv4/dhcpv4.c @@ -28,6 +28,10 @@ LOG_MODULE_REGISTER(net_dhcpv4, CONFIG_NET_DHCPV4_LOG_LEVEL); #include #include +#include +#include +#include + #include "dhcpv4_internal.h" #include "ipv4.h" #include "net_stats.h" @@ -44,6 +48,11 @@ static struct k_work_delayable timeout_work; static struct net_mgmt_event_callback mgmt4_cb; +#if defined(CONFIG_LOG_BACKEND_NET_USE_DHCPV4_OPTION) && \ + defined(CONFIG_LOG_BACKEND_NET_AUTOSTART) +extern const struct log_backend *log_backend_net_get(void); +#endif + #if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS) static sys_slist_t option_callbacks; #endif @@ -810,6 +819,43 @@ static bool dhcpv4_parse_options(struct net_pkt *pkt, break; } #endif +#if defined(CONFIG_LOG_BACKEND_NET_USE_DHCPV4_OPTION) + case DHCPV4_OPTIONS_LOG_SERVER: { + struct sockaddr_in log_server = { 0 }; + + /* Log server option may present 1 or more + * addresses. Each 4 bytes in length. Log + * servers should be listed in order + * of preference. Hence we choose the first + * and skip the rest. + */ + if (length % 4 != 0U) { + NET_ERR("options_log_server, bad length"); + return false; + } + + if (net_pkt_read(pkt, log_server.sin_addr.s4_addr, 4) < 0 || + net_pkt_skip(pkt, length - 4U) < 0) { + NET_ERR("options_log_server, short packet"); + return false; + } + + log_server.sin_family = AF_INET; + log_backend_net_set_ip((struct sockaddr *)&log_server); + +#ifdef CONFIG_LOG_BACKEND_NET_AUTOSTART + const struct log_backend *backend = log_backend_net_get(); + + if (!log_backend_is_active(backend)) { + log_backend_activate(backend, backend->cb->ctx); + } +#endif + + NET_DBG("options_log_server: %s", net_sprint_ipv4_addr(&log_server)); + + break; + } +#endif case DHCPV4_OPTIONS_LEASE_TIME: if (length != 4U) { NET_ERR("options_lease_time, bad length"); diff --git a/subsys/net/lib/dhcpv4/dhcpv4_internal.h b/subsys/net/lib/dhcpv4/dhcpv4_internal.h index 712d361ac80dfcd..1b88e13e93b6612 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4_internal.h +++ b/subsys/net/lib/dhcpv4/dhcpv4_internal.h @@ -54,6 +54,7 @@ struct dhcp_msg { #define DHCPV4_OPTIONS_SUBNET_MASK 1 #define DHCPV4_OPTIONS_ROUTER 3 #define DHCPV4_OPTIONS_DNS_SERVER 6 +#define DHCPV4_OPTIONS_LOG_SERVER 7 #define DHCPV4_OPTIONS_HOST_NAME 12 #define DHCPV4_OPTIONS_REQ_IPADDR 50 #define DHCPV4_OPTIONS_LEASE_TIME 51