mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 17:48:21 +00:00
Add dns_resolver option
This allows one to configure the address of the DNS server to use for lookup operations. Addresses GH-216
This commit is contained in:
parent
fd63168171
commit
af82e87699
4 changed files with 121 additions and 23 deletions
96
src/nb_dns.c
96
src/nb_dns.c
|
@ -86,7 +86,7 @@ struct nb_dns_hostent {
|
|||
|
||||
struct nb_dns_info {
|
||||
int s; /* Resolver file descriptor */
|
||||
struct sockaddr_in server; /* server address to bind to */
|
||||
struct sockaddr_storage server; /* server address to bind to */
|
||||
struct nb_dns_entry *list; /* outstanding requests */
|
||||
struct nb_dns_hostent dns_hostent;
|
||||
};
|
||||
|
@ -109,6 +109,18 @@ my_strerror(int errnum)
|
|||
#endif
|
||||
}
|
||||
|
||||
static const char* sa_ntop(struct sockaddr* sa, char* buf, int len)
|
||||
{
|
||||
if ( sa->sa_family == AF_INET )
|
||||
return inet_ntop(sa->sa_family,
|
||||
&(((struct sockaddr_in*)sa)->sin_addr),
|
||||
buf, len);
|
||||
else
|
||||
return inet_ntop(sa->sa_family,
|
||||
&(((struct sockaddr_in6*)sa)->sin6_addr),
|
||||
buf, len);
|
||||
}
|
||||
|
||||
struct nb_dns_info *
|
||||
nb_dns_init(char *errstr)
|
||||
{
|
||||
|
@ -136,13 +148,12 @@ nb_dns_init(char *errstr)
|
|||
|
||||
for ( i = 0; i < _res.nscount; ++i )
|
||||
{
|
||||
nd->server = _res.nsaddr_list[i];
|
||||
|
||||
memcpy(&nd->server, &_res.nsaddr_list[i], sizeof(struct sockaddr_in));
|
||||
/* XXX support IPv6 */
|
||||
if ( nd->server.sin_family != AF_INET )
|
||||
if ( nd->server.ss_family != AF_INET )
|
||||
continue;
|
||||
|
||||
nd->s = socket(nd->server.sin_family, SOCK_DGRAM, 0);
|
||||
nd->s = socket(nd->server.ss_family, SOCK_DGRAM, 0);
|
||||
|
||||
if ( nd->s < 0 )
|
||||
{
|
||||
|
@ -153,10 +164,14 @@ nb_dns_init(char *errstr)
|
|||
}
|
||||
|
||||
if ( connect(nd->s, (struct sockaddr *)&nd->server,
|
||||
sizeof(struct sockaddr)) < 0 )
|
||||
nd->server.ss_family == AF_INET ?
|
||||
sizeof(struct sockaddr_in) :
|
||||
sizeof(struct sockaddr_in6)) < 0 )
|
||||
{
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "connect(%s): %s",
|
||||
inet_ntoa(nd->server.sin_addr), my_strerror(errno));
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
sa_ntop((struct sockaddr*)&nd->server, s, INET6_ADDRSTRLEN);
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "connect(%s): %s", s,
|
||||
my_strerror(errno));
|
||||
close(nd->s);
|
||||
free(nd);
|
||||
return (NULL);
|
||||
|
@ -170,6 +185,58 @@ nb_dns_init(char *errstr)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
struct nb_dns_info *
|
||||
nb_dns_init2(char *errstr, struct sockaddr* sa)
|
||||
{
|
||||
register struct nb_dns_info *nd;
|
||||
|
||||
nd = (struct nb_dns_info *)malloc(sizeof(*nd));
|
||||
if (nd == NULL) {
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "nb_dns_init: malloc(): %s",
|
||||
my_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
memset(nd, 0, sizeof(*nd));
|
||||
nd->s = -1;
|
||||
|
||||
if ( sa->sa_family == AF_INET )
|
||||
{
|
||||
memcpy(&nd->server, sa, sizeof(struct sockaddr_in));
|
||||
((struct sockaddr_in*)&nd->server)->sin_port = htons(53);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&nd->server, sa, sizeof(struct sockaddr_in6));
|
||||
((struct sockaddr_in6*)&nd->server)->sin6_port = htons(53);
|
||||
}
|
||||
|
||||
nd->s = socket(nd->server.ss_family, SOCK_DGRAM, 0);
|
||||
|
||||
if ( nd->s < 0 )
|
||||
{
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "socket(): %s",
|
||||
my_strerror(errno));
|
||||
free(nd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ( connect(nd->s, (struct sockaddr *)&nd->server,
|
||||
nd->server.ss_family == AF_INET ?
|
||||
sizeof(struct sockaddr_in) :
|
||||
sizeof(struct sockaddr_in6)) < 0 )
|
||||
{
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
sa_ntop((struct sockaddr*)&nd->server, s, INET6_ADDRSTRLEN);
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "connect(%s): %s", s,
|
||||
my_strerror(errno));
|
||||
close(nd->s);
|
||||
free(nd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (nd);
|
||||
}
|
||||
|
||||
void
|
||||
nb_dns_finish(struct nb_dns_info *nd)
|
||||
{
|
||||
|
@ -226,12 +293,12 @@ _nb_dns_cmpsockaddr(register struct sockaddr *sa1,
|
|||
sin6a = (struct sockaddr_in6 *)sa1;
|
||||
sin6b = (struct sockaddr_in6 *)sa2;
|
||||
if (sin6a->sin6_port != sin6b->sin6_port) {
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, serr, 2);
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, serr, 62);
|
||||
return (-1);
|
||||
}
|
||||
if (memcmp(&sin6a->sin6_addr, &sin6b->sin6_addr,
|
||||
sizeof(sin6a->sin6_addr)) != 0) {
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, serr, 3);
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, serr, 63);
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
@ -446,7 +513,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
|
|||
register int msglen, qtype, atype, n, i;
|
||||
register struct nb_dns_entry *ne, *lastne;
|
||||
socklen_t fromlen;
|
||||
struct sockaddr from;
|
||||
struct sockaddr_storage from;
|
||||
u_long msg[MAXPACKET / sizeof(u_long)];
|
||||
register char *bp, *ep;
|
||||
register char **ap, **hap;
|
||||
|
@ -460,7 +527,8 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
|
|||
|
||||
/* This comes from the second half of do_query() */
|
||||
fromlen = sizeof(from);
|
||||
msglen = recvfrom(nd->s, (char *)msg, sizeof(msg), 0, &from, &fromlen);
|
||||
msglen = recvfrom(nd->s, (char *)msg, sizeof(msg), 0,
|
||||
(struct sockaddr*)&from, &fromlen);
|
||||
if (msglen <= 0) {
|
||||
snprintf(errstr, NB_DNS_ERRSIZE, "recvfrom(): %s",
|
||||
my_strerror(errno));
|
||||
|
@ -479,8 +547,8 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
|
|||
}
|
||||
|
||||
/* RES_INSECURE1 style check */
|
||||
if (_nb_dns_cmpsockaddr((struct sockaddr *)&nd->server, &from,
|
||||
errstr) < 0) {
|
||||
if (_nb_dns_cmpsockaddr((struct sockaddr*)&nd->server,
|
||||
(struct sockaddr*)&from, errstr) < 0) {
|
||||
nr->host_errno = NO_RECOVERY;
|
||||
return (-1);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue