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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Syslog protocol
29  *
30  */
31 
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <byteswap.h>
37 #include <ipxe/xfer.h>
38 #include <ipxe/open.h>
39 #include <ipxe/tcpip.h>
40 #include <ipxe/dhcp.h>
41 #include <ipxe/dhcpv6.h>
42 #include <ipxe/settings.h>
43 #include <ipxe/console.h>
44 #include <ipxe/lineconsole.h>
45 #include <ipxe/syslog.h>
46 #include <config/console.h>
47 
48 /* Set default console usage if applicable */
49 #if ! ( defined ( CONSOLE_SYSLOG ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOG ) )
50 #undef CONSOLE_SYSLOG
51 #define CONSOLE_SYSLOG ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI )
52 #endif
53 
54 /** The syslog server */
55 static union {
56  struct sockaddr sa;
58  struct sockaddr_in sin;
60 } logserver = {
61  .st = {
62  .st_port = htons ( SYSLOG_PORT ),
63  },
64 };
65 
66 /** Syslog UDP interface operations */
68 
69 /** Syslog UDP interface descriptor */
72 
73 /** The syslog UDP interface */
75 
76 /******************************************************************************
77  *
78  * Console driver
79  *
80  ******************************************************************************
81  */
82 
83 /** Host name (for log messages) */
84 static char *syslog_hostname;
85 
86 /** Domain name (for log messages) */
87 static char *syslog_domain;
88 
89 /**
90  * Transmit formatted syslog message
91  *
92  * @v xfer Data transfer interface
93  * @v severity Severity
94  * @v message Message
95  * @v terminator Message terminator
96  * @ret rc Return status code
97  */
98 int syslog_send ( struct interface *xfer, unsigned int severity,
99  const char *message, const char *terminator ) {
100  const char *hostname = ( syslog_hostname ? syslog_hostname : "" );
101  const char *domain = ( ( hostname[0] && syslog_domain ) ?
102  syslog_domain : "" );
103 
104  return xfer_printf ( xfer, "<%d>%s%s%s%sipxe: %s%s",
106  severity ), hostname,
107  ( domain[0] ? "." : "" ), domain,
108  ( hostname[0] ? " " : "" ), message, terminator );
109 }
110 
111 /******************************************************************************
112  *
113  * Console driver
114  *
115  ******************************************************************************
116  */
117 
118 /** Syslog line buffer */
120 
121 /** Syslog severity */
123 
124 /**
125  * Handle ANSI set syslog priority (private sequence)
126  *
127  * @v ctx ANSI escape sequence context
128  * @v count Parameter count
129  * @v params List of graphic rendition aspects
130  */
132  unsigned int count __unused,
133  int params[] ) {
134  if ( params[0] >= 0 ) {
135  syslog_severity = params[0];
136  } else {
138  }
139 }
140 
141 /** Syslog ANSI escape sequence handlers */
142 static struct ansiesc_handler syslog_handlers[] = {
144  { 0, NULL }
145 };
146 
147 /** Syslog line console */
148 static struct line_console syslog_line = {
150  .len = sizeof ( syslog_buffer ),
151  .ctx = {
152  .handlers = syslog_handlers,
153  },
154 };
155 
156 /** Syslog recursion marker */
157 static int syslog_entered;
158 
159 /**
160  * Print a character to syslog console
161  *
162  * @v character Character to be printed
163  */
164 static void syslog_putchar ( int character ) {
165  int rc;
166 
167  /* Ignore if we are already mid-logging */
168  if ( syslog_entered )
169  return;
170 
171  /* Fill line buffer */
172  if ( line_putchar ( &syslog_line, character ) == 0 )
173  return;
174 
175  /* Guard against re-entry */
176  syslog_entered = 1;
177 
178  /* Send log message */
180  syslog_buffer, "" ) ) != 0 ) {
181  DBG ( "SYSLOG could not send log message: %s\n",
182  strerror ( rc ) );
183  }
184 
185  /* Clear re-entry flag */
186  syslog_entered = 0;
187 }
188 
189 /** Syslog console driver */
190 struct console_driver syslog_console __console_driver = {
192  .disabled = CONSOLE_DISABLED,
193  .usage = CONSOLE_SYSLOG,
194 };
195 
196 /******************************************************************************
197  *
198  * Settings
199  *
200  ******************************************************************************
201  */
202 
203 /** IPv4 syslog server setting */
204 const struct setting syslog_setting __setting ( SETTING_MISC, syslog ) = {
205  .name = "syslog",
206  .description = "Syslog server",
207  .tag = DHCP_LOG_SERVERS,
208  .type = &setting_type_ipv4,
209 };
210 
211 /** IPv6 syslog server setting */
212 const struct setting syslog6_setting __setting ( SETTING_MISC, syslog6 ) = {
213  .name = "syslog6",
214  .description = "Syslog server",
215  .tag = DHCPV6_LOG_SERVERS,
216  .type = &setting_type_ipv6,
217  .scope = &dhcpv6_scope,
218 };
219 
220 /**
221  * Strip invalid characters from host/domain name
222  *
223  * @v name Name to strip
224  */
225 static void syslog_fix_name ( char *name ) {
226  char *fixed = name;
227  int c;
228 
229  /* Do nothing if name does not exist */
230  if ( ! name )
231  return;
232 
233  /* Strip any non-printable or whitespace characters from the name */
234  do {
235  c = *(name++);
236  *fixed = c;
237  if ( isprint ( c ) && ! isspace ( c ) )
238  fixed++;
239  } while ( c );
240 }
241 
242 /**
243  * Apply syslog settings
244  *
245  * @ret rc Return status code
246  */
247 static int apply_syslog_settings ( void ) {
248  struct sockaddr old_logserver;
249  int rc;
250 
251  /* Fetch hostname and domain name */
252  free ( syslog_hostname );
253  fetch_string_setting_copy ( NULL, &hostname_setting, &syslog_hostname );
255  free ( syslog_domain );
256  fetch_string_setting_copy ( NULL, &domain_setting, &syslog_domain );
258 
259  /* Fetch log server */
260  syslog_console.disabled = CONSOLE_DISABLED;
261  memcpy ( &old_logserver, &logserver, sizeof ( old_logserver ) );
262  logserver.sa.sa_family = 0;
263  if ( fetch_ipv6_setting ( NULL, &syslog6_setting,
264  &logserver.sin6.sin6_addr ) >= 0 ) {
265  logserver.sin6.sin6_family = AF_INET6;
266  } else if ( fetch_ipv4_setting ( NULL, &syslog_setting,
267  &logserver.sin.sin_addr ) >= 0 ) {
268  logserver.sin.sin_family = AF_INET;
269  }
270  if ( logserver.sa.sa_family ) {
271  syslog_console.disabled = 0;
272  DBG ( "SYSLOG using log server %s\n",
273  sock_ntoa ( &logserver.sa ) );
274  }
275 
276  /* Do nothing unless log server has changed */
277  if ( memcmp ( &logserver, &old_logserver, sizeof ( logserver ) ) == 0 )
278  return 0;
279 
280  /* Reset syslog connection */
281  intf_restart ( &syslogger, 0 );
282 
283  /* Do nothing unless we have a log server */
284  if ( syslog_console.disabled ) {
285  DBG ( "SYSLOG has no log server\n" );
286  return 0;
287  }
288 
289  /* Connect to log server */
291  &logserver.sa, NULL ) ) != 0 ) {
292  DBG ( "SYSLOG cannot connect to log server: %s\n",
293  strerror ( rc ) );
294  return rc;
295  }
296 
297  return 0;
298 }
299 
300 /** Syslog settings applicator */
301 struct settings_applicator syslog_applicator __settings_applicator = {
303 };
An object interface operation.
Definition: interface.h:17
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
static struct interface_operation syslogger_operations[]
Syslog UDP interface operations.
Definition: syslog.c:67
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
#define SYSLOG_PRIORITY(facility, severity)
Syslog priority.
Definition: syslog.h:36
A handler for an escape sequence.
Definition: ansiesc.h:34
Dynamic Host Configuration Protocol.
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
#define DHCP_LOG_SERVERS
Syslog servers.
Definition: dhcp.h:74
static char syslog_buffer[SYSLOG_BUFSIZE]
Syslog line buffer.
Definition: syslog.c:119
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1792
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:131
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:142
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
static union @6 logserver
The syslog server.
static unsigned int syslog_severity
Syslog severity.
Definition: syslog.c:122
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition: interface.h:217
#define SOCK_DGRAM
Definition: socket.h:29
#define CONSOLE_DISABLED
Console is disabled for all uses.
Definition: console.h:111
struct sockaddr_in6 sin6
Definition: syslog.c:59
#define CONSOLE_SYSLOG
Definition: syslog.c:51
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
A settings applicator.
Definition: settings.h:251
#define SETTING_MISC
Miscellaneous settings.
Definition: settings.h:80
#define INTF_DESC_PURE(operations)
Define an object interface descriptor for a pure-interface object.
Definition: interface.h:115
#define DHCPV6_LOG_SERVERS
DHCPv6 syslog server option.
Definition: dhcpv6.h:186
IPv4 socket address.
Definition: in.h:84
static void syslog_fix_name(char *name)
Strip invalid characters from host/domain name.
Definition: syslog.c:225
A line-based console.
Definition: lineconsole.h:16
ANSI escape sequence context.
Definition: ansiesc.h:73
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
Character types.
Line-based console.
const struct setting syslog_setting __setting(SETTING_MISC, syslog)
IPv4 syslog server setting.
static void syslog_putchar(int character)
Print a character to syslog console.
Definition: syslog.c:164
size_t line_putchar(struct line_console *line, int character)
Print a character to a line-based console.
Definition: lineconsole.c:43
static int isprint(int character)
Check if character is printable.
Definition: ctype.h:97
Data transfer interfaces.
const char * name
Name.
Definition: settings.h:28
struct sockaddr_tcpip st
Definition: syslog.c:57
static char * syslog_domain
Domain name (for log messages)
Definition: syslog.c:87
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void(* putchar)(int character)
Write a character to the console.
Definition: console.h:68
An object interface.
Definition: interface.h:124
Syslog protocol.
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct sockaddr sa
Definition: syslog.c:56
Transport-network layer interface.
static unsigned int count
Number of entries.
Definition: dwmac.h:225
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:873
User interaction.
Configuration settings.
Generalized socket address structure.
Definition: socket.h:96
An object interface descriptor.
Definition: interface.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct settings_applicator syslog_applicator __settings_applicator
Syslog settings applicator.
Definition: syslog.c:301
static int syslog_entered
Syslog recursion marker.
Definition: syslog.c:157
#define ANSIESC_LOG_PRIORITY
Explicit log message priority.
Definition: ansiesc.h:125
static int apply_syslog_settings(void)
Apply syslog settings.
Definition: syslog.c:247
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:41
static char * syslog_hostname
Host name (for log messages)
Definition: syslog.c:84
Data transfer interface opening.
Console configuration.
static struct ansiesc_handler syslog_handlers[]
Syslog ANSI escape sequence handlers.
Definition: syslog.c:142
A setting.
Definition: settings.h:23
#define SYSLOG_PORT
Syslog server port.
Definition: syslog.h:15
int xfer_printf(struct interface *intf, const char *format,...)
Deliver formatted string.
Definition: xfer.c:334
#define SYSLOG_DEFAULT_SEVERITY
Syslog default severity.
Definition: syslog.h:33
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
Definition: socket.c:42
static struct line_console syslog_line
Syslog line console.
Definition: syslog.c:148
static struct interface_descriptor syslogger_desc
Syslog UDP interface descriptor.
Definition: syslog.c:70
struct console_driver syslog_console __console_driver
Syslog console driver.
Definition: syslog.c:190
#define syslog(priority, fmt,...)
Write message to system log.
Definition: syslog.h:93
int syslog_send(struct interface *xfer, unsigned int severity, const char *message, const char *terminator)
Transmit formatted syslog message.
Definition: syslog.c:98
IPv6 socket address.
Definition: in.h:117
int(* apply)(void)
Apply updated settings.
Definition: settings.h:256
char * buffer
Data buffer.
Definition: lineconsole.h:21
A console driver.
Definition: console.h:55
struct sockaddr_in sin
Definition: syslog.c:58
char message[VMCONSOLE_BUFSIZE]
Definition: vmconsole.c:54
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define SYSLOG_BUFSIZE
Syslog line buffer size.
Definition: syslog.h:21
#define SYSLOG_DEFAULT_FACILITY
Syslog default facility.
Definition: syslog.h:27
struct eth_slow_terminator_tlv terminator
Terminator.
Definition: eth_slow.h:20
int fetch_ipv6_setting(struct settings *settings, const struct setting *setting, struct in6_addr *inp)
Fetch value of IPv6 address setting.
Definition: settings.c:950
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
Dynamic Host Configuration Protocol for IPv6.
static struct interface syslogger
The syslog UDP interface.
Definition: syslog.c:74