Commit Diff
Diff:
e1640064a7a92c518d4f3414a54c96cb41eaa4b2
c25e4088bd7943eacc409e3d66848fbea777a257
Commit:
c25e4088bd7943eacc409e3d66848fbea777a257
Tree:
0e1982f9608f4ed2121a885637116214387df241
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Tue Jun 28 17:04:33 2011 UTC
Message:
* add logging support, a syslog like service that allows one daemon to contact another wildcarddnsd daemon and send it its log, I like this because it aggregates all logs to a dns system. I had this running in production for a day now and it seems to be stable. Here is a sample log entry: logging "these hosts" { logbind yes; loghost ::1; logport 19999; logpasswd peter; } This particular one binds and is a listener, to be a logger leave the logbind out. * Also cleaned up mainloop() somewhat, using recvfrom() with a struct sockaddr caused some corruption in the buf array and recvmsg() would complain and nothing worked anymore. That is ironed out and I have also added a struct cfg to be passing to mainloop() since arguments to mainloop are growing with new ideas and functionality, this keeps the argument rather compacted. Also cfg is calloc'ed and resides on the heap. * adjust Makefiles, but not tested on any other than OpenBSD and FreeBSD 7.3
blob - a438fb026fc20022ff8b4c534d5b9f350887857b
blob + df52216bc37c32f7bfecf1aa751e0d16d78b6d78
--- Makefile.freebsd7
+++ Makefile.freebsd7
@@ -1,6 +1,6 @@
PROG=wildcarddnsd
-SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c bsd-arc4random.c
+SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c bsd-arc4random.c log.c
#CFLAGS= -DDEBUG -g -Wall
CFLAGS= -Wall -g
blob - 64a3b1134642dec379bcd9280dcd780832da8d96
blob + a8a3e541aa744831d264cca9a569ec82a6270588
--- Makefile.freebsd8
+++ Makefile.freebsd8
@@ -1,11 +1,11 @@
PROG=wildcarddnsd
-SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c
+SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c log.c
#CFLAGS= -DDEBUG -g -Wall
CFLAGS= -Wall -g
LDFLAGS= -Wall -g
-#LDADD= -lcrypto -lssl
+LDADD= -lcrypto -lssl
OBJDIR=.
BINDIR=/usr/local/sbin
blob - 6fe251398ba24ecb7a2d6d43a4af13b1b36a04a9
blob + 8a62e12c27355ddab21b1e154ef12dca1f285535
--- Makefile.linux
+++ Makefile.linux
@@ -15,7 +15,8 @@ build:
$(CC) $(CFLAGS) -c recurse.c
$(CC) $(CFLAGS) -c bsd-arc4random.c
$(CC) $(CFLAGS) -c res_random.c
- $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o region.o wildcard.o recurse.o bsd-arc4random.o res_random.o $(LDADD)
+ $(CC) $(CFLAGS) -c log.c
+ $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o region.o wildcard.o recurse.o bsd-arc4random.o res_random.o log.o $(LDADD)
install:
blob - f796462fe24668395f0a3343ebc7b9c19599b9b4
blob + f014681cbd8b1fc3198be6beb1cb8ec2b08d7464
--- Makefile.macosx
+++ Makefile.macosx
@@ -10,7 +10,8 @@ build:
$(CC) $(CFLAGS) -c reply.c
$(CC) $(CFLAGS) -c region.c
$(CC) $(CFLAGS) -c wildcard.c
- $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o region.o wildcard.o
+ $(CC) $(CFLAGS) -c log.c
+ $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o region.o wildcard.o log.o
clean:
rm -f *.o wildcarddnsd
blob - ef25bf5cc5c62d0e4851505ee72250a8abb13b5a
blob + 37d6e44b806083d0d7bdc463ca99b40e6ff831cf
--- Makefile.netbsd
+++ Makefile.netbsd
@@ -1,6 +1,6 @@
PROG=wildcarddnsd
-SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c bsd-arc4random.c
+SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c bsd-arc4random.c log.c
#CFLAGS= -DDEBUG -g -Wall
CFLAGS= -Wall -g
blob - e29be83bd5c2a849e98ab4c0f5c385efc124c6be
blob + 1b992446c6d789069e132dc5e673319c597b01c2
--- Makefile.openbsd
+++ Makefile.openbsd
@@ -1,11 +1,11 @@
PROG=wildcarddnsd
-SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c
+SRCS=main.c parse.c reply.c additional.c region.c wildcard.c recurse.c res_random.c log.c
#CFLAGS= -DDEBUG -g -Wall
CFLAGS= -Wall -g
LDFLAGS= -Wall -g
-#LDADD= -lcrypto -lssl
+LDADD= -lcrypto -lssl
OBJDIR=.
BINDIR=/usr/local/sbin
blob - 6f32a60d78b30177266569d3670d71c70e944cf1
blob + a278baba0d89975b09fa4b2ed1b00fbef6c72c48
--- db.h
+++ db.h
@@ -29,6 +29,7 @@
#define _DB_H
#define CONFFILE "/etc/wildcarddns.conf"
+#define DEFAULT_SOCKET 64
#define ERR_DROP 0x1
#define ERR_NXDOMAIN 0x2
@@ -171,6 +172,27 @@ struct recurses {
SLIST_ENTRY(recurses) entries;
struct recurses *callback; /* callback */
} *sr, *sr1, *sr2;
+
+struct logging {
+ int active;
+ char *hostname;
+ int bind;
+ char *loghost;
+ struct sockaddr_storage loghost2;
+ char *logport;
+ u_int16_t logport2;
+ char *logpasswd;
+};
+
+struct cfg {
+ int udp[DEFAULT_SOCKET]; /* udp sockets */
+ int tcp[DEFAULT_SOCKET]; /* tcp socket */
+ char *ident[DEFAULT_SOCKET]; /* identification of interface */
+ int recurse; /* recurse socket */
+ int log; /* logging socket */
+ int sockcount; /* set sockets */
+ DB *db; /* database */
+};
int parse_file(DB *db, char *);
blob - 11d4251a42508ba7c94606fe421cb835abdf4890
blob + 4ca8ca92aae562ca267d77c924b8ef47c76e25f6
--- example7.conf
+++ example7.conf
@@ -1,6 +1,6 @@
; sample config file that is in production.
;
-version "4";
+version "5";
; WARNING - the way wildcarddnsd originally implemented wildcarding is
; wrong and can cause damage on the Internet (DoS), it can
blob - 69f569b584e1c127908eefdacbbe232d9870758c
blob + b00dfcb99d9da4f4526e6d0603422d82092182b4
--- include.h
+++ include.h
@@ -52,6 +52,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
blob - 4d91918ec28d227fb9194c62a6fd6516ecb6a581
blob + d80efa9fa2cb5b61917a4422149e1e62d55a22b6
--- main.c
+++ main.c
@@ -34,7 +34,7 @@
struct question * build_question(char *, int);
struct question * build_fake_question(char *, int, u_int16_t);
-void mainloop(int *, int *, int, char **, DB *, int);
+void mainloop(struct cfg *cfg);
int free_question(struct question *);
int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
int get_soa(DB *, struct question *, struct domain *, int);
@@ -59,6 +59,8 @@ extern void collects_init(void);
extern void recurseloop(int sp, int *raw, DB *db);
extern int find_recurse(struct sockaddr_storage *, int);
extern void init_recurse(void);
+extern int remotelog(int, char *, ...);
+extern void receivelog(char *buf, int len);
char * dns_label(char *, int *);
int compress_label(u_char *, u_int16_t, int);
@@ -78,7 +80,6 @@ void slave_signal(int);
#define DEFAULT_PRIVILEGE "wdnsd"
#endif
-#define DEFAULT_SOCKET 64
#define PIDFILE "/var/run/wildcarddnsd.pid"
@@ -102,6 +103,7 @@ struct typetable {
/* global variables */
extern char *__progname;
+extern struct logging logging;
static int lflag = 0;
static int rflag = 0;
static u_int16_t port = 53;
@@ -125,10 +127,10 @@ struct tcps {
time_t time;
SLIST_ENTRY(tcps) entries;
} *tn1, *tn2, *tnp;
-
-static const char rcsid[] = "$Id: main.c,v 1.64 2011/04/22 16:43:34 pbug Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.65 2011/06/28 17:04:33 pbug Exp $";
+
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
*
@@ -137,9 +139,10 @@ static const char rcsid[] = "$Id: main.c,v 1.64 2011/0
int
main(int argc, char *argv[])
{
- int udp[DEFAULT_SOCKET];
- int tcp[DEFAULT_SOCKET];
+ static int udp[DEFAULT_SOCKET];
+ static int tcp[DEFAULT_SOCKET];
int raw[2];
+ int lfd;
int ch, i, j;
int gai_error;
@@ -164,6 +167,7 @@ main(int argc, char *argv[])
struct ifaddrs *ifap, *pifap;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
+ struct cfg *cfg;
static DB *db;
@@ -222,9 +226,17 @@ main(int argc, char *argv[])
daemon(0,0);
#endif
+
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
syslog(LOG_INFO, "starting up");
+ /* cfg struct */
+ cfg = calloc(1, sizeof(struct cfg));
+ if (cfg == NULL) {
+ syslog(LOG_ERR, "calloc: %m");
+ exit(1);
+ }
+
/*
* make a shared memory segment for signaling kills between
* processes...
@@ -502,7 +514,7 @@ main(int argc, char *argv[])
slave_shutdown();
exit(1);
}
- }
+ } /* if bflag? */
if (rflag == 1) {
if ((raw[0] = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
@@ -524,6 +536,65 @@ main(int argc, char *argv[])
}
} /* rflag */
+
+
+ /* if we are binding a log socket do it now */
+ if (logging.bind == 1 || logging.active == 1) {
+ switch (logging.loghost2.ss_family) {
+ case AF_INET:
+ lfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (lfd < 0) {
+ syslog(LOG_INFO, "logging socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+ sin = (struct sockaddr_in *)&logging.loghost2;
+ sin->sin_port = htons(logging.logport2);
+ break;
+ case AF_INET6:
+ lfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (lfd < 0) {
+ syslog(LOG_INFO, "logging socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+ sin6 = (struct sockaddr_in6 *)&logging.loghost2;
+ sin6->sin6_port = htons(logging.logport2);
+ break;
+ }
+
+ if (logging.bind == 1) {
+ if (bind(lfd, (struct sockaddr *)&logging.loghost2,
+ logging.loghost2.ss_len) < 0) {
+ syslog(LOG_INFO, "binding log socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (shutdown(lfd, SHUT_WR) < 0) {
+ syslog(LOG_INFO, "shutdown log socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+
+ } else {
+ if (connect(lfd, (struct sockaddr *)&logging.loghost2,
+ logging.loghost2.ss_len) < 0) {
+ syslog(LOG_INFO, "connecting log socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (shutdown(lfd, SHUT_RD) < 0) {
+ syslog(LOG_INFO, "shutdown log socket: %m");
+ slave_shutdown();
+ exit(1);
+ }
+
+ } /* if logging.bind */
+
+ } /* if logging.bind */
+
#ifndef DEBUG
/* chroot to the drop priv user home directory */
if (chroot(pw->pw_dir) < 0) {
@@ -628,8 +699,19 @@ main(int argc, char *argv[])
} /* switch */
} /* rflag */
- (void)mainloop((int *)&udp, (int *)&tcp, i, ident, db, (rflag ? sp[1] : -1));
+
+ cfg->sockcount = i;
+ cfg->db = db;
+ for (i = 0; i < cfg->sockcount; i++) {
+ cfg->udp[i] = udp[i];
+ cfg->tcp[i] = tcp[i];
+ cfg->ident[i] = strdup(ident[i]);
+ }
+ cfg->recurse = (rflag ? sp[1] : -1);
+ cfg->log = lfd;
+
+ (void)mainloop(cfg);
/* NOTREACHED */
return (0);
@@ -1620,7 +1702,7 @@ get_dns_type(int dnstype)
*/
void
-mainloop(int *udp, int *tcp, int sockcount, char **ident, DB *db, int sp)
+mainloop(struct cfg *cfg)
{
fd_set rset;
int sel;
@@ -1633,6 +1715,8 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
int type0, type1;
int lzerrno;
int wildcard = 0;
+ int sp;
+ int lfd;
u_int32_t received_ttl;
#if defined __FreeBSD__ || defined __OpenBSD__
@@ -1658,11 +1742,13 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
socklen_t fromlen = sizeof(sockaddr_large);
socklen_t namelen = sizeof(struct sockaddr_storage);
+ socklen_t logfromlen = sizeof(struct sockaddr_storage);
struct sockaddr *from = (void *)&sockaddr_large;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
struct sockaddr_storage sto;
+ struct sockaddr_storage logfrom;
struct dns_header *dh;
struct question *question, *fakequestion;
@@ -1679,15 +1765,19 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
int flag;
int recursion = 0;
+
SLIST_INIT(&tcpshead);
collects_init();
+ sp = cfg->recurse;
+ lfd = cfg->log;
+
/*
* set descriptors nonblocking, and listen on them
*/
- for (i = 0; i < sockcount; i++) {
- listen(tcp[i], 5);
+ for (i = 0; i < cfg->sockcount; i++) {
+ listen(cfg->tcp[i], 5);
}
for (;;) {
@@ -1709,15 +1799,15 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
}
FD_ZERO(&rset);
- for (i = 0; i < sockcount; i++) {
- if (maxso < tcp[i])
- maxso = tcp[i];
+ for (i = 0; i < cfg->sockcount; i++) {
+ if (maxso < cfg->tcp[i])
+ maxso = cfg->tcp[i];
- if (maxso < udp[i])
- maxso = udp[i];
+ if (maxso < cfg->udp[i])
+ maxso = cfg->udp[i];
- FD_SET(tcp[i], &rset);
- FD_SET(udp[i], &rset);
+ FD_SET(cfg->tcp[i], &rset);
+ FD_SET(cfg->udp[i], &rset);
}
SLIST_FOREACH(tnp, &tcpshead, entries) {
@@ -1727,6 +1817,12 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
FD_SET(tnp->so, &rset);
}
+ if (logging.bind == 1) {
+ if (maxso < lfd)
+ maxso = lfd;
+ FD_SET(lfd, &rset);
+ }
+
tv.tv_sec = 10;
tv.tv_usec = 0;
@@ -1751,11 +1847,11 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
continue;
}
- for (i = 0; i < sockcount; i++) {
- if (FD_ISSET(tcp[i], &rset)) {
+ for (i = 0; i < cfg->sockcount; i++) {
+ if (FD_ISSET(cfg->tcp[i], &rset)) {
fromlen = sizeof(sockaddr_large);
- so = accept(tcp[i], (struct sockaddr*)from, &fromlen);
+ so = accept(cfg->tcp[i], (struct sockaddr*)from, &fromlen);
if (so < 0) {
syslog(LOG_INFO, "tcp accept: %m");
@@ -1779,7 +1875,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
wildcard = find_wildcard((struct sockaddr_storage *)sin, AF_INET);
aregion = find_region((struct sockaddr_storage *)sin, AF_INET);
} else {
- syslog(LOG_INFO, "TCP packet received on descriptor %u interface \"%s\" had weird address family (%u), drop", so, ident[i], from->sa_family);
+ syslog(LOG_INFO, "TCP packet received on descriptor %u interface \"%s\" had weird address family (%u), drop", so, cfg->ident[i], from->sa_family);
close(so);
continue;
}
@@ -1818,7 +1914,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
tn1->maxlen = 0xffff + 2;
tn1->so = so;
tn1->isv6 = is_ipv6;
- tn1->ident = strdup(ident[i]);
+ tn1->ident = strdup(cfg->ident[i]);
tn1->address = strdup(address);
tn1->region = aregion;
tn1->wildcard = wildcard;
@@ -1915,7 +2011,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
/* goto drop beyond this point should goto out instead */
fakequestion = NULL;
- if ((type0 = lookup_zone(db, question, &sd0, &lzerrno, (char *)&replystring, wildcard)) < 0) {
+ if ((type0 = lookup_zone(cfg->db, question, &sd0, &lzerrno, (char *)&replystring, wildcard)) < 0) {
switch (lzerrno) {
default:
@@ -1939,7 +2035,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
*/
memset(&sd0, 0, sizeof(sd0));
- (void)get_soa(db, question, &sd0, wildcard);
+ (void)get_soa(cfg->db, question, &sd0, wildcard);
build_reply( &sreply, tnp->so, pbuf, len,
question, from, fromlen,
@@ -1966,7 +2062,7 @@ tcpnxdomain:
*/
memset(&sd0, 0, sizeof(sd0));
- (void)get_soa(db, question, &sd0, wildcard);
+ (void)get_soa(cfg->db, question, &sd0, wildcard);
build_reply( &sreply, tnp->so, pbuf, len, question,
from, fromlen, &sd0, NULL,
@@ -1981,7 +2077,7 @@ tcpnxdomain:
break;
}
- type1 = lookup_zone(db, fakequestion, &sd1, &lzerrno, (char *)&fakereplystring, wildcard);
+ type1 = lookup_zone(cfg->db, fakequestion, &sd1, &lzerrno, (char *)&fakereplystring, wildcard);
/* break CNAMES pointing to CNAMES */
if (type1 == DNS_TYPE_CNAME)
type1 = 0;
@@ -2024,12 +2120,12 @@ tcpnxdomain:
from, fromlen, &sd0, NULL,
tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_A) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_a(&sreply, db);
+ reply_a(&sreply, cfg->db);
break; /* must break here */
}
@@ -2051,12 +2147,12 @@ tcpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_AAAA) {
build_reply(&sreply, tnp->so, pbuf, len, question, from,
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_aaaa(&sreply, db);
+ reply_aaaa(&sreply, cfg->db);
break; /* must break here */
}
@@ -2071,12 +2167,12 @@ tcpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_MX) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_mx(&sreply, db);
+ reply_mx(&sreply, cfg->db);
break; /* must break here */
}
@@ -2089,7 +2185,7 @@ tcpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
}
break;
@@ -2097,7 +2193,7 @@ tcpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
}
break;
@@ -2110,7 +2206,7 @@ tcpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
}
break;
@@ -2124,7 +2220,7 @@ tcpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_PTR) {
build_reply(&sreply, tnp->so, pbuf, len, question, from,
@@ -2155,7 +2251,7 @@ tcpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, tnp->wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
} else {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
@@ -2186,10 +2282,10 @@ tcpnxdomain:
} /* SLIST_FOREACH */
/* UDP marriage */
- for (i = 0; i < sockcount; i++) {
- if (FD_ISSET(udp[i], &rset)) {
+ for (i = 0; i < cfg->sockcount; i++) {
+ if (FD_ISSET(cfg->udp[i], &rset)) {
istcp = 0;
- so = udp[i];
+ so = cfg->udp[i];
fromlen = sizeof(sockaddr_large);
memset(&msgh, 0, sizeof(msgh));
@@ -2204,7 +2300,7 @@ tcpnxdomain:
len = recvmsg(so, &msgh, 0);
if (len < 0) {
- syslog(LOG_INFO, "recvmsg: on descriptor %u interface \"%s\" %m", so, ident[i]);
+ syslog(LOG_INFO, "recvmsg: on descriptor %u interface \"%s\" %m", so, cfg->ident[i]);
continue;
}
@@ -2270,13 +2366,13 @@ tcpnxdomain:
recurseheader(&rh, IPPROTO_UDP, (struct sockaddr_storage*)sin, &sto, AF_INET);
}
} else {
- syslog(LOG_INFO, "packet received on descriptor %u interface \"%s\" had weird address family (%u), drop", so, ident[i], from->sa_family);
+ syslog(LOG_INFO, "packet received on descriptor %u interface \"%s\" had weird address family (%u), drop", so, cfg->ident[i], from->sa_family);
goto drop;
}
/* if UDP packet check length for minimum / maximum */
if (len > DNS_MAXUDP || len < sizeof(struct dns_header)){
- syslog(LOG_INFO, "on descriptor %u interface \"%s\" illegal dns packet length from %s, drop", so, ident[i], address);
+ syslog(LOG_INFO, "on descriptor %u interface \"%s\" illegal dns packet length from %s, drop", so, cfg->ident[i], address);
goto drop;
}
@@ -2284,7 +2380,7 @@ tcpnxdomain:
/* check if we're a question or reply, drop replies */
if ((ntohs(dh->query) & DNS_REPLY)) {
- syslog(LOG_INFO, "on descriptor %u interface \"%s\" dns header from %s is not a question, drop", so, ident[i], address);
+ syslog(LOG_INFO, "on descriptor %u interface \"%s\" dns header from %s is not a question, drop", so, cfg->ident[i], address);
goto drop;
}
@@ -2293,12 +2389,12 @@ tcpnxdomain:
*/
if (ntohs(dh->question) != 1) {
- syslog(LOG_INFO, "on descriptor %u interface \"%s\" header from %s has no question, drop", so, ident[i], address);
+ syslog(LOG_INFO, "on descriptor %u interface \"%s\" header from %s has no question, drop", so, cfg->ident[i], address);
/* format error */
build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, wildcard, NULL);
reply_fmterror(&sreply);
- syslog(LOG_INFO, "question on descriptor %d interface \"%s\" from %s, did not have question of 1 replying format error", so, ident[i], address);
+ syslog(LOG_INFO, "question on descriptor %d interface \"%s\" from %s, did not have question of 1 replying format error", so, cfg->ident[i], address);
goto drop;
}
@@ -2308,14 +2404,14 @@ tcpnxdomain:
}
if ((question = build_question(buf, len)) == NULL) {
- syslog(LOG_INFO, "on descriptor %u interface \"%s\" malformed question from %s, drop", so, ident[i], address);
+ syslog(LOG_INFO, "on descriptor %u interface \"%s\" malformed question from %s, drop", so, cfg->ident[i], address);
goto drop;
}
/* goto drop beyond this point should goto out instead */
fakequestion = NULL;
- if ((type0 = lookup_zone(db, question, &sd0, &lzerrno, (char *)&replystring, wildcard)) < 0) {
+ if ((type0 = lookup_zone(cfg->db, question, &sd0, &lzerrno, (char *)&replystring, wildcard)) < 0) {
switch (lzerrno) {
default:
syslog(LOG_INFO, "invalid lzerrno! dropping");
@@ -2346,7 +2442,7 @@ tcpnxdomain:
*/
memset(&sd0, 0, sizeof(sd0));
- (void)get_soa(db, question, &sd0, wildcard);
+ (void)get_soa(cfg->db, question, &sd0, wildcard);
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
@@ -2380,7 +2476,7 @@ udpnxdomain:
*/
memset(&sd0, 0, sizeof(sd0));
- (void)get_soa(db, question, &sd0, wildcard);
+ (void)get_soa(cfg->db, question, &sd0, wildcard);
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
@@ -2394,7 +2490,7 @@ udpnxdomain:
break;
}
- type1 = lookup_zone(db, fakequestion, &sd1, &lzerrno, (char *)&fakereplystring, wildcard);
+ type1 = lookup_zone(cfg->db, fakequestion, &sd1, &lzerrno, (char *)&fakereplystring, wildcard);
/* break CNAMES pointing to CNAMES */
if (type1 == DNS_TYPE_CNAME)
type1 = 0;
@@ -2432,12 +2528,12 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_A) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_a(&sreply, db);
+ reply_a(&sreply, cfg->db);
break; /* must break here */
}
@@ -2459,12 +2555,12 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_AAAA) {
build_reply(&sreply, so, buf, len, question, from,
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_aaaa(&sreply, db);
+ reply_aaaa(&sreply, cfg->db);
break; /* must break here */
}
@@ -2479,12 +2575,12 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_MX) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_mx(&sreply, db);
+ reply_mx(&sreply, cfg->db);
break; /* must break here */
}
@@ -2497,7 +2593,7 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
}
break;
@@ -2505,7 +2601,7 @@ udpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
}
break;
@@ -2518,7 +2614,7 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
}
break;
@@ -2532,7 +2628,7 @@ udpnxdomain:
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
break;
} else if (type0 == DNS_TYPE_PTR) {
build_reply(&sreply, so, buf, len, question, from,
@@ -2560,7 +2656,7 @@ udpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
- reply_ns(&sreply, db);
+ reply_ns(&sreply, cfg->db);
} else {
@@ -2573,10 +2669,15 @@ udpnxdomain:
}
udpout:
- if (lflag)
- syslog(LOG_INFO, "request on descriptor %u interface \"%s\" from %s (ttl=%u, region=%d) for \"%s\" type=%s class=%u, answering \"%s\"", so, ident[i], address, received_ttl, aregion, question->converted_name, get_dns_type(ntohs(question->hdr->qtype)), ntohs(question->hdr->qclass), replystring);
+ if (lflag) {
+ syslog(LOG_INFO, "request on descriptor %u interface \"%s\" from %s (ttl=%u, region=%d) for \"%s\" type=%s class=%u, answering \"%s\"", so, cfg->ident[i], address, received_ttl, aregion, question->converted_name, get_dns_type(ntohs(question->hdr->qtype)), ntohs(question->hdr->qclass), replystring);
+ }
+ if (logging.active == 1 && logging.bind == 0) {
+ remotelog(lfd, "request on descriptor %u interface \"%s\" from %s (ttl=%u, region=%d) for \"%s\" type=%s class=%u, answering \"%s\"", so, cfg->ident[i], address, received_ttl, aregion, question->converted_name, get_dns_type(ntohs(question->hdr->qtype)), ntohs(question->hdr->qclass), replystring);
+ }
+
if (fakequestion != NULL) {
free_question(fakequestion);
}
@@ -2586,6 +2687,15 @@ udpnxdomain:
} /* END ISSET */
} /* for */
+
+ if (FD_ISSET(lfd, &rset)) {
+ logfromlen = sizeof(struct sockaddr_storage);
+ len = recvfrom(lfd, buf, sizeof(buf), 0, (struct sockaddr *)&logfrom, &logfromlen);
+ if (len < 0) {
+ syslog(LOG_INFO, "recvfrom: logging %m");
+ } else
+ receivelog(buf, len);
+ }
drop:
blob - 6a884b1035d4af7a8d8f2d60fa58d6bf6fdc5b52
blob + 0d052691a870a18516fe927842d04b57455837e0
--- parse.c
+++ parse.c
@@ -59,7 +59,8 @@ struct myrr_lookup {
enum { CMD_TYPE_VERSION = 1, CMD_TYPE_REGION,
CMD_TYPE_ZONE, CMD_TYPE_INCLUDE,
- CMD_TYPE_WILDCARDONLYFOR, CMD_TYPE_RECURSEFOR };
+ CMD_TYPE_WILDCARDONLYFOR, CMD_TYPE_RECURSEFOR,
+ CMD_TYPE_LOGGING };
struct cmd_lookup {
char *name;
@@ -71,6 +72,7 @@ struct cmd_lookup {
{ "include ", CMD_TYPE_INCLUDE },
{ "wildcard-only-for ", CMD_TYPE_WILDCARDONLYFOR },
{ "recurse-for ", CMD_TYPE_RECURSEFOR },
+ { "logging ", CMD_TYPE_LOGGING },
{ NULL, 0},
};
@@ -81,12 +83,14 @@ struct cmd_lookup {
#define CONFIG_INCLUDE 0x10
#define CONFIG_WILDCARDONLYFOR 0x20
#define CONFIG_RECURSEFOR 0x40
+#define CONFIG_LOGGING 0x80
-#define WILDCARDVERSION 4
+#define WILDCARDVERSION 5
static u_int32_t config = 0;
+struct logging logging;
-static const char rcsid[] = "$Id: parse.c,v 1.30 2011/04/12 10:45:49 pbug Exp $";
+static const char rcsid[] = "$Id: parse.c,v 1.31 2011/06/28 17:04:33 pbug Exp $";
/*
* PARSE_FILE - parse the configfile XXX rewrite me in yacc :(
@@ -107,6 +111,9 @@ parse_file(DB *db, char *file)
struct stat sb, sb0;
struct dirent *dp;
+ memset(&logging, 0, sizeof(struct logging));
+ logging.active = 0;
+
fd = open(file, O_RDONLY, 0);
if (fd < 0) {
syslog(LOG_INFO, "open: %m");
@@ -165,7 +172,7 @@ parse_file(DB *db, char *file)
static int
parse_file0(char *filename, DB *db, FILE *f)
{
- int len, i;
+ int len, i, error;
int tokenlen;
u_int16_t type;
u_int32_t ttl;
@@ -190,6 +197,9 @@ parse_file0(char *filename, DB *db, FILE *f)
struct domain sdomain;
struct in6_addr *ia6;
struct sockaddr_in sin;
+ struct sockaddr_in *psin;
+ struct sockaddr_in6 *psin6;
+ struct addrinfo hints, *res0;
in_addr_t *ia;
@@ -308,6 +318,24 @@ parse_file0(char *filename, DB *db, FILE *f)
confstatus |= CONFIG_RECURSEFOR;
confstatus &= ~CONFIG_START;
goto loop;
+ case CMD_TYPE_LOGGING:
+ if ((config & CONFIG_VERSION) != CONFIG_VERSION) {
+ syslog(LOG_INFO, "%s: must have version at top of config\n", filename);
+ return (-1);
+ }
+ if (strchr(starttoken, '{') == NULL) {
+ syslog(LOG_INFO, "%s: must have opening brace ('{') in recurse-for entry on line %d", filename, line);
+ return (-1);
+ }
+ config |= CONFIG_LOGGING;
+
+ confstatus |= CONFIG_LOGGING;
+ confstatus &= ~CONFIG_START;
+ memset(&logging, 0, sizeof(logging));
+ logging.active = 1;
+ gethostname(buf, sizeof(buf));
+ logging.hostname = strdup(buf);
+ goto loop;
} /* switch */
break;
@@ -1126,7 +1154,7 @@ skip:
if (*starttoken == '}') {
confstatus &= ~(CONFIG_WILDCARDONLYFOR);
confstatus |= CONFIG_START;
- region++;
+ region++; /* XXX */
goto loop;
}
@@ -1160,7 +1188,7 @@ skip:
if (*starttoken == '}') {
confstatus &= ~(CONFIG_RECURSEFOR);
confstatus |= CONFIG_START;
- region++;
+ region++; /* XXX */
goto loop;
}
@@ -1190,6 +1218,134 @@ skip:
return (-1);
}
} /* CONFIG_RECURSEFOR */
+ if (confstatus & CONFIG_LOGGING) {
+ if (*starttoken == '}') {
+ confstatus &= ~(CONFIG_LOGGING);
+ confstatus |= CONFIG_START;
+ goto loop;
+ }
+
+ p = strchr(starttoken, ' ');
+
+ if (p == NULL) {
+ if (*starttoken == '\n')
+ goto loop;
+
+ syslog(LOG_INFO, "%s: (34) malformed line, line %d", filename, line);
+ return (-1);
+ }
+
+ *p++ = '\0';
+
+ if (strcasecmp(starttoken, "logbind") == 0) {
+ starttoken = p;
+
+ p = strchr(starttoken, ';');
+ if (p == NULL) {
+ syslog(LOG_INFO, "%s: (36) malformed line, line %d, must have closing semi-colon", filename, line);
+ return (-1);
+ }
+
+ *p = '\0';
+
+ if (strcasecmp(starttoken, "yes") == 0) {
+ logging.bind = 1;
+ }
+
+ } else if (strcasecmp(starttoken, "loghost") == 0) {
+
+ starttoken = p;
+
+ p = strchr(starttoken, ';');
+ if (p == NULL) {
+ syslog(LOG_INFO, "%s: (35) malformed line, line %d, must have closing semi-colon", filename, line);
+ return (-1);
+ }
+
+ *p = '\0';
+
+ logging.loghost = strdup(starttoken);
+ if (strchr(starttoken, ':') != NULL) {
+ /* IPv6 */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+
+ error = getaddrinfo(starttoken, "www", &hints, &res0);
+ if (error) {
+ syslog(LOG_INFO, "%s line %d: %s", filename, line,
+ gai_strerror(error));
+ return (-1);
+ }
+
+ if (res0 == NULL) {
+ syslog(LOG_INFO, "%s line %d: could not determine IPv6 address", filename, line);
+ return (-1);
+ }
+
+ psin6 = (struct sockaddr_in6 *)&logging.loghost2;
+ psin6->sin6_family = res0->ai_family;
+ memcpy(psin6, res0->ai_addr, res0->ai_addrlen);
+
+ freeaddrinfo(res0);
+ } else {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+
+ error = getaddrinfo(starttoken, "www", &hints, &res0);
+ if (error) {
+ syslog(LOG_INFO, "%s line %d: %s", filename, line,
+ gai_strerror(error));
+ return (-1);
+ }
+
+ if (res0 == NULL) {
+ syslog(LOG_INFO, "%s line %d: could not determine IPv6 address", filename, line);
+ return (-1);
+ }
+
+ psin = (struct sockaddr_in *)&logging.loghost2;
+ psin->sin_family = res0->ai_family;
+ memcpy(psin, res0->ai_addr, res0->ai_addrlen);
+
+ freeaddrinfo(res0);
+ }
+
+ } else if (strcasecmp(starttoken, "logport") == 0) {
+
+ starttoken = p;
+
+ p = strchr(starttoken, ';');
+ if (p == NULL) {
+ syslog(LOG_INFO, "%s: (35) malformed line, line %d, must have closing semi-colon", filename, line);
+ return (-1);
+ }
+
+ *p = '\0';
+
+ logging.logport = strdup(starttoken);
+ logging.logport2 = atoi(starttoken);
+
+ } else if (strcasecmp(starttoken, "logpasswd") == 0) {
+
+ starttoken = p;
+
+ p = strchr(starttoken, ';');
+ if (p == NULL) {
+ syslog(LOG_INFO, "%s: (36) malformed line, line %d, must have closing semi-colon", filename, line);
+ return (-1);
+ }
+
+ *p = '\0';
+
+ logging.logpasswd = strdup(starttoken);
+ }
+
+
+ } /* CONFIG_LOGGING */
loop:
continue;
repomaster@centroid.eu