/****************************************************************************
* 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: conv_stf.c,v 3.21 2005/07/04 09:09:22 dillema Exp $>
*/
#include "totd.h"
#define STF_SUFFIX "\0012\0010\0010\0012\003ip6\003int"
#define STF_PREFIX "2002"
#define STF_BYTES 2
RRset *conv_stf_owner_rrset (RRset *rrs) {
const char *fn = "conv_stf_owner_rrset()";
u_char owner[MAX_DNAME], str[MAX_DNAME];
u_char *own, *ostop, *op;
int owner_len, i, val;
RRset *rrs_new = NULL;
RR_List *rrl;
char buf[4];
syslog (LOG_DEBUG, "%s: start", fn);
if (rrs->key.info->r_type != RT_SOA ||
rrs->key.info->r_type != RT_NS)
return NULL;
/* parse resource record set */
rrl = rr_list_of_rrset (rrs);
if (!rrl)
return NULL;
own = rrset_owner (rrs);
/* XXX need a strdname() routine for this */
ostop = (u_char *) strstr((char *)own, "\007IN-ADDR\004ARPA");
if (!ostop)
ostop = (u_char *)strstr((char *) own, "\007in-addr\004arpa");
if (!ostop) {
/*
* not something we can handle here,
* so don't modify just copy
*/
owner_len = rrs->key.info->owner_len;
memcpy(owner, own, owner_len);
if (T.debug) {
dname_decompress (str, MAX_DNAME, owner,0,0,0);
syslog (LOG_DEBUG, "%s: not a v4 PTR name %s", fn, str);
}
} else {
op = owner;
while (own < ostop) {
for (i = 0; i < *own; i++)
buf[i] = *(own + i + 1);
buf[i] = '\0';
sscanf(buf, "%u", &val);
snprintf(buf, sizeof(buf), "%02x", val & 0xff);
/* length: one nybble is one character */
*op = *(op+2) = '\1';
/* least significant nybble */
*(op+1) = buf[1];
/* most significant nybble */
*(op+3) = buf[0];
op += 4;
own += *own + 1;
}
sprintf((char *)op, "%s", STF_SUFFIX);
/* point to end (after null char) */
op += strlen(STF_SUFFIX) + 1;
owner_len = op - owner;
if (T.debug) {
dname_decompress (str, MAX_DNAME, owner, 0,0,0);
syslog (LOG_DEBUG, "%s: converted PTR %s", fn, owner);
}
}
/* assemble new rrset */
rrs_new = rrset_create (rrs->key.info->r_type,
rrs->key.info->r_class,
owner_len, owner, rrl);
rr_list_free (rrl);
syslog (LOG_DEBUG, "%s: rrs_new %p", fn, (void *)rrs_new);
return (rrs_new);
}
void conv_stf_ns_list (G_List *rrsl) {
const char *fn = "conv_stf_ns_list()";
RRset *rrsp, *rrsp_tmp;
G_List *gl_tmp;
syslog (LOG_DEBUG, "%s: start", fn);
rrsp_tmp = NULL;
rrsl->list_data = NULL;
for (gl_tmp = rrsl->next; gl_tmp->list_data; gl_tmp = gl_tmp->next) {
rrsp = (RRset *) gl_tmp->list_data;
syslog (LOG_DEBUG, "%s: type %s", fn,
string_rtype(rrsp->key.info->r_type));
if (rrsp->key.info->r_type == RT_SOA)
rrsp_tmp = conv_stf_owner_rrset (rrsp);
if (rrsp->key.info->r_type == RT_NS)
rrsp_tmp = conv_stf_owner_rrset (rrsp);
if (rrsp_tmp) {
rrset_free (rrsp);
gl_tmp->list_data = rrsp_tmp;
rrsp_tmp = NULL;
}
}
return;
}
int conv_stf_ptr (u_char *qname) {
const char *fn = "conv_stf_ptr()";
const int off = sizeof(struct in_addr) + STF_BYTES;
u_char qname4[MAX_DNAME], str[MAX_DNAME];
u_char *qn6, *qn4;
int val, qname_len;
syslog (LOG_DEBUG, "%s: start", fn);
/* to small to convert? */
if (strlen((char *)qname) < 8)
return -1;
qn4 = qname4;
qname_len = strlen((char *)qname) + 1;
qn6 = qname + qname_len - off*4 - 8;
if (qn6 < qname)
qn6 = qname + 1;
while (qn6 < qname + qname_len - STF_BYTES*4 - 8) {
val = 0;
if (isdigit(*qn6))
val = *qn6 - '0';
else if (isalpha(*qn6))
val = *qn6 - (isupper(*qn6) ? 'A' - 10 : 'a' - 10);
qn6++;
if (*qn6 != 1) return -1;
qn6++;
if (isdigit(*qn6))
val += 16 * (*qn6 - '0');
else if (isalpha(*qn6))
val += 16 * (*qn6 - (isupper(*qn6) ? 'A'-10 : 'a'-10));
qn6++;
if (*qn6 != 1) return -1;
qn6++;
*qn4 = snprintf((char *)qn4 + 1, 4, "%u", val & 0xff);
qn4 = qn4 + *qn4 + 1;
}
sprintf((char *)qn4, "%s", "\007in-addr\004arpa");
strlcpy((char *)qname, (char *)qname4, MAX_DNAME);
if (T.debug) {
dname_decompress (str, MAX_DNAME, qname, NULL, NULL, NULL);
syslog (LOG_DEBUG, "%s: converted name %s", fn, str);
}
return 0;
}
/*
* returns 1 if netprefix of qname equals stf prefix, else returns 0
*/
int conv_stf_is_stf_ptr (u_char *qname) {
u_char *qname6;
/* first check it's a PTR name, if not return 0 */
if (!(strstr((char *)qname, "INT") || strstr((char *)qname, "int")))
return 0;
qname6 = (u_char *) strstr((char *)qname, "IP6");
if (!qname6)
qname6 = (u_char *) strstr((char *)qname, "ip6");
if (!qname6)
return 0;
qname6 = qname6 - 2;
if (*qname6-- != '2')
return 0;
if (*qname6-- != 1)
return 0;
if (*qname6-- != '0')
return 0;
if (*qname6-- != 1)
return 0;
if (*qname6-- != '0')
return 0;
if (*qname6-- != 1)
return 0;
if (*qname6-- != '2')
return 0;
if (*qname6-- != 1)
return 0;
return 1; /* we matched 0x2002 */
}
syntax highlighted by Code2HTML, v. 0.9.1