11/*-------------------------------------------------------------------------
22 *
3- * ip .c
4- * IPv6-aware network access .
3+ * ifaddr .c
4+ * IP netmask calculations, and enumerating network interfaces .
55 *
66 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 *
1010 * IDENTIFICATION
11- * src/backend/libpq/ip .c
11+ * src/backend/libpq/ifaddr .c
1212 *
1313 * This file and the IPV6 implementation were initially provided by
1414 * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
1717 *-------------------------------------------------------------------------
1818 */
1919
20- /* This is intended to be used in both frontend and backend, so use c.h */
21- #include "c.h"
20+ #include "postgres.h"
2221
2322#include <unistd.h>
2423#include <sys/types.h>
3231#include <arpa/inet.h>
3332#include <sys/file.h>
3433
35- #include "libpq/ip.h"
36-
34+ #include "libpq/ifaddr.h"
3735
3836static int range_sockaddr_AF_INET (const struct sockaddr_in * addr ,
3937 const struct sockaddr_in * netaddr ,
@@ -45,226 +43,6 @@ static int range_sockaddr_AF_INET6(const struct sockaddr_in6 * addr,
4543 const struct sockaddr_in6 * netmask );
4644#endif
4745
48- #ifdef HAVE_UNIX_SOCKETS
49- static int getaddrinfo_unix (const char * path ,
50- const struct addrinfo * hintsp ,
51- struct addrinfo * * result );
52-
53- static int getnameinfo_unix (const struct sockaddr_un * sa , int salen ,
54- char * node , int nodelen ,
55- char * service , int servicelen ,
56- int flags );
57- #endif
58-
59-
60- /*
61- * pg_getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets
62- */
63- int
64- pg_getaddrinfo_all (const char * hostname , const char * servname ,
65- const struct addrinfo * hintp , struct addrinfo * * result )
66- {
67- int rc ;
68-
69- /* not all versions of getaddrinfo() zero *result on failure */
70- * result = NULL ;
71-
72- #ifdef HAVE_UNIX_SOCKETS
73- if (hintp -> ai_family == AF_UNIX )
74- return getaddrinfo_unix (servname , hintp , result );
75- #endif
76-
77- /* NULL has special meaning to getaddrinfo(). */
78- rc = getaddrinfo ((!hostname || hostname [0 ] == '\0' ) ? NULL : hostname ,
79- servname , hintp , result );
80-
81- return rc ;
82- }
83-
84-
85- /*
86- * pg_freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix
87- *
88- * Note: the ai_family field of the original hint structure must be passed
89- * so that we can tell whether the addrinfo struct was built by the system's
90- * getaddrinfo() routine or our own getaddrinfo_unix() routine. Some versions
91- * of getaddrinfo() might be willing to return AF_UNIX addresses, so it's
92- * not safe to look at ai_family in the addrinfo itself.
93- */
94- void
95- pg_freeaddrinfo_all (int hint_ai_family , struct addrinfo * ai )
96- {
97- #ifdef HAVE_UNIX_SOCKETS
98- if (hint_ai_family == AF_UNIX )
99- {
100- /* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */
101- while (ai != NULL )
102- {
103- struct addrinfo * p = ai ;
104-
105- ai = ai -> ai_next ;
106- free (p -> ai_addr );
107- free (p );
108- }
109- }
110- else
111- #endif /* HAVE_UNIX_SOCKETS */
112- {
113- /* struct was built by getaddrinfo() */
114- if (ai != NULL )
115- freeaddrinfo (ai );
116- }
117- }
118-
119-
120- /*
121- * pg_getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets
122- *
123- * The API of this routine differs from the standard getnameinfo() definition
124- * in two ways: first, the addr parameter is declared as sockaddr_storage
125- * rather than struct sockaddr, and second, the node and service fields are
126- * guaranteed to be filled with something even on failure return.
127- */
128- int
129- pg_getnameinfo_all (const struct sockaddr_storage * addr , int salen ,
130- char * node , int nodelen ,
131- char * service , int servicelen ,
132- int flags )
133- {
134- int rc ;
135-
136- #ifdef HAVE_UNIX_SOCKETS
137- if (addr && addr -> ss_family == AF_UNIX )
138- rc = getnameinfo_unix ((const struct sockaddr_un * ) addr , salen ,
139- node , nodelen ,
140- service , servicelen ,
141- flags );
142- else
143- #endif
144- rc = getnameinfo ((const struct sockaddr * ) addr , salen ,
145- node , nodelen ,
146- service , servicelen ,
147- flags );
148-
149- if (rc != 0 )
150- {
151- if (node )
152- strlcpy (node , "???" , nodelen );
153- if (service )
154- strlcpy (service , "???" , servicelen );
155- }
156-
157- return rc ;
158- }
159-
160-
161- #if defined(HAVE_UNIX_SOCKETS )
162-
163- /* -------
164- * getaddrinfo_unix - get unix socket info using IPv6-compatible API
165- *
166- * Bugs: only one addrinfo is set even though hintsp is NULL or
167- * ai_socktype is 0
168- * AI_CANONNAME is not supported.
169- * -------
170- */
171- static int
172- getaddrinfo_unix (const char * path , const struct addrinfo * hintsp ,
173- struct addrinfo * * result )
174- {
175- struct addrinfo hints ;
176- struct addrinfo * aip ;
177- struct sockaddr_un * unp ;
178-
179- * result = NULL ;
180-
181- MemSet (& hints , 0 , sizeof (hints ));
182-
183- if (strlen (path ) >= sizeof (unp -> sun_path ))
184- return EAI_FAIL ;
185-
186- if (hintsp == NULL )
187- {
188- hints .ai_family = AF_UNIX ;
189- hints .ai_socktype = SOCK_STREAM ;
190- }
191- else
192- memcpy (& hints , hintsp , sizeof (hints ));
193-
194- if (hints .ai_socktype == 0 )
195- hints .ai_socktype = SOCK_STREAM ;
196-
197- if (hints .ai_family != AF_UNIX )
198- {
199- /* shouldn't have been called */
200- return EAI_FAIL ;
201- }
202-
203- aip = calloc (1 , sizeof (struct addrinfo ));
204- if (aip == NULL )
205- return EAI_MEMORY ;
206-
207- unp = calloc (1 , sizeof (struct sockaddr_un ));
208- if (unp == NULL )
209- {
210- free (aip );
211- return EAI_MEMORY ;
212- }
213-
214- aip -> ai_family = AF_UNIX ;
215- aip -> ai_socktype = hints .ai_socktype ;
216- aip -> ai_protocol = hints .ai_protocol ;
217- aip -> ai_next = NULL ;
218- aip -> ai_canonname = NULL ;
219- * result = aip ;
220-
221- unp -> sun_family = AF_UNIX ;
222- aip -> ai_addr = (struct sockaddr * ) unp ;
223- aip -> ai_addrlen = sizeof (struct sockaddr_un );
224-
225- strcpy (unp -> sun_path , path );
226-
227- #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
228- unp -> sun_len = sizeof (struct sockaddr_un );
229- #endif
230-
231- return 0 ;
232- }
233-
234- /*
235- * Convert an address to a hostname.
236- */
237- static int
238- getnameinfo_unix (const struct sockaddr_un * sa , int salen ,
239- char * node , int nodelen ,
240- char * service , int servicelen ,
241- int flags )
242- {
243- int ret = -1 ;
244-
245- /* Invalid arguments. */
246- if (sa == NULL || sa -> sun_family != AF_UNIX ||
247- (node == NULL && service == NULL ))
248- return EAI_FAIL ;
249-
250- if (node )
251- {
252- ret = snprintf (node , nodelen , "%s" , "[local]" );
253- if (ret == -1 || ret > nodelen )
254- return EAI_MEMORY ;
255- }
256-
257- if (service )
258- {
259- ret = snprintf (service , servicelen , "%s" , sa -> sun_path );
260- if (ret == -1 || ret > servicelen )
261- return EAI_MEMORY ;
262- }
263-
264- return 0 ;
265- }
266- #endif /* HAVE_UNIX_SOCKETS */
267-
26846
26947/*
27048 * pg_range_sockaddr - is addr within the subnet specified by netaddr/netmask ?
0 commit comments