summaryrefslogtreecommitdiff
path: root/source3/libaddns/dnsmarshall.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2011-01-06 14:53:04 +0100
committerGünther Deschner <gd@samba.org>2011-01-06 16:42:56 +0100
commit7ee75c95481f0d13598577361d18e96cb8394b9c (patch)
tree9dc79864581847d17d7c74fe63cf3bba6970cced /source3/libaddns/dnsmarshall.c
parent4e0d0af9e89e23a5daea8048deff5c9057f08bb9 (diff)
downloadsamba-7ee75c95481f0d13598577361d18e96cb8394b9c.tar.gz
samba-7ee75c95481f0d13598577361d18e96cb8394b9c.tar.bz2
samba-7ee75c95481f0d13598577361d18e96cb8394b9c.zip
lib/addns: move DNS client library to the main directory.
Guenther
Diffstat (limited to 'source3/libaddns/dnsmarshall.c')
-rw-r--r--source3/libaddns/dnsmarshall.c530
1 files changed, 0 insertions, 530 deletions
diff --git a/source3/libaddns/dnsmarshall.c b/source3/libaddns/dnsmarshall.c
deleted file mode 100644
index 5530290c57..0000000000
--- a/source3/libaddns/dnsmarshall.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- Linux DNS client library implementation
- Copyright (C) 2006 Gerald Carter <jerry@samba.org>
-
- ** NOTE! The following LGPL license applies to the libaddns
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "dns.h"
-#include "assert.h"
-
-struct dns_buffer *dns_create_buffer(TALLOC_CTX *mem_ctx)
-{
- struct dns_buffer *result;
-
- if (!(result = talloc(mem_ctx, struct dns_buffer))) {
- return NULL;
- }
-
- result->offset = 0;
- result->error = ERROR_DNS_SUCCESS;
-
- /*
- * Small inital size to excercise the realloc code
- */
- result->size = 2;
-
- if (!(result->data = TALLOC_ARRAY(result, uint8, result->size))) {
- TALLOC_FREE(result);
- return NULL;
- }
-
- return result;
-}
-
-void dns_marshall_buffer(struct dns_buffer *buf, const uint8 *data,
- size_t len)
-{
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- if (buf->offset + len < buf->offset) {
- /*
- * Wraparound!
- */
- buf->error = ERROR_DNS_INVALID_PARAMETER;
- return;
- }
-
- if ((buf->offset + len) > 0xffff) {
- /*
- * Only 64k possible
- */
- buf->error = ERROR_DNS_INVALID_PARAMETER;
- return;
- }
-
- if (buf->offset + len > buf->size) {
- size_t new_size = buf->offset + len;
- uint8 *new_data;
-
- /*
- * Don't do too many reallocs, round up to some multiple
- */
-
- new_size += (64 - (new_size % 64));
-
- if (!(new_data = TALLOC_REALLOC_ARRAY(buf, buf->data, uint8,
- new_size))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
-
- buf->size = new_size;
- buf->data = new_data;
- }
-
- memcpy(buf->data + buf->offset, data, len);
- buf->offset += len;
- return;
-}
-
-void dns_marshall_uint16(struct dns_buffer *buf, uint16 val)
-{
- uint16 n_val = htons(val);
- dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
-}
-
-void dns_marshall_uint32(struct dns_buffer *buf, uint32 val)
-{
- uint32 n_val = htonl(val);
- dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
-}
-
-void dns_unmarshall_buffer(struct dns_buffer *buf, uint8 *data,
- size_t len)
-{
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- if ((len > buf->size) || (buf->offset + len > buf->size)) {
- buf->error = ERROR_DNS_INVALID_MESSAGE;
- return;
- }
-
- memcpy((void *)data, (const void *)(buf->data + buf->offset), len);
- buf->offset += len;
-
- return;
-}
-
-void dns_unmarshall_uint16(struct dns_buffer *buf, uint16 *val)
-{
- uint16 n_val;
-
- dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- *val = ntohs(n_val);
-}
-
-void dns_unmarshall_uint32(struct dns_buffer *buf, uint32 *val)
-{
- uint32 n_val;
-
- dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val));
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- *val = ntohl(n_val);
-}
-
-void dns_marshall_domain_name(struct dns_buffer *buf,
- const struct dns_domain_name *name)
-{
- struct dns_domain_label *label;
- char end_char = '\0';
-
- /*
- * TODO: Implement DNS compression
- */
-
- for (label = name->pLabelList; label != NULL; label = label->next) {
- uint8 len = label->len;
-
- dns_marshall_buffer(buf, (uint8 *)&len, sizeof(len));
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- dns_marshall_buffer(buf, (uint8 *)label->label, len);
- if (!ERR_DNS_IS_OK(buf->error)) return;
- }
-
- dns_marshall_buffer(buf, (uint8 *)&end_char, 1);
-}
-
-static void dns_unmarshall_label(TALLOC_CTX *mem_ctx,
- int level,
- struct dns_buffer *buf,
- struct dns_domain_label **plabel)
-{
- struct dns_domain_label *label;
- uint8 len;
-
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- if (level > 128) {
- /*
- * Protect against recursion
- */
- buf->error = ERROR_DNS_INVALID_MESSAGE;
- return;
- }
-
- dns_unmarshall_buffer(buf, &len, sizeof(len));
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- if (len == 0) {
- *plabel = NULL;
- return;
- }
-
- if ((len & 0xc0) == 0xc0) {
- /*
- * We've got a compressed name. Build up a new "fake" buffer
- * and using the calculated offset.
- */
- struct dns_buffer new_buf;
- uint8 low;
-
- dns_unmarshall_buffer(buf, &low, sizeof(low));
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- new_buf = *buf;
- new_buf.offset = len & 0x3f;
- new_buf.offset <<= 8;
- new_buf.offset |= low;
-
- dns_unmarshall_label(mem_ctx, level+1, &new_buf, plabel);
- buf->error = new_buf.error;
- return;
- }
-
- if ((len & 0xc0) != 0) {
- buf->error = ERROR_DNS_INVALID_NAME;
- return;
- }
-
- if (!(label = talloc(mem_ctx, struct dns_domain_label))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
-
- label->len = len;
-
- if (!(label->label = TALLOC_ARRAY(label, char, len+1))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- goto error;
- }
-
- dns_unmarshall_buffer(buf, (uint8 *)label->label, len);
- if (!ERR_DNS_IS_OK(buf->error)) goto error;
-
- dns_unmarshall_label(label, level+1, buf, &label->next);
- if (!ERR_DNS_IS_OK(buf->error)) goto error;
-
- *plabel = label;
- return;
-
- error:
- TALLOC_FREE(label);
- return;
-}
-
-void dns_unmarshall_domain_name(TALLOC_CTX *mem_ctx,
- struct dns_buffer *buf,
- struct dns_domain_name **pname)
-{
- struct dns_domain_name *name;
-
- if (!ERR_DNS_IS_OK(buf->error)) return;
-
- if (!(name = talloc(mem_ctx, struct dns_domain_name))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
-
- dns_unmarshall_label(name, 0, buf, &name->pLabelList);
-
- if (!ERR_DNS_IS_OK(buf->error)) {
- return;
- }
-
- *pname = name;
- return;
-}
-
-static void dns_marshall_question(struct dns_buffer *buf,
- const struct dns_question *q)
-{
- dns_marshall_domain_name(buf, q->name);
- dns_marshall_uint16(buf, q->q_type);
- dns_marshall_uint16(buf, q->q_class);
-}
-
-static void dns_unmarshall_question(TALLOC_CTX *mem_ctx,
- struct dns_buffer *buf,
- struct dns_question **pq)
-{
- struct dns_question *q;
-
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- if (!(q = talloc(mem_ctx, struct dns_question))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
-
- dns_unmarshall_domain_name(q, buf, &q->name);
- dns_unmarshall_uint16(buf, &q->q_type);
- dns_unmarshall_uint16(buf, &q->q_class);
-
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- *pq = q;
-}
-
-static void dns_marshall_rr(struct dns_buffer *buf,
- const struct dns_rrec *r)
-{
- dns_marshall_domain_name(buf, r->name);
- dns_marshall_uint16(buf, r->type);
- dns_marshall_uint16(buf, r->r_class);
- dns_marshall_uint32(buf, r->ttl);
- dns_marshall_uint16(buf, r->data_length);
- dns_marshall_buffer(buf, r->data, r->data_length);
-}
-
-static void dns_unmarshall_rr(TALLOC_CTX *mem_ctx,
- struct dns_buffer *buf,
- struct dns_rrec **pr)
-{
- struct dns_rrec *r;
-
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- if (!(r = talloc(mem_ctx, struct dns_rrec))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
-
- dns_unmarshall_domain_name(r, buf, &r->name);
- dns_unmarshall_uint16(buf, &r->type);
- dns_unmarshall_uint16(buf, &r->r_class);
- dns_unmarshall_uint32(buf, &r->ttl);
- dns_unmarshall_uint16(buf, &r->data_length);
- r->data = NULL;
-
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- if (r->data_length != 0) {
- if (!(r->data = TALLOC_ARRAY(r, uint8, r->data_length))) {
- buf->error = ERROR_DNS_NO_MEMORY;
- return;
- }
- dns_unmarshall_buffer(buf, r->data, r->data_length);
- }
-
- if (!(ERR_DNS_IS_OK(buf->error))) return;
-
- *pr = r;
-}
-
-DNS_ERROR dns_marshall_request(TALLOC_CTX *mem_ctx,
- const struct dns_request *req,
- struct dns_buffer **pbuf)
-{
- struct dns_buffer *buf;
- uint16 i;
-
- if (!(buf = dns_create_buffer(mem_ctx))) {
- return ERROR_DNS_NO_MEMORY;
- }
-
- dns_marshall_uint16(buf, req->id);
- dns_marshall_uint16(buf, req->flags);
- dns_marshall_uint16(buf, req->num_questions);
- dns_marshall_uint16(buf, req->num_answers);
- dns_marshall_uint16(buf, req->num_auths);
- dns_marshall_uint16(buf, req->num_additionals);
-
- for (i=0; i<req->num_questions; i++) {
- dns_marshall_question(buf, req->questions[i]);
- }
- for (i=0; i<req->num_answers; i++) {
- dns_marshall_rr(buf, req->answers[i]);
- }
- for (i=0; i<req->num_auths; i++) {
- dns_marshall_rr(buf, req->auths[i]);
- }
- for (i=0; i<req->num_additionals; i++) {
- dns_marshall_rr(buf, req->additionals[i]);
- }
-
- if (!ERR_DNS_IS_OK(buf->error)) {
- DNS_ERROR err = buf->error;
- TALLOC_FREE(buf);
- return err;
- }
-
- *pbuf = buf;
- return ERROR_DNS_SUCCESS;
-}
-
-DNS_ERROR dns_unmarshall_request(TALLOC_CTX *mem_ctx,
- struct dns_buffer *buf,
- struct dns_request **preq)
-{
- struct dns_request *req;
- uint16 i;
- DNS_ERROR err;
-
- if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_request))) {
- return ERROR_DNS_NO_MEMORY;
- }
-
- dns_unmarshall_uint16(buf, &req->id);
- dns_unmarshall_uint16(buf, &req->flags);
- dns_unmarshall_uint16(buf, &req->num_questions);
- dns_unmarshall_uint16(buf, &req->num_answers);
- dns_unmarshall_uint16(buf, &req->num_auths);
- dns_unmarshall_uint16(buf, &req->num_additionals);
-
- if (!ERR_DNS_IS_OK(buf->error)) goto error;
-
- err = ERROR_DNS_NO_MEMORY;
-
- if ((req->num_questions != 0) &&
- !(req->questions = TALLOC_ARRAY(req, struct dns_question *,
- req->num_questions))) {
- goto error;
- }
- if ((req->num_answers != 0) &&
- !(req->answers = TALLOC_ARRAY(req, struct dns_rrec *,
- req->num_answers))) {
- goto error;
- }
- if ((req->num_auths != 0) &&
- !(req->auths = TALLOC_ARRAY(req, struct dns_rrec *,
- req->num_auths))) {
- goto error;
- }
- if ((req->num_additionals != 0) &&
- !(req->additionals = TALLOC_ARRAY(req, struct dns_rrec *,
- req->num_additionals))) {
- goto error;
- }
-
- for (i=0; i<req->num_questions; i++) {
- dns_unmarshall_question(req->questions, buf,
- &req->questions[i]);
- }
- for (i=0; i<req->num_answers; i++) {
- dns_unmarshall_rr(req->answers, buf,
- &req->answers[i]);
- }
- for (i=0; i<req->num_auths; i++) {
- dns_unmarshall_rr(req->auths, buf,
- &req->auths[i]);
- }
- for (i=0; i<req->num_additionals; i++) {
- dns_unmarshall_rr(req->additionals, buf,
- &req->additionals[i]);
- }
-
- if (!ERR_DNS_IS_OK(buf->error)) {
- err = buf->error;
- goto error;
- }
-
- *preq = req;
- return ERROR_DNS_SUCCESS;
-
- error:
- err = buf->error;
- TALLOC_FREE(req);
- return err;
-}
-
-struct dns_request *dns_update2request(struct dns_update_request *update)
-{
- struct dns_request *req;
-
- /*
- * This is a non-specified construct that happens to work on Linux/gcc
- * and I would expect it to work everywhere else. dns_request and
- * dns_update_request are essentially the same structures with
- * different names, so any difference would mean that the compiler
- * applied two different variations of padding given the same types in
- * the structures.
- */
-
- req = (struct dns_request *)(void *)update;
-
- /*
- * The assert statement here looks like we could do the equivalent
- * assignments to get portable, but it would mean that we have to
- * allocate the dns_question record for the dns_zone records. We
- * assume that if this assert works then the same holds true for
- * dns_zone<>dns_question as well.
- */
-
-#ifdef DEVELOPER
- assert((req->id == update->id) && (req->flags == update->flags) &&
- (req->num_questions == update->num_zones) &&
- (req->num_answers == update->num_preqs) &&
- (req->num_auths == update->num_updates) &&
- (req->num_additionals == update->num_additionals) &&
- (req->questions ==
- (struct dns_question **)(void *)update->zones) &&
- (req->answers == update->preqs) &&
- (req->auths == update->updates) &&
- (req->additionals == update->additionals));
-#endif
-
- return req;
-}
-
-struct dns_update_request *dns_request2update(struct dns_request *request)
-{
- /*
- * For portability concerns see dns_update2request;
- */
- return (struct dns_update_request *)(void *)request;
-}
-
-DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx,
- struct dns_update_request *update,
- struct dns_buffer **pbuf)
-{
- return dns_marshall_request(mem_ctx, dns_update2request(update), pbuf);
-}
-
-DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx,
- struct dns_buffer *buf,
- struct dns_update_request **pupreq)
-{
- /*
- * See comments above about portability. If the above works, this will
- * as well.
- */
-
- return dns_unmarshall_request(mem_ctx, buf,
- (struct dns_request **)(void *)pupreq);
-}
-
-uint16 dns_response_code(uint16 flags)
-{
- return flags & 0xF;
-}