How to use inet_pton() with the mingw compiler?

前端 未结 2 1323
迷失自我
迷失自我 2021-02-04 16:26

I\'m trying to add IPv6 compatibility to an already IPv4-compatible program in C, but having some problems with the compiler. Currently compiling with mingw32-gcc-4.6.2, which g

2条回答
  •  悲&欢浪女
    2021-02-04 17:01

    Author: Paul Vixie, 1996. Tested in MinGW/GCC:

    int inet_pton(int af, const char *src, char *dst)
    {
        switch (af)
        {
        case AF_INET:
            return inet_pton4(src, dst);
        case AF_INET6:
            return inet_pton6(src, dst);
        default:
            return -1;
        }
    }
    

    ..

    #define NS_INADDRSZ  4
    #define NS_IN6ADDRSZ 16
    #define NS_INT16SZ   2
    

    ..

    int inet_pton4(const char *src, char *dst)
    {
        uint8_t tmp[NS_INADDRSZ], *tp;
    
        int saw_digit = 0;
        int octets = 0;
        *(tp = tmp) = 0;
    
        int ch;
        while ((ch = *src++) != '\0')
        {
            if (ch >= '0' && ch <= '9')
            {
                uint32_t n = *tp * 10 + (ch - '0');
    
                if (saw_digit && *tp == 0)
                    return 0;
    
                if (n > 255)
                    return 0;
    
                *tp = n;
                if (!saw_digit)
                {
                    if (++octets > 4)
                        return 0;
                    saw_digit = 1;
                }
            }
            else if (ch == '.' && saw_digit)
            {
                if (octets == 4)
                    return 0;
                *++tp = 0;
                saw_digit = 0;
            }
            else
                return 0;
        }
        if (octets < 4)
            return 0;
    
        memcpy(dst, tmp, NS_INADDRSZ);
    
        return 1;
    }
    

    ...

    int inet_pton6(const char *src, char *dst)
    {
        static const char xdigits[] = "0123456789abcdef";
        uint8_t tmp[NS_IN6ADDRSZ];
    
        uint8_t *tp = (uint8_t*) memset(tmp, '\0', NS_IN6ADDRSZ);
        uint8_t *endp = tp + NS_IN6ADDRSZ;
        uint8_t *colonp = NULL;
    
        /* Leading :: requires some special handling. */
        if (*src == ':')
        {
            if (*++src != ':')
                return 0;
        }
    
        const char *curtok = src;
        int saw_xdigit = 0;
        uint32_t val = 0;
        int ch;
        while ((ch = tolower(*src++)) != '\0')
        {
            const char *pch = strchr(xdigits, 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 + NS_INT16SZ > endp)
                    return 0;
                *tp++ = (uint8_t) (val >> 8) & 0xff;
                *tp++ = (uint8_t) val & 0xff;
                saw_xdigit = 0;
                val = 0;
                continue;
            }
            if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
                    inet_pton4(curtok, (char*) tp) > 0)
            {
                tp += NS_INADDRSZ;
                saw_xdigit = 0;
                break; /* '\0' was seen by inet_pton4(). */
            }
            return 0;
        }
        if (saw_xdigit)
        {
            if (tp + NS_INT16SZ > endp)
                return 0;
            *tp++ = (uint8_t) (val >> 8) & 0xff;
            *tp++ = (uint8_t) 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;
    
            if (tp == endp)
                return 0;
    
            for (int i = 1; i <= n; i++)
            {
                endp[-i] = colonp[n - i];
                colonp[n - i] = 0;
            }
            tp = endp;
        }
        if (tp != endp)
            return 0;
    
        memcpy(dst, tmp, NS_IN6ADDRSZ);
    
        return 1;
    }
    

提交回复
热议问题