X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftypes.c;h=754c237253d75f6628efac8c21029b20072546b2;hb=26e1c3d691b52d21a8bb52d9bf3f8e2b42ae6cfa;hp=aa34c0ab9945ab43b6256437fa25bded7df8b0b6;hpb=79d4d86add26e3ed27828e1ed4e069b6109607ed;p=adns.git diff --git a/src/types.c b/src/types.c index aa34c0a..754c237 100644 --- a/src/types.c +++ b/src/types.c @@ -4,14 +4,14 @@ */ /* * This file is part of adns, which is - * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson * Copyright (C) 1999-2000,2003,2006 Tony Finch * Copyright (C) 1991 Massachusetts Institute of Technology * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -20,8 +20,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program; if not, write to the Free Software Foundation. */ #include @@ -400,50 +399,46 @@ static unsigned addr_rrtypeflag(adns_rrtype type) { * adns__qf_addr_cname set so that we know that we're in the fixup state. */ -static adns_status pap_addr(const parseinfo *pai, int rrty, size_t rrsz, - int *cbyte_io, int max, adns_rr_addr *storeto) { - const byte *dgram= pai->dgram; - int af, addrlen, salen; +static adns_status pap_addr(const parseinfo *pai, int in_rrty, size_t out_rrsz, + int *cbyte_io, int cbyte_max, adns_rr_addr *out) { + int in_addrlen; + int out_af, out_salen; struct in6_addr v6map; - const void *oaddr= dgram + *cbyte_io; - int avail= max - *cbyte_io; - int step= -1; - void *addrp= 0; - - switch (rrty) { - case adns_r_a: - if ((pai->qu->flags & adns_qf_ipv6_mapv4) && - (pai->qu->answer->type & adns__qtf_bigaddr)) { - if (avail < 4) return adns_s_invaliddata; - memset(v6map.s6_addr + 0, 0x00, 10); - memset(v6map.s6_addr + 10, 0xff, 2); - memcpy(v6map.s6_addr + 12, oaddr, 4); - oaddr= v6map.s6_addr; avail= sizeof(v6map.s6_addr); - if (step < 0) step= 4; - goto aaaa; - } - af= AF_INET; addrlen= 4; - addrp= &storeto->addr.inet.sin_addr; - salen= sizeof(storeto->addr.inet); - break; - case adns_r_aaaa: - aaaa: - af= AF_INET6; addrlen= 16; - addrp= storeto->addr.inet6.sin6_addr.s6_addr; - salen= sizeof(storeto->addr.inet6); - break; + + const void *use_addr= pai->dgram + *cbyte_io; + + switch (in_rrty) { + case adns_r_a: in_addrlen= 4; out_af= AF_INET; break; + case adns_r_aaaa: in_addrlen= 16; out_af= AF_INET6; break; + default: abort(); } - assert(addrp); - assert(offsetof(adns_rr_addr, addr) + salen <= rrsz); - if (addrlen < avail) return adns_s_invaliddata; - if (step < 0) step= addrlen; - *cbyte_io += step; - memset(&storeto->addr, 0, salen); - storeto->len= salen; - storeto->addr.sa.sa_family= af; - memcpy(addrp, oaddr, addrlen); + if ((*cbyte_io + in_addrlen) != cbyte_max) return adns_s_invaliddata; + + if (out_af==AF_INET && + (pai->qu->flags & adns_qf_ipv6_mapv4) && + (pai->qu->answer->type & adns__qtf_bigaddr)) { + memset(v6map.s6_addr + 0, 0x00, 10); + memset(v6map.s6_addr + 10, 0xff, 2); + memcpy(v6map.s6_addr + 12, use_addr, 4); + use_addr= v6map.s6_addr; + out_af= AF_INET6; + } + + switch (out_af) { + case AF_INET: out_salen= sizeof(out->addr.inet); break; + case AF_INET6: out_salen= sizeof(out->addr.inet6); break; + default: abort(); + } + + assert(offsetof(adns_rr_addr, addr) + out_salen <= out_rrsz); + + memset(&out->addr, 0, out_salen); + out->len= out_salen; + out->addr.sa.sa_family= out_af; + adns__addr_inject(use_addr, &out->addr); + *cbyte_io += in_addrlen; return adns_s_ok; } @@ -583,11 +578,11 @@ static adns_status addr_submit(adns_query parent, adns_query *query_r, * available record types. The memory management and callback rules are * the same as for adns__internal_submit. * - * Some differences: the query is linked onto the parent's children list - * before exit (though the parent's state is not changed, and it is not - * linked into the childw list queue); and we fiddle with the `tinfo' - * portion of the context structure (yes, modifying *ctx), since this is, - * in fact, the main purpose of this function. + * Some differences: the query is linked onto the parent's children + * list before exit (though the parent's state is not changed, and + * it is not linked into the childw list queue); and we set the + * `tinfo' portion of the context structure (yes, modifying *ctx), + * since this is, in fact, the main purpose of this function. */ adns_state ads= parent->ads;