[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