Exemple #1
0
int
d_a_p(dns_pkt_a * dpa, char *buf, int limitlen)
{
	int offset, rdlen;
	uint16_t u;
	int i;

	if ((rdlen = nametolbl(dpa->name, buf)) == -1)
		return -1;
	offset = rdlen;
	if (offset + 10 > limitlen)
		err_intret(ERR_DNSPLB);
	buf += offset;
	u = htons(dpa->type);
	memcpy(buf, &u, 2);
	buf += 2;
	offset += 2;
	u = htons(dpa->cl);
	memcpy(buf, &u, 2);
	buf += 2;
	offset += 2;
	i = htonl(dpa->ttl);
	memcpy(buf, &i, 4);
	buf += 4;
	offset += 4;

	if (dpa->type == T_A) {
		if (offset + dpa->rdlength > limitlen)
			err_intret(ERR_DNSPLB);
		memcpy(buf + 2, dpa->rdata, dpa->rdlength);
		offset += dpa->rdlength;
	} else if (dpa->type == T_MX) {
		memcpy(buf + 2, dpa->rdata, 2);
		if ((rdlen = nametolbl(dpa->rdata + 2, buf + 4)) == -1) {
			error(err_str);
			err_ret(ERR_DNSMDA, -1);
		}
		offset += rdlen + 2;
		if (offset > limitlen)
			err_ret(ERR_DNSPLB, -1);
		dpa->rdlength = rdlen + 2;
	} else {
		if ((rdlen = nametolbl(dpa->rdata, buf + 2)) == -1) {
			error(err_str);
			err_ret(ERR_DNSMDA, -1);
		}
		offset += rdlen;
		if (offset > limitlen)
			err_ret(ERR_DNSPLB, -1);
		dpa->rdlength = rdlen;
	}
	u = htons(dpa->rdlength);
	memcpy(buf, &u, 2);
	offset += 2;
	return offset;
}
Exemple #2
0
/*
 * This is a main function: takes the pkt-buf and translate
 * it in structured data.
 * It cares about dns_pkt allocations.
 *
 * Returns:
 * -1 on E_INTRPRT
 *  0 if pkt must be discarded.
 *  Number of bytes read otherwise
 */
int
d_u(char *buf, int pktlen, dns_pkt ** dpp)
{
	dns_pkt *dp;
	int offset = 0, res;
	char *crow;

	crow = buf;
	/* Controls pkt consistency: we must at least read pkt headers */
	if (pktlen < DNS_HDR_SZ)
		err_ret(ERR_DNSMDP, 0);
	*dpp = dp = create_dns_pkt();

	/* Writes headers */
	offset += d_hdr_u(buf, &(dp->pkt_hdr));
	if (pktlen > DNS_MAX_SZ)	/* If pkt is too long: the headers are written,
								 * so we can reply with E_INTRPRT
								 */
		err_intret(ERR_DNSPLB);
	crow += offset;
	/* Writes qsts */
	if (dp->pkt_hdr.qdcount) {
		if ((res = d_qsts_u(buf, crow, dp, pktlen - offset)) == -1) {
			error(err_str);
			err_intret(ERR_DNSMDP);
		}
		offset += res;
		crow += res;
	}

	if (dp->pkt_hdr.ancount) {
		if ((res =
			 d_as_u(buf, crow, &(dp->pkt_answ), pktlen - offset,
					DP_ANCOUNT(dp))) == -1) {
			error(err_str);
			err_intret(ERR_DNSMDP);
		}
		offset += res;
	}
	/*crow+=res;
	   if ((res=dpkttoas(buf,crow,&(dp->pkt_auth),pktlen-offset,DP_NSCOUNT(dp)))==-1)
	   return -1;
	   offset+=res;
	   crow+=res;
	   if ((res=dpkttoas(buf,crow,&(dp->pkt_add),pktlen-offset,DP_ARCOUNT(dp)))==-1)
	   return -1; */
	return offset;
}
Exemple #3
0
/*
 * like d_qs_u. count is the number of section to read.
 * -1 on error.  Bytes readed otherwise.
 */
int d_as_u(char *start_buf,char *buf,dns_pkt_a **dpa,int limit_len,int count)
{
        int offset=0,res;
        int i;

        if (!count) return 0;
        for(i=0;i<count;i++) {
                if ((res=d_a_u(start_buf,buf+offset,dpa,limit_len-offset))==-1) {
                        error(err_str);
                        err_intret(ERR_DNSMDD);
                }
                offset+=res;
        }
        return offset;
}
Exemple #4
0
/*
 * The behavior of this function is in all similar to dpkttoqst.
 * Returns -1 on error. Bytes readed otherwise.
 */
int
d_a_u(char *start_buf, char *buf, dns_pkt_a ** dpa_orig, int limit_len)
{
	int count, rdlen;
	dns_pkt_a *dpa;
	uint16_t s;
	uint32_t ui;

	dpa = dns_add_a(dpa_orig);

	/* get name */
	if ((count = lbltoname(buf, start_buf, dpa->name, limit_len)) == -1) {
		error(err_str);
		err_ret(ERR_DNSMDD, -1);
	}
	buf += count;
	/* Now we have to write 2+2+4+2 bytes */
	if (count + 10 > limit_len)
		err_ret(ERR_DNSPLB, -1);

	memcpy(&s, buf, 2);
	dpa->type = ntohs(s);
	count += 2;
	buf += 2;

	memcpy(&s, buf, 2);
	dpa->cl = ntohs(s);
	count += 2;
	buf += 2;

	memcpy(&ui, buf, 4);
	dpa->ttl = ntohl(ui);
	count += 4;
	buf += 4;

	memcpy(&s, buf, 2);
	dpa->rdlength = ntohs(s);
	count += 2;
	buf += 2;

	rdlen = dpa->rdlength;
	if (rdlen > DNS_MAX_HNAME_LEN)
		err_ret(ERR_DNSMDD, -1);
	/* Now we have to write dpa->rdlength bytes */
	if (count + rdlen > limit_len)
		err_ret(ERR_DNSPLB, -1);
	if (dpa->type == T_A) {
		memcpy(dpa->rdata, buf, rdlen);	/* 32bit address */
		count += rdlen;
	} else if (dpa->type == T_AAAA) {
		memcpy(dpa->rdata, buf, rdlen);	/* 128bit address */
		count += rdlen;
	} else if (dpa->type == T_MX) {
		memcpy(dpa->rdata, buf, 2);
		if ((ui =
			 lbltoname(buf + 2, start_buf, dpa->rdata + 2,
					   rdlen - 2)) == -1) {
			error(err_str);
			err_ret(ERR_DNSMDD, -1);
		}
		if (rdlen != ui + 2) {
			debug(DBG_NORMAL,
				  "In d_a_u(): rdlen (%d) differs from readed bytes (%d).",
				  rdlen, ui + 2);
			err_ret(ERR_DNSMDD, -1);
		}
		count += 2 + ui;
	} else {
		if ((ui = lbltoname(buf, start_buf, dpa->rdata, rdlen)) == -1) {
			error(err_str);
			err_intret(ERR_DNSMDD);
		}
		if (rdlen != ui) {
			debug(DBG_NORMAL,
				  "In d_a_u(): rdlen (%d) differs from readed bytes (%d).",
				  rdlen, ui);
			err_ret(ERR_DNSMDD, -1);
		}
		count += ui;
	}
	return count;
}