Dirk Mueller
2144a0b3f4
Copy from home:jengelh:branches:Base:System/syslogd via accept of submit request 28151 revision 3. Request was accepted with message: thanks! OBS-URL: https://build.opensuse.org/request/show/28151 OBS-URL: https://build.opensuse.org/package/show/Base:System/syslogd?expand=0&rev=12
526 lines
14 KiB
Diff
526 lines
14 KiB
Diff
Index: CHANGES
|
|
===================================================================
|
|
--- CHANGES.orig 2001-03-11 20:35:51.000000000 +0100
|
|
+++ CHANGES 2009-11-24 18:12:53.132378000 +0100
|
|
@@ -1,3 +1,7 @@
|
|
+Version 1.4.1-usagi (2001/03/21)
|
|
+ - syslogd IPv6 support
|
|
+ (based on patch from Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
|
|
+
|
|
Version 1.4.1
|
|
|
|
. klogd will set the console log level only if `-c' is given on the
|
|
Index: Makefile
|
|
===================================================================
|
|
--- Makefile.orig 1998-10-12 22:25:15.000000000 +0200
|
|
+++ Makefile 2009-11-24 18:12:53.137377000 +0100
|
|
@@ -3,7 +3,7 @@
|
|
CC= gcc
|
|
#CFLAGS= -g -DSYSV -Wall
|
|
#LDFLAGS= -g
|
|
-CFLAGS= $(RPM_OPT_FLAGS) -O3 -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce
|
|
+CFLAGS= $(RPM_OPT_FLAGS) -DINET6 -O3 -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce
|
|
LDFLAGS= -s
|
|
|
|
# Look where your install program is.
|
|
Index: syslogd.c
|
|
===================================================================
|
|
--- syslogd.c.orig 2009-11-24 18:12:52.661468000 +0100
|
|
+++ syslogd.c 2009-11-24 18:12:53.143385000 +0100
|
|
@@ -599,6 +599,7 @@ int funix[MAXFUNIX] = { -1, };
|
|
* This table contains plain text for h_errno errors used by the
|
|
* net subsystem.
|
|
*/
|
|
+#ifndef INET6 /* not */
|
|
const char *sys_h_errlist[] = {
|
|
"No problem", /* NETDB_SUCCESS */
|
|
"Authoritative answer: host not found", /* HOST_NOT_FOUND */
|
|
@@ -607,6 +608,7 @@ const char *sys_h_errlist[] = {
|
|
"Valid name, no data record of requested type", /* NO_DATA */
|
|
"no address, look for MX record" /* NO_ADDRESS */
|
|
};
|
|
+#endif
|
|
|
|
/*
|
|
* This structure represents the files that will have log
|
|
@@ -625,7 +627,18 @@ struct filed {
|
|
char f_uname[MAXUNAMES][UNAMESZ+1];
|
|
struct {
|
|
char f_hname[MAXHOSTNAMELEN+1];
|
|
+#ifdef INET6
|
|
+ union {
|
|
+ struct sockaddr sa;
|
|
+ struct sockaddr_in sin;
|
|
+ struct sockaddr_in6 sin6;
|
|
+ } f_sa;
|
|
+#define f_addr f_sa.sa
|
|
+#define f_addr4 f_sa.sin
|
|
+#define f_addr6 f_sa.sin6
|
|
+#else
|
|
struct sockaddr_in f_addr;
|
|
+#endif
|
|
} f_forw; /* forwarding address */
|
|
char f_fname[MAXFNAME];
|
|
} f_un;
|
|
@@ -732,7 +745,11 @@ char LocalHostName[MAXHOSTNAMELEN+1]; /*
|
|
char *LocalDomain; /* our local domain name */
|
|
int InetInuse = 0; /* non-zero if INET sockets are being used */
|
|
int finet = -1; /* Internet datagram socket */
|
|
+#ifdef INET6
|
|
+sa_family_t family; /* socket address family */
|
|
+#else
|
|
int LogPort; /* port number for INET connections */
|
|
+#endif
|
|
int Initialized = 0; /* set when we have initialized ourselves */
|
|
int MarkInterval = 20 * 60; /* interval between marks in seconds */
|
|
int MarkSeq = 0; /* mark sequence number */
|
|
@@ -759,10 +776,10 @@ void fprintlog(register struct filed *f,
|
|
void endtty();
|
|
void wallmsg(register struct filed *f, struct iovec *iov);
|
|
void reapchild();
|
|
-const char *cvthname(struct sockaddr_in *f);
|
|
+const char *cvthname(struct sockaddr *f);
|
|
void domark();
|
|
void debug_switch();
|
|
-void logerror(char *type);
|
|
+void logerror(const char *type);
|
|
void die(int sig);
|
|
#ifndef TESTING
|
|
void doexit(int sig);
|
|
@@ -782,6 +799,10 @@ static int create_unix_socket(const char
|
|
#endif
|
|
#ifdef SYSLOG_INET
|
|
static int create_inet_socket();
|
|
+#ifdef INET6
|
|
+static void setup_inetaddr_all();
|
|
+static const char *setup_inetaddr(struct filed *f);
|
|
+#endif
|
|
#endif
|
|
|
|
int main(argc, argv)
|
|
@@ -816,7 +837,12 @@ int main(argc, argv)
|
|
#ifndef TESTING
|
|
int fd;
|
|
#ifdef SYSLOG_INET
|
|
+#ifdef INET6
|
|
+ struct sockaddr_storage frominet;
|
|
+ char hbuf[INET6_ADDRSTRLEN];
|
|
+#else
|
|
struct sockaddr_in frominet;
|
|
+#endif
|
|
char *from;
|
|
#endif
|
|
pid_t ppid = getpid();
|
|
@@ -1137,11 +1163,21 @@ int main(argc, argv)
|
|
memset(line, '\0', sizeof(line));
|
|
i = recvfrom(finet, line, MAXLINE - 2, 0, \
|
|
(struct sockaddr *) &frominet, &len);
|
|
+#ifdef INET6
|
|
+ if (getnameinfo((struct sockaddr *)&frominet, len,
|
|
+ hbuf, sizeof(hbuf), NULL, 0,
|
|
+ NI_NUMERICHOST)) {
|
|
+ strcpy(hbuf, "???");
|
|
+ }
|
|
+ dprintf("Message from inetd socket: #%d, host: %s\n",
|
|
+ inetm, hbuf);
|
|
+#else
|
|
dprintf("Message from inetd socket: #%d, host: %s\n",
|
|
inetm, inet_ntoa(frominet.sin_addr));
|
|
+#endif
|
|
if (i > 0) {
|
|
line[i] = line[i+1] = '\0';
|
|
- from = (char *)cvthname(&frominet);
|
|
+ from = (char *)cvthname((struct sockaddr*)&frominet);
|
|
/*
|
|
* Here we could check if the host is permitted
|
|
* to send us syslog messages. We just have to
|
|
@@ -1227,17 +1263,50 @@ static int create_unix_socket(const char
|
|
static int create_inet_socket()
|
|
{
|
|
int fd, on = 1;
|
|
+#ifdef INET6
|
|
+ struct addrinfo hints, *res;
|
|
+ int error;
|
|
+#else
|
|
struct sockaddr_in sin;
|
|
+#endif
|
|
|
|
+#ifdef INET6
|
|
+ fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
+ if (fd >= 0) {
|
|
+ family = AF_INET6;
|
|
+ } else {
|
|
+ family = AF_INET;
|
|
+ dprintf("cannot create INET6 socket.\n");
|
|
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
+ }
|
|
+#else
|
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
+#endif
|
|
if (fd < 0) {
|
|
logerror("syslog: Unknown protocol, suspending inet service.");
|
|
return fd;
|
|
}
|
|
|
|
+#ifdef NO_BIND_AT_FORWARD_ONLY
|
|
+ if (AcceptRemote == 0)
|
|
+ return fd;
|
|
+#endif
|
|
+#ifdef INET6
|
|
+ memset(&hints, 0, sizeof(hints));
|
|
+ hints.ai_flags = AI_PASSIVE;
|
|
+ hints.ai_family = family;
|
|
+ hints.ai_socktype = SOCK_DGRAM;
|
|
+ error = getaddrinfo(NULL, "syslog", &hints, &res);
|
|
+ if (error) {
|
|
+ logerror(gai_strerror(error));
|
|
+ close(fd);
|
|
+ return -1;
|
|
+ }
|
|
+#else
|
|
memset(&sin, 0, sizeof(sin));
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = LogPort;
|
|
+#endif
|
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, \
|
|
(char *) &on, sizeof(on)) < 0 ) {
|
|
logerror("setsockopt(REUSEADDR), suspending inet");
|
|
@@ -1253,13 +1322,77 @@ static int create_inet_socket()
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
+#ifdef INET6
|
|
+ error = bind(fd, res->ai_addr, res->ai_addrlen);
|
|
+ freeaddrinfo(res);
|
|
+ if (error < 0) {
|
|
+#else
|
|
if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
|
+#endif
|
|
logerror("bind, suspending inet");
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
return fd;
|
|
}
|
|
+
|
|
+#ifdef INET6
|
|
+
|
|
+static void setup_inetaddr_all()
|
|
+{
|
|
+ struct filed *f;
|
|
+#ifdef SYSV
|
|
+ int lognum;
|
|
+
|
|
+ for (lognum = 0; lognum <= nlogs; lognum++) {
|
|
+ f = &Files[lognum];
|
|
+#else
|
|
+ for (f = Files; f; f = f->f_next) {
|
|
+#endif
|
|
+ if (f->f_type == F_FORW_UNKN) {
|
|
+ if (setup_inetaddr(f)) {
|
|
+ f->f_prevcount = INET_RETRY_MAX;
|
|
+ f->f_time = time( (time_t *)0 );
|
|
+ } else {
|
|
+ f->f_type = F_FORW;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static const char *setup_inetaddr(struct filed *f)
|
|
+{
|
|
+ struct addrinfo hints, *res;
|
|
+ int error;
|
|
+
|
|
+ memset(&hints, 0, sizeof(hints));
|
|
+ hints.ai_family = family == AF_INET6 ? AF_UNSPEC : AF_INET;
|
|
+ hints.ai_socktype = SOCK_DGRAM;
|
|
+ error = getaddrinfo(f->f_un.f_forw.f_hname, "syslog", &hints, &res);
|
|
+ if (error) {
|
|
+ return gai_strerror(error);
|
|
+ }
|
|
+ if (res->ai_addrlen > sizeof(f->f_un.f_forw.f_sa)) {
|
|
+ freeaddrinfo(res);
|
|
+ return "addrlen too large";
|
|
+ }
|
|
+ if (family == AF_INET6 && res->ai_family == AF_INET) {
|
|
+ /* v4mapped addr */
|
|
+ f->f_un.f_forw.f_addr.sa_family = AF_INET6;
|
|
+ f->f_un.f_forw.f_addr6.sin6_port =
|
|
+ ((struct sockaddr_in *)res->ai_addr)->sin_port;
|
|
+ f->f_un.f_forw.f_addr6.sin6_addr.s6_addr16[5] = 0xffff;
|
|
+ memcpy(&f->f_un.f_forw.f_addr6.sin6_addr.s6_addr32[3],
|
|
+ &((struct sockaddr_in *)res->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ } else {
|
|
+ memcpy(&f->f_un.f_forw.f_addr, res->ai_addr, res->ai_addrlen);
|
|
+ }
|
|
+ freeaddrinfo(res);
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+#endif /* end of INET6 */
|
|
#endif
|
|
|
|
char **
|
|
@@ -1679,8 +1812,12 @@ void fprintlog(f, from, flags, msg)
|
|
register int l;
|
|
char line[MAXLINE + 1];
|
|
time_t fwd_suspend;
|
|
+#ifdef INET6
|
|
+ const char *errmsg;
|
|
+#else
|
|
struct hostent *hp;
|
|
#endif
|
|
+#endif
|
|
|
|
dprintf("Called fprintlog, ");
|
|
|
|
@@ -1734,22 +1871,27 @@ void fprintlog(f, from, flags, msg)
|
|
fwd_suspend);
|
|
}
|
|
break;
|
|
-
|
|
+
|
|
/*
|
|
* The trick is to wait some time, then retry to get the
|
|
* address. If that fails retry x times and then give up.
|
|
*
|
|
* You'll run into this problem mostly if the name server you
|
|
* need for resolving the address is on the same machine, but
|
|
- * is started after syslogd.
|
|
+ * is started after syslogd.
|
|
*/
|
|
case F_FORW_UNKN:
|
|
dprintf(" %s\n", f->f_un.f_forw.f_hname);
|
|
fwd_suspend = time((time_t *) 0) - f->f_time;
|
|
if ( fwd_suspend >= INET_SUSPEND_TIME ) {
|
|
dprintf("Forwarding suspension to unknown over, retrying\n");
|
|
+#ifdef INET6
|
|
+ if ((errmsg = setup_inetaddr(f))) {
|
|
+ dprintf("Failure: %s\n", errmsg);
|
|
+#else
|
|
if ( (hp = gethostbyname(f->f_un.f_forw.f_hname)) == NULL ) {
|
|
dprintf("Failure: %s\n", sys_h_errlist[h_errno]);
|
|
+#endif
|
|
dprintf("Retries: %d\n", f->f_prevcount);
|
|
if ( --f->f_prevcount < 0 ) {
|
|
dprintf("Giving up.\n");
|
|
@@ -1760,7 +1902,9 @@ void fprintlog(f, from, flags, msg)
|
|
}
|
|
else {
|
|
dprintf("%s found, resuming.\n", f->f_un.f_forw.f_hname);
|
|
+#ifndef INET6 /* not */
|
|
memcpy((char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length);
|
|
+#endif
|
|
f->f_prevcount = 0;
|
|
f->f_type = F_FORW;
|
|
goto f_forw;
|
|
@@ -1783,27 +1927,31 @@ void fprintlog(f, from, flags, msg)
|
|
dprintf("Not sending message to remote.\n");
|
|
else {
|
|
f->f_time = now;
|
|
-/* afx: add <sourcehost
|
|
+/* afx: add <sourcehost
|
|
*/
|
|
- if ((TagForward == 1) &&
|
|
+ if ((TagForward == 1) &&
|
|
strncmp(f->f_prevhost,LocalHostName,MAXHOSTNAMELEN+1)) {
|
|
- (void) snprintf(line, sizeof(line), "<%d><%s: %s\n",
|
|
- f->f_prevpri, f->f_prevhost,
|
|
+ (void) snprintf(line, sizeof(line), "<%d><%s: %s\n",
|
|
+ f->f_prevpri, f->f_prevhost,
|
|
(char *) iov[4].iov_base);
|
|
} else {
|
|
(void) snprintf(line, sizeof(line), "<%d>%s\n",
|
|
- f->f_prevpri,
|
|
+ f->f_prevpri,
|
|
(char *) iov[4].iov_base);
|
|
}
|
|
-/* end afx */
|
|
+/* end afx */
|
|
l = strlen(line);
|
|
if (l > MAXLINE)
|
|
l = MAXLINE;
|
|
if (sendto(finet, line, l, 0, \
|
|
(struct sockaddr *) &f->f_un.f_forw.f_addr,
|
|
- sizeof(f->f_un.f_forw.f_addr)) != l) {
|
|
+#ifdef INET6
|
|
+ family == AF_INET6 ?
|
|
+ sizeof(struct sockaddr_in6) :
|
|
+#endif
|
|
+ sizeof(struct sockaddr_in)) != l) {
|
|
int e = errno;
|
|
- dprintf("INET sendto error: %d = %s.\n",
|
|
+ dprintf("INET sendto error: %d = %s.\n",
|
|
e, strerror(e));
|
|
f->f_type = F_FORW_SUSP;
|
|
errno = e;
|
|
@@ -2025,28 +2173,53 @@ void reapchild()
|
|
/*
|
|
* Return a printable representation of a host address.
|
|
*/
|
|
-const char *cvthname(f)
|
|
- struct sockaddr_in *f;
|
|
+const char *cvthname(struct sockaddr *f)
|
|
{
|
|
+#ifdef INET6
|
|
+ static char hname[NI_MAXHOST];
|
|
+ int error;
|
|
+#else
|
|
struct hostent *hp;
|
|
+ char *hname;
|
|
+#endif
|
|
register char *p;
|
|
int count;
|
|
|
|
- if (f->sin_family != AF_INET) {
|
|
+#ifdef INET6
|
|
+ if (((struct sockaddr *)f)->sa_family == AF_INET6 &&
|
|
+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)f)->sin6_addr)) {
|
|
+ ((struct sockaddr *)f)->sa_family = AF_INET;
|
|
+ ((struct sockaddr_in *)f)->sin_addr.s_addr =
|
|
+ ((struct sockaddr_in6 *)f)->sin6_addr.s6_addr32[3];
|
|
+ }
|
|
+ error = getnameinfo((struct sockaddr *)f,
|
|
+ ((struct sockaddr *)f)->sa_family == AF_INET6 ?
|
|
+ sizeof(struct sockaddr_in6)
|
|
+ : sizeof(struct sockaddr_in),
|
|
+ hname, sizeof(hname), NULL, 0, 0);
|
|
+ if (error) {
|
|
+ dprintf("Malformed from address %s\n", gai_strerror(error));
|
|
+ return ("???");
|
|
+ }
|
|
+#else
|
|
+ if (((struct sockaddr_in *)f)->sin_family != AF_INET) {
|
|
dprintf("Malformed from address.\n");
|
|
return ("???");
|
|
}
|
|
- hp = gethostbyaddr((char *) &f->sin_addr, sizeof(struct in_addr), \
|
|
- f->sin_family);
|
|
+ hp = gethostbyaddr((char *) &(((struct sockaddr_in *)&f)->sin_addr),
|
|
+ sizeof(struct in_addr),
|
|
+ ((struct sockaddr_in *)f)->sin_family);
|
|
if (hp == 0) {
|
|
dprintf("Host name for your address (%s) unknown.\n",
|
|
- inet_ntoa(f->sin_addr));
|
|
- return (inet_ntoa(f->sin_addr));
|
|
+ inet_ntoa(((struct sockaddr_in *)f)->sin_addr));
|
|
+ return (inet_ntoa(((struct sockaddr_in *)f)->sin_addr));
|
|
}
|
|
+ hname = hp->h_name;
|
|
+#endif
|
|
/*
|
|
* Convert to lower case, just like LocalDomain above
|
|
*/
|
|
- for (p = (char *)hp->h_name; *p ; p++)
|
|
+ for (p = hname; *p ; p++)
|
|
if (isupper(*p))
|
|
*p = tolower(*p);
|
|
|
|
@@ -2054,17 +2227,17 @@ const char *cvthname(f)
|
|
* Notice that the string still contains the fqdn, but your
|
|
* hostname and domain are separated by a '\0'.
|
|
*/
|
|
- if ((p = strchr(hp->h_name, '.'))) {
|
|
+ if ((p = strchr(hname, '.'))) {
|
|
if (strcmp(p + 1, LocalDomain) == 0) {
|
|
*p = '\0';
|
|
- return (hp->h_name);
|
|
+ return (hname);
|
|
} else {
|
|
if (StripDomains) {
|
|
count=0;
|
|
while (StripDomains[count]) {
|
|
if (strcmp(p + 1, StripDomains[count]) == 0) {
|
|
*p = '\0';
|
|
- return (hp->h_name);
|
|
+ return (hname);
|
|
}
|
|
count++;
|
|
}
|
|
@@ -2072,9 +2245,9 @@ const char *cvthname(f)
|
|
if (LocalHosts) {
|
|
count=0;
|
|
while (LocalHosts[count]) {
|
|
- if (!strcmp(hp->h_name, LocalHosts[count])) {
|
|
+ if (!strcmp(hname, LocalHosts[count])) {
|
|
*p = '\0';
|
|
- return (hp->h_name);
|
|
+ return (hname);
|
|
}
|
|
count++;
|
|
}
|
|
@@ -2082,7 +2255,7 @@ const char *cvthname(f)
|
|
}
|
|
}
|
|
|
|
- return (hp->h_name);
|
|
+ return (hname);
|
|
}
|
|
|
|
void domark()
|
|
@@ -2132,7 +2305,7 @@ void debug_switch()
|
|
* Print syslogd errors some place.
|
|
*/
|
|
void logerror(type)
|
|
- char *type;
|
|
+ const char *type;
|
|
{
|
|
char buf[100];
|
|
|
|
@@ -2226,6 +2399,7 @@ void init()
|
|
#else
|
|
char cline[BUFSIZ];
|
|
#endif
|
|
+#ifndef INET6 /* not */
|
|
struct servent *sp;
|
|
|
|
sp = getservbyname("syslog", "udp");
|
|
@@ -2236,6 +2410,7 @@ void init()
|
|
return;
|
|
}
|
|
LogPort = sp->s_port;
|
|
+#endif
|
|
|
|
/*
|
|
* Close all open log files and free log descriptor array.
|
|
@@ -2384,6 +2559,10 @@ void init()
|
|
InetInuse = 0;
|
|
}
|
|
inetm = finet;
|
|
+#ifdef INET6
|
|
+ if (finet >= 0)
|
|
+ setup_inetaddr_all();
|
|
+#endif
|
|
#endif
|
|
|
|
Initialized = 1;
|
|
@@ -2471,7 +2650,7 @@ void cfline(line, f)
|
|
int singlpri = 0;
|
|
int ignorepri = 0;
|
|
int syncfile;
|
|
-#ifdef SYSLOG_INET
|
|
+#if defined(SYSLOG_INET) && !defined(INET6)
|
|
struct hostent *hp;
|
|
#endif
|
|
char buf[MAXLINE];
|
|
@@ -2630,6 +2809,9 @@ void cfline(line, f)
|
|
#ifdef SYSLOG_INET
|
|
(void) strcpy(f->f_un.f_forw.f_hname, ++p);
|
|
dprintf("forwarding host: %s\n", p); /*ASP*/
|
|
+#ifdef INET6
|
|
+ f->f_type = F_FORW_UNKN;
|
|
+#else
|
|
if ( (hp = gethostbyname(p)) == NULL ) {
|
|
f->f_type = F_FORW_UNKN;
|
|
f->f_prevcount = INET_RETRY_MAX;
|
|
@@ -2644,6 +2826,7 @@ void cfline(line, f)
|
|
f->f_un.f_forw.f_addr.sin_port = LogPort;
|
|
if ( f->f_type == F_FORW )
|
|
memcpy((char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length);
|
|
+#endif
|
|
/*
|
|
* Otherwise the host might be unknown due to an
|
|
* inaccessible nameserver (perhaps on the same
|