9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: lucio@proxima.alt.za
To: 9fans@cse.psu.edu
Subject: Re: [9fans] $smtp dns failure
Date: Tue, 16 Jan 2007 20:52:49 +0200	[thread overview]
Message-ID: <d56c69ee0347a8e6aade6849d89de80d@proxima.alt.za> (raw)
In-Reply-To: <ee9e417a0701161044i5fc77ddfrbfa3585f3cd91036@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 391 bytes --]

> unfortunately i don't think there
> is a library routine that will tell us whether a string is a valid
> ip address.

I had to enhance the APE "bsd" library to implement the OpenLDAP
client tools.  I'm sure importing inet_pton.c from NetBSD to Plan 9
native will not be much more effort.  I do believe it loses the
ability to understand 127.1, but I have not verified this.

++L

[-- Attachment #2: inet_pton.c --]
[-- Type: text/plain, Size: 11071 bytes --]

/*      $NetBSD: inet_pton.c,v 1.16 2000/02/07 18:51:02 itojun Exp $    */

/* Copyright (c) 1996 by Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

/*
 * WARNING: Don't even consider trying to compile this on a system where
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 */

static int      inet_pton4 (const char *src, unsigned char *dst, int pton);
static int      inet_pton6 (const char *src, unsigned char *dst);

/* int
 * inet_pton(af, src, dst)
 *      convert from presentation format (which usually means ASCII printable)
 *      to network format (which is usually some kind of binary format).
 * return:
 *      1 if the address was valid for the specified address family
 *      0 if the address wasn't valid (`dst' is untouched in this case)
 *      -1 if some other error occurred (`dst' is untouched in this case, too)
 * author:
 *      Paul Vixie, 1996.
 */
int
inet_pton(af, src, dst)
        int af;
        const char *src;
        void *dst;
{
        switch (af) {
        case AF_INET:
                return (inet_pton4(src, dst, 1));
        case AF_INET6:
                return (inet_pton6(src, dst));
        default:
                errno = EAFNOSUPPORT;
                return (-1);
        }
        /* NOTREACHED */
}

/* int
 * inet_pton4(src, dst, pton)
 *      when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand.
 *      when last arg is 1: inet_pton(). decimal dotted-quad only.
 * return:
 *      1 if `src' is a valid input, else 0.
 * notice:
 *      does not touch `dst' unless it's returning 1.
 * author:
 *      Paul Vixie, 1996.
 */
#define INADDRSZ (4)
static int
inet_pton4(src, dst, pton)
        const char *src;
        unsigned char *dst;
        int pton;
{
        unsigned int val;
        unsigned int digit;
        int base, n;
        unsigned char c;
        unsigned int parts[4];
        unsigned int *pp = parts;

        c = *src;
        for (;;) {
                /*
                 * Collect number up to ``.''.
                 * Values are specified as for C:
                 * 0x=hex, 0=octal, isdigit=decimal.
                 */
                if (!isdigit(c))
                        return (0);
                val = 0; base = 10;
                if (c == '0') {
                        c = *++src;
                        if (c == 'x' || c == 'X')
                                base = 16, c = *++src;
                        else if (isdigit(c) && c != '9')
                                base = 8;
                }
                /* inet_pton() takes decimal only */
                if (pton && base != 10)
                        return (0);
                for (;;) {
                        if (isdigit(c)) {
                                digit = c - '0';
                                if (digit >= base)
                                        break;
                                val = (val * base) + digit;
                                c = *++src;
                        } else if (base == 16 && isxdigit(c)) {
                                digit = c + 10 - (islower(c) ? 'a' : 'A');
                                if (digit >= 16)
                                        break;
                                val = (val << 4) | digit;
                                c = *++src;
                        } else
                                break;
                }
                if (c == '.') {
                        /*
                         * Internet format:
                         *      a.b.c.d
                         *      a.b.c   (with c treated as 16 bits)
                         *      a.b     (with b treated as 24 bits)
                         *      a       (with a treated as 32 bits)
                         */
                        if (pp >= parts + 3)
                                return (0);
                        *pp++ = val;
                        c = *++src;
                } else
                        break;
        }
        /*
         * Check for trailing characters.
         */
        if (c != '\0' && !isspace(c))
                return (0);
        /*
         * Concoct the address according to
         * the number of parts specified.
         */
        n = pp - parts + 1;
        /* inet_pton() takes dotted-quad only.  it does not take shorthand. */
        if (pton && n != 4)
                return (0);
        switch (n) {

        case 0:
                return (0);             /* initial nondigit */

        case 1:                         /* a -- 32 bits */
                break;

        case 2:                         /* a.b -- 8.24 bits */
                if (parts[0] > 0xff || val > 0xffffff)
                        return (0);
                val |= parts[0] << 24;
                break;

        case 3:                         /* a.b.c -- 8.8.16 bits */
                if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
                        return (0);
                val |= (parts[0] << 24) | (parts[1] << 16);
                break;

        case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
                if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
                        return (0);
                val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
                break;
        }
        if (dst) {
                val = htonl(val);
                memcpy(dst, &val, INADDRSZ);
        }
        return (1);
}

/* int
 * inet_pton6(src, dst)
 *      convert presentation level address to network order binary form.
 * return:
 *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
 * notice:
 *      (1) does not touch `dst' unless it's returning 1.
 *      (2) :: in a full address is silently ignored.
 * credit:
 *      inspired by Mark Andrews.
 * author:
 *      Paul Vixie, 1996.
 */
#define	IN6ADDRSZ	(16)
static int
inet_pton6(src, dst)
        const char *src;
        unsigned char *dst;
{
        static const char xdigits_l[] = "0123456789abcdef",
                          xdigits_u[] = "0123456789ABCDEF";
        unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
        const char *xdigits, *curtok;
        int ch, saw_xdigit;
        unsigned int val;

        memset((tp = tmp), '\0', IN6ADDRSZ);
        endp = tp + IN6ADDRSZ;
        colonp = NULL;
        /* Leading :: requires some special handling. */
        if (*src == ':')
                if (*++src != ':')
                        return (0);
        curtok = src;
        saw_xdigit = 0;
        val = 0;
        while ((ch = *src++) != '\0') {
                const char *pch;

                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
                        pch = strchr((xdigits = xdigits_u), ch);
                if (pch != NULL) {
                        val <<= 4;
                        val |= (pch - xdigits);
                        if (val > 0xffff)
                                return (0);
                        saw_xdigit = 1;
                        continue;
                }
                if (ch == ':') {
                        curtok = src;
                        if (!saw_xdigit) {
                                if (colonp)
                                        return (0);
                                colonp = tp;
                                continue;
                        } else if (*src == '\0')
                                return (0);
                        if (tp + 2 > endp)
                                return (0);
                        *tp++ = (unsigned char) (val >> 8) & 0xff;
                        *tp++ = (unsigned char) val & 0xff;
                        saw_xdigit = 0;
                        val = 0;
                        continue;
                }
                if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
                    inet_pton4(curtok, tp, 1) > 0) {
                        tp += INADDRSZ;
                        saw_xdigit = 0;
                        break;  /* '\0' was seen by inet_pton4(). */
                }
                return (0);
        }
        if (saw_xdigit) {
                if (tp + 2 > endp)
                        return (0);
                *tp++ = (unsigned char) (val >> 8) & 0xff;
                *tp++ = (unsigned char) val & 0xff;
        }
        if (colonp != NULL) {
                /*
                 * Since some memmove()'s erroneously fail to handle
                 * overlapping regions, we'll do the shift by hand.
                 */
                const int n = tp - colonp;
                int i;

                if (tp == endp)
                        return (0);
                for (i = 1; i <= n; i++) {
                        endp[- i] = colonp[n - i];
                        colonp[n - i] = 0;
                }
                tp = endp;
        }
        if (tp != endp)
                return (0);
        memcpy(dst, tmp, IN6ADDRSZ);
        return (1);
}

