11/*
2- * Copyright (c) 1996 by Internet Software Consortium.
2+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3+ * Copyright (c) 1996,1999 by Internet Software Consortium.
34 *
45 * Permission to use, copy, modify, and distribute this software for any
56 * purpose with or without fee is hereby granted, provided that the above
67 * copyright notice and this permission notice appear in all copies.
78 *
8- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15- * SOFTWARE.
9+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1616 *
17- * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_ntop.c,v 1.18 2003/11/29 19:51:58 pgsql Exp $
17+ * $PostgreSQL: pgsql/src/backend/utils/adt/inet_net_ntop.c,v 1.19 2005/02/01 00:59:09 tgl Exp $
1818 */
1919
20+ #if defined(LIBC_SCCS )&& !defined(lint )
21+ static const char rcsid []= "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $" ;
22+ #endif
23+
2024#include "postgres.h"
2125
26+ #include <sys/types.h>
2227#include <sys/socket.h>
2328#include <netinet/in.h>
2429#include <arpa/inet.h>
2530
26- #include <errno.h>
27-
2831#include "utils/inet.h"
2932#include "utils/builtins.h"
3033
34+
3135#define NS_IN6ADDRSZ 16
3236#define NS_INT16SZ 2
3337
@@ -81,7 +85,7 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
8185 *pointer to dst, or NULL if an error occurred (check errno).
8286 * note:
8387 *network byte order assumed. this means 192.5.5.240/28 has
84- *0x11110000 in its fourth octet.
88+ *0b11110000 in its fourth octet.
8589 * author:
8690 *Paul Vixie (ISC), July 1996
8791 */
@@ -98,31 +102,36 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
98102errno = EINVAL ;
99103return (NULL );
100104}
105+
101106if (bits == 0 )
102107{
103108if (size < sizeof "0" )
104109gotoemsgsize ;
105110* dst ++ = '0' ;
111+ size -- ;
106112* dst = '\0' ;
107113}
108114
109115/* Format whole octets. */
110116for (b = bits /8 ;b > 0 ;b -- )
111117{
112- if (size < sizeof ". 255" )
118+ if (size <= sizeof "255. " )
113119gotoemsgsize ;
114120t = dst ;
115- if (dst != odst )
116- * dst ++ = '.' ;
117121dst += SPRINTF ((dst ,"%u" ,* src ++ ));
122+ if (b > 1 )
123+ {
124+ * dst ++ = '.' ;
125+ * dst = '\0' ;
126+ }
118127size -= (size_t ) (dst - t );
119128}
120129
121130/* Format partial octet. */
122131b = bits %8 ;
123132if (b > 0 )
124133{
125- if (size < sizeof ".255" )
134+ if (size <= sizeof ".255" )
126135gotoemsgsize ;
127136t = dst ;
128137if (dst != odst )
@@ -133,10 +142,9 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
133142}
134143
135144/* Format CIDR /width. */
136- if (size < sizeof "/32" )
145+ if (size <= sizeof "/32" )
137146gotoemsgsize ;
138147dst += SPRINTF ((dst ,"/%u" ,bits ));
139-
140148return (odst );
141149
142150emsgsize :
@@ -146,7 +154,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
146154
147155/*
148156 * static char *
149- *inet_net_ntop_ipv6 (src, bits, fakebits, dst, size)
157+ *inet_cidr_ntop_ipv6 (src, bits, fakebits, dst, size)
150158 *convert IPv6 network number from network to presentation format.
151159 *generates CIDR style result always. Picks the shortest representation
152160 *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)
173181tmp_zero_l ;
174182int i ;
175183int is_ipv4 = 0 ;
176- int double_colon = 0 ;
177184unsignedchar inbuf [16 ];
178185char outbuf [sizeof ("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128" )];
179186char * cp ;
@@ -187,14 +194,12 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
187194}
188195
189196cp = outbuf ;
190- double_colon = 0 ;
191197
192198if (bits == 0 )
193199{
194200* cp ++ = ':' ;
195201* cp ++ = ':' ;
196202* cp = '\0' ;
197- double_colon = 1 ;
198203}
199204else
200205{
@@ -244,8 +249,8 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
244249}
245250
246251if (zero_l != words && zero_s == 0 && ((zero_l == 6 )||
247- ((zero_l == 5 && s [10 ]== 0xff && s [11 ]== 0xff )||
248- ((zero_l == 7 && s [14 ]!= 0 && s [15 ]!= 1 )))))
252+ ((zero_l == 5 && s [10 ]== 0xff && s [11 ]== 0xff )||
253+ ((zero_l == 7 && s [14 ]!= 0 && s [15 ]!= 1 )))))
249254is_ipv4 = 1 ;
250255
251256/* Format whole words. */
@@ -257,10 +262,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
257262if (p == zero_s )
258263* cp ++ = ':' ;
259264if (p == words - 1 )
260- {
261265* cp ++ = ':' ;
262- double_colon = 1 ;
263- }
264266s ++ ;
265267s ++ ;
266268continue ;
@@ -286,18 +288,8 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
286288}
287289}
288290}
289-
290- if (!double_colon )
291- {
292- if (bits < 128 - 32 )
293- cp += SPRINTF ((cp ,"::" ));
294- else if (bits < 128 - 16 )
295- cp += SPRINTF ((cp ,":0" ));
296- }
297-
298291/* Format CIDR /width. */
299292SPRINTF ((cp ,"/%u" ,bits ));
300-
301293if (strlen (outbuf )+ 1 > size )
302294gotoemsgsize ;
303295strcpy (dst ,outbuf );
@@ -309,6 +301,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
309301return (NULL );
310302}
311303
304+
312305/*
313306 * char *
314307 * 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)
368361/* Always format all four octets, regardless of mask length. */
369362for (b = len ;b > 0 ;b -- )
370363{
371- if (size < sizeof ".255" )
364+ if (size <= sizeof ".255" )
372365gotoemsgsize ;
373366t = dst ;
374367if (dst != odst )
@@ -380,7 +373,7 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
380373/* don't print masklen if 32 bits */
381374if (bits != 32 )
382375{
383- if (size < sizeof "/32" )
376+ if (size <= sizeof "/32" )
384377gotoemsgsize ;
385378dst += SPRINTF ((dst ,"/%u" ,bits ));
386379}
@@ -401,7 +394,7 @@ decoct(const u_char *src, int bytes, char *dst, size_t size)
401394
402395for (b = 1 ;b <=bytes ;b ++ )
403396{
404- if (size < sizeof "255." )
397+ if (size <= sizeof "255." )
405398return (0 );
406399t = dst ;
407400dst += SPRINTF ((dst ,"%u" ,* src ++ ));