/* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2011 Emil Mikulic.
*
* dns.c: synchronous DNS in a child process.
*
* GNU General Public License version 2. (see COPYING.GPL)
*/
-#include "darkstat.h"
+#include "cdefs.h"
#include "conv.h"
#include "decode.h"
#include "dns.h"
#include "queue.h"
#include "str.h"
#include "tree.h"
+#include "bsd.h" /* for setproctitle, strlcpy */
#include <sys/param.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
+#ifdef __NetBSD__
+# define gethostbyaddr(addr, len, type) \
+ gethostbyaddr((const char *)(addr), len, type)
+#endif
+
static void dns_main(void) _noreturn_; /* the child process runs this */
#define CHILD 0 /* child process uses this socket */
struct dns_reply {
struct addr addr;
int error; /* for gai_strerror(), or 0 if no error */
- char name[MAXHOSTNAMELEN];
+ char name[256]; /* http://tools.ietf.org/html/rfc1034#section-3.1 */
};
void
type = "site-local";
else if (IN6_IS_ADDR_MULTICAST(&reply.addr.ip.v6))
type = "multicast";
- } else { /* AF_INET */
- if (IN_MULTICAST(reply.addr.ip.v4))
+ } else {
+ assert(reply.addr.family == IPv4);
+ if (IN_MULTICAST(htonl(reply.addr.ip.v4)))
type = "multicast";
}
xasprintf(name, "(%s)", type);
{
struct addr ip;
-#ifdef HAVE_SETPROCTITLE
setproctitle("DNS child");
-#endif
fd_set_nonblock(sock[CHILD]);
verbosef("DNS child entering main DNS loop");
for (;;) {
struct dns_reply reply;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
+ struct hostent *he;
char host[NI_MAXHOST];
int ret, flags;
sin.sin_addr.s_addr = ip.ip.v4;
ret = getnameinfo((struct sockaddr *) &sin, sizeof(sin),
host, sizeof(host), NULL, 0, flags);
+ if (ret == EAI_FAMILY) {
+ verbosef("getnameinfo error %s, trying gethostbyname",
+ gai_strerror(ret));
+ he = gethostbyaddr(&sin.sin_addr.s_addr,
+ sizeof(sin.sin_addr.s_addr), sin.sin_family);
+ if (he == NULL) {
+ ret = EAI_FAIL;
+ verbosef("gethostbyname error %s", hstrerror(h_errno));
+ } else {
+ ret = 0;
+ strlcpy(host, he->h_name, sizeof(host));
+ }
+ }
break;
case IPv6:
sin6.sin6_family = AF_INET6;