Procházet zdrojové kódy

[syslog] Add support for sending console output to a syslog server

Originally-implemented-by: Anselm Martin Hoffmeister <anselm@hoffmeister.be>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown před 13 roky
rodič
revize
e49d81689c
3 změnil soubory, kde provedl 243 přidání a 0 odebrání
  1. 1
    0
      src/config/console.h
  2. 36
    0
      src/include/ipxe/syslog.h
  3. 206
    0
      src/net/udp/syslog.c

+ 1
- 0
src/config/console.h Zobrazit soubor

@@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
19 19
 //#define	CONSOLE_DIRECT_VGA	/* Direct access to VGA card */
20 20
 //#define	CONSOLE_BTEXT		/* Who knows what this does? */
21 21
 //#define	CONSOLE_PC_KBD		/* Direct access to PC keyboard */
22
+//#define	CONSOLE_SYSLOG		/* Syslog console */
22 23
 
23 24
 #include <config/local/console.h>
24 25
 

+ 36
- 0
src/include/ipxe/syslog.h Zobrazit soubor

@@ -0,0 +1,36 @@
1
+#ifndef _IPXE_SYSLOG_H
2
+#define _IPXE_SYSLOG_H
3
+
4
+/** @file
5
+ *
6
+ * Syslog protocol
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+/** Syslog server port */
13
+#define SYSLOG_PORT 514
14
+
15
+/** Syslog line buffer size
16
+ *
17
+ * This is a policy decision
18
+ */
19
+#define SYSLOG_BUFSIZE 128
20
+
21
+/** Syslog facility
22
+ *
23
+ * This is a policy decision
24
+ */
25
+#define SYSLOG_FACILITY 0 /* kernel */
26
+
27
+/** Syslog severity
28
+ *
29
+ * This is a policy decision
30
+ */
31
+#define SYSLOG_SEVERITY 6 /* informational */
32
+
33
+/** Syslog priority */
34
+#define SYSLOG_PRIORITY( facility, severity ) ( 8 * (facility) + (severity) )
35
+
36
+#endif /* _IPXE_SYSLOG_H */

+ 206
- 0
src/net/udp/syslog.c Zobrazit soubor

