static int encode_bitstring(const char **bp, const char *end,
							unsigned char **labelp,
							unsigned char ** dst,
							unsigned const char *eom)
{
	int afterslash = 0;
	const char *cp = *bp;
	unsigned char *tp;
	const char *beg_blen;
	int value = 0, count = 0, tbcount = 0, blen = 0;

	beg_blen = NULL;

	/* a bitstring must contain at least 2 characters */
	if (end - cp < 2)
		return EINVAL;

	/* XXX: currently, only hex strings are supported */
	if (*cp++ != 'x')
		return EINVAL;
	if (!isxdigit((unsigned char) *cp)) /*%< reject '\[x/BLEN]' */
		return EINVAL;

	for (tp = *dst + 1; cp < end && tp < eom; cp++) {
		unsigned char c = *cp;

		switch (c) {
		case ']':       /*%< end of the bitstring */
			if (afterslash) {
				char *end_blen;
				if (beg_blen == NULL)
					return EINVAL;
				blen = (int)strtol(beg_blen, &end_blen, 10);
				if (*end_blen != ']')
					return EINVAL;
			}
			if (count)
				*tp++ = ((value << 4) & 0xff);
			cp++;   /*%< skip ']' */
			goto done;
		case '/':
			afterslash = 1;
			break;
		default:
			if (afterslash) {
				if (!__isdigit_char(c))
					return EINVAL;
				if (beg_blen == NULL) {
					if (c == '0') {
						/* blen never begings with 0 */
						return EINVAL;
					}
					beg_blen = cp;
				}
			} else {
				if (!__isdigit_char(c)) {
					c = c | 0x20; /* lowercase */
					c = c - 'a';
					if (c > 5) /* not a-f? */
						return EINVAL;
					c += 10 + '0';
				}
				value <<= 4;
				value += (c - '0');
				count += 4;
				tbcount += 4;
				if (tbcount > 256)
					return EINVAL;
				if (count == 8) {
					*tp++ = value;
					count = 0;
				}
			}
			break;
		}
	}
  done:
	if (cp >= end || tp >= eom)
		return EMSGSIZE;

	/*
	 * bit length validation:
	 * If a <length> is present, the number of digits in the <bit-data>
	 * MUST be just sufficient to contain the number of bits specified
	 * by the <length>. If there are insignificant bits in a final
	 * hexadecimal or octal digit, they MUST be zero.
	 * RFC2673, Section 3.2.
	 */
	if (blen > 0) {
		int traillen;

		if (((blen + 3) & ~3) != tbcount)
			return EINVAL;
		traillen = tbcount - blen; /*%< between 0 and 3 */
		if (((value << (8 - traillen)) & 0xff) != 0)
			return EINVAL;
	}
	else
		blen = tbcount;
	if (blen == 256)
		blen = 0;

	/* encode the type and the significant bit fields */
	**labelp = DNS_LABELTYPE_BITSTRING;
	**dst = blen;

	*bp = cp;
	*dst = tp;

	return 0;
}
static int encode_bitstring(const char **bp, const char *end,
							unsigned char **labelp,
							unsigned char ** dst,
							unsigned const char *eom)
{
	int afterslash = 0;
	const char *cp = *bp;
	unsigned char *tp;
	const char *beg_blen;
	int value = 0, count = 0, tbcount = 0, blen = 0;

	beg_blen = NULL;

	 
	if (end - cp < 2)
		return EINVAL;

	 
	if (*cp++ != 'x')
		return EINVAL;
	if (!isxdigit((unsigned char) *cp))  
		return EINVAL;

	for (tp = *dst + 1; cp < end && tp < eom; cp++) {
		unsigned char c = *cp;

		switch (c) {
		case ']':        
			if (afterslash) {
				char *end_blen;
				if (beg_blen == NULL)
					return EINVAL;
				blen = (int)strtol(beg_blen, &end_blen, 10);
				if (*end_blen != ']')
					return EINVAL;
			}
			if (count)
				*tp++ = ((value << 4) & 0xff);
			cp++;    
			goto done;
		case '/':
			afterslash = 1;
			break;
		default:
			if (afterslash) {
				if (!__isdigit_char(c))
					return EINVAL;
				if (beg_blen == NULL) {
					if (c == '0') {
						 
						return EINVAL;
					}
					beg_blen = cp;
				}
			} else {
				if (!__isdigit_char(c)) {
					c = c | 0x20;  
					c = c - 'a';
					if (c > 5)  
						return EINVAL;
					c += 10 + '0';
				}
				value <<= 4;
				value += (c - '0');
				count += 4;
				tbcount += 4;
				if (tbcount > 256)
					return EINVAL;
				if (count == 8) {
					*tp++ = value;
					count = 0;
				}
			}
			break;
		}
	}
  done:
	if (cp >= end || tp >= eom)
		return EMSGSIZE;

	 
	if (blen > 0) {
		int traillen;

		if (((blen + 3) & ~3) != tbcount)
			return EINVAL;
		traillen = tbcount - blen;  
		if (((value << (8 - traillen)) & 0xff) != 0)
			return EINVAL;
	}
	else
		blen = tbcount;
	if (blen == 256)
		blen = 0;

	 
	**labelp = DNS_LABELTYPE_BITSTRING;
	**dst = blen;

	*bp = cp;
	*dst = tp;

	return 0;
}