/****************************************************************************
* Copyright (C) 1998 WIDE Project. All rights reserved.
* Copyright (C) 1999,2000,2001,2002 University of Tromso. All rights reserved.
* Copyright (C) 2002 Invenia Innovation AS. All rights reserved.
*
* Author: Feike W. Dillema, feico@pasta.cs.uit.no.
* based on newbie code by Yusuke DOI, Keio Univ. Murai Lab.
****************************************************************************/
/*
* <$Id: res_record.c,v 3.33 2002/03/06 14:56:02 dillema Exp $>
*/
#include "totd.h"
RR *rr_alloc (uint32_t ttl, int rd_len, u_char *rdata) {
RR *ret;
if (T.debug > 5)
syslog (LOG_DEBUG, "rr_alloc(): start ttl = %d, rd_len = %d", ttl, rd_len);
ret = (RR *) malloc (rd_len + RR_HEAD_LEN);
if (!ret)
return NULL;
ret->ttl = ttl;
ret->rd_len = rd_len;
if (rdata)
memcpy (rr_rdata (ret), rdata, ret->rd_len);
return ret;
}
RR_List *rr_list_alloc (void) {
RR_List *ret;
if (T.debug > 5)
syslog (LOG_DEBUG, "start: rr_list_alloc(void)");
ret = (RR_List *) malloc (sizeof (RR_List));
if (!ret)
return NULL;
ret->next = NULL;
ret->rrp = NULL;
ret->cnt = -1;
return ret;
}
void rr_list_free (RR_List *rrl) {
char *fn = "rr_list_free()";
RR_List *rrl_tmp;
if (!rrl) {
if (T.debug > 5)
syslog (LOG_DEBUG, "%s start: NULL: immediate return", fn);
return;
}
if (T.debug > 5)
syslog (LOG_DEBUG, "%s start: (%p)", fn, rrl);
for ( /* void */ ; rrl->next; rrl = rrl_tmp) {
if (rrl->rrp) {
if (T.debug > 5)
syslog (LOG_DEBUG, "%s: free %p", fn, rrl->rrp);
free (rrl->rrp);
}
rrl_tmp = rrl->next;
free (rrl);
}
free (rrl); /* last watchdog */
return;
}
RR_List *rr_list_add (RR_List *rrl, uint32_t ttl, int rd_len, u_char *rdata) {
RR_List *rrl_tmp;
if (T.debug > 5)
syslog (LOG_DEBUG, "start: rr_list_add(....,ttl=%d,rd_len=%d...)", ttl, rd_len);
rrl_tmp = (RR_List *) malloc (sizeof (RR_List));
if (!rrl_tmp)
return NULL;
rrl_tmp->rrp = rr_alloc (ttl, rd_len, rdata);
if (!rrl_tmp->rrp) {
free (rrl_tmp);
return NULL;
}
rrl_tmp->next = rrl;
rrl_tmp->cnt = rrl->cnt + 1;
return rrl_tmp;
}
RR *rrset_get_rr_f (int n, RRset *rrset) {
uint16_t offset;
offset = *(uint16_t *) ((u_char *) rrset->data.p + DATADATA_HEAD_LEN +
+sizeof (uint16_t) * n);
return (RR *) (((u_char *) rrset->data.p) + offset);
}
RR_List *rr_list_of_rrset (RRset *rrsp) {
RR_List *rrl, *rrl_tmp;
RR *rrp;
int i;
rrl = rr_list_alloc();
if (!rrl)
return NULL;
if (!rrsp->data.p)
return rrl; /* no record -- empty list */
for (i = 0; i < rrsp->data.d->data_cnt; i++) {
rrp = (RR *) (rrsp->data.p + data_offset (i, rrsp->data.d));
rrl_tmp = rr_list_add (rrl, rrp->ttl, rrp->rd_len, rr_rdata (rrp));
if (!rrl_tmp) {
rr_list_free (rrl);
return NULL;
}
rrl = rrl_tmp;
}
return rrl;
}
RRset *rrset_alloc (void) {
RRset *ret;
ret = (RRset *) malloc (sizeof (RRset));
if (!ret)
return NULL;
ret->key_len = 0;
ret->key.p = NULL;
ret->data_len = 0;
ret->data.p = NULL;
ret->links = 1;
if (T.debug > 5)
syslog (LOG_DEBUG, "rrset_alloc(): allocated %p", ret);
return ret;
}
RRset *rrset_create (uint16_t r_type, uint16_t r_class, uint16_t owner_len,
u_char *owner, RR_List *rrl) {
RR_List *rrl_tmp;
int len;
RRset *rrs;
if (T.debug > 5)
syslog (LOG_DEBUG, "start: rrset_create(%s,%s,....)",
string_rtype (r_type), string_rclass (r_class));
rrs = rrset_alloc();
if (!rrs)
return NULL;
/* make key */
len = owner_len + KEYINFO_HEAD_LEN;
rrs->key.p = malloc (len);
if (!rrs->key.p) {
rrset_free (rrs);
return NULL;
}
rrs->key_len = len;
rrs->key.info->r_type = r_type;
rrs->key.info->r_class = r_class;
rrs->key.info->owner_len = owner_len;
memcpy (rrset_owner (rrs), owner, owner_len);
/* return, if no data */
if (!rrl)
return rrs;
/* make data */
len = ((rrl->cnt + 1) * sizeof(uint16_t) + DATADATA_HEAD_LEN);
len += (len % 4 == 0) ? 0 : (4 - len % 4); /* padding */
for (rrl_tmp = rrl; rrl_tmp->next; rrl_tmp = rrl_tmp->next) {
rrl_tmp->offset = len; /* store current data offset */
len += RR_HEAD_LEN + rrl_tmp->rrp->rd_len;
len += (len % 4 == 0) ? 0 : (4 - len % 4);
}
if (T.debug > 5)
syslog (LOG_DEBUG, "rrset_create: final length %d", len);
rrs->data.p = malloc (len);
if (!rrs->data.p) {
rrset_free (rrs);
return NULL;
}
rrs->data_len = len;
/* write RRs */
rrs->data.d->data_cnt = rrl->cnt + 1; /* because zero origin */
for (rrl_tmp = rrl; rrl_tmp->next; rrl_tmp = rrl_tmp->next) {
data_offset (rrl_tmp->cnt, rrs->data.p) = rrl_tmp->offset;
memcpy (rrs->data.p + rrl_tmp->offset, (u_char *) rrl_tmp->rrp, rrl_tmp->rrp->rd_len + RR_HEAD_LEN);
}
return rrs;
}
RRset *rrset_create_single (u_char *dname, int dname_len, uint16_t rtype,
uint16_t rclass, uint32_t ttl, uint16_t rd_len,
u_char *rd) {
RR_List *rrlp;
RR_List *rrlp_tmp;
RRset *rrsp;
rrlp = rr_list_alloc ();
if (!rrlp)
return NULL;
rrlp_tmp = rr_list_add (rrlp, ttl, rd_len, rd);
if (!rrlp_tmp) {
rr_list_free (rrlp);
return NULL;
}
rrlp = rrlp_tmp;
rrsp = rrset_create (rtype, rclass, dname_len, dname, rrlp);
if (!rrsp) {
rr_list_free (rrlp);
return NULL;
}
rr_list_free (rrlp);
return rrsp;
}
void rrset_freev (void *p) {
rrset_free ((RRset *) p);
return;
}
void rrset_free (RRset *rrset) {
if (rrset->links <= 1) {
if (T.debug > 5)
syslog (LOG_DEBUG, "rrset_free(%p): link %d -> destroyed",
rrset, rrset->links);
if (rrset->key.p)
free (rrset->key.p);
if (rrset->data.p)
free (rrset->data.p);
free (rrset);
} else {
if (T.debug > 5)
syslog (LOG_DEBUG, "rrset_free(%p): link %d -> %d",
rrset, rrset->links, rrset->links - 1);
rrset->links--;
}
}
RRset *rrset_copy (RRset *rrset) {
if (T.debug > 5)
syslog (LOG_DEBUG, "rrset_copy(%p): link %d -> %d", rrset,
rrset->links, rrset->links + 1);
rrset->links++;
return rrset;
}
void *rrset_copyv (void *rrsetv) {
return (void *) rrset_copy ((RRset *) rrsetv);
}
void *rrset_dupv (void *rrsetv) {
return (void *) rrset_dup ((RRset *) rrsetv);
}
RRset *rrset_dup (RRset *rrset) {
RRset *rrsp_new = NULL;
rrsp_new = rrset_alloc ();
if (!rrsp_new)
return NULL;
rrsp_new->key.p = NULL;
rrsp_new->data.p = NULL;
if (rrset->key.p) {
rrsp_new->key.p = malloc (rrset->key_len);
if (!rrsp_new->key.p) {
free (rrsp_new);
return NULL;
}
memcpy (rrsp_new->key.p, rrset->key.p, rrset->key_len);
rrsp_new->key_len = rrset->key_len;
}
if (rrset->data.p) {
rrsp_new->data.p = malloc (rrset->data_len);
if (!rrsp_new->data.p) {
if (rrsp_new->key.p)
free (rrsp_new->key.p);
free (rrsp_new);
return NULL;
}
memcpy (rrsp_new->data.p, rrset->data.p, rrset->data_len);
rrsp_new->data_len = rrset->data_len;
}
return rrsp_new;
}
void rrset_couple_free (RRset_Couple * rc) {
if (rc->rrs)
rrset_free (rc->rrs);
if (rc->rrl)
rr_list_free (rc->rrl);
free (rc);
}
void rrset_couple_freev (void *rcv) {
rrset_couple_free ((RRset_Couple *) rcv);
}
syntax highlighted by Code2HTML, v. 0.9.1