From df9856d691fbca1e8ff4b45603ecfbdd68871ea0 Mon Sep 17 00:00:00 2001 From: olli Date: Sat, 7 Aug 2010 16:20:12 +0000 Subject: syslogd(8) already supports *sending* log messages to non- standard ports, but it can't *receive* them (port 514 is hardcoded). This commit adds that missing feature. (NB: I actually needed this feature for a server farm where multiple jails run with shared IP addresses, and every jail should have its own syslogd process.) As a side effect, syslogd now compiles with WARNS=6. Approved by: des (mentor) MFC after: 3 weeks --- usr.sbin/syslogd/Makefile | 2 +- usr.sbin/syslogd/syslogd.8 | 27 +++++++++++++++++++++++---- usr.sbin/syslogd/syslogd.c | 40 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 9 deletions(-) (limited to 'usr.sbin/syslogd') diff --git a/usr.sbin/syslogd/Makefile b/usr.sbin/syslogd/Makefile index 1682b49..3a2a80b 100644 --- a/usr.sbin/syslogd/Makefile +++ b/usr.sbin/syslogd/Makefile @@ -12,7 +12,7 @@ SRCS= syslogd.c ttymsg.c DPADD= ${LIBUTIL} LDADD= -lutil -WARNS?= 3 +WARNS?= 6 .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8 index aae9b4f..ff0141d 100644 --- a/usr.sbin/syslogd/syslogd.8 +++ b/usr.sbin/syslogd/syslogd.8 @@ -171,10 +171,29 @@ The options are ignored if the .Fl s option is also specified. -.It Fl b Ar bind_address -Specify one specific IP address or hostname to bind to. -If a hostname is specified, -the IPv4 or IPv6 address which corresponds to it is used. +.It Xo +.Fl b +.Sm off +.Ar bind_address Op : Ar service +.Sm on +.Xc +.It Xo +.Fl b +.Sm off +.Li : Ar service +.Sm on +.Xc +Bind to a specific address and/or port. +The address can be specified as a hostname, +and the port as a service name. +If an IPv6 address is specified, it should be enclosed with +.Ql \&[ +and +.Ql \&] . +The default +.Ar service +is +.Ql syslog . .It Fl C Create log files that do not exist (permission is set to .Li 0600 ) . diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index b803969..e97f8dc 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -317,7 +317,7 @@ static void dodie(int); static void dofsync(void); static void domark(int); static void fprintlog(struct filed *, int, const char *); -static int *socksetup(int, const char *); +static int *socksetup(int, char *); static void init(int); static void logerror(const char *); static void logmsg(int, const char *, const char *, int); @@ -345,7 +345,8 @@ main(int argc, char *argv[]) struct sockaddr_storage frominet; fd_set *fdsr = NULL; char line[MAXLINE + 1]; - const char *bindhostname, *hname; + char *bindhostname; + const char *hname; struct timeval tv, *tvp; struct sigaction sact; struct funix *fx, *fx1; @@ -2605,16 +2606,47 @@ log_deadchild(pid_t pid, int status, const char *name) } static int * -socksetup(int af, const char *bindhostname) +socksetup(int af, char *bindhostname) { struct addrinfo hints, *res, *r; + const char *bindservice; + char *cp; int error, maxs, *s, *socks; + /* + * We have to handle this case for backwards compatibility: + * If there are two (or more) colons but no '[' and ']', + * assume this is an inet6 address without a service. + */ + bindservice = "syslog"; + if (bindhostname != NULL) { +#ifdef INET6 + if (*bindhostname == '[' && + (cp = strchr(bindhostname + 1, ']')) != NULL) { + ++bindhostname; + *cp = '\0'; + if (cp[1] == ':' && cp[2] != '\0') + bindservice = cp + 2; + } else { +#endif + cp = strchr(bindhostname, ':'); + if (cp != NULL && strchr(cp + 1, ':') == NULL) { + *cp = '\0'; + if (cp[1] != '\0') + bindservice = cp + 1; + if (cp == bindhostname) + bindhostname = NULL; + } +#ifdef INET6 + } +#endif + } + memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = af; hints.ai_socktype = SOCK_DGRAM; - error = getaddrinfo(bindhostname, "syslog", &hints, &res); + error = getaddrinfo(bindhostname, bindservice, &hints, &res); if (error) { logerror(gai_strerror(error)); errno = 0; -- cgit v1.1