]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[syslog] Add support for IPv6 syslog server
authorMichael Brown <mcb30@ipxe.org>
Thu, 5 Dec 2013 01:21:51 +0000 (01:21 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 5 Dec 2013 01:27:33 +0000 (01:27 +0000)
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>
src/include/ipxe/dhcpv6.h
src/net/tcp/syslogs.c
src/net/udp/syslog.c

index a0a8d05b02044f377db8dcc124546f364cc933c1..70cccf0ba9c93ccad08fe212a0477907bfd012a7 100644 (file)
@@ -152,6 +152,13 @@ struct dhcpv6_user_class_option {
 /** DHCPv6 domain search list option */
 #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
  *
index 503ed177ae76f7e0fbe7376e46556e9325a74c5b..5180e4dab6117edee96f549889bd8683dd940595 100644 (file)
@@ -49,7 +49,6 @@ struct console_driver syslogs_console __console_driver;
 
 /** The encrypted syslog server */
 static struct sockaddr_tcpip logserver = {
-       .st_family = AF_INET,
        .st_port = htons ( SYSLOG_PORT ),
 };
 
index 6554ab9bf1792c1f64a8e7ef1d560e9652c94e5b..9569f39531af5827cd1d629f8e43a2583d735527 100644 (file)
@@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/open.h>
 #include <ipxe/tcpip.h>
 #include <ipxe/dhcp.h>
+#include <ipxe/dhcpv6.h>
 #include <ipxe/settings.h>
 #include <ipxe/console.h>
 #include <ipxe/lineconsole.h>
@@ -45,9 +46,15 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #endif
 
 /** The syslog server */
-static struct sockaddr_tcpip logserver = {
-       .st_family = AF_INET,
-       .st_port = htons ( SYSLOG_PORT ),
+static union {
+       struct sockaddr sa;
+       struct sockaddr_tcpip st;
+       struct sockaddr_in sin;
+       struct sockaddr_in6 sin6;
+} logserver = {
+       .st = {
+               .st_port = htons ( SYSLOG_PORT ),
+       },
 };
 
 /** 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 ) = {
        .name = "syslog",
        .description = "Syslog server",
@@ -195,16 +202,22 @@ const struct setting syslog_setting __setting ( SETTING_MISC ) = {
        .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
  *
  * @ret rc             Return status code
  */
 static int apply_syslog_settings ( void ) {
-       struct sockaddr_in *sin_logserver =
-               ( struct sockaddr_in * ) &logserver;
-       struct in_addr old_addr;
-       int len;
+       struct sockaddr old_logserver;
        int rc;
 
        /* Fetch hostname and domain name */
@@ -215,14 +228,23 @@ static int apply_syslog_settings ( void ) {
 
        /* Fetch log server */
        syslog_console.disabled = CONSOLE_DISABLED;
-       old_addr.s_addr = sin_logserver->sin_addr.s_addr;
-       if ( ( len = fetch_ipv4_setting ( NULL, &syslog_setting,
-                                         &sin_logserver->sin_addr ) ) >= 0 ) {
+       memcpy ( &old_logserver, &logserver, sizeof ( old_logserver ) );
+       logserver.sa.sa_family = 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;
+               DBG ( "SYSLOG using log server %s\n",
+                     sock_ntoa ( &logserver.sa ) );
        }
 
        /* 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;
 
        /* Reset syslog connection */
@@ -236,14 +258,11 @@ static int apply_syslog_settings ( void ) {
 
        /* Connect to log server */
        if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM,
-                                      ( ( struct sockaddr * ) &logserver ),
-                                      NULL ) ) != 0 ) {
+                                      &logserver.sa, NULL ) ) != 0 ) {
                DBG ( "SYSLOG cannot connect to log server: %s\n",
                      strerror ( rc ) );
                return rc;
        }
-       DBG ( "SYSLOG using log server %s\n",
-             inet_ntoa ( sin_logserver->sin_addr ) );
 
        return 0;
 }