コード例 #1
0
ファイル: msgencode.c プロジェクト: thozza/unbound
void
attach_edns_record(sldns_buffer* pkt, struct edns_data* edns)
{
	size_t len;
	size_t rdatapos;
	struct edns_option* opt;
	if(!edns || !edns->edns_present)
		return;
	/* inc additional count */
	sldns_buffer_write_u16_at(pkt, 10,
		sldns_buffer_read_u16_at(pkt, 10) + 1);
	len = sldns_buffer_limit(pkt);
	sldns_buffer_clear(pkt);
	sldns_buffer_set_position(pkt, len);
	/* write EDNS record */
	sldns_buffer_write_u8(pkt, 0); /* '.' label */
	sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_OPT); /* type */
	sldns_buffer_write_u16(pkt, edns->udp_size); /* class */
	sldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */
	sldns_buffer_write_u8(pkt, edns->edns_version);
	sldns_buffer_write_u16(pkt, edns->bits);
	rdatapos = sldns_buffer_position(pkt);
	sldns_buffer_write_u16(pkt, 0); /* rdatalen */
	/* write rdata */
	for(opt=edns->opt_list; opt; opt=opt->next) {
		sldns_buffer_write_u16(pkt, opt->opt_code);
		sldns_buffer_write_u16(pkt, opt->opt_len);
		if(opt->opt_len != 0)
			sldns_buffer_write(pkt, opt->opt_data, opt->opt_len);
	}
	if(edns->opt_list)
		sldns_buffer_write_u16_at(pkt, rdatapos, 
			sldns_buffer_position(pkt)-rdatapos-2);
	sldns_buffer_flip(pkt);
}
コード例 #2
0
ファイル: msgencode.c プロジェクト: thozza/unbound
/** compress a domain name */
static int
write_compressed_dname(sldns_buffer* pkt, uint8_t* dname, int labs,
	struct compress_tree_node* p)
{
	/* compress it */
	int labcopy = labs - p->labs;
	uint8_t lablen;
	uint16_t ptr;

	if(labs == 1) {
		/* write root label */
		if(sldns_buffer_remaining(pkt) < 1)
			return 0;
		sldns_buffer_write_u8(pkt, 0);
		return 1;
	}

	/* copy the first couple of labels */
	while(labcopy--) {
		lablen = *dname++;
		if(sldns_buffer_remaining(pkt) < (size_t)lablen+1)
			return 0;
		sldns_buffer_write_u8(pkt, lablen);
		sldns_buffer_write(pkt, dname, lablen);
		dname += lablen;
	}
	/* insert compression ptr */
	if(sldns_buffer_remaining(pkt) < 2)
		return 0;
	ptr = PTR_CREATE(p->offset);
	sldns_buffer_write_u16(pkt, ptr);
	return 1;
}
コード例 #3
0
ファイル: worker.c プロジェクト: gokzy/netbsd-src
/**
 * Fill CH class answer into buffer. Keeps query.
 * @param pkt: buffer
 * @param str: string to put into text record (<255).
 * @param edns: edns reply information.
 * @param worker: worker with scratch region.
 */
