summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
eca4e30)
The sortlist is now IPv6 aware. The nameserver configuration could cope
with IPv6 addresses, but the transport machinery can't, so we pick them
out by hand. PTR reverse-query handling still doesn't do anything
special, because we don't have AAAA query support yet.
I've also hacked adnshost's `-i' and `--reverse' options to use the new
functions, and they'll accept IPv6 addresses, but the underlying
adns_submit_reverse machinery will reject them still.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
+
+static void sockaddr_aton(const char *text, adns_rr_addr *a) {
+ int err;
+
+ a->len= sizeof(a->addr);
+ err= adns_text2addr(text,0,adns_qf_addrlit_scope_forbid,
+ &a->addr.sa,&a->len);
+ if (err == EINVAL) usageerr("invalid IP address %s",text);
+ else if (err) sysfail("adns_text2addr",err);
+}
void of_ptr(const struct optioninfo *oi, const char *arg, const char *arg2) {
struct query_node *qun;
int quflags, r;
void of_ptr(const struct optioninfo *oi, const char *arg, const char *arg2) {
struct query_node *qun;
int quflags, r;
- struct sockaddr_in sa;
-
- memset(&sa,0,sizeof(sa));
- sa.sin_family= AF_INET;
- if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
prep_query(&qun,&quflags);
qun->owner= xstrsave(arg);
prep_query(&qun,&quflags);
qun->owner= xstrsave(arg);
- r= adns_submit_reverse(ads,
- (struct sockaddr*)&sa,
+ r= adns_submit_reverse(ads, &a.addr.sa,
ov_type == adns_r_none ? adns_r_ptr : ov_type,
quflags,
qun,
ov_type == adns_r_none ? adns_r_ptr : ov_type,
quflags,
qun,
void of_reverse(const struct optioninfo *oi, const char *arg, const char *arg2) {
struct query_node *qun;
int quflags, r;
void of_reverse(const struct optioninfo *oi, const char *arg, const char *arg2) {
struct query_node *qun;
int quflags, r;
- struct sockaddr_in sa;
-
- memset(&sa,0,sizeof(sa));
- sa.sin_family= AF_INET;
- if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
prep_query(&qun,&quflags);
qun->owner= xmalloc(strlen(arg) + strlen(arg2) + 2);
sprintf(qun->owner, "%s %s", arg,arg2);
prep_query(&qun,&quflags);
qun->owner= xmalloc(strlen(arg) + strlen(arg2) + 2);
sprintf(qun->owner, "%s %s", arg,arg2);
- r= adns_submit_reverse_any(ads,
- (struct sockaddr*)&sa, arg2,
+ r= adns_submit_reverse_any(ads, &a.addr.sa,arg2,
ov_type == adns_r_none ? adns_r_txt : ov_type,
quflags,
qun,
ov_type == adns_r_none ? adns_r_txt : ov_type,
quflags,
qun,
if (port_r) *port_r= ntohs(port);
return 0;
}
if (port_r) *port_r= ntohs(port);
return 0;
}
+
+char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf) {
+ int err;
+ int len= ADNS_ADDR2TEXT_BUFLEN;
+
+ err= adns_addr2text(sa, 0, buf, &len, 0);
+ if (err == EIO)
+ err= adns_addr2text(sa, adns_qf_addrlit_scope_numeric, buf, &len, 0);
+ assert(!err);
+ return buf;
+}
void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
int serv, adns_query qu, const char *fmt, va_list al) {
void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
int serv, adns_query qu, const char *fmt, va_list al) {
+ char buf[ADNS_ADDR2TEXT_BUFLEN];
const char *bef, *aft;
vbuf vb;
const char *bef, *aft;
vbuf vb;
- assert(ads->servers[serv].addr.sa.sa_family==AF_INET);
adns__lprintf(ads,"%sNS=%s",bef,
adns__lprintf(ads,"%sNS=%s",bef,
- inet_ntoa(ads->servers[serv].addr.inet.sin_addr));
+ adns__sockaddr_ntoa(&ads->servers[serv].addr.sa, buf));
* byte-order). Assumes that sa->sa_family is already set correctly.
*/
* byte-order). Assumes that sa->sa_family is already set correctly.
*/
+char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf);
+/* Convert sa to a string, and write it to buf, which must be at least
+ * ADNS_ADDR2TEXT_BUFLEN bytes long (unchecked). Return buf; can't fail.
+ */
+
/* From setup.c: */
int adns__setnonblock(adns_state ads, int fd); /* => errno value */
/* From setup.c: */
int adns__setnonblock(adns_state ads, int fd); /* => errno value */
static void addserver(adns_state ads, const struct sockaddr *sa, int n) {
int i;
adns_rr_addr *ss;
static void addserver(adns_state ads, const struct sockaddr *sa, int n) {
int i;
adns_rr_addr *ss;
- const struct sockaddr_in *sin;
+ char buf[ADNS_ADDR2TEXT_BUFLEN];
- assert(sa->sa_family==AF_INET); /* for inet_ntoa */
- sin= (const void *)sa;
+ if (sa->sa_family != AF_INET) {
+ adns__debug(ads,-1,0,"non-IPv4 nameserver %s ignored",
+ adns__sockaddr_ntoa(sa, buf));
+ return;
+ }
for (i=0; i<ads->nservers; i++) {
if (adns__sockaddr_equal_p(sa, &ads->servers[i].addr.sa)) {
adns__debug(ads,-1,0,"duplicate nameserver %s ignored",
for (i=0; i<ads->nservers; i++) {
if (adns__sockaddr_equal_p(sa, &ads->servers[i].addr.sa)) {
adns__debug(ads,-1,0,"duplicate nameserver %s ignored",
- inet_ntoa(sin->sin_addr));
+ adns__sockaddr_ntoa(sa, buf));
return;
}
}
if (ads->nservers>=MAXSERVERS) {
adns__diag(ads,-1,0,"too many nameservers, ignoring %s",
return;
}
}
if (ads->nservers>=MAXSERVERS) {
adns__diag(ads,-1,0,"too many nameservers, ignoring %s",
- inet_ntoa(sin->sin_addr));
+ adns__sockaddr_ntoa(sa, buf));
static void ccf_nameserver(adns_state ads, const char *fn,
int lno, const char *buf) {
static void ccf_nameserver(adns_state ads, const char *fn,
int lno, const char *buf) {
- struct sockaddr_in sin;
-
- memset(&sin,0,sizeof(sin));
- sin.sin_family= AF_INET;
- sin.sin_port= htons(DNS_PORT);
- if (!inet_aton(buf,&sin.sin_addr)) {
+ adns_rr_addr a;
+ char addrbuf[ADNS_ADDR2TEXT_BUFLEN];
+ int err;
+
+ a.len= sizeof(a.addr);
+ err= adns_text2addr(buf,DNS_PORT, 0, &a.addr.sa,&a.len);
+ switch (err) {
+ case 0:
+ break;
+ case EINVAL:
configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf);
return;
configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf);
return;
+ default:
+ configparseerr(ads,fn,lno,"failed to parse nameserver address `%s': %s",
+ buf,strerror(err));
+ return;
- adns__debug(ads,-1,0,"using nameserver %s",inet_ntoa(sin.sin_addr));
- addserver(ads,(const struct sockaddr *)&sin,sizeof(sin));
+ adns__debug(ads,-1,0,"using nameserver %s",
+ adns__sockaddr_ntoa(&a.addr.sa, addrbuf));
+ addserver(ads,&a.addr.sa,a.len);
}
static void ccf_search(adns_state ads, const char *fn,
}
static void ccf_search(adns_state ads, const char *fn,
ads->searchlist= newptrs;
}
ads->searchlist= newptrs;
}
+static int gen_pton(const char *text, int *af_io, union gen_addr *a) {
+ adns_rr_addr addr;
+ int err;
+
+ addr.len= sizeof(addr.addr);
+ err= adns_text2addr(text,0, adns_qf_addrlit_scope_forbid,
+ &addr.addr.sa, &addr.len);
+ if (err) { assert(err == EINVAL); return 0; }
+ if (*af_io == AF_UNSPEC) *af_io= addr.addr.sa.sa_family;
+ else if (*af_io != addr.addr.sa.sa_family) return 0;
+ adns__sockaddr_extract(&addr.addr.sa, a, 0);
+ return 1;
+}
+
static void ccf_sortlist(adns_state ads, const char *fn,
int lno, const char *buf) {
const char *word;
static void ccf_sortlist(adns_state ads, const char *fn,
int lno, const char *buf) {
const char *word;
const char *maskwhat;
struct sortlist *sl;
int l;
const char *maskwhat;
struct sortlist *sl;
int l;
int initial= -1;
if (!buf) return;
int initial= -1;
if (!buf) return;
if (slash) *slash++= 0;
sl= &ads->sortlist[ads->nsortlist];
if (slash) *slash++= 0;
sl= &ads->sortlist[ads->nsortlist];
- if (!inet_aton(tbuf, &sl->base.v4)) {
+ af= AF_UNSPEC;
+ if (!gen_pton(tbuf, &af, &sl->base)) {
configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf);
continue;
}
configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf);
continue;
}
if (slash) {
if (slash[strspn(slash, "0123456789")]) {
maskwhat = "mask";
if (slash) {
if (slash[strspn(slash, "0123456789")]) {
maskwhat = "mask";
- if (!inet_aton(slash, &sl->mask.v4)) {
+ if (!gen_pton(slash,&af,&sl->mask)) {
configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash);
continue;
}
configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash);
continue;
}
* _intstr (mf,csp,cs)
* _manyistr (mf,cs)
* _txt (pa)
* _intstr (mf,csp,cs)
* _manyistr (mf,cs)
* _txt (pa)
- * _inaddr (pa,di,cs +search_sortlist, dip_genaddr)
+ * _inaddr (pa,di,cs
+ * +search_sortlist, dip_genaddr, csp_genaddr)
* _addr (pa,di,div,csp,cs,gsz
* +search_sortlist_sa, dip_sockaddr)
* _domain (pap,csp,cs)
* _addr (pa,di,div,csp,cs,gsz
* +search_sortlist_sa, dip_sockaddr)
* _domain (pap,csp,cs)
- * _inaddr (pa,di,cs +search_sortlist, dip_genaddr)
+ * _inaddr (pa,di,cs +search_sortlist, dip_genaddr, csp_genaddr)
*/
static adns_status pa_inaddr(const parseinfo *pai, int cbyte,
*/
static adns_status pa_inaddr(const parseinfo *pai, int cbyte,
return dip_genaddr(ads,AF_INET,datap_a,datap_b);
}
return dip_genaddr(ads,AF_INET,datap_a,datap_b);
}
-static adns_status cs_inaddr(vbuf *vb, const void *datap) {
- const struct in_addr *rrp= datap, rr= *rrp;
- const char *ia;
+static adns_status csp_genaddr(vbuf *vb, int af, const void *p) {
+ char buf[ADNS_ADDR2TEXT_BUFLEN];
+ int len= sizeof(buf);
+ adns_rr_addr a;
+ int err;
- ia= inet_ntoa(rr); assert(ia);
- CSP_ADDSTR(ia);
+ memset(&a, 0, sizeof(a));
+ a.addr.sa.sa_family= af;
+ adns__sockaddr_inject(p, 0, &a.addr.sa);
+ err= adns_addr2text(&a.addr.sa,0, buf,&len, 0); assert(!err);
+ CSP_ADDSTR(buf);
+static adns_status cs_inaddr(vbuf *vb, const void *datap) {
+ return csp_genaddr(vb, AF_INET,datap);
+}
+
/*
* _addr (pa,di,div,csp,cs,gsz +search_sortlist_sa, dip_sockaddr)
*/
/*
* _addr (pa,di,div,csp,cs,gsz +search_sortlist_sa, dip_sockaddr)
*/
}
static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) {
}
static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) {
- const char *ia;
- char buf[30];
+ char buf[ADNS_ADDR2TEXT_BUFLEN];
+ int len= sizeof(buf);
+ int err;
switch (rrp->addr.inet.sin_family) {
case AF_INET:
CSP_ADDSTR("INET ");
switch (rrp->addr.inet.sin_family) {
case AF_INET:
CSP_ADDSTR("INET ");
- ia= inet_ntoa(rrp->addr.inet.sin_addr); assert(ia);
- CSP_ADDSTR(ia);
+ goto a2t;
+ case AF_INET6:
+ CSP_ADDSTR("INET6 ");
+ goto a2t;
+ a2t:
+ err= adns_addr2text(&rrp->addr.sa,0, buf,&len, 0); assert(!err);
+ CSP_ADDSTR(buf);
break;
default:
sprintf(buf,"AF=%u",rrp->addr.sa.sa_family);
break;
default:
sprintf(buf,"AF=%u",rrp->addr.sa.sa_family);