X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/e062dcae8f9acfc112459cf7b2d8c925cda08249..c7836bc9e8b0ed6a04e9008545e29de410d9693e:/src/types.c diff --git a/src/types.c b/src/types.c index 4b5e752..8993451 100644 --- a/src/types.c +++ b/src/types.c @@ -21,14 +21,20 @@ */ #include +#include #include #include "internal.h" +static int dip_inaddr(struct in_addr a, struct in_addr b) { + /* fixme implement sortlist */ + return 0; +} + static adns_status pa_inaddr(adns_query qu, int serv, const byte *dgram, int dglen, int cbyte, int max, - void *datap) { + int nsstart, int *arstart_io, void *datap) { struct in_addr *storeto= datap; if (max-cbyte != 4) return adns_s_invaliddata; @@ -36,11 +42,6 @@ static adns_status pa_inaddr(adns_query qu, int serv, return adns_s_ok; } -static int dip_inaddr(struct in_addr a, struct in_addr b) { - /* fixme implement sortlist */ - return 0; -} - static int di_inaddr(const void *datap_a, const void *datap_b) { const struct in_addr *ap= datap_a, *bp= datap_b; @@ -55,14 +56,52 @@ static adns_status cs_inaddr(vbuf *vb, const void *datap) { return adns__vbuf_appendstr(vb,ia) ? adns_s_ok : adns_s_nolocalmem; } -static adns_status pap_domain(adns_query qu, int serv, +static adns_status pa_addr(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + void *datap) { + adns_addr *storeto= datap; + + if (max-cbyte != 4) return adns_s_invaliddata; + storeto->len= sizeof(storeto->addr.inet); + memset(&storeto->addr,0,sizeof(storeto->addr.inet)); + storeto->addr.inet.sin_family= AF_INET; + storeto->addr.inet.sin_port= 0; + memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4); + return adns_s_ok; +} + +static int di_addr(const void *datap_a, const void *datap_b) { + const adns_addr *ap= datap_a, *bp= datap_b; + + return dip_inaddr(ap->addr.inet.sin_addr,bp->addr.inet.sin_addr); +} + +static adns_status cs_addr(vbuf *vb, const void *datap) { + const adns_addr *rrp= datap; + const char *ia; + static char buf[30]; + + switch (rrp->addr.inet.sin_family) { + case AF_INET: + if (!adns__vbuf_appendstr(vb,"AF_INET ")) return adns_s_nolocalmem; + ia= inet_ntoa(rrp->addr.inet.sin_addr); assert(ia); + if (!adns__vbuf_appendstr(vb,ia)) return adns_s_nolocalmem; + break; + default: + sprintf(buf,"AF=%u",rrp->addr.sa.sa_family); + if (!adns__vbuf_appendstr(vb,buf)) return adns_s_nolocalmem; + break; + } + return adns_s_ok; +} + +static adns_status pap_domain(adns_query qu, int serv, parsedomain_flags flags, const byte *dgram, int dglen, int *cbyte_io, int max, char **domain_r) { adns_status st; char *dm; - st= adns__parse_domain(qu->ads,serv,qu,&qu->vb,qu->flags, - dgram,dglen, cbyte_io,max); + st= adns__parse_domain(qu->ads,serv,qu,&qu->vb,flags, dgram,dglen, cbyte_io,max); if (st) return st; if (!qu->vb.used) return adns_s_invaliddata; @@ -76,13 +115,15 @@ static adns_status pap_domain(adns_query qu, int serv, return adns_s_ok; } -static adns_status pa_domain_raw(adns_query qu, int serv, - const byte *dgram, int dglen, int cbyte, int max, - void *datap) { +static adns_status pa_host_raw(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + int nsstart, int *arstart_io, void *datap) { char **rrp= datap; adns_status st; - st= pap_domain(qu,serv,dgram,dglen,&cbyte,max,rrp); + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,rrp); if (st) return st; if (cbyte != max) return adns_s_invaliddata; @@ -91,7 +132,7 @@ static adns_status pa_domain_raw(adns_query qu, int serv, static adns_status pa_mx_raw(adns_query qu, int serv, const byte *dgram, int dglen, int cbyte, int max, - void *datap) { + int nsstart, int *arstart_io, void *datap) { adns_rr_intstr *rrp= datap; adns_status st; int pref; @@ -99,13 +140,111 @@ static adns_status pa_mx_raw(adns_query qu, int serv, if (cbyte+2 > max) return adns_s_invaliddata; GET_W(cbyte,pref); rrp->i= pref; - st= pap_domain(qu,serv,dgram,dglen,&cbyte,max,&rrp->str); + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->str); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } + +static adns_status pap_findaddrs(adns_query qu, int serv, adns_rr_hostaddr *ha, + const byte *dgram, int dglen, int *cbyte_io, + int dmstart, int count) { + int rri, nrrs; + int type, class, rdlen, rdstart, ownermatched; + + for (rri=0, nrrs=-1; rrivb.used= 0; + nrrs= 0; + } + if (!adns__vbuf_ensure(&qu->vb,qu->vb.used+sizeof(adns_addr))) + return adns_s_nolocalmem; + st= pa_addr(qu,serv, dgram,dglen, rdstart,rdstart+rdlen, + qu->vb.buf + qu->vb.used); + if (st) return st; + qu->vb.used += sizeof(adns_addr); + nrrs++; + } + if (nrrs >= 0) { + ha->rrs= adns__alloc_interim(qu,qu->vb.used); + if (!ha->rrs) return adns_s_nolocalmem; + ha->nrrs= nrrs; + ha->astatus= adns_s_ok; + } + return adns_s_ok; +} + +static adns_status pap_hostaddr(adns_query qu, int serv, + const byte *dgram, int dglen, int *cbyte_io, int max, + int nsstart, int nscount, int arcount, void *datap) { + adns_rr_hostaddr **rrp= datap; + adns_status st; + int dmstart, cbyte; + + dmstart= cbyte= *cbyte_io; + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->dm); + if (st) return st; + *cbyte_io= cbyte; + + rrp->astatus= adns_s_ok; + rrp->naddrs= -1; + rrp->addrs= 0; + + cbyte= nsstart; + + st= pap_findaddrs(qu, rrp, dgram,dglen,&cbyte, dmstart); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + st= pap_findaddrs(qu, rrp, dgram,dglen,&cbyte, dmstart); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; +} + +static adns_status pa_hostaddr(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + int nsstart, void *datap) { + adns_rr_hostaddr **rrp= datap; + adns_status st; + int dmstart; + + dmstart= cbyte; + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->dm); + if (st) return st; + if (cbyte != max) return adns_s_invaliddata; + + rrp->astatus= adns_s_ok; + rrp->naddrs= -1; + rrp->addrs= 0; + + cbyte= nsstart; + + st= pap_findaddrs(qu, rrp, dgram,dglen, dmstart,&cbyte); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + st= pap_findaddrs(qu, rrp, dgram,dglen, dmstart,&cbyte); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + assert(!"additional section didn't have required data"); +} + static int di_mx_raw(const void *datap_a, const void *datap_b) { const adns_rr_intstr *ap= datap_a, *bp= datap_b; @@ -116,7 +255,7 @@ static int di_mx_raw(const void *datap_a, const void *datap_b) { static adns_status pa_txt(adns_query qu, int serv, const byte *dgram, int dglen, int startbyte, int max, - void *datap) { + int nsstart, int *arstart_io, void *datap) { adns_rr_intstr **rrp= datap, *table, *te; int ti, tc, cbyte, l; @@ -253,31 +392,32 @@ static const typeinfo typeinfos[] = { /* Must be in ascending order of rrtype ! */ /* rr type code rrt fmt mem.mgmt member parser comparer */ - { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr, di_inaddr }, - { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_domain_raw, 0 }, - { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_domain_raw, 0 }, -#if 0 /*fixme*/ - { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa, 0 }, -#endif - { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_domain_raw, 0 }, -#if 0 /*fixme*/ - { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo, 0 }, -#endif - { adns_r_mx_raw, "MX", "raw", DEEP_MEMB(intstr), pa_mx_raw, di_mx_raw }, - { adns_r_txt, "TXT", 0, DEEP_MEMB(manyistr), pa_txt, 0 }, -#if 0 /*fixme*/ - { adns_r_rp_raw, "RP", "raw", DEEP_MEMB(strpair), pa_rp, 0 }, -#endif -#if 0 /*fixme*/ - - { adns_r_ns, "NS", "+addr", DEEP_MEMB(dmaddr), pa_dmaddr, di_dmaddr }, - { adns_r_ptr, "PTR","checked", DEEP_MEMB(str), pa_ptr, 0 }, - { adns_r_mx, "MX", "+addr", DEEP_MEMB(intdmaddr), pa_mx, di_mx }, + { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr, di_inaddr }, + { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, + { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_host_raw, 0 }, +#if 0 /*fixme*/ + { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa, 0 }, +#endif + { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, +#if 0 /*fixme*/ + { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo, 0 }, +#endif + { adns_r_mx_raw, "MX", "raw", DEEP_MEMB(intstr), pa_mx_raw, di_mx_raw }, + { adns_r_txt, "TXT", 0, DEEP_MEMB(manyistr), pa_txt, 0 }, +#if 0 /*fixme*/ + { adns_r_rp_raw, "RP", "raw", DEEP_MEMB(strpair), pa_rp, 0 }, +#endif + + { adns_r_addr, "A", "addr", FLAT_MEMB(addr), pa_addr, di_addr }, + { adns_r_ns, "NS", "+addr", DEEP_MEMB(dmaddr), pa_hostaddr, di_hostaddr }, +#if 0 /*fixme*/ + { adns_r_ptr, "PTR","checked", DEEP_MEMB(str), pa_ptr, 0 }, + { adns_r_mx, "MX", "+addr", DEEP_MEMB(intdmaddr), pa_mx, di_mx }, #endif #if 0 /*fixme*/ - { adns_r_soa, "SOA", "822", DEEP_MEMB(soa), pa_soa, 0 }, - { adns_r_rp, "RP", "822", DEEP_MEMB(strpair), pa_rp, 0 }, + { adns_r_soa, "SOA","822", DEEP_MEMB(soa), pa_soa, 0 }, + { adns_r_rp, "RP", "822", DEEP_MEMB(strpair), pa_rp, 0 }, #endif };