Changeset eecccf1


Ignore:
Timestamp:
2006-05-25T23:08:15Z (18 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
1cda4f3
Parents:
1705ec3
Message:

Add replacement functions for log_link(), inet_pton() and inet_ntop()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • win32.c

    r1705ec3 reecccf1  
    315315        g_free(lpszStrings[1]);
    316316}
     317
     318void log_link(int level, int output) { /* FIXME */ }
     319
     320#ifndef NS_INADDRSZ
     321#define NS_INADDRSZ     4
     322#endif
     323#ifndef NS_IN6ADDRSZ
     324#define NS_IN6ADDRSZ    16
     325#endif
     326#ifndef NS_INT16SZ
     327#define NS_INT16SZ      2
     328#endif
     329
     330static const char *inet_ntop4(const guchar *src, char *dst, size_t size);
     331static const char *inet_ntop6(const guchar *src, char *dst, size_t size);
     332
     333/* char *
     334 * inet_ntop(af, src, dst, size)
     335 *      convert a network format address to presentation format.
     336 * return:
     337 *      pointer to presentation format address (`dst'), or NULL (see errno).
     338 * author:
     339 *      Paul Vixie, 1996.
     340 */
     341const char *
     342inet_ntop(af, src, dst, size)
     343        int af;
     344        const void *src;
     345        char *dst;
     346        size_t size;
     347{
     348        switch (af) {
     349        case AF_INET:
     350                return (inet_ntop4(src, dst, size));
     351        case AF_INET6:
     352                return (inet_ntop6(src, dst, size));
     353        default:
     354                errno = WSAEAFNOSUPPORT;
     355                return (NULL);
     356        }
     357        /* NOTREACHED */
     358}
     359
     360/* const char *
     361 * inet_ntop4(src, dst, size)
     362 *      format an IPv4 address
     363 * return:
     364 *      `dst' (as a const)
     365 * notes:
     366 *      (1) uses no statics
     367 *      (2) takes a u_char* not an in_addr as input
     368 * author:
     369 *      Paul Vixie, 1996.
     370 */
     371static const char *
     372inet_ntop4(src, dst, size)
     373        const u_char *src;
     374        char *dst;
     375        size_t size;
     376{
     377        static const char fmt[] = "%u.%u.%u.%u";
     378        char tmp[sizeof "255.255.255.255"];
     379        int nprinted;
     380
     381        nprinted = g_snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
     382        if (nprinted < 0)
     383                return (NULL);  /* we assume "errno" was set by "g_snprintf()" */
     384        if ((size_t)nprinted > size) {
     385                errno = ENOSPC;
     386                return (NULL);
     387        }
     388        strcpy(dst, tmp);
     389        return (dst);
     390}
     391
     392/* const char *
     393 * inet_ntop6(src, dst, size)
     394 *      convert IPv6 binary address into presentation (printable) format
     395 * author:
     396 *      Paul Vixie, 1996.
     397 */
     398static const char *
     399inet_ntop6(src, dst, size)
     400        const u_char *src;
     401        char *dst;
     402        size_t size;
     403{
     404        /*
     405         * Note that int32_t and int16_t need only be "at least" large enough
     406         * to contain a value of the specified size.  On some systems, like
     407         * Crays, there is no such thing as an integer variable with 16 bits.
     408         * Keep this in mind if you think this function should have been coded
     409         * to use pointer overlays.  All the world's not a VAX.
     410         */
     411        char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
     412        struct { int base, len; } best, cur;
     413        guint words[NS_IN6ADDRSZ / NS_INT16SZ];
     414        int i;
     415
     416        /*
     417         * Preprocess:
     418         *      Copy the input (bytewise) array into a wordwise array.
     419         *      Find the longest run of 0x00's in src[] for :: shorthanding.
     420         */
     421        memset(words, '\0', sizeof words);
     422        for (i = 0; i < NS_IN6ADDRSZ; i++)
     423                words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
     424        best.base = -1;
     425        cur.base = -1;
     426        for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
     427                if (words[i] == 0) {
     428                        if (cur.base == -1)
     429                                cur.base = i, cur.len = 1;
     430                        else
     431                                cur.len++;
     432                } else {
     433                        if (cur.base != -1) {
     434                                if (best.base == -1 || cur.len > best.len)
     435                                        best = cur;
     436                                cur.base = -1;
     437                        }
     438                }
     439        }
     440        if (cur.base != -1) {
     441                if (best.base == -1 || cur.len > best.len)
     442                        best = cur;
     443        }
     444        if (best.base != -1 && best.len < 2)
     445                best.base = -1;
     446
     447        /*
     448         * Format the result.
     449         */
     450        tp = tmp;
     451        for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
     452                /* Are we inside the best run of 0x00's? */
     453                if (best.base != -1 && i >= best.base &&
     454                    i < (best.base + best.len)) {
     455                        if (i == best.base)
     456                                *tp++ = ':';
     457                        continue;
     458                }
     459                /* Are we following an initial run of 0x00s or any real hex? */
     460                if (i != 0)
     461                        *tp++ = ':';
     462                /* Is this address an encapsulated IPv4? */
     463                if (i == 6 && best.base == 0 &&
     464                    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
     465                        if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
     466                                return (NULL);
     467                        tp += strlen(tp);
     468                        break;
     469                }
     470                tp += g_snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]);
     471        }
     472        /* Was it a trailing run of 0x00's? */
     473        if (best.base != -1 && (best.base + best.len) ==
     474            (NS_IN6ADDRSZ / NS_INT16SZ))
     475                *tp++ = ':';
     476        *tp++ = '\0';
     477
     478        /*
     479         * Check for overflow, copy, and we're done.
     480         */
     481        if ((size_t)(tp - tmp) > size) {
     482                errno = ENOSPC;
     483                return (NULL);
     484        }
     485        strcpy(dst, tmp);
     486        return (dst);
     487}
     488
     489#ifdef AF_INET
     490static int inet_pton4(const char *src, u_char *dst);
     491#endif
     492#ifdef AF_INET6
     493static int inet_pton6(const char *src, u_char *dst);
     494#endif
     495
     496/* int
     497 * inet_pton(af, src, dst)
     498 *      convert from presentation format (which usually means ASCII printable)
     499 *      to network format (which is usually some kind of binary format).
     500 * return:
     501 *      1 if the address was valid for the specified address family
     502 *      0 if the address wasn't valid (`dst' is untouched in this case)
     503 *      -1 if some other error occurred (`dst' is untouched in this case, too)
     504 * author:
     505 *      Paul Vixie, 1996.
     506 */
     507int
     508inet_pton(af, src, dst)
     509        int af;
     510        const char *src;
     511        void *dst;
     512{
     513        switch (af) {
     514#ifdef AF_INET
     515        case AF_INET:
     516                return (inet_pton4(src, dst));
     517#endif
     518#ifdef AF_INET6
     519        case AF_INET6:
     520                return (inet_pton6(src, dst));
     521#endif
     522        default:
     523                errno = WSAEAFNOSUPPORT;
     524                return (-1);
     525        }
     526        /* NOTREACHED */
     527}
     528
     529#ifdef AF_INET
     530/* int
     531 * inet_pton4(src, dst)
     532 *      like inet_aton() but without all the hexadecimal and shorthand.
     533 * return:
     534 *      1 if `src' is a valid dotted quad, else 0.
     535 * notice:
     536 *      does not touch `dst' unless it's returning 1.
     537 * author:
     538 *      Paul Vixie, 1996.
     539 */
     540static int
     541inet_pton4(src, dst)
     542        const char *src;
     543        u_char *dst;
     544{
     545        static const char digits[] = "0123456789";
     546        int saw_digit, octets, ch;
     547        u_char tmp[NS_INADDRSZ], *tp;
     548
     549        saw_digit = 0;
     550        octets = 0;
     551        *(tp = tmp) = 0;
     552        while ((ch = *src++) != '\0') {
     553                const char *pch;
     554
     555                if ((pch = strchr(digits, ch)) != NULL) {
     556                        u_int new = *tp * 10 + (pch - digits);
     557
     558                        if (new > 255)
     559                                return (0);
     560                        *tp = new;
     561                        if (! saw_digit) {
     562                                if (++octets > 4)
     563                                        return (0);
     564                                saw_digit = 1;
     565                        }
     566                } else if (ch == '.' && saw_digit) {
     567                        if (octets == 4)
     568                                return (0);
     569                        *++tp = 0;
     570                        saw_digit = 0;
     571                } else
     572                        return (0);
     573        }
     574        if (octets < 4)
     575                return (0);
     576        memcpy(dst, tmp, NS_INADDRSZ);
     577        return (1);
     578}
     579#endif
     580
     581#ifdef AF_INET6
     582/* int
     583 * inet_pton6(src, dst)
     584 *      convert presentation level address to network order binary form.
     585 * return:
     586 *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
     587 * notice:
     588 *      (1) does not touch `dst' unless it's returning 1.
     589 *      (2) :: in a full address is silently ignored.
     590 * credit:
     591 *      inspired by Mark Andrews.
     592 * author:
     593 *      Paul Vixie, 1996.
     594 */
     595static int
     596inet_pton6(src, dst)
     597        const char *src;
     598        u_char *dst;
     599{
     600        static const char xdigits_l[] = "0123456789abcdef",
     601                          xdigits_u[] = "0123456789ABCDEF";
     602        u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
     603        const char *xdigits, *curtok;
     604        int ch, saw_xdigit;
     605        u_int val;
     606
     607        memset((tp = tmp), '\0', NS_IN6ADDRSZ);
     608        endp = tp + NS_IN6ADDRSZ;
     609        colonp = NULL;
     610        /* Leading :: requires some special handling. */
     611        if (*src == ':')
     612                if (*++src != ':')
     613                        return (0);
     614        curtok = src;
     615        saw_xdigit = 0;
     616        val = 0;
     617        while ((ch = *src++) != '\0') {
     618                const char *pch;
     619
     620                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
     621                        pch = strchr((xdigits = xdigits_u), ch);
     622                if (pch != NULL) {
     623                        val <<= 4;
     624                        val |= (pch - xdigits);
     625                        if (val > 0xffff)
     626                                return (0);
     627                        saw_xdigit = 1;
     628                        continue;
     629                }
     630                if (ch == ':') {
     631                        curtok = src;
     632                        if (!saw_xdigit) {
     633                                if (colonp)
     634                                        return (0);
     635                                colonp = tp;
     636                                continue;
     637                        } else if (*src == '\0') {
     638                                return (0);
     639                        }
     640                        if (tp + NS_INT16SZ > endp)
     641                                return (0);
     642                        *tp++ = (u_char) (val >> 8) & 0xff;
     643                        *tp++ = (u_char) val & 0xff;
     644                        saw_xdigit = 0;
     645                        val = 0;
     646                        continue;
     647                }
     648                if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
     649                    inet_pton4(curtok, tp) > 0) {
     650                        tp += NS_INADDRSZ;
     651                        saw_xdigit = 0;
     652                        break;  /* '\0' was seen by inet_pton4(). */
     653                }
     654                return (0);
     655        }
     656        if (saw_xdigit) {
     657                if (tp + NS_INT16SZ > endp)
     658                        return (0);
     659                *tp++ = (u_char) (val >> 8) & 0xff;
     660                *tp++ = (u_char) val & 0xff;
     661        }
     662        if (colonp != NULL) {
     663                /*
     664                 * Since some memmove()'s erroneously fail to handle
     665                 * overlapping regions, we'll do the shift by hand.
     666                 */
     667                const int n = tp - colonp;
     668                int i;
     669
     670                if (tp == endp)
     671                        return (0);
     672                for (i = 1; i <= n; i++) {
     673                        endp[- i] = colonp[n - i];
     674                        colonp[n - i] = 0;
     675                }
     676                tp = endp;
     677        }
     678        if (tp != endp)
     679                return (0);
     680        memcpy(dst, tmp, NS_IN6ADDRSZ);
     681        return (1);
     682}
     683#endif
Note: See TracChangeset for help on using the changeset viewer.