00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <ldns/config.h>
00016
00017 #include <ldns/ldns.h>
00018
00019
00020
00021
00022
00023
00024
00025
00026 ldns_status
00027 ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name)
00028 {
00029 if (ldns_buffer_reserve(buffer, ldns_rdf_size(name))) {
00030 ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name));
00031 }
00032 return ldns_buffer_status(buffer);
00033 }
00034
00035 ldns_status
00036 ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
00037 {
00038 if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
00039 ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
00040 }
00041 return ldns_buffer_status(buffer);
00042 }
00043
00044
00045 ldns_status
00046 ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
00047 {
00048 uint16_t rr_count;
00049 uint16_t i;
00050
00051 rr_count = ldns_rr_list_rr_count(rr_list);
00052 for(i = 0; i < rr_count; i++) {
00053 (void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i),
00054 LDNS_SECTION_ANY);
00055 }
00056 return ldns_buffer_status(buffer);
00057 }
00058
00059 ldns_status
00060 ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
00061 {
00062 uint16_t i;
00063 uint16_t rdl_pos = 0;
00064
00065 if (ldns_rr_owner(rr)) {
00066 (void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr));
00067 }
00068
00069 if (ldns_buffer_reserve(buffer, 4)) {
00070 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00071 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00072 }
00073
00074 if (section != LDNS_SECTION_QUESTION) {
00075 if (ldns_buffer_reserve(buffer, 6)) {
00076 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00077
00078 rdl_pos = ldns_buffer_position(buffer);
00079 ldns_buffer_write_u16(buffer, 0);
00080 }
00081
00082 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00083 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00084 }
00085
00086 if (rdl_pos != 0) {
00087 ldns_buffer_write_u16_at(buffer, rdl_pos,
00088 ldns_buffer_position(buffer)
00089 - rdl_pos - 2);
00090 }
00091 }
00092 return ldns_buffer_status(buffer);
00093 }
00094
00095 ldns_status
00096 ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00097 {
00098 uint16_t i;
00099
00100
00101 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00102 return LDNS_STATUS_ERR;
00103 }
00104
00105
00106
00107 for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
00108 if (ldns_rr_rdf(rr, i)) {
00109 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00110 }
00111 }
00112
00113 return ldns_buffer_status(buffer);
00114 }
00115
00116 ldns_status
00117 ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00118 {
00119 uint16_t i;
00120
00121 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00122 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00123 }
00124
00125 return ldns_buffer_status(buffer);
00126 }
00127
00128
00129
00130
00131 static ldns_status
00132 ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00133 {
00134 uint8_t flags;
00135 uint16_t arcount;
00136
00137 if (ldns_buffer_reserve(buffer, 12)) {
00138 ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
00139
00140 flags = ldns_pkt_qr(packet) << 7
00141 | ldns_pkt_get_opcode(packet) << 3
00142 | ldns_pkt_aa(packet) << 2
00143 | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
00144 ldns_buffer_write_u8(buffer, flags);
00145
00146 flags = ldns_pkt_ra(packet) << 7
00147
00148 | ldns_pkt_ad(packet) << 5
00149 | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet);
00150 ldns_buffer_write_u8(buffer, flags);
00151
00152 ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
00153 ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
00154 ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
00155
00156 arcount = ldns_pkt_arcount(packet);
00157 if (ldns_pkt_tsig(packet)) {
00158 arcount++;
00159 }
00160 if (ldns_pkt_edns(packet)) {
00161 arcount++;
00162 }
00163 ldns_buffer_write_u16(buffer, arcount);
00164 }
00165
00166 return ldns_buffer_status(buffer);
00167 }
00168
00169 ldns_status
00170 ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00171 {
00172 ldns_rr_list *rr_list;
00173 uint16_t i;
00174
00175
00176 ldns_rr *edns_rr;
00177 uint8_t edata[4];
00178
00179 (void) ldns_hdr2buffer_wire(buffer, packet);
00180
00181 rr_list = ldns_pkt_question(packet);
00182 if (rr_list) {
00183 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00184 (void) ldns_rr2buffer_wire(buffer,
00185 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
00186 }
00187 }
00188 rr_list = ldns_pkt_answer(packet);
00189 if (rr_list) {
00190 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00191 (void) ldns_rr2buffer_wire(buffer,
00192 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
00193 }
00194 }
00195 rr_list = ldns_pkt_authority(packet);
00196 if (rr_list) {
00197 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00198 (void) ldns_rr2buffer_wire(buffer,
00199 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
00200 }
00201 }
00202 rr_list = ldns_pkt_additional(packet);
00203 if (rr_list) {
00204 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00205 (void) ldns_rr2buffer_wire(buffer,
00206 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
00207 }
00208 }
00209
00210
00211 if (ldns_pkt_edns(packet)) {
00212 edns_rr = ldns_rr_new();
00213 ldns_rr_set_owner(edns_rr,
00214 ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
00215 ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
00216 ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
00217 edata[0] = ldns_pkt_edns_extended_rcode(packet);
00218 edata[1] = ldns_pkt_edns_version(packet);
00219 ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
00220 ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
00221 (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
00222 ldns_rr_free(edns_rr);
00223 }
00224
00225
00226 if (ldns_pkt_tsig(packet)) {
00227 (void) ldns_rr2buffer_wire(buffer,
00228 ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
00229 }
00230
00231 return LDNS_STATUS_OK;
00232 }
00233
00234 ldns_status
00235 ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
00236 {
00237 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00238 uint8_t *result = NULL;
00239 ldns_status status;
00240 *result_size = 0;
00241 *dest = NULL;
00242
00243 status = ldns_rdf2buffer_wire(buffer, rdf);
00244 if (status == LDNS_STATUS_OK) {
00245 *result_size = ldns_buffer_position(buffer);
00246 result = (uint8_t *) ldns_buffer_export(buffer);
00247 } else {
00248 return status;
00249 }
00250
00251 if (result) {
00252 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00253 memcpy(*dest, result, ldns_buffer_position(buffer));
00254 }
00255
00256 ldns_buffer_free(buffer);
00257 return status;
00258 }
00259
00260 ldns_status
00261 ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
00262 {
00263 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00264 uint8_t *result = NULL;
00265 ldns_status status;
00266 *result_size = 0;
00267 *dest = NULL;
00268
00269 status = ldns_rr2buffer_wire(buffer, rr, section);
00270 if (status == LDNS_STATUS_OK) {
00271 *result_size = ldns_buffer_position(buffer);
00272 result = (uint8_t *) ldns_buffer_export(buffer);
00273 } else {
00274 return status;
00275 }
00276
00277 if (result) {
00278 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00279 memcpy(*dest, result, ldns_buffer_position(buffer));
00280 }
00281
00282 ldns_buffer_free(buffer);
00283 return status;
00284 }
00285
00286 ldns_status
00287 ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
00288 {
00289 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00290 uint8_t *result = NULL;
00291 ldns_status status;
00292 *result_size = 0;
00293 *dest = NULL;
00294
00295 status = ldns_pkt2buffer_wire(buffer, packet);
00296 if (status == LDNS_STATUS_OK) {
00297 *result_size = ldns_buffer_position(buffer);
00298 result = (uint8_t *) ldns_buffer_export(buffer);
00299 } else {
00300 return status;
00301 }
00302
00303 if (result) {
00304 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00305 memcpy(*dest, result, ldns_buffer_position(buffer));
00306 }
00307
00308 ldns_buffer_free(buffer);
00309 return status;
00310 }