/*
 * Ascii internet address interpretation routine.
 * The value returned is in network order.
 */
unsigned long
inet_addr(cp)
        register const char *cp;
{
        struct in_addr val;

        if (inet_pton4(cp, (unsigned char *)(void *)&val.s_addr, 0))
                return (val.s_addr);
        return (INADDR_NONE);
}

/*
 * Check whether "cp" is a valid ascii representation
 * of an Internet address and convert to a binary address.
 * Returns 1 if the address is valid, 0 if not.
 * This replaces inet_addr, the return value from which
 * cannot distinguish between failure and a local broadcast address.
 */
int
inet_aton(cp, addr)
        register const char *cp;
        struct in_addr *addr;
{
        return inet_pton4(cp, (unsigned char *)(void *)&addr->s_addr, 0);
}

  reply	other threads:[~2007-01-16 18:52 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-15 16:55 Matthias Teege
2007-01-15 18:05 ` Federico Benavento
2007-01-15 19:22   ` Russ Cox
2007-01-15 18:10 ` geoff
2007-01-15 20:02   ` Matthias Teege
2007-01-15 23:35     ` Steve Simon
2007-01-16 16:46       ` Matthias Teege
2007-01-16 18:21         ` Steve Simon
2007-01-16 18:31           ` erik quanstrom
2007-01-16 18:44             ` Russ Cox
2007-01-16 18:52               ` lucio [this message]
2007-01-16 19:05               ` erik quanstrom
2007-01-16 19:30                 ` Russ Cox
2007-01-15 19:28 erik quanstrom
2007-01-15 19:42 ` Paul Lalonde
2007-01-16 17:01 erik quanstrom
2007-01-16 20:31 erik quanstrom
2007-01-16 20:50 ` geoff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d56c69ee0347a8e6aade6849d89de80d@proxima.alt.za \
    --to=lucio@proxima.alt.za \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).