static void
chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
	struct worker* worker)
{
	size_t len = strlen(str);
	unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
	unsigned int cd = LDNS_CD_WIRE(sldns_buffer_begin(pkt));
	if(len>255) len=255; /* cap size of TXT record */
	sldns_buffer_clear(pkt);
	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */
	sldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA));
	if(rd) LDNS_RD_SET(sldns_buffer_begin(pkt));
	if(cd) LDNS_CD_SET(sldns_buffer_begin(pkt));
	sldns_buffer_write_u16(pkt, 1); /* qdcount */
	sldns_buffer_write_u16(pkt, 1); /* ancount */
	sldns_buffer_write_u16(pkt, 0); /* nscount */
	sldns_buffer_write_u16(pkt, 0); /* arcount */
	(void)query_dname_len(pkt); /* skip qname */
	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */
	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */
	sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
	sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
	sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
	sldns_buffer_write_u32(pkt, 0); /* TTL */
	sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
	sldns_buffer_write_u8(pkt, len);
	sldns_buffer_write(pkt, str, len);
	sldns_buffer_flip(pkt);
	edns->edns_version = EDNS_ADVERTISED_VERSION;
	edns->udp_size = EDNS_ADVERTISED_SIZE;
	edns->bits &= EDNS_DO;
	if(!edns_opt_inplace_reply(edns, worker->scratchpad))
		edns->opt_list = NULL;
	attach_edns_record(pkt, edns);
}
コード例 #4
0
ファイル: dname.c プロジェクト: chigumaya/unbound
int
dname_buffer_write(sldns_buffer* pkt, uint8_t* dname)
{
    uint8_t lablen;

    if(sldns_buffer_remaining(pkt) < 1)
        return 0;
    lablen = *dname++;
    sldns_buffer_write_u8(pkt, lablen);
    while(lablen) {
        if(sldns_buffer_remaining(pkt) < (size_t)lablen+1)
            return 0;
        sldns_buffer_write(pkt, dname, lablen);
        dname += lablen;
        lablen = *dname++;
        sldns_buffer_write_u8(pkt, lablen);
    }
    return 1;
}
コード例 #5
0
ファイル: unitdname.c プロジェクト: schvin/unbound
/** setup looped dname and out-of-bounds dname ptr */
static void
dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
{
	sldns_buffer_write_u16(loopbuf, 0xd54d);  /* id */
	sldns_buffer_write_u16(loopbuf, 0x12);    /* flags  */
	sldns_buffer_write_u16(loopbuf, 1);       /* qdcount */
	sldns_buffer_write_u16(loopbuf, 0);       /* ancount */
	sldns_buffer_write_u16(loopbuf, 0);       /* nscount */
	sldns_buffer_write_u16(loopbuf, 0);       /* arcount */
	sldns_buffer_write_u8(loopbuf, 0xc0); /* PTR back at itself */
	sldns_buffer_write_u8(loopbuf, 0x0c);
	sldns_buffer_flip(loopbuf);

	sldns_buffer_write_u16(boundbuf, 0xd54d);  /* id */
	sldns_buffer_write_u16(boundbuf, 0x12);    /* flags  */
	sldns_buffer_write_u16(boundbuf, 1);       /* qdcount */
	sldns_buffer_write_u16(boundbuf, 0);       /* ancount */
	sldns_buffer_write_u16(boundbuf, 0);       /* nscount */
	sldns_buffer_write_u16(boundbuf, 0);       /* arcount */
	sldns_buffer_write_u8(boundbuf, 0x01); /* len=1 */
	sldns_buffer_write_u8(boundbuf, (uint8_t)'A'); /* A. label */
	sldns_buffer_write_u8(boundbuf, 0xc0); /* PTR out of bounds */
	sldns_buffer_write_u8(boundbuf, 0xcc);
	sldns_buffer_flip(boundbuf);
}
コード例 #6
0
ファイル: msgencode.c プロジェクト: 2asoft/freebsd
void
attach_edns_record(sldns_buffer* pkt, struct edns_data* edns)
{
	size_t len;
	if(!edns || !edns->edns_present)
		return;
	/* inc additional count */
	sldns_buffer_write_u16_at(pkt, 10,
		sldns_buffer_read_u16_at(pkt, 10) + 1);
	len = sldns_buffer_limit(pkt);
	sldns_buffer_clear(pkt);
	sldns_buffer_set_position(pkt, len);
	/* write EDNS record */
	sldns_buffer_write_u8(pkt, 0); /* '.' label */
	sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_OPT); /* type */
	sldns_buffer_write_u16(pkt, edns->udp_size); /* class */
	sldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */
	sldns_buffer_write_u8(pkt, edns->edns_version);
	sldns_buffer_write_u16(pkt, edns->bits);
	sldns_buffer_write_u16(pkt, 0); /* rdatalen */
	sldns_buffer_flip(pkt);
}
コード例 #7
0
ファイル: msgencode.c プロジェクト: thozza/unbound
/** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */
static int
compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, 
	struct regional* region, struct compress_tree_node** tree, 
	size_t owner_pos, uint16_t* owner_ptr, int owner_labs)
{
	struct compress_tree_node* p;
	struct compress_tree_node** insertpt = NULL;
	if(!*owner_ptr) {
		/* compress first time dname */
		if((p = compress_tree_lookup(tree, key->rk.dname, 
			owner_labs, &insertpt))) {
			if(p->labs == owner_labs) 
				/* avoid ptr chains, since some software is
				 * not capable of decoding ptr after a ptr. */
				*owner_ptr = htons(PTR_CREATE(p->offset));
			if(!write_compressed_dname(pkt, key->rk.dname, 
				owner_labs, p))
				return RETVAL_TRUNC;
			/* check if typeclass+4 ttl + rdatalen is available */
			if(sldns_buffer_remaining(pkt) < 4+4+2)
				return RETVAL_TRUNC;
		} else {
			/* no compress */
			if(sldns_buffer_remaining(pkt) < key->rk.dname_len+4+4+2)
				return RETVAL_TRUNC;
			sldns_buffer_write(pkt, key->rk.dname, 
				key->rk.dname_len);
			if(owner_pos <= PTR_MAX_OFFSET)
				*owner_ptr = htons(PTR_CREATE(owner_pos));
		}
		if(!compress_tree_store(key->rk.dname, owner_labs, 
			owner_pos, region, p, insertpt))
			return RETVAL_OUTMEM;
	} else {
		/* always compress 2nd-further RRs in RRset */
		if(owner_labs == 1) {
			if(sldns_buffer_remaining(pkt) < 1+4+4+2) 
				return RETVAL_TRUNC;
			sldns_buffer_write_u8(pkt, 0);
		} else {
			if(sldns_buffer_remaining(pkt) < 2+4+4+2) 
				return RETVAL_TRUNC;
			sldns_buffer_write(pkt, owner_ptr, 2);
		}
	}
	return RETVAL_OK;
}
コード例 #8
0
ファイル: readhex.c プロジェクト: Bluecoreg/monero
/* takes a hex string and puts into buffer */
void hex_to_buf(sldns_buffer* pkt, const char* hex)
{
	const char* p = hex;
	int val;
	sldns_buffer_clear(pkt);
	while(*p) {
		skip_whites(&p);
		if(sldns_buffer_position(pkt) == sldns_buffer_limit(pkt))
			fatal_exit("hex_to_buf: buffer too small");
		if(!isalnum((unsigned char)*p))
			break;
		val = sldns_hexdigit_to_int(*p++) << 4;
		skip_whites(&p);
		log_assert(*p && isalnum((unsigned char)*p));
		val |= sldns_hexdigit_to_int(*p++);
		sldns_buffer_write_u8(pkt, (uint8_t)val);
		skip_whites(&p);
	}
	sldns_buffer_flip(pkt);
}
コード例 #9
0
ファイル: val_anchor.c プロジェクト: Coder420/bitmonero
/** skip through file to { or ; */
static int 
skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec) 
{
	int rdlen;
	sldns_buffer_clear(buf);
	while((rdlen=readkeyword_bindfile(in, buf, line, 1))) {
		if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) {
			sldns_buffer_clear(buf);
			continue;
		}
		if(rdlen != 1 || *sldns_buffer_begin(buf) != (uint8_t)spec) {
			sldns_buffer_write_u8(buf, 0);
			log_err("trusted-keys, line %d, expected %c", 
				*line, spec);
			return 0;
		}
		return 1;
	}
	log_err("trusted-keys, line %d, expected %c got EOF", *line, spec);
	return 0;
}
コード例 #10
0
ファイル: val_anchor.c プロジェクト: Coder420/bitmonero
/** 
 * read contents of trusted-keys{ ... ; clauses and insert keys into storage.
 * @param anchors: where to store keys
 * @param buf: buffer to use
 * @param line: line number in file
 * @param in: file to read from.
 * @return 0 on error.
 */