@@ -0,0 +1,206 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * Syslog protocol
24
+ *
25
+ */
26
+
27
+#include <stdint.h>
28
+#include <byteswap.h>
29
+#include <ipxe/xfer.h>
30
+#include <ipxe/open.h>
31
+#include <ipxe/tcpip.h>
32
+#include <ipxe/dhcp.h>
33
+#include <ipxe/settings.h>
34
+#include <ipxe/console.h>
35
+#include <ipxe/ansiesc.h>
36
+#include <ipxe/syslog.h>
37
+
38
+/** The syslog server */
39
+static struct sockaddr_tcpip logserver = {
40
+	.st_port = htons ( SYSLOG_PORT ),
41
+};
42
+
43
+/** Syslog UDP interface operations */
44
+static struct interface_operation syslogger_operations[] = {};
45
+
46
+/** Syslog UDP interface descriptor */
47
+static struct interface_descriptor syslogger_desc =
48
+	INTF_DESC_PURE ( syslogger_operations );
49
+
50
+/** The syslog UDP interface */
51
+static struct interface syslogger = INTF_INIT ( syslogger_desc );
52
+
53
+/******************************************************************************
54
+ *
55
+ * Console driver
56
+ *
57
+ ******************************************************************************
58
+ */
59
+
60
+/** Syslog line buffer */
61
+static char syslog_buffer[SYSLOG_BUFSIZE];
62
+
63
+/** Index into syslog line buffer */
64
+static unsigned int syslog_idx;
65
+
66
+/** Syslog recursion marker */
67
+static int syslog_entered;
68
+
69
+/** Syslog ANSI escape sequence handlers */
70
+static struct ansiesc_handler syslog_ansiesc_handlers[] = {
71
+	{ 0, NULL }
72
+};
73
+
74
+/** Syslog ANSI escape sequence context */
75
+static struct ansiesc_context syslog_ansiesc_ctx = {
76
+	.handlers = syslog_ansiesc_handlers,
77
+};
78
+
79
+/**
80
+ * Print a character to syslog console
81
+ *
82
+ * @v character		Character to be printed
83
+ */
84
+static void syslog_putchar ( int character ) {
85
+	int rc;
86
+
87
+	/* Do nothing if we have no log server */
88
+	if ( ! logserver.st_family )
89
+		return;
90
+
91
+	/* Ignore if we are already mid-logging */
92
+	if ( syslog_entered )
93
+		return;
94
+
95
+	/* Strip ANSI escape sequences */
96
+	character = ansiesc_process ( &syslog_ansiesc_ctx, character );
97
+	if ( character < 0 )
98
+		return;
99
+
100
+	/* Ignore carriage return */
101
+	if ( character == '\r' )
102
+		return;
103
+
104
+	/* Treat newline as a terminator */
105
+	if ( character == '\n' )
106
+		character = 0;
107
+
108
+	/* Add character to buffer */
109
+	syslog_buffer[syslog_idx++] = character;
110
+
111
+	/* Do nothing more unless we reach end-of-line (or end-of-buffer) */
112
+	if ( ( character != 0 ) &&
113
+	     ( syslog_idx < ( sizeof ( syslog_buffer ) - 1 /* NUL */ ) ) ) {
114
+		return;
115
+	}
116
+
117
+	/* Reset to start of buffer */
118
+	syslog_idx = 0;
119
+
120
+	/* Guard against re-entry */
121
+	syslog_entered = 1;
122
+
123
+	/* Send log message */
124
+	if ( ( rc = xfer_printf ( &syslogger, "<%d>ipxe: %s",
125
+				  SYSLOG_PRIORITY ( SYSLOG_FACILITY,
126
+						    SYSLOG_SEVERITY ),
127
+				  syslog_buffer ) ) != 0 ) {
128
+		DBG ( "SYSLOG could not send log message: %s\n",
129
+		      strerror ( rc ) );
130
+	}
131
+
132
+	/* Clear re-entry flag */
133
+	syslog_entered = 0;
134
+}
135
+
136
+/** Syslog console driver */
137
+struct console_driver syslog_console __console_driver = {
138
+	.putchar = syslog_putchar,
139
+};
140
+
141
+/******************************************************************************
142
+ *
143
+ * Settings
144
+ *
145
+ ******************************************************************************
146
+ */
147
+
148
+/** Syslog server setting */
149
+struct setting syslog_setting __setting = {
150
+	.name = "syslog",
151
+	.description = "Syslog server",
152
+	.tag = DHCP_LOG_SERVERS,
153
+	.type = &setting_type_ipv4,
154
+};
155
+
156
+/**
157
+ * Apply syslog settings
158
+ *
159
+ * @ret rc		Return status code
160
+ */
161
+static int apply_syslog_settings ( void ) {
162
+	struct sockaddr_in *sin_logserver =
163
+		( struct sockaddr_in * ) &logserver;
164
+	struct in_addr old_addr;
165
+	int len;
166
+	int rc;
167
+
168
+	/* Fetch log server */
169
+	old_addr.s_addr = sin_logserver->sin_addr.s_addr;
170
+	logserver.st_family = 0;
171
+	if ( ( len = fetch_ipv4_setting ( NULL, &syslog_setting,
172
+					  &sin_logserver->sin_addr ) ) >= 0 ) {
173
+		sin_logserver->sin_family = AF_INET;
174
+	}
175
+
176
+	/* Do nothing unless log server has changed */
177
+	if ( sin_logserver->sin_addr.s_addr == old_addr.s_addr )
178
+		return 0;
179
+
180
+	/* Reset syslog connection */
181
+	intf_restart ( &syslogger, 0 );
182
+
183
+	/* Do nothing unless we have a log server */
184
+	if ( ! logserver.st_family ) {
185
+		DBG ( "SYSLOG has no log server\n" );
186
+		return 0;
187
+	}
188
+
189
+	/* Connect to log server */
190
+	if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM,
191
+				       ( ( struct sockaddr * ) &logserver ),
192
+				       NULL ) ) != 0 ) {
193
+		DBG ( "SYSLOG cannot connect to log server: %s\n",
194
+		      strerror ( rc ) );
195
+		return rc;
196
+	}
197
+	DBG ( "SYSLOG using log server %s\n",
198
+	      inet_ntoa ( sin_logserver->sin_addr ) );
199
+
200
+	return 0;
201
+}
202
+
203
+/** Syslog settings applicator */
204
+struct settings_applicator syslog_applicator __settings_applicator = {
205
+	.apply = apply_syslog_settings,
206
+};

Načítá se…
Zrušit
Uložit