| 1 | /* |
| 2 | * types.c |
| 3 | * - RR-type-specific code, and the machinery to call it |
| 4 | */ |
| 5 | /* |
| 6 | * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2, or (at your option) |
| 11 | * any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software Foundation, |
| 20 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 21 | */ |
| 22 | |
| 23 | #include "internal.h" |
| 24 | |
| 25 | static adns_status rp_inaddr(adns_query qu, int serv, |
| 26 | const byte *dgram, int dglen, int cbyte, int max, |
| 27 | void *store_r) { |
| 28 | struct in_addr *dr= store_r; |
| 29 | |
| 30 | if (max-cbyte != 4) return adns_s_invaliddata; |
| 31 | memcpy(dr,dgram+cbyte,4); |
| 32 | return adns_s_ok; |
| 33 | } |
| 34 | |
| 35 | static void rmf_null(adns_query qu, void *data) { } |
| 36 | |
| 37 | #define TYPE_SF(size,func,free) size, rp_##func, rmf_##free |
| 38 | #define TYPE_SN(size,func) size, rp_##func, rmf_null |
| 39 | #define TYPESZ_M(member) (sizeof(((adns_answer*)0)->rrs.member)) |
| 40 | #define TYPE_MF(member,parse) TYPE_SF(TYPESZ_M(member),parse,member) |
| 41 | #define TYPE_MN(member,parse) TYPE_SN(TYPESZ_M(member),parse) |
| 42 | |
| 43 | /* TYPE_<ms><nf> |
| 44 | * ms is M specify member name |
| 45 | * or S specify size explicitly |
| 46 | * nf is F full memory management, dependent on member name or specified func |
| 47 | * N no memory management required |
| 48 | */ |
| 49 | |
| 50 | static const typeinfo typeinfos[] = { |
| 51 | /* Must be in ascending order of rrtype ! */ |
| 52 | /* rr type code name style member size parser */ |
| 53 | |
| 54 | { adns_r_a, "A", TYPE_MN( inaddr, inaddr ) }, |
| 55 | #if 0 /*fixme*/ |
| 56 | { adns_r_ns_raw, "NS(raw)", TYPE_MF( str, domain_raw ) }, |
| 57 | { adns_r_cname, "CNAME", TYPE_MF( str, domain_raw ) }, |
| 58 | { adns_r_soa_raw, "SOA(raw)", TYPE_MF( soa, soa ) }, |
| 59 | { adns_r_null, "NULL", TYPE_SN( 0, null ) }, |
| 60 | { adns_r_ptr_raw, "PTR(raw)", TYPE_MF( str, domain_raw ) }, |
| 61 | { adns_r_hinfo, "HINFO", TYPE_MF( strpair, hinfo ) }, |
| 62 | { adns_r_mx_raw, "MX(raw)", TYPE_MF( intstr, mx_raw ) }, |
| 63 | { adns_r_txt, "TXT", TYPE_MF( str, txt ) }, |
| 64 | { adns_r_rp_raw, "RP(raw)", TYPE_MF( strpair, rp ) }, |
| 65 | |
| 66 | { adns_r_ns, "NS(+addr)", TYPE_MF( dmaddr, dmaddr ) }, |
| 67 | { adns_r_ptr, "PTR(checked)", TYPE_MF( str, ptr ) }, |
| 68 | { adns_r_mx, "MX(+addr)", TYPE_MF( intdmaddr, mx ) }, |
| 69 | |
| 70 | { adns_r_soa, "SOA(822)", TYPE_MF( soa, soa ) }, |
| 71 | { adns_r_rp, "RP(822)", TYPE_MF( strpair, rp ) }, |
| 72 | #endif |
| 73 | }; |
| 74 | |
| 75 | const typeinfo *adns__findtype(adns_rrtype type) { |
| 76 | const typeinfo *begin, *end, *mid; |
| 77 | |
| 78 | begin= typeinfos; end= typeinfos+(sizeof(typeinfos)/sizeof(typeinfo)); |
| 79 | |
| 80 | while (begin < end) { |
| 81 | mid= begin + ((end-begin)>>1); |
| 82 | if (mid->type == type) return mid; |
| 83 | if (type > mid->type) begin= mid+1; |
| 84 | else end= mid; |
| 85 | } |
| 86 | return 0; |
| 87 | } |