iPXE
syslog.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * Syslog protocol
30 *
31 */
32
33#include <stdint.h>
34#include <stdlib.h>
35#include <string.h>
36#include <ctype.h>
37#include <byteswap.h>
38#include <ipxe/xfer.h>
39#include <ipxe/open.h>
40#include <ipxe/tcpip.h>
41#include <ipxe/dhcp.h>
42#include <ipxe/dhcpv6.h>
43#include <ipxe/settings.h>
44#include <ipxe/console.h>
45#include <ipxe/lineconsole.h>
46#include <ipxe/syslog.h>
47#include <config/console.h>
48
49/* Set default console usage if applicable */
50#if ! ( defined ( CONSOLE_SYSLOG ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOG ) )
51#undef CONSOLE_SYSLOG
52#define CONSOLE_SYSLOG ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI )
53#endif
54
55/** The syslog server */
56static union {
57 struct sockaddr sa;
61} logserver = {
62 .st = {
63 .st_port = htons ( SYSLOG_PORT ),
64 },
65};
66
67/** Syslog UDP interface operations */
69
70/** Syslog UDP interface descriptor */
73
74/** The syslog UDP interface */
76
77/******************************************************************************
78 *
79 * Console driver
80 *
81 ******************************************************************************
82 */
83
84/** Host name (for log messages) */
85static char *syslog_hostname;
86
87/** Domain name (for log messages) */
88static char *syslog_domain;
89
90/**
91 * Transmit formatted syslog message
92 *
93 * @v xfer Data transfer interface
94 * @v severity Severity
95 * @v message Message
96 * @v terminator Message terminator
97 * @ret rc Return status code
98 */
99int syslog_send ( struct interface *xfer, unsigned int severity,
100 const char *message, const char *terminator ) {
101 const char *hostname = ( syslog_hostname ? syslog_hostname : "" );
102 const char *domain = ( ( hostname[0] && syslog_domain ) ?
103 syslog_domain : "" );
104
105 return xfer_printf ( xfer, "<%d>%s%s%s%sipxe: %s%s",
107 severity ), hostname,
108 ( domain[0] ? "." : "" ), domain,
109 ( hostname[0] ? " " : "" ), message, terminator );
110}
111
112/******************************************************************************
113 *
114 * Console driver
115 *
116 ******************************************************************************
117 */
118
119/** Syslog line buffer */
121
122/** Syslog severity */
124
125/**
126 * Handle ANSI set syslog priority (private sequence)
127 *
128 * @v ctx ANSI escape sequence context
129 * @v count Parameter count
130 * @v params List of graphic rendition aspects
131 */
133 unsigned int count __unused,
134 int params[] ) {
135 if ( params[0] >= 0 ) {
136 syslog_severity = params[0];
137 } else {
139 }
140}
141
142/** Syslog ANSI escape sequence handlers */
147
148/** Syslog line console */
149static struct line_console syslog_line = {
150 .buffer = syslog_buffer,
151 .len = sizeof ( syslog_buffer ),
152 .ctx = {
153 .handlers = syslog_handlers,
154 },
155};
156
157/** Syslog recursion marker */
158static int syslog_entered;
159
160/**
161 * Print a character to syslog console
162 *
163 * @v character Character to be printed
164 */
165static void syslog_putchar ( int character ) {
166 int rc;
167
168 /* Ignore if we are already mid-logging */
169 if ( syslog_entered )
170 return;
171
172 /* Fill line buffer */
173 if ( line_putchar ( &syslog_line, character ) == 0 )
174 return;
175
176 /* Guard against re-entry */
177 syslog_entered = 1;
178
179 /* Send log message */
181 syslog_buffer, "" ) ) != 0 ) {
182 DBG ( "SYSLOG could not send log message: %s\n",
183 strerror ( rc ) );
184 }
185
186 /* Clear re-entry flag */
187 syslog_entered = 0;
188}
189
190/** Syslog console driver */
191struct console_driver syslog_console __console_driver = {
192 .putchar = syslog_putchar,
193 .disabled = CONSOLE_DISABLED,
194 .usage = CONSOLE_SYSLOG,
195};
196
197/******************************************************************************
198 *
199 * Settings
200 *
201 ******************************************************************************
202 */
203
204/** IPv4 syslog server setting */
205const struct setting syslog_setting __setting ( SETTING_MISC, syslog ) = {
206 .name = "syslog",
207 .description = "Syslog server",
208 .tag = DHCP_LOG_SERVERS,
209 .type = &setting_type_ipv4,
210};
211
212/** IPv6 syslog server setting */
213const struct setting syslog6_setting __setting ( SETTING_MISC, syslog6 ) = {
214 .name = "syslog6",
215 .description = "Syslog server",
216 .tag = DHCPV6_LOG_SERVERS,
217 .type = &setting_type_ipv6,
218 .scope = &dhcpv6_scope,
219};
220
221/**
222 * Strip invalid characters from host/domain name
223 *
224 * @v name Name to strip
225 */
226static void syslog_fix_name ( char *name ) {
227 char *fixed = name;
228 int c;
229
230 /* Do nothing if name does not exist */
231 if ( ! name )
232 return;
233
234 /* Strip any non-printable or whitespace characters from the name */
235 do {
236 c = *(name++);
237 *fixed = c;
238 if ( isprint ( c ) && ! isspace ( c ) )
239 fixed++;
240 } while ( c );
241}
242
243/**
244 * Apply syslog settings
245 *
246 * @ret rc Return status code
247 */
248static int apply_syslog_settings ( void ) {
249 struct sockaddr old_logserver;
250 int rc;
251
252 /* Fetch hostname and domain name */
254 fetch_string_setting_copy ( NULL, &hostname_setting, &syslog_hostname );
257 fetch_string_setting_copy ( NULL, &domain_setting, &syslog_domain );
259
260 /* Fetch log server */
261 syslog_console.disabled = CONSOLE_DISABLED;
262 memcpy ( &old_logserver, &logserver, sizeof ( old_logserver ) );
263 logserver.sa.sa_family = 0;
264 if ( fetch_ipv6_setting ( NULL, &syslog6_setting,
265 &logserver.sin6.sin6_addr ) >= 0 ) {
266 logserver.sin6.sin6_family = AF_INET6;
267 } else if ( fetch_ipv4_setting ( NULL, &syslog_setting,
268 &logserver.sin.sin_addr ) >= 0 ) {
269 logserver.sin.sin_family = AF_INET;
270 }
271 if ( logserver.sa.sa_family ) {
272 syslog_console.disabled = 0;
273 DBG ( "SYSLOG using log server %s\n",
274 sock_ntoa ( &logserver.sa ) );
275 }
276
277 /* Do nothing unless log server has changed */
278 if ( memcmp ( &logserver, &old_logserver, sizeof ( logserver ) ) == 0 )
279 return 0;
280
281 /* Reset syslog connection */
282 intf_restart ( &syslogger, 0 );
283
284 /* Do nothing unless we have a log server */
285 if ( syslog_console.disabled ) {
286 DBG ( "SYSLOG has no log server\n" );
287 return 0;
288 }
289
290 /* Connect to log server */
292 &logserver.sa, NULL ) ) != 0 ) {
293 DBG ( "SYSLOG cannot connect to log server: %s\n",
294 strerror ( rc ) );
295 return rc;
296 }
297
298 return 0;
299}
300
301/** Syslog settings applicator */
302struct settings_applicator syslog_applicator __settings_applicator = {
303 .apply = apply_syslog_settings,
304};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_eq_context ctx
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
const char * name
Definition ath9k_hw.c:1986
Console configuration.
int isspace(int character)
Check to see if character is a space.
Definition ctype.c:42
Character types.
static int isprint(int character)
Check if character is printable.
Definition ctype.h:98
Dynamic Host Configuration Protocol for IPv6.
#define DHCPV6_LOG_SERVERS
DHCPv6 syslog server option.
Definition dhcpv6.h:187
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition eltorito.h:1
struct eth_slow_terminator_tlv terminator
Terminator.
Definition eth_slow.h:9
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define AF_INET6
IPv6 Internet addresses.
Definition socket.h:65
#define ANSIESC_LOG_PRIORITY
Explicit log message priority.
Definition ansiesc.h:126
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define SOCK_DGRAM
Definition socket.h:30
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DHCP_LOG_SERVERS
Syslog servers.
Definition dhcp.h:75
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_MISC
Miscellaneous settings.
Definition settings.h:81
#define htons(value)
Definition byteswap.h:136
User interaction.
#define CONSOLE_DISABLED
Console is disabled for all uses.
Definition console.h:112
#define __console_driver
Mark a struct console_driver as being part of the console drivers table.
Definition console.h:134
Dynamic Host Configuration Protocol.
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
Transport-network layer interface.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
#define INTF_DESC_PURE(operations)
Define an object interface descriptor for a pure-interface object.
Definition interface.h:116
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition interface.h:218
Syslog protocol.
#define SYSLOG_DEFAULT_SEVERITY
Syslog default severity.
Definition syslog.h:34
#define SYSLOG_PRIORITY(facility, severity)
Syslog priority.
Definition syslog.h:37
#define SYSLOG_PORT
Syslog server port.
Definition syslog.h:16
#define SYSLOG_BUFSIZE
Syslog line buffer size.
Definition syslog.h:22
#define SYSLOG_DEFAULT_FACILITY
Syslog default facility.
Definition syslog.h:28
size_t line_putchar(struct line_console *line, int character)
Print a character to a line-based console.
Definition lineconsole.c:44
Line-based console.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition open.c:143
Data transfer interface opening.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition settings.c:1793
int fetch_ipv6_setting(struct settings *settings, const struct setting *setting, struct in6_addr *inp)
Fetch value of IPv6 address setting.
Definition settings.c:951
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition settings.c:874
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
Definition socket.c:43
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
ANSI escape sequence context.
Definition ansiesc.h:74
A handler for an escape sequence.
Definition ansiesc.h:35
A console driver.
Definition console.h:56
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A line-based console.
Definition lineconsole.h:17
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
IPv6 socket address.
Definition in.h:118
IPv4 socket address.
Definition in.h:85
TCP/IP socket address.
Definition tcpip.h:76
Generalized socket address structure.
Definition socket.h:97
static int apply_syslog_settings(void)
Apply syslog settings.
Definition syslog.c:248
struct sockaddr_in6 sin6
Definition syslog.c:60
static unsigned int syslog_severity
Syslog severity.
Definition syslog.c:123
static char * syslog_domain
Domain name (for log messages)
Definition syslog.c:88
static struct interface_descriptor syslogger_desc
Syslog UDP interface descriptor.
Definition syslog.c:71
int syslog_send(struct interface *xfer, unsigned int severity, const char *message, const char *terminator)
Transmit formatted syslog message.
Definition syslog.c:99
static struct interface_operation syslogger_operations[]
Syslog UDP interface operations.
Definition syslog.c:68
static struct line_console syslog_line
Syslog line console.
Definition syslog.c:149
struct sockaddr_tcpip st
Definition syslog.c:58
struct sockaddr sa
Definition syslog.c:57
static char syslog_buffer[SYSLOG_BUFSIZE]
Syslog line buffer.
Definition syslog.c:120
static struct ansiesc_handler syslog_handlers[]
Syslog ANSI escape sequence handlers.
Definition syslog.c:143
static void syslog_putchar(int character)
Print a character to syslog console.
Definition syslog.c:165
static struct interface syslogger
The syslog UDP interface.
Definition syslog.c:75
#define CONSOLE_SYSLOG
Definition syslog.c:52
struct sockaddr_in sin
Definition syslog.c:59
static char * syslog_hostname
Host name (for log messages)
Definition syslog.c:85
static void syslog_handle_priority(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[])
Handle ANSI set syslog priority (private sequence)
Definition syslog.c:132
static void syslog_fix_name(char *name)
Strip invalid characters from host/domain name.
Definition syslog.c:226
static int syslog_entered
Syslog recursion marker.
Definition syslog.c:158
#define syslog(priority, fmt,...)
Write message to system log.
Definition syslog.h:94
static struct sockaddr_tcpip logserver
The encrypted syslog server.
Definition syslogs.c:58
char message[VMCONSOLE_BUFSIZE]
Definition vmconsole.c:54
int xfer_printf(struct interface *intf, const char *format,...)
Deliver formatted string.
Definition xfer.c:335
Data transfer interfaces.