Subject: bin/8934: IPv6 support for syslogd
To: None <gnats-bugs@gnats.netbsd.org>
From: Feico Dillema <dillema@acm.org>
List: netbsd-bugs
Date: 12/02/1999 05:23:01
>Number: 8934
>Category: bin
>Synopsis: syslogd lacks IPv6 support
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Dec 2 05:20:59 1999
>Last-Modified:
>Originator: Feico Dillema
>Organization:
University of Tromsų
>Release: Thu Dec 2 1999
>Environment:
System: NetBSD drifter 1.4P NetBSD 1.4P (DRIFTER) #2: Tue Nov 23 17:28:15 PST 1999 root@drifter.dillema.net:/usr/cvs/src/sys/arch/i386/compile/DRIFTER i386
>Description:
-current syslogd supports only logging over unix and inet sockets,
and not over inet6.
>How-To-Repeat:
NA
>Fix:
A simple patch for syslogd.c (and its Makefile) is attached to this email
that makes syslogd use the new resolver API (getaddrinfo()) for address
family independence and when compiled with option INET6 defined will
try to bind to an inet6 socket in addition to an the regular inet socket.
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syslogd.c.diff"
*** syslogd.c.orig Wed Dec 1 14:39:39 1999
--- syslogd.c Thu Dec 2 13:52:24 1999
***************
*** 140,146 ****
char f_uname[MAXUNAMES][UT_NAMESIZE+1];
struct {
char f_hname[MAXHOSTNAMELEN+1];
! struct sockaddr_in f_addr;
} f_forw; /* forwarding address */
char f_fname[MAXPATHLEN];
} f_un;
--- 140,146 ----
char f_uname[MAXUNAMES][UT_NAMESIZE+1];
struct {
char f_hname[MAXHOSTNAMELEN+1];
! struct addrinfo *f_addr;
} f_forw; /* forwarding address */
char f_fname[MAXPATHLEN];
} f_un;
***************
*** 186,192 ****
char LocalHostName[MAXHOSTNAMELEN+1]; /* our hostname */
char *LocalDomain; /* our local domain name */
int InetInuse = 0; /* non-zero if INET sockets are being used */
! int finet; /* Internet datagram socket */
int LogPort; /* port number for INET connections */
int Initialized = 0; /* set when we have initialized ourselves */
int MarkInterval = 20 * 60; /* interval between marks in seconds */
--- 186,192 ----
char LocalHostName[MAXHOSTNAMELEN+1]; /* our hostname */
char *LocalDomain; /* our local domain name */
int InetInuse = 0; /* non-zero if INET sockets are being used */
! int finet, finet6; /* Internet datagram socket */
int LogPort; /* port number for INET connections */
int Initialized = 0; /* set when we have initialized ourselves */
int MarkInterval = 20 * 60; /* interval between marks in seconds */
***************
*** 195,206 ****
char **LogPaths; /* array of pathnames to read messages from */
void cfline __P((char *, struct filed *));
! char *cvthname __P((struct sockaddr_in *));
int decode __P((const char *, CODE *));
void die __P((int));
void domark __P((int));
void fprintlog __P((struct filed *, int, char *));
int getmsgbufsize __P((void));
void init __P((int));
void logerror __P((char *));
void logmsg __P((int, char *, char *, int));
--- 195,207 ----
char **LogPaths; /* array of pathnames to read messages from */
void cfline __P((char *, struct filed *));
! char *cvthname __P((struct sockaddr_storage *));
int decode __P((const char *, CODE *));
void die __P((int));
void domark __P((int));
void fprintlog __P((struct filed *, int, char *));
int getmsgbufsize __P((void));
+ int socksetup __P((int));
void init __P((int));
void logerror __P((char *));
void logmsg __P((int, char *, char *, int));
***************
*** 219,228 ****
char *argv[];
{
int ch, *funix, i, j, fklog, len, linesize;
! int nfinetix, nfklogix, nfunixbaseix, nfds;
int funixsize = 0, funixmaxsize = 0;
struct sockaddr_un sunx, fromunix;
! struct sockaddr_in sin, frominet;
char *p, *line, **pp;
struct pollfd *readfds;
--- 220,229 ----
char *argv[];
{
int ch, *funix, i, j, fklog, len, linesize;
! int nfinetix, nfinet6ix, nfklogix, nfunixbaseix, nfds;
int funixsize = 0, funixmaxsize = 0;
struct sockaddr_un sunx, fromunix;
! struct sockaddr_storage frominet;
char *p, *line, **pp;
struct pollfd *readfds;
***************
*** 318,349 ****
dprintf("listening on unix dgram socket %s\n", *pp);
}
! if (!SecureMode)
! finet = socket(AF_INET, SOCK_DGRAM, 0);
! else
finet = -1;
if (finet >= 0) {
- struct servent *sp;
-
- sp = getservbyname("syslog", "udp");
- if (sp == NULL) {
- errno = 0;
- logerror("syslog/udp: unknown service");
- die(0);
- }
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = LogPort = sp->s_port;
- if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- logerror("bind");
- if (!Debug)
- die(0);
- } else {
- InetInuse = 1;
- }
dprintf("listening on inet socket\n");
}
if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0) {
dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
} else {
--- 319,346 ----
dprintf("listening on unix dgram socket %s\n", *pp);
}
! if (!SecureMode) {
! finet = socksetup(AF_INET);
! #ifdef INET6
! finet6 = socksetup(AF_INET6);
! #else
! finet6 = -1;
! #endif
! }
! else {
finet = -1;
+ finet6 = -1;
+ }
if (finet >= 0) {
dprintf("listening on inet socket\n");
+ InetInuse = 1;
}
+ if (finet6 >= 0) {
+ dprintf("listening on inet6 socket\n");
+ InetInuse = 1;
+ }
+
if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0) {
dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
} else {
***************
*** 377,382 ****
--- 374,384 ----
readfds[nfinetix].fd = finet;
readfds[nfinetix].events = POLLIN | POLLPRI;
}
+ if (finet6 >= 0) {
+ nfinet6ix = nfds++;
+ readfds[nfinet6ix].fd = finet6;
+ readfds[nfinet6ix].events = POLLIN | POLLPRI;
+ }
nfunixbaseix = nfds;
for (j = 0, pp = LogPaths; *pp; pp++) {
readfds[nfds].fd = funix[j++];
***************
*** 441,446 ****
--- 443,460 ----
} else if (i < 0 && errno != EINTR)
logerror("recvfrom inet");
}
+ if (finet6 >= 0 &&
+ (readfds[nfinet6ix].revents & (POLLIN | POLLPRI))) {
+ dprintf("inet6 socket active\n");
+ len = sizeof(frominet);
+ i = recvfrom(finet6, line, MAXLINE, 0,
+ (struct sockaddr *)&frominet, &len);
+ if (i > 0) {
+ line[i] = '\0';
+ printline(cvthname(&frominet), line);
+ } else if (i < 0 && errno != EINTR)
+ logerror("recvfrom inet6");
+ }
}
}
***************
*** 721,727 ****
{
struct iovec iov[6];
struct iovec *v;
! int l;
char line[MAXLINE + 1], repbuf[80], greetings[200];
v = iov;
--- 735,742 ----
{
struct iovec iov[6];
struct iovec *v;
! struct addrinfo *r;
! int l, lsent;
char line[MAXLINE + 1], repbuf[80], greetings[200];
v = iov;
***************
*** 785,798 ****
}
if (l > MAXLINE)
l = MAXLINE;
! if ((finet >= 0) &&
! (sendto(finet, line, l, 0,
! (struct sockaddr *)&f->f_un.f_forw.f_addr,
! sizeof(f->f_un.f_forw.f_addr)) != l)) {
! int e = errno;
! f->f_type = F_UNUSED;
! errno = e;
! logerror("sendto");
}
break;
--- 800,820 ----
}
if (l > MAXLINE)
l = MAXLINE;
! if (finet >= 0 || finet6 >= 0) {
! for (r = f->f_un.f_forw.f_addr; r; r = r->ai_next) {
! if (r->ai_family == AF_INET)
! lsent = sendto(finet, line, l, 0, r->ai_addr, r->ai_addrlen);
! #ifdef INET6
! if (r->ai_family == AF_INET6)
! lsent = sendto(finet6, line, l, 0, r->ai_addr, r->ai_addrlen);
! #endif
! if (lsent == l)
! break;
! }
! if (lsent != l) {
! f->f_type = F_UNUSED;
! logerror("sendto");
! }
}
break;
***************
*** 920,946 ****
*/
char *
cvthname(f)
! struct sockaddr_in *f;
{
! struct hostent *hp;
! char *p;
! dprintf("cvthname(%s)\n", inet_ntoa(f->sin_addr));
! if (f->sin_family != AF_INET) {
! dprintf("Malformed from address\n");
return ("???");
}
! hp = gethostbyaddr((char *)&f->sin_addr,
! sizeof(struct in_addr), 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));
}
! if ((p = strchr(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
*p = '\0';
! return (hp->h_name);
}
void
--- 942,978 ----
*/
char *
cvthname(f)
! struct sockaddr_storage *f;
{
! int error;
! char *p, *host, *ip;
! host = malloc(NI_MAXHOST);
! ip = malloc(NI_MAXHOST);
! if (host == NULL || ip == NULL) {
! logerror("couldn't allocate name strings");
! die(0);
! }
! error = getnameinfo((struct sockaddr*)f, ((struct sockaddr*)f)->sa_len, ip,
! NI_MAXHOST, NULL, 0, NI_NUMERICHOST|NI_DGRAM);
!
! dprintf("cvthname(%s)\n", ip);
!
! if (error) {
! dprintf("Malformed from address %s\n", gai_strerror(error));
return ("???");
}
!
! error = getnameinfo((struct sockaddr*)f, ((struct sockaddr*)f)->sa_len, host,
! NI_MAXHOST, NULL, 0, NI_DGRAM);
! if (error) {
! dprintf("Host name for your address (%s) unknown\n", ip);
! return (ip);
}
! if ((p = strchr(host, '.')) && strcmp(p + 1, LocalDomain) == 0)
*p = '\0';
! return (host);
}
void
***************
*** 1125,1134 ****
char *line;
struct filed *f;
{
! struct hostent *hp;
! int i, pri;
! char *bp, *p, *q;
! char buf[MAXLINE], ebuf[100];
dprintf("cfline(%s)\n", line);
--- 1157,1166 ----
char *line;
struct filed *f;
{
! struct addrinfo hints, *res;
! int error, i, pri;
! char *bp, *p, *q;
! char buf[MAXLINE], ebuf[100];
dprintf("cfline(%s)\n", line);
***************
*** 1204,1221 ****
if (!InetInuse)
break;
(void)strcpy(f->f_un.f_forw.f_hname, ++p);
! hp = gethostbyname(p);
! if (hp == NULL) {
! extern int h_errno;
!
! logerror((char *)hstrerror(h_errno));
break;
}
! memset(&f->f_un.f_forw.f_addr, 0,
! sizeof(f->f_un.f_forw.f_addr));
! f->f_un.f_forw.f_addr.sin_family = AF_INET;
! f->f_un.f_forw.f_addr.sin_port = LogPort;
! memmove(&f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length);
f->f_type = F_FORW;
break;
--- 1236,1251 ----
if (!InetInuse)
break;
(void)strcpy(f->f_un.f_forw.f_hname, ++p);
! memset(&hints, 0, sizeof(hints));
! hints.ai_family = AF_UNSPEC;
! hints.ai_socktype = SOCK_DGRAM;
! hints.ai_protocol = 0;
! error = getaddrinfo(f->f_un.f_forw.f_hname, "syslog", &hints, &res);
! if (error) {
! logerror(gai_strerror(error));
break;
}
! f->f_un.f_forw.f_addr = res;
f->f_type = F_FORW;
break;
***************
*** 1302,1305 ****
--- 1332,1372 ----
return (0);
}
return (msgbufsize);
+ }
+
+ int
+ socksetup(af)
+ int af;
+ {
+ struct addrinfo hints, *res;
+ int error, sock;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_DGRAM;
+ error = getaddrinfo(NULL, "syslog", &hints, &res);
+ if (error) {
+ logerror(gai_strerror(error));
+ errno = 0;
+ die(0);
+ }
+ if (res->ai_next)
+ logerror("resolved to multiple addr");
+ else {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock >= 0) {
+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
+ close (sock);
+ sock = -1;
+ logerror("bind");
+ if (!Debug)
+ die(0);
+ }
+ }
+ }
+ if (res)
+ freeaddrinfo(res);
+
+ return(sock);
}
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="Makefile.diff"
*** Makefile.orig Thu Dec 2 13:58:11 1999
--- Makefile Thu Dec 2 00:18:06 1999
***************
*** 7,11 ****
--- 7,12 ----
LDADD+=-lutil
#make symlink to old socket location for transitional period
SYMLINKS= /var/run/log /dev/log
+ CPPFLAGS+=-DINET6
.include <bsd.prog.mk>
--RnlQjJ0d97Da+TV1--
>Audit-Trail:
>Unformatted:
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit