Hi, I have added functionality that allows syslogd to receive and send UDP packets via inet6 sockets.
I will split this diff into smaller parts to make review and discussion easier. bluhm Index: usr.sbin/syslogd/privsep.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v retrieving revision 1.34 diff -u -p -u -p -r1.34 privsep.c --- usr.sbin/syslogd/privsep.c 23 Nov 2008 04:29:42 -0000 1.34 +++ usr.sbin/syslogd/privsep.c 18 Aug 2014 23:48:18 -0000 @@ -67,8 +67,8 @@ enum cmd_types { PRIV_OPEN_UTMP, /* open utmp for reading only */ PRIV_OPEN_CONFIG, /* open config file for reading only */ PRIV_CONFIG_MODIFIED, /* check if config file has been modified */ - PRIV_GETHOSTSERV, /* resolve host/service names */ - PRIV_GETHOSTBYADDR, /* resolve numeric address into hostname */ + PRIV_GETADDRINFO, /* resolve host/service names */ + PRIV_GETNAMEINFO, /* resolve numeric address into hostname */ PRIV_DONE_CONFIG_PARSE /* signal that the initial config parse is done */ }; @@ -76,7 +76,7 @@ static int priv_fd = -1; static volatile pid_t child_pid = -1; static char config_file[MAXPATHLEN]; static struct stat cf_info; -static int allow_gethostbyaddr = 0; +static int allow_getnameinfo = 0; static volatile sig_atomic_t cur_state = STATE_INIT; /* Queue for the allowed logfiles */ @@ -100,12 +100,12 @@ static int may_read(int, void *, size_t int priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[]) { - int i, fd, socks[2], cmd, addr_len, addr_af, result, restart; - size_t path_len, hostname_len, servname_len; - char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN]; + int i, fd, socks[2], cmd, addr_len, result, restart; + size_t path_len, protoname_len, hostname_len, servname_len; + char path[MAXPATHLEN], protoname[16], hostname[MAXHOSTNAMELEN]; char servname[MAXHOSTNAMELEN]; + struct sockaddr_storage addr; struct stat cf_stat; - struct hostent *hp; struct passwd *pw; struct addrinfo hints, *res0; struct sigaction sa; @@ -177,6 +177,8 @@ priv_init(char *conf, int numeric, int l close(pfd[PFD_UNIX_0 + i].fd); if (pfd[PFD_INET].fd != -1) close(pfd[PFD_INET].fd); + if (pfd[PFD_INET6].fd != -1) + close(pfd[PFD_INET6].fd); if (pfd[PFD_CTLSOCK].fd != -1) close(pfd[PFD_CTLSOCK].fd); if (pfd[PFD_CTLCONN].fd != -1) @@ -191,11 +193,11 @@ priv_init(char *conf, int numeric, int l if (stat(config_file, &cf_info) < 0) err(1, "stat config file failed"); - /* Save whether or not the child can have access to gethostbyaddr(3) */ + /* Save whether or not the child can have access to getnameinfo(3) */ if (numeric > 0) - allow_gethostbyaddr = 0; + allow_getnameinfo = 0; else - allow_gethostbyaddr = 1; + allow_getnameinfo = 1; TAILQ_INIT(&lognames); increase_state(STATE_CONFIG); @@ -210,7 +212,7 @@ priv_init(char *conf, int numeric, int l /* Expecting: length, path */ must_read(socks[0], &path_len, sizeof(size_t)); if (path_len == 0 || path_len > sizeof(path)) - _exit(0); + _exit(1); must_read(socks[0], &path, path_len); path[path_len - 1] = '\0'; check_tty_name(path, path_len); @@ -229,7 +231,7 @@ priv_init(char *conf, int numeric, int l /* Expecting: length, path */ must_read(socks[0], &path_len, sizeof(size_t)); if (path_len == 0 || path_len > sizeof(path)) - _exit(0); + _exit(1); must_read(socks[0], &path, path_len); path[path_len - 1] = '\0'; check_log_name(path, path_len); @@ -289,24 +291,46 @@ priv_init(char *conf, int numeric, int l increase_state(STATE_RUNNING); break; - case PRIV_GETHOSTSERV: - dprintf("[priv]: msg PRIV_GETHOSTSERV received\n"); - /* Expecting: len, hostname, len, servname */ + case PRIV_GETADDRINFO: + dprintf("[priv]: msg PRIV_GETADDRINFO received\n"); + /* Expecting: len, proto, len, host, len, serv */ + must_read(socks[0], &protoname_len, sizeof(size_t)); + if (protoname_len == 0 || + protoname_len > sizeof(protoname)) + _exit(1); + must_read(socks[0], &protoname, protoname_len); + protoname[protoname_len - 1] = '\0'; + must_read(socks[0], &hostname_len, sizeof(size_t)); - if (hostname_len == 0 || hostname_len > sizeof(hostname)) - _exit(0); + if (hostname_len == 0 || + hostname_len > sizeof(hostname)) + _exit(1); must_read(socks[0], &hostname, hostname_len); hostname[hostname_len - 1] = '\0'; must_read(socks[0], &servname_len, sizeof(size_t)); - if (servname_len == 0 || servname_len > sizeof(servname)) - _exit(0); + if (servname_len == 0 || + servname_len > sizeof(servname)) + _exit(1); must_read(socks[0], &servname, servname_len); servname[servname_len - 1] = '\0'; - memset(&hints, '\0', sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; + memset(&hints, 0, sizeof(hints)); + if (strcmp(protoname, "udp") == 0) { + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else if (strcmp(protoname, "udp4") == 0) { + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else if (strcmp(protoname, "udp6") == 0) { + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else { + errx(1, "unknown protocol %s", protoname); + } i = getaddrinfo(hostname, servname, &hints, &res0); if (i != 0 || res0 == NULL) { addr_len = 0; @@ -320,24 +344,24 @@ priv_init(char *conf, int numeric, int l } break; - case PRIV_GETHOSTBYADDR: - dprintf("[priv]: msg PRIV_GETHOSTBYADDR received\n"); - if (!allow_gethostbyaddr) - errx(1, "rejected attempt to gethostbyaddr"); - /* Expecting: length, address, address family */ + case PRIV_GETNAMEINFO: + dprintf("[priv]: msg PRIV_GETNAMEINFO received\n"); + if (!allow_getnameinfo) + errx(1, "rejected attempt to getnameinfo"); + /* Expecting: length, sockaddr */ must_read(socks[0], &addr_len, sizeof(int)); - if (addr_len <= 0 || addr_len > sizeof(hostname)) - _exit(0); - must_read(socks[0], hostname, addr_len); - must_read(socks[0], &addr_af, sizeof(int)); - hp = gethostbyaddr(hostname, addr_len, addr_af); - if (hp == NULL) { + if (addr_len <= 0 || addr_len > sizeof(addr)) + _exit(1); + must_read(socks[0], &addr, addr_len); + if (getnameinfo((struct sockaddr *)&addr, addr_len, + hostname, sizeof(hostname), NULL, 0, + NI_NOFQDN|NI_NAMEREQD|NI_DGRAM) != 0) { addr_len = 0; must_write(socks[0], &addr_len, sizeof(int)); } else { - addr_len = strlen(hp->h_name) + 1; + addr_len = strlen(hostname) + 1; must_write(socks[0], &addr_len, sizeof(int)); - must_write(socks[0], hp->h_name, addr_len); + must_write(socks[0], hostname, addr_len); } break; default: @@ -362,7 +386,7 @@ priv_init(char *conf, int numeric, int l execvp(argv[0], argv); } unlink(_PATH_LOGPID); - _exit(1); + _exit(0); } static int @@ -659,25 +683,30 @@ priv_config_parse_done(void) /* Name/service to address translation. Response is placed into addr, and * the length is returned (zero on error) */ int -priv_gethostserv(char *host, char *serv, struct sockaddr *addr, +priv_getaddrinfo(char *proto, char *host, char *serv, struct sockaddr *addr, size_t addr_len) { - char hostcpy[MAXHOSTNAMELEN], servcpy[MAXHOSTNAMELEN]; + char protocpy[16], hostcpy[MAXHOSTNAMELEN], servcpy[MAXHOSTNAMELEN]; int cmd, ret_len; - size_t hostname_len, servname_len; + size_t protoname_len, hostname_len, servname_len; if (priv_fd < 0) - errx(1, "%s: called from privileged portion", "priv_gethostserv"); + errx(1, "%s: called from privileged portion", "priv_getaddrinfo"); - if (strlcpy(hostcpy, host, sizeof hostcpy) >= sizeof(hostcpy)) - errx(1, "%s: overflow attempt in hostname", "priv_gethostserv"); + if (strlcpy(protocpy, proto, sizeof(protocpy)) >= sizeof(protocpy)) + errx(1, "%s: overflow attempt in protoname", "priv_getaddrinfo"); + protoname_len = strlen(protocpy) + 1; + if (strlcpy(hostcpy, host, sizeof(hostcpy)) >= sizeof(hostcpy)) + errx(1, "%s: overflow attempt in hostname", "priv_getaddrinfo"); hostname_len = strlen(hostcpy) + 1; - if (strlcpy(servcpy, serv, sizeof servcpy) >= sizeof(servcpy)) - errx(1, "%s: overflow attempt in servname", "priv_gethostserv"); + if (strlcpy(servcpy, serv, sizeof(servcpy)) >= sizeof(servcpy)) + errx(1, "%s: overflow attempt in servname", "priv_getaddrinfo"); servname_len = strlen(servcpy) + 1; - cmd = PRIV_GETHOSTSERV; + cmd = PRIV_GETADDRINFO; must_write(priv_fd, &cmd, sizeof(int)); + must_write(priv_fd, &protoname_len, sizeof(size_t)); + must_write(priv_fd, protocpy, protoname_len); must_write(priv_fd, &hostname_len, sizeof(size_t)); must_write(priv_fd, hostcpy, hostname_len); must_write(priv_fd, &servname_len, sizeof(size_t)); @@ -692,7 +721,7 @@ priv_gethostserv(char *host, char *serv, /* Make sure we aren't overflowing the passed in buffer */ if (addr_len < ret_len) - errx(1, "%s: overflow attempt in return", "priv_gethostserv"); + errx(1, "%s: overflow attempt in return", "priv_getaddrinfo"); /* Read the resolved address and make sure we got all of it */ memset(addr, '\0', addr_len); @@ -704,33 +733,33 @@ priv_gethostserv(char *host, char *serv, /* Reverse address resolution; response is placed into res, and length of * response is returned (zero on error) */ int -priv_gethostbyaddr(char *addr, int addr_len, int af, char *res, size_t res_len) +priv_getnameinfo(struct sockaddr *sa, socklen_t salen, char *host, + size_t hostlen) { int cmd, ret_len; if (priv_fd < 0) - errx(1, "%s called from privileged portion", "priv_gethostbyaddr"); + errx(1, "%s called from privileged portion", "priv_getnameinfo"); - cmd = PRIV_GETHOSTBYADDR; + cmd = PRIV_GETNAMEINFO; must_write(priv_fd, &cmd, sizeof(int)); - must_write(priv_fd, &addr_len, sizeof(int)); - must_write(priv_fd, addr, addr_len); - must_write(priv_fd, &af, sizeof(int)); + must_write(priv_fd, &salen, sizeof(int)); + must_write(priv_fd, sa, salen); /* Expect back an integer size, and then a string of that length */ must_read(priv_fd, &ret_len, sizeof(int)); /* Check there was no error (indicated by a return of 0) */ if (!ret_len) - return 0; + return (-1); /* Check we don't overflow the passed in buffer */ - if (res_len < ret_len) - errx(1, "%s: overflow attempt in return", "priv_gethostbyaddr"); + if (hostlen < ret_len) + errx(1, "%s: overflow attempt in return", "priv_getnameinfo"); /* Read the resolved hostname */ - must_read(priv_fd, res, ret_len); - return ret_len; + must_read(priv_fd, host, ret_len); + return (0); } /* Pass the signal through to child */ @@ -797,7 +826,7 @@ must_read(int fd, void *buf, size_t n) if (errno == EINTR || errno == EAGAIN) continue; case 0: - _exit(0); + _exit(1); default: pos += res; } @@ -819,7 +848,7 @@ must_write(int fd, void *buf, size_t n) if (errno == EINTR || errno == EAGAIN) continue; case 0: - _exit(0); + _exit(1); default: pos += res; } Index: usr.sbin/syslogd/syslogd.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.111 diff -u -p -u -p -r1.111 syslogd.c --- usr.sbin/syslogd/syslogd.c 14 Jul 2014 04:02:33 -0000 1.111 +++ usr.sbin/syslogd/syslogd.c 18 Aug 2014 23:48:18 -0000 @@ -127,7 +127,7 @@ struct filed { union { char f_uname[MAXUNAMES][UT_NAMESIZE+1]; struct { - char f_hname[MAXHOSTNAMELEN]; + char f_loghost[2*MAXHOSTNAMELEN]; struct sockaddr_storage f_addr; } f_forw; /* forwarding address */ char f_fname[MAXPATHLEN]; @@ -188,13 +188,14 @@ int Debug; /* debug flag */ int Startup = 1; /* startup flag */ char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ char *LocalDomain; /* our local domain name */ -int InetInuse = 0; /* non-zero if INET sockets are being used */ int Initialized = 0; /* set when we have initialized ourselves */ int MarkInterval = 20 * 60; /* interval between marks in seconds */ int MarkSeq = 0; /* mark sequence number */ int SecureMode = 1; /* when true, speak only unix domain socks */ int NoDNS = 0; /* when true, will refrain from doing DNS lookups */ +int IPv4Only = 0; /* when true, disable IPv6 */ +int IPv6Only = 0; /* when true, disable IPv4 */ int IncludeHostname = 0; /* include RFC 3164 style hostnames when forwarding */ char *ctlsock_path = NULL; /* Path to control socket */ @@ -250,7 +251,7 @@ volatile sig_atomic_t WantDie; volatile sig_atomic_t DoInit; struct filed *cfline(char *, char *); -void cvthname(struct sockaddr_in *, char *, size_t); +void cvthname(struct sockaddr *, char *, size_t); int decode(const char *, const CODE *); void dodie(int); void doinit(int); @@ -268,6 +269,7 @@ void reapchild(int); char *ttymsg(struct iovec *, int, char *, int); void usage(void); void wallmsg(struct filed *, struct iovec *); +int loghost(char *, char **, char **, char **); int getmsgbufsize(void); int unix_socket(char *, int, mode_t); void double_rbuf(int); @@ -282,7 +284,7 @@ main(int argc, char *argv[]) { int ch, i, linesize, fd; struct sockaddr_un fromunix; - struct sockaddr_in frominet; + struct sockaddr_storage from; socklen_t len; char *p, *line; char resolve[MAXHOSTNAMELEN]; @@ -290,8 +292,14 @@ main(int argc, char *argv[]) struct addrinfo hints, *res, *res0; FILE *fp; - while ((ch = getopt(argc, argv, "dhnuf:m:p:a:s:")) != -1) + while ((ch = getopt(argc, argv, "46dhnuf:m:p:a:s:")) != -1) switch (ch) { + case '4': /* disable IPv6 */ + IPv4Only = 1; + break; + case '6': /* disable IPv4 */ + IPv6Only = 1; + break; case 'd': /* debug */ Debug++; break; @@ -369,7 +377,7 @@ main(int argc, char *argv[]) } memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; + hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; @@ -384,13 +392,18 @@ main(int argc, char *argv[]) for (res = res0; res; res = res->ai_next) { struct pollfd *pfdp; - if (res->ai_family == AF_INET) + switch (res->ai_family) { + case AF_INET: + if (IPv6Only) + continue; pfdp = &pfd[PFD_INET]; - else { - /* - * XXX AF_INET6 is skipped on purpose, need to - * fix '@' handling first. - */ + break; + case AF_INET6: + if (IPv4Only) + continue; + pfdp = &pfd[PFD_INET6]; + break; + default: continue; } @@ -410,7 +423,6 @@ main(int argc, char *argv[]) continue; } - InetInuse = 1; pfdp->fd = fd; if (SecureMode) shutdown(pfdp->fd, SHUT_RD); @@ -582,18 +594,31 @@ main(int argc, char *argv[]) } } if ((pfd[PFD_INET].revents & POLLIN) != 0) { - len = sizeof(frominet); + len = sizeof(from); i = recvfrom(pfd[PFD_INET].fd, line, MAXLINE, 0, - (struct sockaddr *)&frominet, &len); + (struct sockaddr *)&from, &len); if (i > 0) { line[i] = '\0'; - cvthname(&frominet, resolve, - sizeof resolve); + cvthname((struct sockaddr *)&from, resolve, + sizeof(resolve)); dprintf("cvthname res: %s\n", resolve); printline(resolve, line); } else if (i < 0 && errno != EINTR) logerror("recvfrom inet"); } + if ((pfd[PFD_INET6].revents & POLLIN) != 0) { + len = sizeof(from); + i = recvfrom(pfd[PFD_INET6].fd, line, MAXLINE, 0, + (struct sockaddr *)&from, &len); + if (i > 0) { + line[i] = '\0'; + cvthname((struct sockaddr *)&from, resolve, + sizeof(resolve)); + dprintf("cvthname res: %s\n", resolve); + printline(resolve, line); + } else if (i < 0 && errno != EINTR) + logerror("recvfrom inet6"); + } if ((pfd[PFD_CTLSOCK].revents & POLLIN) != 0) ctlsock_accept_handler(); if ((pfd[PFD_CTLCONN].revents & POLLIN) != 0) @@ -627,7 +652,7 @@ usage(void) { (void)fprintf(stderr, - "usage: syslogd [-dhnu] [-a path] [-f config_file] [-m mark_interval]\n" + "usage: syslogd [-46dhnu] [-a path] [-f config_file] [-m mark_interval]\n" " [-p log_socket] [-s reporting_socket]\n"); exit(1); } @@ -849,7 +874,7 @@ fprintlog(struct filed *f, int flags, ch { struct iovec iov[6]; struct iovec *v; - int l, retryonce; + int fd, l, retryonce; char line[MAXLINE + 1], repbuf[80], greetings[500]; v = iov; @@ -905,14 +930,25 @@ fprintlog(struct filed *f, int flags, ch break; case F_FORW: - dprintf(" %s\n", f->f_un.f_forw.f_hname); + dprintf(" %s\n", f->f_un.f_forw.f_loghost); + switch (f->f_un.f_forw.f_addr.ss_family) { + case AF_INET: + fd = pfd[PFD_INET].fd; + break; + case AF_INET6: + fd = pfd[PFD_INET6].fd; + break; + default: + fd = -1; + break; + } if ((l = snprintf(line, sizeof(line), "<%d>%.15s %s%s%s", f->f_prevpri, (char *)iov[0].iov_base, IncludeHostname ? LocalHostName : "", IncludeHostname ? " " : "", (char *)iov[4].iov_base)) >= sizeof(line) || l == -1) l = strlen(line); - if (sendto(pfd[PFD_INET].fd, line, l, 0, + if (sendto(fd, line, l, 0, (struct sockaddr *)&f->f_un.f_forw.f_addr, f->f_un.f_forw.f_addr.ss_len) != l) { switch (errno) { @@ -1014,7 +1050,7 @@ fprintlog(struct filed *f, int flags, ch case F_MEMBUF: dprintf("\n"); snprintf(line, sizeof(line), "%.15s %s %s", - (char *)iov[0].iov_base, (char *)iov[2].iov_base, + (char *)iov[0].iov_base, (char *)iov[2].iov_base, (char *)iov[4].iov_base); if (ringbuf_append_line(f->f_un.f_mb.f_rb, line) == 1) f->f_un.f_mb.f_overflow = 1; @@ -1096,38 +1132,19 @@ reapchild(int signo) * Return a printable representation of a host address. */ void -cvthname(struct sockaddr_in *f, char *result, size_t res_len) +cvthname(struct sockaddr *f, char *result, size_t res_len) { - sigset_t omask, nmask; - char *p, *ip; - int ret_len; - - if (f->sin_family != AF_INET) { + if (getnameinfo(f, f->sa_len, result, res_len, NULL, 0, + NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM) != 0) { dprintf("Malformed from address\n"); strlcpy(result, "???", res_len); return; } - - ip = inet_ntoa(f->sin_addr); - dprintf("cvthname(%s)\n", ip); - if (NoDNS) { - strlcpy(result, ip, res_len); + if (NoDNS) return; - } - sigemptyset(&nmask); - sigaddset(&nmask, SIGHUP); - sigprocmask(SIG_BLOCK, &nmask, &omask); - - ret_len = priv_gethostbyaddr((char *)&f->sin_addr, - sizeof(struct in_addr), f->sin_family, result, res_len); - - sigprocmask(SIG_SETMASK, &omask, NULL); - if (ret_len == 0) { - dprintf("Host name for your address (%s) unknown\n", ip); - strlcpy(result, ip, res_len); - } else if ((p = strchr(result, '.')) && strcmp(p + 1, LocalDomain) == 0) - *p = '\0'; + if (priv_getnameinfo(f, f->sa_len, result, res_len) != 0) + dprintf("Host name for your address (%s) unknown\n", result); } void @@ -1367,7 +1384,7 @@ init(void) break; case F_FORW: - printf("%s", f->f_un.f_forw.f_hname); + printf("%s", f->f_un.f_forw.f_loghost); break; case F_USERS: @@ -1429,7 +1446,7 @@ cfline(char *line, char *prog) { int i, pri, addr_len; size_t rb_len; - char *bp, *p, *q, *cp; + char *bp, *p, *q, *proto, *host, *port; char buf[MAXLINE], ebuf[100]; struct filed *xf, *f, *d; @@ -1526,24 +1543,49 @@ cfline(char *line, char *prog) switch (*p) { case '@': - if (!InetInuse) - break; - if ((cp = strrchr(++p, ':')) != NULL) - *cp++ = '\0'; - if ((strlcpy(f->f_un.f_forw.f_hname, p, - sizeof(f->f_un.f_forw.f_hname)) >= - sizeof(f->f_un.f_forw.f_hname))) { - snprintf(ebuf, sizeof(ebuf), "hostname too long \"%s\"", + if ((strlcpy(f->f_un.f_forw.f_loghost, p, + sizeof(f->f_un.f_forw.f_loghost)) >= + sizeof(f->f_un.f_forw.f_loghost))) { + snprintf(ebuf, sizeof(ebuf), "loghost too long \"%s\"", p); logerror(ebuf); break; } - addr_len = priv_gethostserv(f->f_un.f_forw.f_hname, - cp == NULL ? "syslog" : cp, - (struct sockaddr*)&f->f_un.f_forw.f_addr, + if (loghost(++p, &proto, &host, &port) == -1) { + snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"", + f->f_un.f_forw.f_loghost); + logerror(ebuf); + break; + } + if (proto == NULL || strcmp(proto, "udp") == 0) { + /* no further checks */ + } else if (strcmp(proto, "udp4") == 0) { + if (pfd[PFD_INET].fd == -1) { + snprintf(ebuf, sizeof(ebuf), "no udp4 \"%s\"", + f->f_un.f_forw.f_loghost); + logerror(ebuf); + break; + } + } else if (strcmp(proto, "udp6") == 0) { + if (pfd[PFD_INET6].fd == -1) { + snprintf(ebuf, sizeof(ebuf), "no udp6 \"%s\"", + f->f_un.f_forw.f_loghost); + logerror(ebuf); + break; + } + } else { + snprintf(ebuf, sizeof(ebuf), "bad protocol \"%s\"", + f->f_un.f_forw.f_loghost); + logerror(ebuf); + break; + } + addr_len = priv_getaddrinfo(proto == NULL ? "udp" : proto, + host, port == NULL ? "syslog" : port, + (struct sockaddr*)&f->f_un.f_forw.f_addr, sizeof(f->f_un.f_forw.f_addr)); if (addr_len < 1) { - snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"", p); + snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"", + f->f_un.f_forw.f_loghost); logerror(ebuf); break; } @@ -1652,6 +1694,33 @@ cfline(char *line, char *prog) return (f); } +/* + * Parse the host and port parts from a loghost string. + */ +int +loghost(char *str, char **proto, char **host, char **port) +{ + *proto = NULL; + if ((*host = strchr(str, ':')) && + (*host)[1] == '/' && (*host)[2] == '/') { + *proto = str; + **host = '\0'; + str = *host + 3; + } + *host = str; + if (**host == '[') { + (*host)++; + str = strchr(*host, ']'); + if (str == NULL) + return (-1); + *str++ = '\0'; + } + *port = strrchr(str, ':'); + if (*port != NULL) + *(*port)++ = '\0'; + + return (0); +} /* * Retrieve the size of the kernel message buffer, via sysctl. Index: usr.sbin/syslogd/syslogd.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.h,v retrieving revision 1.8 diff -u -p -u -p -r1.8 syslogd.h --- usr.sbin/syslogd/syslogd.h 19 Aug 2013 06:09:23 -0000 1.8 +++ usr.sbin/syslogd/syslogd.h 18 Aug 2014 23:47:01 -0000 @@ -26,8 +26,8 @@ FILE *priv_open_utmp(void); FILE *priv_open_config(void); void priv_config_parse_done(void); int priv_config_modified(void); -int priv_gethostserv(char *, char *, struct sockaddr *, size_t); -int priv_gethostbyaddr(char *, int, int, char *, size_t); +int priv_getaddrinfo(char *, char *, char *, struct sockaddr *, size_t); +int priv_getnameinfo(struct sockaddr *, socklen_t, char *, size_t); /* Terminal message */ char *ttymsg(struct iovec *, int, char *, int);
pgpsjpe3q8a5j.pgp
Description: PGP signature