static int
process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, 
	int* line, FILE* in)
{
	/* loop over contents, collate strings before ; */
	/* contents is (numbered): 0   1    2  3 4   5  6 7 8    */
	/*                           name. 257 3 5 base64 base64 */
	/* quoted value:           0 "111"  0  0 0   0  0 0 0    */
	/* comments value:         1 "000"  1  1  1 "0  0 0 0"  1 */
	int contnum = 0;
	int quoted = 0;
	int comments = 1;
	int rdlen;
	char* str = 0;
	sldns_buffer_clear(buf);
	while((rdlen=readkeyword_bindfile(in, buf, line, comments))) {
		if(rdlen == 1 && sldns_buffer_position(buf) == 1
			&& isspace((unsigned char)*sldns_buffer_begin(buf))) {
			/* starting whitespace is removed */
			sldns_buffer_clear(buf);
			continue;
		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '"') {
			/* remove " from the string */
			if(contnum == 0) {
				quoted = 1;
				comments = 0;
			}
			sldns_buffer_skip(buf, -1);
			if(contnum > 0 && quoted) {
				if(sldns_buffer_remaining(buf) < 8+1) {
					log_err("line %d, too long", *line);
					return 0;
				}
				sldns_buffer_write(buf, " DNSKEY ", 8);
				quoted = 0;
				comments = 1;
			} else if(contnum > 0)
				comments = !comments;
			continue;
		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == ';') {

			if(contnum < 5) {
				sldns_buffer_write_u8(buf, 0);
				log_err("line %d, bad key", *line);
				return 0;
			}
			sldns_buffer_skip(buf, -1);
			sldns_buffer_write_u8(buf, 0);
			str = strdup((char*)sldns_buffer_begin(buf));
			if(!str) {
				log_err("line %d, allocation failure", *line);
				return 0;
			}
			if(!anchor_store_str(anchors, buf, str)) {
				log_err("line %d, bad key", *line);
				free(str);
				return 0;
			}
			free(str);
			sldns_buffer_clear(buf);
			contnum = 0;
			quoted = 0;
			comments = 1;
			continue;
		} else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '}') {
			if(contnum > 0) {
				sldns_buffer_write_u8(buf, 0);
				log_err("line %d, bad key before }", *line);
				return 0;
			}
			return 1;
		} else if(rdlen == 1 && 
			isspace((unsigned char)sldns_buffer_current(buf)[-1])) {
			/* leave whitespace here */
		} else {
			/* not space or whatnot, so actual content */
			contnum ++;
			if(contnum == 1 && !quoted) {
				if(sldns_buffer_remaining(buf) < 8+1) {
					log_err("line %d, too long", *line);
					return 0;
				}	
				sldns_buffer_write(buf, " DNSKEY ", 8);
			}
		}
	}

	log_err("line %d, EOF before }", *line);
	return 0;
}
コード例 #11
0
ファイル: val_anchor.c プロジェクト: Coder420/bitmonero
/** 
 * Read a keyword skipping bind comments; spaces, specials, restkeywords. 
 * The file is split into the following tokens:
 *	* special characters, on their own, rdlen=1, { } doublequote ;
 *	* whitespace becomes a single ' ' or tab. Newlines become spaces.
 *	* other words ('keywords')
 *	* comments are skipped if desired
 *		/ / C++ style comment to end of line
 *		# to end of line
 *		/ * C style comment * /
 * @param in: file to read from.
 * @param buf: buffer, what is read is stored after current buffer position.
 *	Space is left in the buffer to write a terminating 0.
 * @param line: line number is increased per line, for error reports.
 * @param comments: if 0, comments are not possible and become text.
 *	if 1, comments are skipped entirely.
 *	In BIND files, this is when reading quoted strings, for example
 *	" base 64 text with / / in there "
 * @return the number of character written to the buffer. 
 *	0 on end of file.
 */
