[syslog] Add support for IPv6 syslog server

Note that IANA has not yet assigned a DHCPv6 option code for the
syslog server.  When a code is assigned, the definition of
DHCPV6_LOG_SERVERS should be updated.  Until then, an IPv6 address of
a syslog server can be configured manually using e.g.

  set syslog6 3ffe:302:11:2::8309

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/17/head
Michael Brown 2013-12-05 01:21:51 +00:00
parent 2649e8ef70
commit 44a0dc7848
3 changed files with 42 additions and 17 deletions

View File

@ -152,6 +152,13 @@ struct dhcpv6_user_class_option {
/** DHCPv6 domain search list option */ /** DHCPv6 domain search list option */
#define DHCPV6_DOMAIN_LIST 24 #define DHCPV6_DOMAIN_LIST 24
/** DHCPv6 syslog server option
*
* This option code has not yet been assigned by IANA. Please update
* this definition once an option code has been assigned.
*/
#define DHCPV6_LOG_SERVERS 0xffffffffUL
/** /**
* Any DHCPv6 option * Any DHCPv6 option
* *

View File

@ -49,7 +49,6 @@ struct console_driver syslogs_console __console_driver;
/** The encrypted syslog server */ /** The encrypted syslog server */
static struct sockaddr_tcpip logserver = { static struct sockaddr_tcpip logserver = {
.st_family = AF_INET,
.st_port = htons ( SYSLOG_PORT ), .st_port = htons ( SYSLOG_PORT ),
}; };

View File

@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/open.h> #include <ipxe/open.h>
#include <ipxe/tcpip.h> #include <ipxe/tcpip.h>
#include <ipxe/dhcp.h> #include <ipxe/dhcp.h>
#include <ipxe/dhcpv6.h>
#include <ipxe/settings.h> #include <ipxe/settings.h>
#include <ipxe/console.h> #include <ipxe/console.h>
#include <ipxe/lineconsole.h> #include <ipxe/lineconsole.h>
@ -45,9 +46,15 @@ FILE_LICENCE ( GPL2_OR_LATER );
#endif #endif
/** The syslog server */ /** The syslog server */
static struct sockaddr_tcpip logserver = { static union {
.st_family = AF_INET, struct sockaddr sa;
.st_port = htons ( SYSLOG_PORT ), struct sockaddr_tcpip st;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} logserver = {
.st = {
.st_port = htons ( SYSLOG_PORT ),
},
}; };
/** Syslog UDP interface operations */ /** Syslog UDP interface operations */
@ -187,7 +194,7 @@ struct console_driver syslog_console __console_driver = {
****************************************************************************** ******************************************************************************
*/ */
/** Syslog server setting */ /** IPv4 syslog server setting */
const struct setting syslog_setting __setting ( SETTING_MISC ) = { const struct setting syslog_setting __setting ( SETTING_MISC ) = {
.name = "syslog", .name = "syslog",
.description = "Syslog server", .description = "Syslog server",
@ -195,16 +202,22 @@ const struct setting syslog_setting __setting ( SETTING_MISC ) = {
.type = &setting_type_ipv4, .type = &setting_type_ipv4,
}; };
/** IPv6 syslog server setting */
const struct setting syslog6_setting __setting ( SETTING_MISC ) = {
.name = "syslog6",
.description = "Syslog server",
.tag = DHCPV6_LOG_SERVERS,
.type = &setting_type_ipv6,
.scope = &ipv6_scope,
};
/** /**
* Apply syslog settings * Apply syslog settings
* *
* @ret rc Return status code * @ret rc Return status code
*/ */
static int apply_syslog_settings ( void ) { static int apply_syslog_settings ( void ) {
struct sockaddr_in *sin_logserver = struct sockaddr old_logserver;
( struct sockaddr_in * ) &logserver;
struct in_addr old_addr;
int len;
int rc; int rc;
/* Fetch hostname and domain name */ /* Fetch hostname and domain name */
@ -215,14 +228,23 @@ static int apply_syslog_settings ( void ) {
/* Fetch log server */ /* Fetch log server */
syslog_console.disabled = CONSOLE_DISABLED; syslog_console.disabled = CONSOLE_DISABLED;
old_addr.s_addr = sin_logserver->sin_addr.s_addr; memcpy ( &old_logserver, &logserver, sizeof ( old_logserver ) );
if ( ( len = fetch_ipv4_setting ( NULL, &syslog_setting, logserver.sa.sa_family = 0;
&sin_logserver->sin_addr ) ) >= 0 ) { if ( fetch_ipv6_setting ( NULL, &syslog6_setting,
&logserver.sin6.sin6_addr ) >= 0 ) {
logserver.sin6.sin6_family = AF_INET6;
} else if ( fetch_ipv4_setting ( NULL, &syslog_setting,
&logserver.sin.sin_addr ) >= 0 ) {
logserver.sin.sin_family = AF_INET;
}
if ( logserver.sa.sa_family ) {
syslog_console.disabled = 0; syslog_console.disabled = 0;
DBG ( "SYSLOG using log server %s\n",
sock_ntoa ( &logserver.sa ) );
} }
/* Do nothing unless log server has changed */ /* Do nothing unless log server has changed */
if ( sin_logserver->sin_addr.s_addr == old_addr.s_addr ) if ( memcmp ( &logserver, &old_logserver, sizeof ( logserver ) ) == 0 )
return 0; return 0;
/* Reset syslog connection */ /* Reset syslog connection */
@ -236,14 +258,11 @@ static int apply_syslog_settings ( void ) {
/* Connect to log server */ /* Connect to log server */
if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM, if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM,
( ( struct sockaddr * ) &logserver ), &logserver.sa, NULL ) ) != 0 ) {
NULL ) ) != 0 ) {
DBG ( "SYSLOG cannot connect to log server: %s\n", DBG ( "SYSLOG cannot connect to log server: %s\n",
strerror ( rc ) ); strerror ( rc ) );
return rc; return rc;
} }
DBG ( "SYSLOG using log server %s\n",
inet_ntoa ( sin_logserver->sin_addr ) );
return 0; return 0;
} }