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