static int
readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments)
{
	int c;
	int numdone = 0;
	while((c = getc(in)) != EOF ) {
		if(comments && c == '#') {	/*   # blabla   */
			skip_to_eol(in);
			(*line)++;
			continue;
		} else if(comments && c=='/' && numdone>0 && /* /_/ bla*/
			sldns_buffer_read_u8_at(buf, 
			sldns_buffer_position(buf)-1) == '/') {
			sldns_buffer_skip(buf, -1);
			numdone--;
			skip_to_eol(in);
			(*line)++;
			continue;
		} else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */
			sldns_buffer_read_u8_at(buf, 
			sldns_buffer_position(buf)-1) == '/') {
			sldns_buffer_skip(buf, -1);
			numdone--;
			/* skip to end of comment */
			while(c != EOF && (c=getc(in)) != EOF ) {
				if(c == '*') {
					if((c=getc(in)) == '/')
						break;
				}
				if(c == '\n')
					(*line)++;
			}
			continue;
		}
		/* not a comment, complete the keyword */
		if(numdone > 0) {
			/* check same type */
			if(isspace((unsigned char)c)) {
				ungetc(c, in);
				return numdone;
			}
			if(is_bind_special(c)) {
				ungetc(c, in);
				return numdone;
			}
		}
		if(c == '\n') {
			c = ' ';
			(*line)++;
		}
		/* space for 1 char + 0 string terminator */
		if(sldns_buffer_remaining(buf) < 2) {
			fatal_exit("trusted-keys, %d, string too long", *line);
		}
		sldns_buffer_write_u8(buf, (uint8_t)c);
		numdone++;
		if(isspace((unsigned char)c)) {
			/* collate whitespace into ' ' */
			while((c = getc(in)) != EOF ) {
				if(c == '\n')
					(*line)++;
				if(!isspace((unsigned char)c)) {
					ungetc(c, in);
					break;
				}
			}
			return numdone;
		}
		if(is_bind_special(c))
			return numdone;
	}
	return numdone;
}