diff --git a/src/backend/utils/adt/inet_net_ntop.c b/src/backend/utils/adt/inet_net_ntop.c index fd19eadde1..79a9f1cc3d 100644 --- a/src/backend/utils/adt/inet_net_ntop.c +++ b/src/backend/utils/adt/inet_net_ntop.c @@ -1,33 +1,37 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. * - * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_ntop.c,v 1.18 2003/11/29 19:51:58 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_ntop.c,v 1.19 2005/02/01 00:59:09 tgl Exp $ */ +#if defined(LIBC_SCCS) && !defined(lint) +static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $"; +#endif + #include "postgres.h" +#include #include #include #include -#include - #include "utils/inet.h" #include "utils/builtins.h" + #define NS_IN6ADDRSZ 16 #define NS_INT16SZ 2 @@ -81,7 +85,7 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) * pointer to dst, or NULL if an error occurred (check errno). * note: * network byte order assumed. this means 192.5.5.240/28 has - * 0x11110000 in its fourth octet. + * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), July 1996 */ @@ -98,23 +102,28 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) errno = EINVAL; return (NULL); } + if (bits == 0) { if (size < sizeof "0") goto emsgsize; *dst++ = '0'; + size--; *dst = '\0'; } /* Format whole octets. */ for (b = bits / 8; b > 0; b--) { - if (size < sizeof ".255") + if (size <= sizeof "255.") goto emsgsize; t = dst; - if (dst != odst) - *dst++ = '.'; dst += SPRINTF((dst, "%u", *src++)); + if (b > 1) + { + *dst++ = '.'; + *dst = '\0'; + } size -= (size_t) (dst - t); } @@ -122,7 +131,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) b = bits % 8; if (b > 0) { - if (size < sizeof ".255") + if (size <= sizeof ".255") goto emsgsize; t = dst; if (dst != odst) @@ -133,10 +142,9 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) } /* Format CIDR /width. */ - if (size < sizeof "/32") + if (size <= sizeof "/32") goto emsgsize; dst += SPRINTF((dst, "/%u", bits)); - return (odst); emsgsize: @@ -146,7 +154,7 @@ emsgsize: /* * static char * - * inet_net_ntop_ipv6(src, bits, fakebits, dst, size) + * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size) * convert IPv6 network number from network to presentation format. * generates CIDR style result always. Picks the shortest representation * unless the IP is really IPv4. @@ -173,7 +181,6 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) tmp_zero_l; int i; int is_ipv4 = 0; - int double_colon = 0; unsigned char inbuf[16]; char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; char *cp; @@ -187,14 +194,12 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) } cp = outbuf; - double_colon = 0; if (bits == 0) { *cp++ = ':'; *cp++ = ':'; *cp = '\0'; - double_colon = 1; } else { @@ -244,8 +249,8 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) } if (zero_l != words && zero_s == 0 && ((zero_l == 6) || - ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || - ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) + ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || + ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) is_ipv4 = 1; /* Format whole words. */ @@ -257,10 +262,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) if (p == zero_s) *cp++ = ':'; if (p == words - 1) - { *cp++ = ':'; - double_colon = 1; - } s++; s++; continue; @@ -286,18 +288,8 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) } } } - - if (!double_colon) - { - if (bits < 128 - 32) - cp += SPRINTF((cp, "::")); - else if (bits < 128 - 16) - cp += SPRINTF((cp, ":0")); - } - /* Format CIDR /width. */ SPRINTF((cp, "/%u", bits)); - if (strlen(outbuf) + 1 > size) goto emsgsize; strcpy(dst, outbuf); @@ -309,6 +301,7 @@ emsgsize: return (NULL); } + /* * char * * inet_net_ntop(af, src, bits, dst, size) @@ -368,7 +361,7 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) /* Always format all four octets, regardless of mask length. */ for (b = len; b > 0; b--) { - if (size < sizeof ".255") + if (size <= sizeof ".255") goto emsgsize; t = dst; if (dst != odst) @@ -380,7 +373,7 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) /* don't print masklen if 32 bits */ if (bits != 32) { - if (size < sizeof "/32") + if (size <= sizeof "/32") goto emsgsize; dst += SPRINTF((dst, "/%u", bits)); } @@ -401,7 +394,7 @@ decoct(const u_char *src, int bytes, char *dst, size_t size) for (b = 1; b <= bytes; b++) { - if (size < sizeof "255.") + if (size <= sizeof "255.") return (0); t = dst; dst += SPRINTF((dst, "%u", *src++)); diff --git a/src/backend/utils/adt/inet_net_pton.c b/src/backend/utils/adt/inet_net_pton.c index 090c7949cb..a6911740cd 100644 --- a/src/backend/utils/adt/inet_net_pton.c +++ b/src/backend/utils/adt/inet_net_pton.c @@ -1,43 +1,47 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. * - * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_pton.c,v 1.19 2004/10/07 15:21:53 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_pton.c,v 1.20 2005/02/01 00:59:09 tgl Exp $ */ +#if defined(LIBC_SCCS) && !defined(lint) +static const char rcsid[] = "Id: inet_net_pton.c,v 1.4.2.3 2004/03/17 00:40:11 marka Exp $"; +#endif + #include "postgres.h" +#include #include #include #include - #include #include -#include #include "utils/inet.h" - #include "utils/builtins.h" + static int inet_net_pton_ipv4(const char *src, u_char *dst); static int inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size); static int inet_net_pton_ipv6(const char *src, u_char *dst); static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size); + /* - * static int + * int * inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. @@ -85,19 +89,18 @@ inet_net_pton(int af, const char *src, void *dst, size_t size) * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has - * 0x11110000 in its fourth octet. + * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */ static int inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) { - static const char - xdigits[] = "0123456789abcdef", - digits[] = "0123456789"; + static const char xdigits[] = "0123456789abcdef"; + static const char digits[] = "0123456789"; int n, ch, - tmp, + tmp = 0, dirty, bits; const u_char *odst = dst; @@ -107,10 +110,9 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) && isxdigit((unsigned char) src[1])) { /* Hexadecimal: Eat nybble string. */ - if (size <= 0) + if (size <= 0U) goto emsgsize; dirty = 0; - tmp = 0; src++; /* skip x or X. */ while ((ch = *src++) != '\0' && isxdigit((unsigned char) ch)) { @@ -124,7 +126,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) tmp = (tmp << 4) | n; if (++dirty == 2) { - if (size-- <= 0) + if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; dirty = 0; @@ -132,7 +134,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) } if (dirty) { /* Odd trailing nybble? */ - if (size-- <= 0) + if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) (tmp << 4); } @@ -153,7 +155,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) goto enoent; } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch)); - if (size-- <= 0) + if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; if (ch == '\0' || ch == '/') @@ -200,22 +202,28 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) if (*odst >= 240) /* Class E */ bits = 32; else if (*odst >= 224) /* Class D */ - bits = 4; + bits = 8; else if (*odst >= 192) /* Class C */ bits = 24; else if (*odst >= 128) /* Class B */ bits = 16; - else - /* Class A */ + else /* Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ - if (bits >= 8 && bits < ((dst - odst) * 8)) + if (bits < ((dst - odst) * 8)) bits = (dst - odst) * 8; + + /* + * If there are no additional bits specified for a class D address + * adjust bits to 4. + */ + if (bits == 8 && *odst == 224) + bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { - if (size-- <= 0) + if (size-- <= 0U) goto emsgsize; *dst++ = '\0'; }