u_char *dname_decompress (u_char *buf, int buflen, u_char *dname,
			  u_char *m_head, u_char *m_tail, int *written) {
	int token_len, written_len, iter;
	u_char *cp, *next;
	int pktsiz = m_tail - m_head;

	next = NULL;
	written_len = token_len = 0;
	for (cp = dname; *cp; cp += token_len) {
		iter = 0;
	  top:
		if ((*cp & DNCMP_MASK) == DNCMP_MASK) {
			uint16_t ui;

			if (iter++ >= pktsiz) /* we're probably in a loop. */
				return NULL;

			if (!m_head || !m_tail) /* irregular redirect */
				return NULL;

			/* redirect */
			next = cp + 2;
			GETSHORT (ui, cp);
			ui = ui & ~DNCMP_MASK_INT16T;

			cp = m_head + ui;
			if (cp < m_head || m_tail < cp)
				return NULL;

			goto top;
		}

		token_len = labellen(cp);
		if (token_len < 0)
			return NULL;
		else
			token_len++;

		if (T.debug > 4)
			syslog (LOG_DEBUG, "token_len: %d", token_len);

		if (written_len + token_len >= buflen)
			return NULL; /* buffer overrun */
		if (m_tail && cp + token_len > m_tail)
			return NULL; /* out of bounds */

		if (written) {
			/* non-printable dname string */
			memcpy (buf, cp, token_len);
			written_len += token_len;
			buf += token_len;
		} else {
			/* write printable string */
			if ((*cp & DNCMP_MASK) != EDNS0_MASK) {
				memcpy (buf, cp + 1, token_len - 1);
				*(buf + (token_len - 1)) = DNAME_DELIM;
				written_len += token_len;
				buf += token_len;
			} else if (*cp == EDNS0_ELT_BITLABEL) {
				int bitlength, i;
				u_char *wp;

				/* a bit conservative test, but simple */
				if (written_len + token_len*2 + 7 >= buflen)
					return NULL; /* buffer overrun */

				wp = buf;
				wp += sprintf((char *)wp, "\\[x");
				for (i = 1; i < token_len-1; i++) {
					u_char d1, d2;
					uint b;

					b = (int) *(cp + 1 + i);
					d1 = hex[(b >> 4) & 0x0f];
					d2 = hex[b & 0x0f];
					wp += sprintf((char *)wp, "%c%c", d1, d2);
				}
				bitlength = *(cp + 1) ? *(cp + 1) : 256;
				wp += sprintf((char *)wp, "/%u].", bitlength);

				written_len += (wp - buf);
				buf += written_len;
			}
		}
	}

	*buf = '\0';
	if (written)
		*written = written_len + 1;

	if (!next)
		next = cp+1;

	return next;
}
u_char *dname_decompress (u_char *buf, int buflen, u_char *dname,
			  u_char *m_head, u_char *m_tail, int *written) {
	int token_len, written_len, iter;
	u_char *cp, *next;
	int pktsiz = m_tail - m_head;

	next = NULL;
	written_len = token_len = 0;
	for (cp = dname; *cp; cp += token_len) {
		iter = 0;
	  top:
		if ((*cp & DNCMP_MASK) == DNCMP_MASK) {
			uint16_t ui;

			if (iter++ >= pktsiz)  
				return NULL;

			if (!m_head || !m_tail)  
				return NULL;

			 
			next = cp + 2;
			GETSHORT (ui, cp);
			ui = ui & ~DNCMP_MASK_INT16T;

			cp = m_head + ui;
			if (cp < m_head || m_tail < cp)
				return NULL;

			goto top;
		}

		token_len = labellen(cp);
		if (token_len < 0)
			return NULL;
		else
			token_len++;

		if (T.debug > 4)
			syslog (LOG_DEBUG, "token_len: %d", token_len);

		if (written_len + token_len >= buflen)
			return NULL;  
		if (m_tail && cp + token_len > m_tail)
			return NULL;  

		if (written) {
			 
			memcpy (buf, cp, token_len);
			written_len += token_len;
			buf += token_len;
		} else {
			 
			if ((*cp & DNCMP_MASK) != EDNS0_MASK) {
				memcpy (buf, cp + 1, token_len - 1);
				*(buf + (token_len - 1)) = DNAME_DELIM;
				written_len += token_len;
				buf += token_len;
			} else if (*cp == EDNS0_ELT_BITLABEL) {
				int bitlength, i;
				u_char *wp;

				 
				if (written_len + token_len*2 + 7 >= buflen)
					return NULL;  

				wp = buf;
				wp += sprintf((char *)wp, "\\[x");
				for (i = 1; i < token_len-1; i++) {
					u_char d1, d2;
					uint b;

					b = (int) *(cp + 1 + i);
					d1 = hex[(b >> 4) & 0x0f];
					d2 = hex[b & 0x0f];
					wp += sprintf((char *)wp, "%c%c", d1, d2);
				}
				bitlength = *(cp + 1) ? *(cp + 1) : 256;
				wp += sprintf((char *)wp, "/%u].", bitlength);

				written_len += (wp - buf);
				buf += written_len;
			}
		}
	}

	*buf = '\0';
	if (written)
		*written = written_len + 1;

	if (!next)
		next = cp+1;

	return next;
}