Subject: RFC: enhancement to syslogd - always printing local time
To: None <tech-userlevel@netbsd.org>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: tech-userlevel
Date: 01/09/2006 23:09:33
--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

syslogd has currently an undocumented feature - if it does not recognize
the timestamp field in the received message, it generates it, based on the
local time.

I would like to optionally generate timestamp field for all messages
received from network, regardless of validity of the timestamp field.

My motivation is that I take care of switches which don't have NTP, so
their time is meaningless. (Another motivation is that they don't pad the
time values with zeros, so if any of the fields is less than 10, syslogd
will consider the timestamp incorrect, otherwise it will consider it
correct, making the output inconsistent. See:
Jan  9 19:17:24 <local7.info>192.168.11.246 Feb 08 12:30:9 192.168.11.246 trapmgmt:Unit 1, Port 33 link-up notification.
Feb 08 12:31:10 <local7.info>192.168.11.246 192.168.11.246 trapmgmt:Unit 1, Port 37 link-down notification.
)

I expect that such a feature can be generally useful, especially for the
first reason. (Devices that don't keep time properly must be quite common.)
So here is a patch which implements a -T option, causing syslogd to
generate a timestamp field for all messages received over the network.

Is it worth integrating in NetBSD sources?

Bye	Pavel

--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syslogd.patch"

Index: syslogd.8
===================================================================
RCS file: /home/pavel/cvs/src/usr.sbin/syslogd/syslogd.8,v
retrieving revision 1.37
diff -u -u -r1.37 syslogd.8
--- syslogd.8	19 Nov 2004 18:48:29 -0000	1.37
+++ syslogd.8	7 Jan 2006 14:25:38 -0000
@@ -123,6 +123,12 @@
 to
 .Ar chroot_dir
 after the sockets and log files have been opened.
+.It Fl T
+Always use the local time and date for messages received from the
+network, instead of the timestamp field supplied in the message
+by the remote host.
+This is useful if some of the originating hosts can't keep time
+properly or are unable to generate a correct timestamp.
 .It Fl u Ar user
 Set UID to
 .Ar user
@@ -188,6 +194,13 @@
 the log socket).
 Commonly, the program name and the process id is included.
 .Pp
+The date and time are taken from the received message.
+If the format of the timestamp field is incorrect, time obtained from
+the local host is used instead.
+This can be overriden by the
+.Fl T
+flag.
+.Pp
 Accesses from UDP socket can be filtered by libwrap configuration files, like
 .Pa /etc/hosts.deny .
 Specify
@@ -208,6 +221,7 @@
 This priority code should map into the priorities defined in the
 include file
 .Aq Pa sys/syslog.h .
+See RFC 3164 for detailed description of the message format.
 .Pp
 Messages from the local kernel that are not tagged with a priority code
 receive the default facility
@@ -238,6 +252,12 @@
 .Xr services 5 ,
 .Xr syslog.conf 5 ,
 .Xr newsyslog 8
+.Rs
+.%R RFC
+.%N 3164
+.%D August 2001
+.%T The BSD syslog Protocol
+.Re
 .Sh HISTORY
 The
 .Nm
Index: syslogd.c
===================================================================
RCS file: /home/pavel/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.75
diff -u -u -r1.75 syslogd.c
--- syslogd.c	9 Jan 2005 00:07:27 -0000	1.75
+++ syslogd.c	7 Jan 2006 14:34:05 -0000
@@ -242,6 +242,7 @@
 int	NumForwards = 0;	/* number of forwarding actions in conf file */
 char	**LogPaths;		/* array of pathnames to read messages from */
 int	NoRepeat = 0;		/* disable "repeated"; log always */
+int	RemoteAddDate = 0;	/* always add date to messages from network */
 int	SyncKernel = 0;		/* write kernel messages synchronously */
 int	UniquePriority = 0;	/* only log specified priority */
 int	LogFacPri = 0;		/* put facility and priority in log messages: */
@@ -263,7 +264,7 @@
 void	log_deadchild(pid_t, int, const char *);
 int	matches_spec(const char *, const char *,
 		     char *(*)(const char *, const char *));
-void	printline(char *, char *);
+void	printline(char *, char *, int);
 void	printsys(char *);
 int	p_open(char *, pid_t *);
 void	trim_localdomain(char *);
@@ -313,7 +314,7 @@
 
 	(void)setlocale(LC_ALL, "");
 
-	while ((ch = getopt(argc, argv, "dnsSf:m:p:P:ru:g:t:Uv")) != -1)
+	while ((ch = getopt(argc, argv, "dnsSf:m:p:P:ru:g:t:TUv")) != -1)
 		switch(ch) {
 		case 'd':		/* debug */
 			Debug++;
@@ -354,6 +355,9 @@
 			if (*root == '\0')
 				usage();
 			break;
+		case 'T':
+			RemoteAddDate = 1;
+			break;
 		case 'u':
 			user = optarg;
 			if (*user == '\0')
@@ -601,7 +605,7 @@
 {
 
 	(void)fprintf(stderr,
-	    "usage: %s [-dnrSsUv] [-f config_file] [-g group] [-m mark_interval]\n"
+	    "usage: %s [-dnrSsTUv] [-f config_file] [-g group] [-m mark_interval]\n"
 	    "\t[-P file_list] [-p log_socket [-p log_socket2 ...]]\n"
 	    "\t[-t chroot_dir] [-u user]\n", getprogname());
 	exit(1);
@@ -665,7 +669,7 @@
 	    (struct sockaddr *)&fromunix, &sunlen);
 	if (rv > 0) {
 		linebuf[rv] = '\0';
-		printline(LocalHostName, linebuf);
+		printline(LocalHostName, linebuf, 0);
 	} else if (rv < 0 && errno != EINTR) {
 		logerror("recvfrom() unix `%s'", myname.sun_path);
 	}
@@ -708,7 +712,8 @@
 
 	linebuf[rv] = '\0';
 	if (!reject)
-		printline(cvthname(&frominet), linebuf);
+		printline(cvthname(&frominet), linebuf,
+			  RemoteAddDate ? ADDDATE : 0);
 }
 
 /*
@@ -770,7 +775,7 @@
  * on the appropriate log files.
  */
 void
-printline(char *hname, char *msg)
+printline(char *hname, char *msg, int flags)
 {
 	int c, pri;
 	char *p, *q, line[MAXLINE + 1];
@@ -817,7 +822,7 @@
 	}
 	*q = '\0';
 
-	logmsg(pri, line, hname, 0);
+	logmsg(pri, line, hname, flags);
 }
 
 /*

--ZPt4rx8FFjLCG7dd--