int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
               u_char *dst, size_t dstsiz)
{
	const u_char *srcp, *dstlim;
	u_char *dstp;
	int n, len, checked;

	len = -1;
	checked = 0;
	dstp = dst;
	srcp = src;
	dstlim = dst + dstsiz;
	if (srcp < msg || srcp >= eom) {
		__set_errno(EMSGSIZE);
		return -1;
	}
	/* Fetch next label in domain name. */
	while ((n = *srcp++) != 0) {
		/* Check for indirection. */
		switch (n & NS_CMPRSFLGS) {
			case 0:
				/* Limit checks. */
				if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				checked += n + 1;
				*dstp++ = n;
				memcpy(dstp, srcp, n);
				dstp += n;
				srcp += n;
				break;

			case NS_CMPRSFLGS:
				if (srcp >= eom) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				if (len < 0)
					len = srcp - src + 1;
				srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
				if (srcp < msg || srcp >= eom) {  /* Out of range. */
					__set_errno(EMSGSIZE);
					return -1;
				}
				checked += 2;
				/*
				 * Check for loops in the compressed name;
				 * if we've looked at the whole message,
				 * there must be a loop.
				 */
				if (checked >= eom - msg) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				break;

			default:
				__set_errno(EMSGSIZE);
				return -1;                    /* flag error */
		}
	}
	*dstp = '\0';
	if (len < 0)
		len = srcp - src;
	return len;
}
int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
               u_char *dst, size_t dstsiz)
{
	const u_char *srcp, *dstlim;
	u_char *dstp;
	int n, len, checked;

	len = -1;
	checked = 0;
	dstp = dst;
	srcp = src;
	dstlim = dst + dstsiz;
	if (srcp < msg || srcp >= eom) {
		__set_errno(EMSGSIZE);
		return -1;
	}
	 
	while ((n = *srcp++) != 0) {
		 
		switch (n & NS_CMPRSFLGS) {
			case 0:
				 
				if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				checked += n + 1;
				*dstp++ = n;
				memcpy(dstp, srcp, n);
				dstp += n;
				srcp += n;
				break;

			case NS_CMPRSFLGS:
				if (srcp >= eom) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				if (len < 0)
					len = srcp - src + 1;
				srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
				if (srcp < msg || srcp >= eom) {   
					__set_errno(EMSGSIZE);
					return -1;
				}
				checked += 2;
				 
				if (checked >= eom - msg) {
					__set_errno(EMSGSIZE);
					return -1;
				}
				break;

			default:
				__set_errno(EMSGSIZE);
				return -1;                     
		}
	}
	*dstp = '\0';
	if (len < 0)
		len = srcp - src;
	return len;
}