[uClibc]Re: dn_EXPAND

Eduardo B. Fonseca ebf-sender-808baf at aedsolucoes.com.br
Thu Nov 7 21:04:20 UTC 2002


Argh... 

	I'm so into this that I mistyped the function name! It is the dn_EXPAND
function... sorry again for OBVIOUS errors :))

Eduardo.

On Thu, 2002-11-07 at 19:02, Eduardo B. Fonseca wrote:
> Hello Guys,
> 
> 	Attached is a rip off code from glibc that contains the whole dn_search
> function. I did not test it yet, so I don't know if it will work (as I
> said before, I never did this level of programming). It links perfectly
> with exim and postfix, but I could not test it because I'm ripping off
> the res_search function. 
> 	This file replaces resolv.c on uclibc/libresolv/resolv.c function. I
> guess I will have a more complete one (with res_search) done within 2 or
> 3 days...
> 	Please, forgive me for any obvious errors :)
> 
> Thanks!
> 
> Eduardo B. Fonseca
> ebf at aedsolucoes.com.br
> 
> 
> ----
> 

> /*
> 
> 	Code ripped off from glibc-2.2.5
> 	Eduardo B. Fonseca <ebf at aedsolucoes.com.br>
> 
> */
> 
> #include <sys/types.h>
> #include <sys/param.h>
> #include <netinet/in.h>
> #include <arpa/nameser.h>
> #include <ctype.h>
> #include <resolv.h>
> #include <stdio.h>
> #include <string.h>
> #include <unistd.h>
> #include <errno.h>
> 
> static const char	digits[] = "0123456789";
> 
> static int
> special(int ch) {
> 	switch (ch) {
> 	case 0x22: /* '"' */
> 	case 0x2E: /* '.' */
> 	case 0x3B: /* ';' */
> 	case 0x5C: /* '\\' */
> 	/* Special modifiers in zone files. */
> 	case 0x40: /* '@' */
> 	case 0x24: /* '$' */
> 		return (1);
> 	default:
> 		return (0);
> 	}
> }
> 
> static int
> printable(int ch) {
> 	return (ch > 0x20 && ch < 0x7f);
> }
> 
> 
> int
> ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
> 	const u_char *cp;
> 	char *dn, *eom;
> 	u_char c;
> 	u_int n;
> 
> 	cp = src;
> 	dn = dst;
> 	eom = dst + dstsiz;
> 
> 	while ((n = *cp++) != 0) {
> 		if ((n & NS_CMPRSFLGS) != 0) {
> 			/* Some kind of compression pointer. */
> 			//__set_errno (EMSGSIZE);
> 			return (-1);
> 		}
> 		if (dn != dst) {
> 			if (dn >= eom) {
> 				//__set_errno (EMSGSIZE);
> 				return (-1);
> 			}
> 			*dn++ = '.';
> 		}
> 		if (dn + n >= eom) {
> 			//__set_errno (EMSGSIZE);
> 			return (-1);
> 		}
> 		for ((void)NULL; n > 0; n--) {
> 			c = *cp++;
> 			if (special(c)) {
> 				if (dn + 1 >= eom) {
> 					//__set_errno (EMSGSIZE);
> 					return (-1);
> 				}
> 				*dn++ = '\\';
> 				*dn++ = (char)c;
> 			} else if (!printable(c)) {
> 				if (dn + 3 >= eom) {
> 					//__set_errno (EMSGSIZE);
> 					return (-1);
> 				}
> 				*dn++ = '\\';
> 				*dn++ = digits[c / 100];
> 				*dn++ = digits[(c % 100) / 10];
> 				*dn++ = digits[c % 10];
> 			} else {
> 				if (dn >= eom) {
> 					//__set_errno (EMSGSIZE);
> 					return (-1);
> 				}
> 				*dn++ = (char)c;
> 			}
> 		}
> 	}
> 	if (dn == dst) {
> 		if (dn >= eom) {
> 			//__set_errno (EMSGSIZE);
> 			return (-1);
> 		}
> 		*dn++ = '.';
> 	}
> 	if (dn >= eom) {
> 		//__set_errno (EMSGSIZE);
> 		return (-1);
> 	}
> 	*dn++ = '\0';
> 	return (dn - dst);
> }
> 
> 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_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
> 		   char *dst, size_t dstsiz)
> {
> 	u_char tmp[NS_MAXCDNAME];
> 	int n;
> 
> 	if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
> 		return (-1);
> 	if (ns_name_ntop(tmp, dst, dstsiz) == -1)
> 		return (-1);
> 	return (n);
> }
> 
> int
> dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
> 	  char *dst, int dstsiz)
> {
> 	int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
> 
> 	if (n > 0 && dst[0] == '.')
> 		dst[0] = '\0';
> 	return (n);
> }




More information about the uClibc mailing list