| 1 | /**/ |
| 2 | |
| 3 | #include "internal.h" |
| 4 | |
| 5 | static adns_status rp_inaddr(adns_state ads, adns_query qu, int serv, |
| 6 | const byte *dgram, int dglen, int cbyte, int max, |
| 7 | void *store_r) { |
| 8 | struct in_addr *dr= store_r; |
| 9 | |
| 10 | if (max-cbyte != 4) return adns_s_invaliddata; |
| 11 | memcpy(dr,dgram+cbyte,4); |
| 12 | return adns_s_ok; |
| 13 | } |
| 14 | |
| 15 | static adns_status rmf_null(adns_state ads, adns_query qu, void *data) { } |
| 16 | |
| 17 | #define TYPE_SF(size,func,free) size, rp_#func, rmf_#free |
| 18 | #define TYPE_SN(size,func) size, rp_#func, rmf_null |
| 19 | #define TYPESZ_M(member) (sizeof(((adns_answer*)0)->rrs.member)) |
| 20 | #define TYPE_MF(member,parse) TYPE_SF(TYPESZ_M(member),parse,member) |
| 21 | #define TYPE_MN(member,parse) TYPE_SN(TYPESZ_M(member),parse) |
| 22 | |
| 23 | /* TYPE_<ms><nf> |
| 24 | * ms is M specify member name |
| 25 | * or S specify size explicitly |
| 26 | * nf is F full memory management, dependent on member name or specified func |
| 27 | * N no memory management required |
| 28 | */ |
| 29 | |
| 30 | static const typeinfo typeinfos[] = { |
| 31 | /* Must be in ascending order of rrtype ! */ |
| 32 | /* rr type code style member size parser */ |
| 33 | |
| 34 | { adns_r_a, TYPE_MN( inaddr, inaddr ) }, |
| 35 | #if 0 /*fixme*/ |
| 36 | { adns_r_ns_raw, TYPE_MF( str, domain_raw ) }, |
| 37 | { adns_r_cname, TYPE_MF( str, domain_raw ) }, |
| 38 | { adns_r_soa_raw, TYPE_MF( soa, soa ) }, |
| 39 | { adns_r_null, TYPE_SN( 0, null ) }, |
| 40 | { adns_r_ptr_raw, TYPE_MF( str, domain_raw ) }, |
| 41 | { adns_r_hinfo, TYPE_MF( strpair, hinfo ) }, |
| 42 | { adns_r_mx_raw, TYPE_MF( intstr, mx_raw ) }, |
| 43 | { adns_r_txt, TYPE_MF( str, txt ) }, |
| 44 | { adns_r_rp_raw, TYPE_MF( strpair, rp ) }, |
| 45 | |
| 46 | { adns_r_ns, TYPE_MF( dmaddr, dmaddr ) }, |
| 47 | { adns_r_ptr, TYPE_MF( str, ptr ) }, |
| 48 | { adns_r_mx, TYPE_MF( intdmaddr, mx ) }, |
| 49 | |
| 50 | { adns_r_soa, TYPE_MF( soa, soa ) }, |
| 51 | { adns_r_rp, TYPE_MF( strpair, rp ) }, |
| 52 | #endif |
| 53 | }; |
| 54 | |
| 55 | const typeinfo adns__findtype(adns_rrtype type) { |
| 56 | const typeinfo *begin, *end; |
| 57 | |
| 58 | begin= typeinfos; end= typeinfos+(sizeof(typeinfos)/sizeof(typeinfo)); |
| 59 | |
| 60 | while (begin < end) { |
| 61 | mid= begin + ((end-begin)>>1); |
| 62 | if (mid->type == type) return mid; |
| 63 | if (type > mid->type) begin= mid+1; |
| 64 | else end= mid; |
| 65 | } |
| 66 | return 0; |
| 67 | } |