00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dns.h"
00026 #include "assert.h"
00027
00028 struct dns_buffer *dns_create_buffer(TALLOC_CTX *mem_ctx)
00029 {
00030 struct dns_buffer *result;
00031
00032 if (!(result = talloc(mem_ctx, struct dns_buffer))) {
00033 return NULL;
00034 }
00035
00036 result->offset = 0;
00037 result->error = ERROR_DNS_SUCCESS;
00038
00039
00040
00041
00042 result->size = 2;
00043
00044 if (!(result->data = TALLOC_ARRAY(result, uint8, result->size))) {
00045 TALLOC_FREE(result);
00046 return NULL;
00047 }
00048
00049 return result;
00050 }
00051
00052 void dns_marshall_buffer(struct dns_buffer *buf, const uint8 *data,
00053 size_t len)
00054 {
00055 if (!ERR_DNS_IS_OK(buf->error)) return;
00056
00057 if (buf->offset + len < buf->offset) {
00058
00059
00060
00061 buf->error = ERROR_DNS_INVALID_PARAMETER;
00062 return;
00063 }
00064
00065 if ((buf->offset + len) > 0xffff) {
00066
00067
00068
00069 buf->error = ERROR_DNS_INVALID_PARAMETER;
00070 return;
00071 }
00072
00073 if (buf->offset + len > buf->size) {
00074 size_t new_size = buf->offset + len;
00075 uint8 *new_data;
00076
00077
00078
00079
00080
00081 new_size += (64 - (new_size % 64));
00082
00083 if (!(new_data = TALLOC_REALLOC_ARRAY(buf, buf->data, uint8,
00084 new_size))) {
00085 buf->error = ERROR_DNS_NO_MEMORY;
00086 return;
00087 }
00088
00089 buf->size = new_size;
00090 buf->data = new_data;
00091 }
00092
00093 memcpy(buf->data + buf->offset, data, len);
00094 buf->offset += len;
00095 return;
00096 }
00097
00098 void dns_marshall_uint16(struct dns_buffer *buf, uint16 val)
00099 {
00100 uint16 n_val = htons(val);
00101 dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
00102 }
00103
00104 void dns_marshall_uint32(struct dns_buffer *buf, uint32 val)
00105 {
00106 uint32 n_val = htonl(val);
00107 dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
00108 }
00109
00110 void dns_unmarshall_buffer(struct dns_buffer *buf, uint8 *data,
00111 size_t len)
00112 {
00113 if (!(ERR_DNS_IS_OK(buf->error))) return;
00114
00115 if ((len > buf->size) || (buf->offset + len > buf->size)) {
00116 buf->error = ERROR_DNS_INVALID_MESSAGE;
00117 return;
00118 }
00119
00120 memcpy((void *)data, (const void *)(buf->data + buf->offset), len);
00121 buf->offset += len;
00122
00123 return;
00124 }
00125
00126 void dns_unmarshall_uint16(struct dns_buffer *buf, uint16 *val)
00127 {
00128 uint16 n_val;
00129
00130 dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
00131 if (!(ERR_DNS_IS_OK(buf->error))) return;
00132
00133 *val = ntohs(n_val);
00134 }
00135
00136 void dns_unmarshall_uint32(struct dns_buffer *buf, uint32 *val)
00137 {
00138 uint32 n_val;
00139
00140 dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
00141 if (!(ERR_DNS_IS_OK(buf->error))) return;
00142
00143 *val = ntohl(n_val);
00144 }
00145
00146 void dns_marshall_domain_name(struct dns_buffer *buf,
00147 const struct dns_domain_name *name)
00148 {
00149 struct dns_domain_label *label;
00150 char end_char = '\0';
00151
00152
00153
00154
00155
00156 for (label = name->pLabelList; label != NULL; label = label->next) {
00157 uint8 len = label->len;
00158
00159 dns_marshall_buffer(buf, (uint8 *)&len, sizeof(len));
00160 if (!ERR_DNS_IS_OK(buf->error)) return;
00161
00162 dns_marshall_buffer(buf, (uint8 *)label->label, len);
00163 if (!ERR_DNS_IS_OK(buf->error)) return;
00164 }
00165
00166 dns_marshall_buffer(buf, (uint8 *)&end_char, 1);
00167 }
00168
00169 static void dns_unmarshall_label(TALLOC_CTX *mem_ctx,
00170 int level,
00171 struct dns_buffer *buf,
00172 struct dns_domain_label **plabel)
00173 {
00174 struct dns_domain_label *label;
00175 uint8 len;
00176
00177 if (!ERR_DNS_IS_OK(buf->error)) return;
00178
00179 if (level > 128) {
00180
00181
00182
00183 buf->error = ERROR_DNS_INVALID_MESSAGE;
00184 return;
00185 }
00186
00187 dns_unmarshall_buffer(buf, &len, sizeof(len));
00188 if (!ERR_DNS_IS_OK(buf->error)) return;
00189
00190 if (len == 0) {
00191 *plabel = NULL;
00192 return;
00193 }
00194
00195 if ((len & 0xc0) == 0xc0) {
00196
00197
00198
00199
00200 struct dns_buffer new_buf;
00201 uint8 low;
00202
00203 dns_unmarshall_buffer(buf, &low, sizeof(low));
00204 if (!ERR_DNS_IS_OK(buf->error)) return;
00205
00206 new_buf = *buf;
00207 new_buf.offset = len & 0x3f;
00208 new_buf.offset <<= 8;
00209 new_buf.offset |= low;
00210
00211 dns_unmarshall_label(mem_ctx, level+1, &new_buf, plabel);
00212 buf->error = new_buf.error;
00213 return;
00214 }
00215
00216 if ((len & 0xc0) != 0) {
00217 buf->error = ERROR_DNS_INVALID_NAME;
00218 return;
00219 }
00220
00221 if (!(label = talloc(mem_ctx, struct dns_domain_label))) {
00222 buf->error = ERROR_DNS_NO_MEMORY;
00223 return;
00224 }
00225
00226 label->len = len;
00227
00228 if (!(label->label = TALLOC_ARRAY(label, char, len+1))) {
00229 buf->error = ERROR_DNS_NO_MEMORY;
00230 goto error;
00231 }
00232
00233 dns_unmarshall_buffer(buf, (uint8 *)label->label, len);
00234 if (!ERR_DNS_IS_OK(buf->error)) goto error;
00235
00236 dns_unmarshall_label(label, level+1, buf, &label->next);
00237 if (!ERR_DNS_IS_OK(buf->error)) goto error;
00238
00239 *plabel = label;
00240 return;
00241
00242 error:
00243 TALLOC_FREE(label);
00244 return;
00245 }
00246
00247 void dns_unmarshall_domain_name(TALLOC_CTX *mem_ctx,
00248 struct dns_buffer *buf,
00249 struct dns_domain_name **pname)
00250 {
00251 struct dns_domain_name *name;
00252
00253 if (!ERR_DNS_IS_OK(buf->error)) return;
00254
00255 if (!(name = talloc(mem_ctx, struct dns_domain_name))) {
00256 buf->error = ERROR_DNS_NO_MEMORY;
00257 }
00258
00259 dns_unmarshall_label(name, 0, buf, &name->pLabelList);
00260
00261 if (!ERR_DNS_IS_OK(buf->error)) {
00262 return;
00263 }
00264
00265 *pname = name;
00266 return;
00267 }
00268
00269 static void dns_marshall_question(struct dns_buffer *buf,
00270 const struct dns_question *q)
00271 {
00272 dns_marshall_domain_name(buf, q->name);
00273 dns_marshall_uint16(buf, q->q_type);
00274 dns_marshall_uint16(buf, q->q_class);
00275 }
00276
00277 static void dns_unmarshall_question(TALLOC_CTX *mem_ctx,
00278 struct dns_buffer *buf,
00279 struct dns_question **pq)
00280 {
00281 struct dns_question *q;
00282
00283 if (!(ERR_DNS_IS_OK(buf->error))) return;
00284
00285 if (!(q = talloc(mem_ctx, struct dns_question))) {
00286 buf->error = ERROR_DNS_NO_MEMORY;
00287 return;
00288 }
00289
00290 dns_unmarshall_domain_name(q, buf, &q->name);
00291 dns_unmarshall_uint16(buf, &q->q_type);
00292 dns_unmarshall_uint16(buf, &q->q_class);
00293
00294 if (!(ERR_DNS_IS_OK(buf->error))) return;
00295
00296 *pq = q;
00297 }
00298
00299 static void dns_marshall_rr(struct dns_buffer *buf,
00300 const struct dns_rrec *r)
00301 {
00302 dns_marshall_domain_name(buf, r->name);
00303 dns_marshall_uint16(buf, r->type);
00304 dns_marshall_uint16(buf, r->r_class);
00305 dns_marshall_uint32(buf, r->ttl);
00306 dns_marshall_uint16(buf, r->data_length);
00307 dns_marshall_buffer(buf, r->data, r->data_length);
00308 }
00309
00310 static void dns_unmarshall_rr(TALLOC_CTX *mem_ctx,
00311 struct dns_buffer *buf,
00312 struct dns_rrec **pr)
00313 {
00314 struct dns_rrec *r;
00315
00316 if (!(ERR_DNS_IS_OK(buf->error))) return;
00317
00318 if (!(r = talloc(mem_ctx, struct dns_rrec))) {
00319 buf->error = ERROR_DNS_NO_MEMORY;
00320 return;
00321 }
00322
00323 dns_unmarshall_domain_name(r, buf, &r->name);
00324 dns_unmarshall_uint16(buf, &r->type);
00325 dns_unmarshall_uint16(buf, &r->r_class);
00326 dns_unmarshall_uint32(buf, &r->ttl);
00327 dns_unmarshall_uint16(buf, &r->data_length);
00328 r->data = NULL;
00329
00330 if (!(ERR_DNS_IS_OK(buf->error))) return;
00331
00332 if (r->data_length != 0) {
00333 if (!(r->data = TALLOC_ARRAY(r, uint8, r->data_length))) {
00334 buf->error = ERROR_DNS_NO_MEMORY;
00335 return;
00336 }
00337 dns_unmarshall_buffer(buf, r->data, r->data_length);
00338 }
00339
00340 if (!(ERR_DNS_IS_OK(buf->error))) return;
00341
00342 *pr = r;
00343 }
00344
00345 DNS_ERROR dns_marshall_request(TALLOC_CTX *mem_ctx,
00346 const struct dns_request *req,
00347 struct dns_buffer **pbuf)
00348 {
00349 struct dns_buffer *buf;
00350 uint16 i;
00351
00352 if (!(buf = dns_create_buffer(mem_ctx))) {
00353 return ERROR_DNS_NO_MEMORY;
00354 }
00355
00356 dns_marshall_uint16(buf, req->id);
00357 dns_marshall_uint16(buf, req->flags);
00358 dns_marshall_uint16(buf, req->num_questions);
00359 dns_marshall_uint16(buf, req->num_answers);
00360 dns_marshall_uint16(buf, req->num_auths);
00361 dns_marshall_uint16(buf, req->num_additionals);
00362
00363 for (i=0; i<req->num_questions; i++) {
00364 dns_marshall_question(buf, req->questions[i]);
00365 }
00366 for (i=0; i<req->num_answers; i++) {
00367 dns_marshall_rr(buf, req->answers[i]);
00368 }
00369 for (i=0; i<req->num_auths; i++) {
00370 dns_marshall_rr(buf, req->auths[i]);
00371 }
00372 for (i=0; i<req->num_additionals; i++) {
00373 dns_marshall_rr(buf, req->additionals[i]);
00374 }
00375
00376 if (!ERR_DNS_IS_OK(buf->error)) {
00377 DNS_ERROR err = buf->error;
00378 TALLOC_FREE(buf);
00379 return err;
00380 }
00381
00382 *pbuf = buf;
00383 return ERROR_DNS_SUCCESS;
00384 }
00385
00386 DNS_ERROR dns_unmarshall_request(TALLOC_CTX *mem_ctx,
00387 struct dns_buffer *buf,
00388 struct dns_request **preq)
00389 {
00390 struct dns_request *req;
00391 uint16 i;
00392 DNS_ERROR err;
00393
00394 if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_request))) {
00395 return ERROR_DNS_NO_MEMORY;
00396 }
00397
00398 dns_unmarshall_uint16(buf, &req->id);
00399 dns_unmarshall_uint16(buf, &req->flags);
00400 dns_unmarshall_uint16(buf, &req->num_questions);
00401 dns_unmarshall_uint16(buf, &req->num_answers);
00402 dns_unmarshall_uint16(buf, &req->num_auths);
00403 dns_unmarshall_uint16(buf, &req->num_additionals);
00404
00405 if (!ERR_DNS_IS_OK(buf->error)) goto error;
00406
00407 err = ERROR_DNS_NO_MEMORY;
00408
00409 if ((req->num_questions != 0) &&
00410 !(req->questions = TALLOC_ARRAY(req, struct dns_question *,
00411 req->num_questions))) {
00412 goto error;
00413 }
00414 if ((req->num_answers != 0) &&
00415 !(req->answers = TALLOC_ARRAY(req, struct dns_rrec *,
00416 req->num_answers))) {
00417 goto error;
00418 }
00419 if ((req->num_auths != 0) &&
00420 !(req->auths = TALLOC_ARRAY(req, struct dns_rrec *,
00421 req->num_auths))) {
00422 goto error;
00423 }
00424 if ((req->num_additionals != 0) &&
00425 !(req->additionals = TALLOC_ARRAY(req, struct dns_rrec *,
00426 req->num_additionals))) {
00427 goto error;
00428 }
00429
00430 for (i=0; i<req->num_questions; i++) {
00431 dns_unmarshall_question(req->questions, buf,
00432 &req->questions[i]);
00433 }
00434 for (i=0; i<req->num_answers; i++) {
00435 dns_unmarshall_rr(req->answers, buf,
00436 &req->answers[i]);
00437 }
00438 for (i=0; i<req->num_auths; i++) {
00439 dns_unmarshall_rr(req->auths, buf,
00440 &req->auths[i]);
00441 }
00442 for (i=0; i<req->num_additionals; i++) {
00443 dns_unmarshall_rr(req->additionals, buf,
00444 &req->additionals[i]);
00445 }
00446
00447 if (!ERR_DNS_IS_OK(buf->error)) {
00448 err = buf->error;
00449 goto error;
00450 }
00451
00452 *preq = req;
00453 return ERROR_DNS_SUCCESS;
00454
00455 error:
00456 err = buf->error;
00457 TALLOC_FREE(req);
00458 return err;
00459 }
00460
00461 struct dns_request *dns_update2request(struct dns_update_request *update)
00462 {
00463 struct dns_request *req;
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 req = (struct dns_request *)(void *)update;
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 #ifdef DEVELOPER
00485 assert((req->id == update->id) && (req->flags == update->flags) &&
00486 (req->num_questions == update->num_zones) &&
00487 (req->num_answers == update->num_preqs) &&
00488 (req->num_auths == update->num_updates) &&
00489 (req->num_additionals == update->num_additionals) &&
00490 (req->questions ==
00491 (struct dns_question **)(void *)update->zones) &&
00492 (req->answers == update->preqs) &&
00493 (req->auths == update->updates) &&
00494 (req->additionals == update->additionals));
00495 #endif
00496
00497 return req;
00498 }
00499
00500 struct dns_update_request *dns_request2update(struct dns_request *request)
00501 {
00502
00503
00504
00505 return (struct dns_update_request *)(void *)request;
00506 }
00507
00508 DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx,
00509 struct dns_update_request *update,
00510 struct dns_buffer **pbuf)
00511 {
00512 return dns_marshall_request(mem_ctx, dns_update2request(update), pbuf);
00513 }
00514
00515 DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx,
00516 struct dns_buffer *buf,
00517 struct dns_update_request **pupreq)
00518 {
00519
00520
00521
00522
00523
00524 return dns_unmarshall_request(mem_ctx, buf,
00525 (struct dns_request **)(void *)pupreq);
00526 }
00527
00528 uint16 dns_response_code(uint16 flags)
00529 {
00530 return flags & 0xF;
00531 }