3 * - RR-type-specific code, and the machinery to call it
6 * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
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)
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.
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.
23 #include <arpa/inet.h>
27 static adns_status
pa_inaddr(adns_query qu
, int serv
,
28 const byte
*dgram
, int dglen
, int cbyte
, int max
,
30 struct in_addr
*dr
= store_r
;
32 if (max
-cbyte
!= 4) return adns_s_invaliddata
;
33 memcpy(dr
,dgram
+cbyte
,4);
37 static adns_status
cs_inaddr(vbuf
*vb
, const void *data
) {
38 const struct in_addr
*dp
= data
;
41 ia
= inet_ntoa(*dp
); assert(ia
);
42 return adns__vbuf_appendstr(vb
,ia
) ? adns_s_ok
: adns_s_nolocalmem
;
45 static void fr_null(adns_query qu
, void *data
) { }
47 #define TYPE_SF(size,func,cp,free) size, pa_##func, fr_##free, cs_##cp
48 #define TYPE_SN(size,func,cp) size, pa_##func, fr_null, cs_##cp
49 #define TYPESZ_M(member) (sizeof(((adns_answer*)0)->rrs.member))
50 #define TYPE_MF(memb,parse) TYPE_SF(TYPESZ_M(memb),parse,memb,memb)
51 #define TYPE_MN(memb,parse) TYPE_SN(TYPESZ_M(memb),parse,memb)
53 #define DEEP_MEMB(memb) TYPESZ_M(memb), fr_##memb, cs_##memb
54 #define FLAT_MEMB(memb) TYPESZ_M(memb), fr_null, cs_##memb
55 #define NULL_MEMB 0, fr_null, cs_null
58 * ms is M specify member name
59 * or S specify size explicitly
60 * nf is F full memory management, dependent on member name or specified func
61 * N no memory management required
64 static const typeinfo typeinfos
[] = {
65 /* Must be in ascending order of rrtype ! */
66 /* rr type code rrt fmt mem.mgmt member parser */
68 { adns_r_a
, "A", 0, FLAT_MEMB(inaddr
), pa_inaddr
},
70 { adns_r_ns_raw
, "NS", "raw", DEEP_MEMB(str
), pa_domain_raw
},
71 { adns_r_cname
, "CNAME", 0, DEEP_MEMB(str
), pa_domain_raw
},
72 { adns_r_soa_raw
, "SOA", "raw", DEEP_MEMB(soa
), pa_soa
},
73 { adns_r_null
, "NULL", 0, NULL_MEMB
, pa_null
},
74 { adns_r_ptr_raw
, "PTR", "raw", DEEP_MEMB(str
), pa_domain_raw
},
75 { adns_r_hinfo
, "HINFO", 0, DEEP_MEMB(strpair
), pa_hinfo
},
76 { adns_r_mx_raw
, "MX", "raw", DEEP_MEMB(intstr
), pa_mx_raw
},
77 { adns_r_txt
, "TXT", 0, DEEP_MEMB(str
), pa_txt
},
78 { adns_r_rp_raw
, "RP", "raw", DEEP_MEMB(strpair
), pa_rp
},
80 { adns_r_ns
, "NS", "+addr", DEEP_MEMB(dmaddr
), pa_dmaddr
},
81 { adns_r_ptr
, "PTR", "checked", DEEP_MEMB(str
), pa_ptr
},
82 { adns_r_mx
, "MX", "+addr", DEEP_MEMB(intdmaddr
), pa_mx
},
84 { adns_r_soa
, "SOA", "822", DEEP_MEMB(soa
), pa_soa
},
85 { adns_r_rp
, "RP", "822", DEEP_MEMB(strpair
), pa_rp
},
89 const typeinfo
*adns__findtype(adns_rrtype type
) {
90 const typeinfo
*begin
, *end
, *mid
;
92 begin
= typeinfos
; end
= typeinfos
+(sizeof(typeinfos
)/sizeof(typeinfo
));
95 mid
= begin
+ ((end
-begin
)>>1);
96 if (mid
->type
== type
) return mid
;
97 if (type
> mid
->type
) begin
= mid
+1;