xref: /freebsd/contrib/libpcap/sockutils.c (revision afdbf109c6a661a729938f68211054a0a50d38ac)
1ada6f083SXin LI /*
2ada6f083SXin LI  * Copyright (c) 2002 - 2003
3ada6f083SXin LI  * NetGroup, Politecnico di Torino (Italy)
4ada6f083SXin LI  * All rights reserved.
5ada6f083SXin LI  *
6ada6f083SXin LI  * Redistribution and use in source and binary forms, with or without
7ada6f083SXin LI  * modification, are permitted provided that the following conditions
8ada6f083SXin LI  * are met:
9ada6f083SXin LI  *
10ada6f083SXin LI  * 1. Redistributions of source code must retain the above copyright
11ada6f083SXin LI  * notice, this list of conditions and the following disclaimer.
12ada6f083SXin LI  * 2. Redistributions in binary form must reproduce the above copyright
13ada6f083SXin LI  * notice, this list of conditions and the following disclaimer in the
14ada6f083SXin LI  * documentation and/or other materials provided with the distribution.
15ada6f083SXin LI  * 3. Neither the name of the Politecnico di Torino nor the names of its
16ada6f083SXin LI  * contributors may be used to endorse or promote products derived from
17ada6f083SXin LI  * this software without specific prior written permission.
18ada6f083SXin LI  *
19ada6f083SXin LI  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20ada6f083SXin LI  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21ada6f083SXin LI  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22ada6f083SXin LI  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23ada6f083SXin LI  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24ada6f083SXin LI  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25ada6f083SXin LI  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26ada6f083SXin LI  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27ada6f083SXin LI  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28ada6f083SXin LI  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29ada6f083SXin LI  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30ada6f083SXin LI  *
31ada6f083SXin LI  */
32ada6f083SXin LI 
33b00ab754SHans Petter Selasky #include <config.h>
34ada6f083SXin LI 
35ada6f083SXin LI /*
36ada6f083SXin LI  * \file sockutils.c
37ada6f083SXin LI  *
38ada6f083SXin LI  * The goal of this file is to provide a common set of primitives for socket
39ada6f083SXin LI  * manipulation.
40ada6f083SXin LI  *
41ada6f083SXin LI  * Although the socket interface defined in the RFC 2553 (and its updates)
42ada6f083SXin LI  * is excellent, there are still differences between the behavior of those
43ada6f083SXin LI  * routines on UN*X and Windows, and between UN*Xes.
44ada6f083SXin LI  *
45ada6f083SXin LI  * These calls provide an interface similar to the socket interface, but
46ada6f083SXin LI  * that hides the differences between operating systems.  It does not
47ada6f083SXin LI  * attempt to significantly improve on the socket interface in other
48ada6f083SXin LI  * ways.
49ada6f083SXin LI  */
50ada6f083SXin LI 
51b00ab754SHans Petter Selasky #include "ftmacros.h"
52b00ab754SHans Petter Selasky 
53b00ab754SHans Petter Selasky #include <string.h>
54ada6f083SXin LI #include <errno.h>	/* for the errno variable */
55ada6f083SXin LI #include <stdio.h>	/* for the stderr file */
56ada6f083SXin LI #include <stdlib.h>	/* for malloc() and free() */
576f9cba8fSJoseph Mingrone #include <limits.h>	/* for INT_MAX */
58ada6f083SXin LI 
59b00ab754SHans Petter Selasky #include "pcap-int.h"
60b00ab754SHans Petter Selasky 
61ada6f083SXin LI #include "sockutils.h"
62b00ab754SHans Petter Selasky #include "portability.h"
63ada6f083SXin LI 
64ada6f083SXin LI #ifdef _WIN32
65ada6f083SXin LI   /*
66ada6f083SXin LI    * Winsock initialization.
67ada6f083SXin LI    *
686f9cba8fSJoseph Mingrone    * Ask for Winsock 2.2.
69ada6f083SXin LI    */
70ada6f083SXin LI   #define WINSOCK_MAJOR_VERSION 2
71ada6f083SXin LI   #define WINSOCK_MINOR_VERSION 2
72ada6f083SXin LI 
73ada6f083SXin LI   static int sockcount = 0;	/*!< Variable that allows calling the WSAStartup() only one time */
74ada6f083SXin LI #endif
75ada6f083SXin LI 
76ada6f083SXin LI /* Some minor differences between UNIX and Win32 */
77ada6f083SXin LI #ifdef _WIN32
78ada6f083SXin LI   #define SHUT_WR SD_SEND	/* The control code for shutdown() is different in Win32 */
79ada6f083SXin LI #endif
80ada6f083SXin LI 
81ada6f083SXin LI /* Size of the buffer that has to keep error messages */
82ada6f083SXin LI #define SOCK_ERRBUF_SIZE 1024
83ada6f083SXin LI 
84ada6f083SXin LI /* Constants; used in order to keep strings here */
85ada6f083SXin LI #define SOCKET_NO_NAME_AVAILABLE "No name available"
86ada6f083SXin LI #define SOCKET_NO_PORT_AVAILABLE "No port available"
87ada6f083SXin LI #define SOCKET_NAME_NULL_DAD "Null address (possibly DAD Phase)"
88ada6f083SXin LI 
89b00ab754SHans Petter Selasky /*
90b00ab754SHans Petter Selasky  * On UN*X, send() and recv() return ssize_t.
91b00ab754SHans Petter Selasky  *
92b00ab754SHans Petter Selasky  * On Windows, send() and recv() return an int.
93b00ab754SHans Petter Selasky  *
946f9cba8fSJoseph Mingrone  *   With MSVC, there *is* no ssize_t.
95b00ab754SHans Petter Selasky  *
96b00ab754SHans Petter Selasky  *   With MinGW, there is an ssize_t type; it is either an int (32 bit)
97b00ab754SHans Petter Selasky  *   or a long long (64 bit).
98b00ab754SHans Petter Selasky  *
99b00ab754SHans Petter Selasky  * So, on Windows, if we don't have ssize_t defined, define it as an
100b00ab754SHans Petter Selasky  * int, so we can use it, on all platforms, as the type of variables
101b00ab754SHans Petter Selasky  * that hold the return values from send() and recv().
102b00ab754SHans Petter Selasky  */
103b00ab754SHans Petter Selasky #if defined(_WIN32) && !defined(_SSIZE_T_DEFINED)
104b00ab754SHans Petter Selasky typedef int ssize_t;
105b00ab754SHans Petter Selasky #endif
106b00ab754SHans Petter Selasky 
107ada6f083SXin LI /****************************************************
108ada6f083SXin LI  *                                                  *
109ada6f083SXin LI  * Locally defined functions                        *
110ada6f083SXin LI  *                                                  *
111ada6f083SXin LI  ****************************************************/
112ada6f083SXin LI 
113ada6f083SXin LI static int sock_ismcastaddr(const struct sockaddr *saddr);
114ada6f083SXin LI 
115ada6f083SXin LI /****************************************************
116ada6f083SXin LI  *                                                  *
117ada6f083SXin LI  * Function bodies                                  *
118ada6f083SXin LI  *                                                  *
119ada6f083SXin LI  ****************************************************/
120ada6f083SXin LI 
1216f9cba8fSJoseph Mingrone #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1226f9cba8fSJoseph Mingrone const uint8_t *fuzzBuffer;
1236f9cba8fSJoseph Mingrone size_t fuzzSize;
1246f9cba8fSJoseph Mingrone size_t fuzzPos;
1256f9cba8fSJoseph Mingrone 
sock_initfuzz(const uint8_t * Data,size_t Size)1266f9cba8fSJoseph Mingrone void sock_initfuzz(const uint8_t *Data, size_t Size) {
1276f9cba8fSJoseph Mingrone 	fuzzPos = 0;
1286f9cba8fSJoseph Mingrone 	fuzzSize = Size;
1296f9cba8fSJoseph Mingrone 	fuzzBuffer = Data;
1306f9cba8fSJoseph Mingrone }
1316f9cba8fSJoseph Mingrone 
fuzz_recv(char * bufp,int remaining)1326f9cba8fSJoseph Mingrone static int fuzz_recv(char *bufp, int remaining) {
1336f9cba8fSJoseph Mingrone 	if (remaining > fuzzSize - fuzzPos) {
1346f9cba8fSJoseph Mingrone 		remaining = fuzzSize - fuzzPos;
1356f9cba8fSJoseph Mingrone 	}
1366f9cba8fSJoseph Mingrone 	if (fuzzPos < fuzzSize) {
1376f9cba8fSJoseph Mingrone 		memcpy(bufp, fuzzBuffer + fuzzPos, remaining);
1386f9cba8fSJoseph Mingrone 	}
1396f9cba8fSJoseph Mingrone 	fuzzPos += remaining;
1406f9cba8fSJoseph Mingrone 	return remaining;
1416f9cba8fSJoseph Mingrone }
1426f9cba8fSJoseph Mingrone #endif
1436f9cba8fSJoseph Mingrone 
sock_geterrcode(void)1446f9cba8fSJoseph Mingrone int sock_geterrcode(void)
1456f9cba8fSJoseph Mingrone {
1466f9cba8fSJoseph Mingrone #ifdef _WIN32
1476f9cba8fSJoseph Mingrone 	return GetLastError();
1486f9cba8fSJoseph Mingrone #else
1496f9cba8fSJoseph Mingrone 	return errno;
1506f9cba8fSJoseph Mingrone #endif
1516f9cba8fSJoseph Mingrone }
1526f9cba8fSJoseph Mingrone 
153ada6f083SXin LI /*
1546f9cba8fSJoseph Mingrone  * Format an error message given an errno value (UN*X) or a Winsock error
155b00ab754SHans Petter Selasky  * (Windows).
156b00ab754SHans Petter Selasky  */
sock_vfmterrmsg(char * errbuf,size_t errbuflen,int errcode,const char * fmt,va_list ap)1576f9cba8fSJoseph Mingrone void sock_vfmterrmsg(char *errbuf, size_t errbuflen, int errcode,
1586f9cba8fSJoseph Mingrone     const char *fmt, va_list ap)
159b00ab754SHans Petter Selasky {
16057e22627SCy Schubert 	if (errbuf == NULL)
16157e22627SCy Schubert 		return;
16257e22627SCy Schubert 
163b00ab754SHans Petter Selasky #ifdef _WIN32
164*afdbf109SJoseph Mingrone 	pcapint_vfmt_errmsg_for_win32_err(errbuf, errbuflen, errcode,
1656f9cba8fSJoseph Mingrone 	    fmt, ap);
166b00ab754SHans Petter Selasky #else
167*afdbf109SJoseph Mingrone 	pcapint_vfmt_errmsg_for_errno(errbuf, errbuflen, errcode,
1686f9cba8fSJoseph Mingrone 	    fmt, ap);
169b00ab754SHans Petter Selasky #endif
170b00ab754SHans Petter Selasky }
171b00ab754SHans Petter Selasky 
sock_fmterrmsg(char * errbuf,size_t errbuflen,int errcode,const char * fmt,...)1726f9cba8fSJoseph Mingrone void sock_fmterrmsg(char *errbuf, size_t errbuflen, int errcode,
1736f9cba8fSJoseph Mingrone     const char *fmt, ...)
174ada6f083SXin LI {
1756f9cba8fSJoseph Mingrone 	va_list ap;
1766f9cba8fSJoseph Mingrone 
1776f9cba8fSJoseph Mingrone 	va_start(ap, fmt);
1786f9cba8fSJoseph Mingrone 	sock_vfmterrmsg(errbuf, errbuflen, errcode, fmt, ap);
1796f9cba8fSJoseph Mingrone 	va_end(ap);
1806f9cba8fSJoseph Mingrone }
1816f9cba8fSJoseph Mingrone 
1826f9cba8fSJoseph Mingrone /*
1836f9cba8fSJoseph Mingrone  * Format an error message for the last socket error.
1846f9cba8fSJoseph Mingrone  */
sock_geterrmsg(char * errbuf,size_t errbuflen,const char * fmt,...)1856f9cba8fSJoseph Mingrone void sock_geterrmsg(char *errbuf, size_t errbuflen, const char *fmt, ...)
1866f9cba8fSJoseph Mingrone {
1876f9cba8fSJoseph Mingrone 	va_list ap;
1886f9cba8fSJoseph Mingrone 
1896f9cba8fSJoseph Mingrone 	va_start(ap, fmt);
1906f9cba8fSJoseph Mingrone 	sock_vfmterrmsg(errbuf, errbuflen, sock_geterrcode(), fmt, ap);
1916f9cba8fSJoseph Mingrone 	va_end(ap);
1926f9cba8fSJoseph Mingrone }
1936f9cba8fSJoseph Mingrone 
1946f9cba8fSJoseph Mingrone /*
1956f9cba8fSJoseph Mingrone  * Types of error.
1966f9cba8fSJoseph Mingrone  *
1976f9cba8fSJoseph Mingrone  * These are sorted by how likely they are to be the "underlying" problem,
1986f9cba8fSJoseph Mingrone  * so that lower-rated errors for a given address in a given family
1996f9cba8fSJoseph Mingrone  * should not overwrite higher-rated errors for another address in that
2006f9cba8fSJoseph Mingrone  * family, and higher-rated errors should overwrite lower-rated errors.
2016f9cba8fSJoseph Mingrone  */
2026f9cba8fSJoseph Mingrone typedef enum {
2036f9cba8fSJoseph Mingrone 	SOCK_CONNERR,		/* connection error */
2046f9cba8fSJoseph Mingrone 	SOCK_HOSTERR,		/* host error */
2056f9cba8fSJoseph Mingrone 	SOCK_NETERR,		/* network error */
2066f9cba8fSJoseph Mingrone 	SOCK_AFNOTSUPERR,	/* address family not supported */
2076f9cba8fSJoseph Mingrone 	SOCK_UNKNOWNERR,	/* unknown error */
2086f9cba8fSJoseph Mingrone 	SOCK_NOERR		/* no error */
2096f9cba8fSJoseph Mingrone } sock_errtype;
2106f9cba8fSJoseph Mingrone 
sock_geterrtype(int errcode)2116f9cba8fSJoseph Mingrone static sock_errtype sock_geterrtype(int errcode)
2126f9cba8fSJoseph Mingrone {
2136f9cba8fSJoseph Mingrone 	switch (errcode) {
2146f9cba8fSJoseph Mingrone 
215ada6f083SXin LI #ifdef _WIN32
2166f9cba8fSJoseph Mingrone 	case WSAECONNRESET:
2176f9cba8fSJoseph Mingrone 	case WSAECONNABORTED:
2186f9cba8fSJoseph Mingrone 	case WSAECONNREFUSED:
219ada6f083SXin LI #else
2206f9cba8fSJoseph Mingrone 	case ECONNRESET:
2216f9cba8fSJoseph Mingrone 	case ECONNABORTED:
2226f9cba8fSJoseph Mingrone 	case ECONNREFUSED:
223ada6f083SXin LI #endif
2246f9cba8fSJoseph Mingrone 		/*
2256f9cba8fSJoseph Mingrone 		 * Connection error; this means the problem is probably
2266f9cba8fSJoseph Mingrone 		 * that there's no server set up on the remote machine,
2276f9cba8fSJoseph Mingrone 		 * or that it is set up, but it's IPv4-only or IPv6-only
2286f9cba8fSJoseph Mingrone 		 * and we're trying the wrong address family.
2296f9cba8fSJoseph Mingrone 		 *
2306f9cba8fSJoseph Mingrone 		 * These overwrite all other errors, as they indicate
231*afdbf109SJoseph Mingrone 		 * that, even if something else went wrong in another
2326f9cba8fSJoseph Mingrone 		 * attempt, this probably wouldn't work even if the
2336f9cba8fSJoseph Mingrone 		 * other problems were fixed.
2346f9cba8fSJoseph Mingrone 		 */
2356f9cba8fSJoseph Mingrone 		return (SOCK_CONNERR);
2366f9cba8fSJoseph Mingrone 
2376f9cba8fSJoseph Mingrone #ifdef _WIN32
2386f9cba8fSJoseph Mingrone 	case WSAENETUNREACH:
2396f9cba8fSJoseph Mingrone 	case WSAETIMEDOUT:
2406f9cba8fSJoseph Mingrone 	case WSAEHOSTDOWN:
2416f9cba8fSJoseph Mingrone 	case WSAEHOSTUNREACH:
2426f9cba8fSJoseph Mingrone #else
2436f9cba8fSJoseph Mingrone 	case ENETUNREACH:
2446f9cba8fSJoseph Mingrone 	case ETIMEDOUT:
2456f9cba8fSJoseph Mingrone 	case EHOSTDOWN:
2466f9cba8fSJoseph Mingrone 	case EHOSTUNREACH:
2476f9cba8fSJoseph Mingrone #endif
2486f9cba8fSJoseph Mingrone 		/*
2496f9cba8fSJoseph Mingrone 		 * Network errors that could be IPv4-specific, IPv6-
2506f9cba8fSJoseph Mingrone 		 * specific, or present with both.
2516f9cba8fSJoseph Mingrone 		 *
2526f9cba8fSJoseph Mingrone 		 * Don't overwrite connection errors, but overwrite
2536f9cba8fSJoseph Mingrone 		 * everything else.
2546f9cba8fSJoseph Mingrone 		 */
2556f9cba8fSJoseph Mingrone 		return (SOCK_HOSTERR);
2566f9cba8fSJoseph Mingrone 
2576f9cba8fSJoseph Mingrone #ifdef _WIN32
2586f9cba8fSJoseph Mingrone 	case WSAENETDOWN:
2596f9cba8fSJoseph Mingrone 	case WSAENETRESET:
2606f9cba8fSJoseph Mingrone #else
2616f9cba8fSJoseph Mingrone 	case ENETDOWN:
2626f9cba8fSJoseph Mingrone 	case ENETRESET:
2636f9cba8fSJoseph Mingrone #endif
2646f9cba8fSJoseph Mingrone 		/*
2656f9cba8fSJoseph Mingrone 		 * Network error; this means we don't know whether
2666f9cba8fSJoseph Mingrone 		 * there's a server set up on the remote machine,
2676f9cba8fSJoseph Mingrone 		 * and we don't have a reason to believe that IPv6
2686f9cba8fSJoseph Mingrone 		 * any worse or better than IPv4.
2696f9cba8fSJoseph Mingrone 		 *
2706f9cba8fSJoseph Mingrone 		 * These probably indicate a local failure, e.g.
2716f9cba8fSJoseph Mingrone 		 * an interface is down.
2726f9cba8fSJoseph Mingrone 		 *
2736f9cba8fSJoseph Mingrone 		 * Don't overwrite connection errors or host errors,
2746f9cba8fSJoseph Mingrone 		 * but overwrite everything else.
2756f9cba8fSJoseph Mingrone 		 */
2766f9cba8fSJoseph Mingrone 		return (SOCK_NETERR);
2776f9cba8fSJoseph Mingrone 
2786f9cba8fSJoseph Mingrone #ifdef _WIN32
2796f9cba8fSJoseph Mingrone 	case WSAEAFNOSUPPORT:
2806f9cba8fSJoseph Mingrone #else
2816f9cba8fSJoseph Mingrone 	case EAFNOSUPPORT:
2826f9cba8fSJoseph Mingrone #endif
2836f9cba8fSJoseph Mingrone 		/*
2846f9cba8fSJoseph Mingrone 		 * "Address family not supported" probably means
2856f9cba8fSJoseph Mingrone 		 * "No soup^WIPv6 for you!".
2866f9cba8fSJoseph Mingrone 		 *
2876f9cba8fSJoseph Mingrone 		 * Don't overwrite connection errors, host errors, or
2886f9cba8fSJoseph Mingrone 		 * network errors (none of which we should get for this
2896f9cba8fSJoseph Mingrone 		 * address family if it's not supported), but overwrite
2906f9cba8fSJoseph Mingrone 		 * everything else.
2916f9cba8fSJoseph Mingrone 		 */
2926f9cba8fSJoseph Mingrone 		return (SOCK_AFNOTSUPERR);
2936f9cba8fSJoseph Mingrone 
2946f9cba8fSJoseph Mingrone 	default:
2956f9cba8fSJoseph Mingrone 		/*
2966f9cba8fSJoseph Mingrone 		 * Anything else.
2976f9cba8fSJoseph Mingrone 		 *
2986f9cba8fSJoseph Mingrone 		 * Don't overwrite any errors.
2996f9cba8fSJoseph Mingrone 		 */
3006f9cba8fSJoseph Mingrone 		return (SOCK_UNKNOWNERR);
3016f9cba8fSJoseph Mingrone 	}
302ada6f083SXin LI }
303ada6f083SXin LI 
304ada6f083SXin LI /*
30557e22627SCy Schubert  * \brief This function initializes the socket mechanism if it hasn't
30657e22627SCy Schubert  * already been initialized or reinitializes it after it has been
30757e22627SCy Schubert  * cleaned up.
308ada6f083SXin LI  *
30957e22627SCy Schubert  * On UN*Xes, it doesn't need to do anything; on Windows, it needs to
31057e22627SCy Schubert  * initialize Winsock.
311ada6f083SXin LI  *
31257e22627SCy Schubert  * \param errbuf: a pointer to an user-allocated buffer that will contain
31357e22627SCy Schubert  * the complete error message. This buffer has to be at least 'errbuflen'
31457e22627SCy Schubert  * in length. It can be NULL; in this case no error message is supplied.
315ada6f083SXin LI  *
31657e22627SCy Schubert  * \param errbuflen: length of the buffer that will contains the error.
31757e22627SCy Schubert  * The error message cannot be larger than 'errbuflen - 1' because the
31857e22627SCy Schubert  * last char is reserved for the string terminator.
319ada6f083SXin LI  *
32057e22627SCy Schubert  * \return '0' if everything is fine, '-1' if some errors occurred. The
32157e22627SCy Schubert  * error message is returned in the buffer pointed to by 'errbuf' variable.
322ada6f083SXin LI  */
323b00ab754SHans Petter Selasky #ifdef _WIN32
sock_init(char * errbuf,int errbuflen)324ada6f083SXin LI int sock_init(char *errbuf, int errbuflen)
325ada6f083SXin LI {
326ada6f083SXin LI 	if (sockcount == 0)
327ada6f083SXin LI 	{
328ada6f083SXin LI 		WSADATA wsaData;			/* helper variable needed to initialize Winsock */
329ada6f083SXin LI 
330ada6f083SXin LI 		if (WSAStartup(MAKEWORD(WINSOCK_MAJOR_VERSION,
331ada6f083SXin LI 		    WINSOCK_MINOR_VERSION), &wsaData) != 0)
332ada6f083SXin LI 		{
333ada6f083SXin LI 			if (errbuf)
3346f9cba8fSJoseph Mingrone 				snprintf(errbuf, errbuflen, "Failed to initialize Winsock\n");
335ada6f083SXin LI 			return -1;
336ada6f083SXin LI 		}
337ada6f083SXin LI 	}
338ada6f083SXin LI 
339ada6f083SXin LI 	sockcount++;
34057e22627SCy Schubert 	return 0;
34157e22627SCy Schubert }
342b00ab754SHans Petter Selasky #else
sock_init(char * errbuf _U_,int errbuflen _U_)343b00ab754SHans Petter Selasky int sock_init(char *errbuf _U_, int errbuflen _U_)
344b00ab754SHans Petter Selasky {
34557e22627SCy Schubert 	/*
34657e22627SCy Schubert 	 * Nothing to do on UN*Xes.
34757e22627SCy Schubert 	 */
348ada6f083SXin LI 	return 0;
349ada6f083SXin LI }
35057e22627SCy Schubert #endif
351ada6f083SXin LI 
352ada6f083SXin LI /*
35357e22627SCy Schubert  * \brief This function cleans up the socket mechanism if we have no
35457e22627SCy Schubert  * sockets left open.
355ada6f083SXin LI  *
35657e22627SCy Schubert  * On UN*Xes, it doesn't need to do anything; on Windows, it needs
35757e22627SCy Schubert  * to clean up Winsock.
358ada6f083SXin LI  *
359ada6f083SXin LI  * \return No error values.
360ada6f083SXin LI  */
sock_cleanup(void)361ada6f083SXin LI void sock_cleanup(void)
362ada6f083SXin LI {
363ada6f083SXin LI #ifdef _WIN32
364ada6f083SXin LI 	sockcount--;
365ada6f083SXin LI 
366ada6f083SXin LI 	if (sockcount == 0)
367ada6f083SXin LI 		WSACleanup();
368ada6f083SXin LI #endif
369ada6f083SXin LI }
370ada6f083SXin LI 
371ada6f083SXin LI /*
372ada6f083SXin LI  * \brief It checks if the sockaddr variable contains a multicast address.
373ada6f083SXin LI  *
374ada6f083SXin LI  * \return '0' if the address is multicast, '-1' if it is not.
375ada6f083SXin LI  */
sock_ismcastaddr(const struct sockaddr * saddr)376ada6f083SXin LI static int sock_ismcastaddr(const struct sockaddr *saddr)
377ada6f083SXin LI {
378ada6f083SXin LI 	if (saddr->sa_family == PF_INET)
379ada6f083SXin LI 	{
380ada6f083SXin LI 		struct sockaddr_in *saddr4 = (struct sockaddr_in *) saddr;
381ada6f083SXin LI 		if (IN_MULTICAST(ntohl(saddr4->sin_addr.s_addr))) return 0;
382ada6f083SXin LI 		else return -1;
383ada6f083SXin LI 	}
384ada6f083SXin LI 	else
385ada6f083SXin LI 	{
386ada6f083SXin LI 		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
387ada6f083SXin LI 		if (IN6_IS_ADDR_MULTICAST(&saddr6->sin6_addr)) return 0;
388ada6f083SXin LI 		else return -1;
389ada6f083SXin LI 	}
390ada6f083SXin LI }
391ada6f083SXin LI 
3926f9cba8fSJoseph Mingrone struct addr_status {
3936f9cba8fSJoseph Mingrone 	struct addrinfo *info;
3946f9cba8fSJoseph Mingrone 	int errcode;
3956f9cba8fSJoseph Mingrone 	sock_errtype errtype;
3966f9cba8fSJoseph Mingrone };
3976f9cba8fSJoseph Mingrone 
3986f9cba8fSJoseph Mingrone /*
3996f9cba8fSJoseph Mingrone  * Sort by IPv4 address vs. IPv6 address.
4006f9cba8fSJoseph Mingrone  */
compare_addrs_to_try_by_address_family(const void * a,const void * b)4016f9cba8fSJoseph Mingrone static int compare_addrs_to_try_by_address_family(const void *a, const void *b)
4026f9cba8fSJoseph Mingrone {
4036f9cba8fSJoseph Mingrone 	const struct addr_status *addr_a = (const struct addr_status *)a;
4046f9cba8fSJoseph Mingrone 	const struct addr_status *addr_b = (const struct addr_status *)b;
4056f9cba8fSJoseph Mingrone 
4066f9cba8fSJoseph Mingrone 	return addr_a->info->ai_family - addr_b->info->ai_family;
4076f9cba8fSJoseph Mingrone }
4086f9cba8fSJoseph Mingrone 
4096f9cba8fSJoseph Mingrone /*
4106f9cba8fSJoseph Mingrone  * Sort by error type and, within a given error type, by error code and,
4116f9cba8fSJoseph Mingrone  * within a given error code, by IPv4 address vs. IPv6 address.
4126f9cba8fSJoseph Mingrone  */
compare_addrs_to_try_by_status(const void * a,const void * b)4136f9cba8fSJoseph Mingrone static int compare_addrs_to_try_by_status(const void *a, const void *b)
4146f9cba8fSJoseph Mingrone {
4156f9cba8fSJoseph Mingrone 	const struct addr_status *addr_a = (const struct addr_status *)a;
4166f9cba8fSJoseph Mingrone 	const struct addr_status *addr_b = (const struct addr_status *)b;
4176f9cba8fSJoseph Mingrone 
4186f9cba8fSJoseph Mingrone 	if (addr_a->errtype == addr_b->errtype)
4196f9cba8fSJoseph Mingrone 	{
4206f9cba8fSJoseph Mingrone 		if (addr_a->errcode == addr_b->errcode)
4216f9cba8fSJoseph Mingrone 		{
4226f9cba8fSJoseph Mingrone 			return addr_a->info->ai_family - addr_b->info->ai_family;
4236f9cba8fSJoseph Mingrone 		}
4246f9cba8fSJoseph Mingrone 		return addr_a->errcode - addr_b->errcode;
4256f9cba8fSJoseph Mingrone 	}
4266f9cba8fSJoseph Mingrone 
4276f9cba8fSJoseph Mingrone 	return addr_a->errtype - addr_b->errtype;
4286f9cba8fSJoseph Mingrone }
4296f9cba8fSJoseph Mingrone 
sock_create_socket(struct addrinfo * addrinfo,char * errbuf,int errbuflen)430*afdbf109SJoseph Mingrone static PCAP_SOCKET sock_create_socket(struct addrinfo *addrinfo, char *errbuf,
4316f9cba8fSJoseph Mingrone     int errbuflen)
4326f9cba8fSJoseph Mingrone {
433*afdbf109SJoseph Mingrone 	PCAP_SOCKET sock;
4346f9cba8fSJoseph Mingrone #ifdef SO_NOSIGPIPE
4356f9cba8fSJoseph Mingrone 	int on = 1;
4366f9cba8fSJoseph Mingrone #endif
4376f9cba8fSJoseph Mingrone 
4386f9cba8fSJoseph Mingrone 	sock = socket(addrinfo->ai_family, addrinfo->ai_socktype,
4396f9cba8fSJoseph Mingrone 	    addrinfo->ai_protocol);
4406f9cba8fSJoseph Mingrone 	if (sock == INVALID_SOCKET)
4416f9cba8fSJoseph Mingrone 	{
4426f9cba8fSJoseph Mingrone 		sock_geterrmsg(errbuf, errbuflen, "socket() failed");
4436f9cba8fSJoseph Mingrone 		return INVALID_SOCKET;
4446f9cba8fSJoseph Mingrone 	}
4456f9cba8fSJoseph Mingrone 
4466f9cba8fSJoseph Mingrone 	/*
4476f9cba8fSJoseph Mingrone 	 * Disable SIGPIPE, if we have SO_NOSIGPIPE.  We don't want to
4486f9cba8fSJoseph Mingrone 	 * have to deal with signals if the peer closes the connection,
4496f9cba8fSJoseph Mingrone 	 * especially in client programs, which may not even be aware that
4506f9cba8fSJoseph Mingrone 	 * they're sending to sockets.
4516f9cba8fSJoseph Mingrone 	 */
4526f9cba8fSJoseph Mingrone #ifdef SO_NOSIGPIPE
4536f9cba8fSJoseph Mingrone 	if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (char *)&on,
4546f9cba8fSJoseph Mingrone 	    sizeof (int)) == -1)
4556f9cba8fSJoseph Mingrone 	{
4566f9cba8fSJoseph Mingrone 		sock_geterrmsg(errbuf, errbuflen,
4576f9cba8fSJoseph Mingrone 		    "setsockopt(SO_NOSIGPIPE) failed");
4586f9cba8fSJoseph Mingrone 		closesocket(sock);
4596f9cba8fSJoseph Mingrone 		return INVALID_SOCKET;
4606f9cba8fSJoseph Mingrone 	}
4616f9cba8fSJoseph Mingrone #endif
4626f9cba8fSJoseph Mingrone 	return sock;
4636f9cba8fSJoseph Mingrone }
4646f9cba8fSJoseph Mingrone 
465ada6f083SXin LI /*
466ada6f083SXin LI  * \brief It initializes a network connection both from the client and the server side.
467ada6f083SXin LI  *
468ada6f083SXin LI  * In case of a client socket, this function calls socket() and connect().
469ada6f083SXin LI  * In the meanwhile, it checks for any socket error.
470ada6f083SXin LI  * If an error occurs, it writes the error message into 'errbuf'.
471ada6f083SXin LI  *
472ada6f083SXin LI  * In case of a server socket, the function calls socket(), bind() and listen().
473ada6f083SXin LI  *
4746f9cba8fSJoseph Mingrone  * This function is usually preceded by the sock_initaddress().
4756f9cba8fSJoseph Mingrone  *
4766f9cba8fSJoseph Mingrone  * \param host: for client sockets, the host name to which we're trying
4776f9cba8fSJoseph Mingrone  * to connect.
478ada6f083SXin LI  *
479ada6f083SXin LI  * \param addrinfo: pointer to an addrinfo variable which will be used to
480ada6f083SXin LI  * open the socket and such. This variable is the one returned by the previous call to
481ada6f083SXin LI  * sock_initaddress().
482ada6f083SXin LI  *
483ada6f083SXin LI  * \param server: '1' if this is a server socket, '0' otherwise.
484ada6f083SXin LI  *
485ada6f083SXin LI  * \param nconn: number of the connections that are allowed to wait into the listen() call.
486ada6f083SXin LI  * This value has no meanings in case of a client socket.
487ada6f083SXin LI  *
488ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
489ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
490ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
491ada6f083SXin LI  *
492ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
493ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
494ada6f083SXin LI  *
495ada6f083SXin LI  * \return the socket that has been opened (that has to be used in the following sockets calls)
496b00ab754SHans Petter Selasky  * if everything is fine, INVALID_SOCKET if some errors occurred. The error message is returned
497ada6f083SXin LI  * in the 'errbuf' variable.
498ada6f083SXin LI  */
sock_open(const char * host,struct addrinfo * addrinfo,int server,int nconn,char * errbuf,int errbuflen)499*afdbf109SJoseph Mingrone PCAP_SOCKET sock_open(const char *host, struct addrinfo *addrinfo,
500*afdbf109SJoseph Mingrone     int server, int nconn, char *errbuf, int errbuflen)
501ada6f083SXin LI {
502*afdbf109SJoseph Mingrone 	PCAP_SOCKET sock;
503ada6f083SXin LI 
504ada6f083SXin LI 	/* This is a server socket */
505ada6f083SXin LI 	if (server)
506ada6f083SXin LI 	{
5076f9cba8fSJoseph Mingrone 		int on;
5086f9cba8fSJoseph Mingrone 
5096f9cba8fSJoseph Mingrone 		/*
5106f9cba8fSJoseph Mingrone 		 * Attempt to create the socket.
5116f9cba8fSJoseph Mingrone 		 */
5126f9cba8fSJoseph Mingrone 		sock = sock_create_socket(addrinfo, errbuf, errbuflen);
5136f9cba8fSJoseph Mingrone 		if (sock == INVALID_SOCKET)
5146f9cba8fSJoseph Mingrone 		{
5156f9cba8fSJoseph Mingrone 			return INVALID_SOCKET;
5166f9cba8fSJoseph Mingrone 		}
5176f9cba8fSJoseph Mingrone 
51857e22627SCy Schubert 		/*
51957e22627SCy Schubert 		 * Allow a new server to bind the socket after the old one
52057e22627SCy Schubert 		 * exited, even if lingering sockets are still present.
52157e22627SCy Schubert 		 *
52257e22627SCy Schubert 		 * Don't treat an error as a failure.
52357e22627SCy Schubert 		 */
5246f9cba8fSJoseph Mingrone 		on = 1;
52557e22627SCy Schubert 		(void)setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5266f9cba8fSJoseph Mingrone 		    (char *)&on, sizeof (on));
52757e22627SCy Schubert 
528b00ab754SHans Petter Selasky #if defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY)
529ada6f083SXin LI 		/*
530b00ab754SHans Petter Selasky 		 * Force the use of IPv6-only addresses.
531b00ab754SHans Petter Selasky 		 *
532b00ab754SHans Petter Selasky 		 * RFC 3493 indicates that you can support IPv4 on an
533b00ab754SHans Petter Selasky 		 * IPv6 socket:
534b00ab754SHans Petter Selasky 		 *
535b00ab754SHans Petter Selasky 		 *    https://tools.ietf.org/html/rfc3493#section-3.7
536b00ab754SHans Petter Selasky 		 *
537b00ab754SHans Petter Selasky 		 * and that this is the default behavior.  This means
538b00ab754SHans Petter Selasky 		 * that if we first create an IPv6 socket bound to the
539b00ab754SHans Petter Selasky 		 * "any" address, it is, in effect, also bound to the
540b00ab754SHans Petter Selasky 		 * IPv4 "any" address, so when we create an IPv4 socket
541b00ab754SHans Petter Selasky 		 * and try to bind it to the IPv4 "any" address, it gets
542b00ab754SHans Petter Selasky 		 * EADDRINUSE.
543b00ab754SHans Petter Selasky 		 *
544b00ab754SHans Petter Selasky 		 * Not all network stacks support IPv4 on IPv6 sockets;
545b00ab754SHans Petter Selasky 		 * pre-NT 6 Windows stacks don't support it, and the
546b00ab754SHans Petter Selasky 		 * OpenBSD stack doesn't support it for security reasons
547b00ab754SHans Petter Selasky 		 * (see the OpenBSD inet6(4) man page).  Therefore, we
548b00ab754SHans Petter Selasky 		 * don't want to rely on this behavior.
549b00ab754SHans Petter Selasky 		 *
550b00ab754SHans Petter Selasky 		 * So we try to disable it, using either the IPV6_V6ONLY
551b00ab754SHans Petter Selasky 		 * option from RFC 3493:
552b00ab754SHans Petter Selasky 		 *
553b00ab754SHans Petter Selasky 		 *    https://tools.ietf.org/html/rfc3493#section-5.3
554b00ab754SHans Petter Selasky 		 *
555b00ab754SHans Petter Selasky 		 * or the IPV6_BINDV6ONLY option from older UN*Xes.
556ada6f083SXin LI 		 */
557b00ab754SHans Petter Selasky #ifndef IPV6_V6ONLY
558b00ab754SHans Petter Selasky   /* For older systems */
559b00ab754SHans Petter Selasky   #define IPV6_V6ONLY IPV6_BINDV6ONLY
560b00ab754SHans Petter Selasky #endif /* IPV6_V6ONLY */
561ada6f083SXin LI 		if (addrinfo->ai_family == PF_INET6)
562ada6f083SXin LI 		{
5636f9cba8fSJoseph Mingrone 			on = 1;
564b00ab754SHans Petter Selasky 			if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
565b00ab754SHans Petter Selasky 			    (char *)&on, sizeof (int)) == -1)
566ada6f083SXin LI 			{
567ada6f083SXin LI 				if (errbuf)
5686f9cba8fSJoseph Mingrone 					snprintf(errbuf, errbuflen, "setsockopt(IPV6_V6ONLY)");
569b00ab754SHans Petter Selasky 				closesocket(sock);
570b00ab754SHans Petter Selasky 				return INVALID_SOCKET;
571ada6f083SXin LI 			}
572ada6f083SXin LI 		}
573b00ab754SHans Petter Selasky #endif /* defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY) */
574ada6f083SXin LI 
575ada6f083SXin LI 		/* WARNING: if the address is a mcast one, I should place the proper Win32 code here */
576ada6f083SXin LI 		if (bind(sock, addrinfo->ai_addr, (int) addrinfo->ai_addrlen) != 0)
577ada6f083SXin LI 		{
5786f9cba8fSJoseph Mingrone 			sock_geterrmsg(errbuf, errbuflen, "bind() failed");
579b00ab754SHans Petter Selasky 			closesocket(sock);
580b00ab754SHans Petter Selasky 			return INVALID_SOCKET;
581ada6f083SXin LI 		}
582ada6f083SXin LI 
583ada6f083SXin LI 		if (addrinfo->ai_socktype == SOCK_STREAM)
584ada6f083SXin LI 			if (listen(sock, nconn) == -1)
585ada6f083SXin LI 			{
5866f9cba8fSJoseph Mingrone 				sock_geterrmsg(errbuf, errbuflen,
5876f9cba8fSJoseph Mingrone 				    "listen() failed");
588b00ab754SHans Petter Selasky 				closesocket(sock);
589b00ab754SHans Petter Selasky 				return INVALID_SOCKET;
590ada6f083SXin LI 			}
591ada6f083SXin LI 
592ada6f083SXin LI 		/* server side ended */
593ada6f083SXin LI 		return sock;
594ada6f083SXin LI 	}
595ada6f083SXin LI 	else	/* we're the client */
596ada6f083SXin LI 	{
5976f9cba8fSJoseph Mingrone 		struct addr_status *addrs_to_try;
598ada6f083SXin LI 		struct addrinfo *tempaddrinfo;
5996f9cba8fSJoseph Mingrone 		size_t numaddrinfos;
6006f9cba8fSJoseph Mingrone 		size_t i;
6016f9cba8fSJoseph Mingrone 		int current_af = AF_UNSPEC;
602ada6f083SXin LI 
603ada6f083SXin LI 		/*
6046f9cba8fSJoseph Mingrone 		 * We have to loop though all the addrinfos returned.
6056f9cba8fSJoseph Mingrone 		 * For instance, we can have both IPv6 and IPv4 addresses,
6066f9cba8fSJoseph Mingrone 		 * but the service we're trying to connect to is unavailable
6076f9cba8fSJoseph Mingrone 		 * in IPv6, so we have to try in IPv4 as well.
6086f9cba8fSJoseph Mingrone 		 *
6096f9cba8fSJoseph Mingrone 		 * How many addrinfos do we have?
610ada6f083SXin LI 		 */
6116f9cba8fSJoseph Mingrone 		numaddrinfos =  0;
6126f9cba8fSJoseph Mingrone 		for (tempaddrinfo = addrinfo; tempaddrinfo != NULL;
6136f9cba8fSJoseph Mingrone 		    tempaddrinfo = tempaddrinfo->ai_next)
614ada6f083SXin LI 		{
6156f9cba8fSJoseph Mingrone 			numaddrinfos++;
6166f9cba8fSJoseph Mingrone 		}
617ada6f083SXin LI 
6186f9cba8fSJoseph Mingrone 		if (numaddrinfos == 0)
6196f9cba8fSJoseph Mingrone 		{
6206f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
6216f9cba8fSJoseph Mingrone 			    "There are no addresses in the address list");
6226f9cba8fSJoseph Mingrone 			return INVALID_SOCKET;
6236f9cba8fSJoseph Mingrone 		}
6246f9cba8fSJoseph Mingrone 
6256f9cba8fSJoseph Mingrone 		/*
6266f9cba8fSJoseph Mingrone 		 * Allocate an array of struct addr_status and fill it in.
6276f9cba8fSJoseph Mingrone 		 */
6286f9cba8fSJoseph Mingrone 		addrs_to_try = calloc(numaddrinfos, sizeof *addrs_to_try);
6296f9cba8fSJoseph Mingrone 		if (addrs_to_try == NULL)
6306f9cba8fSJoseph Mingrone 		{
6316f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
6326f9cba8fSJoseph Mingrone 			    "Out of memory connecting to %s", host);
6336f9cba8fSJoseph Mingrone 			return INVALID_SOCKET;
6346f9cba8fSJoseph Mingrone 		}
6356f9cba8fSJoseph Mingrone 
6366f9cba8fSJoseph Mingrone 		for (tempaddrinfo = addrinfo, i = 0; tempaddrinfo != NULL;
6376f9cba8fSJoseph Mingrone 		    tempaddrinfo = tempaddrinfo->ai_next, i++)
6386f9cba8fSJoseph Mingrone 		{
6396f9cba8fSJoseph Mingrone 			addrs_to_try[i].info = tempaddrinfo;
6406f9cba8fSJoseph Mingrone 			addrs_to_try[i].errcode = 0;
6416f9cba8fSJoseph Mingrone 			addrs_to_try[i].errtype = SOCK_NOERR;
6426f9cba8fSJoseph Mingrone 		}
6436f9cba8fSJoseph Mingrone 
6446f9cba8fSJoseph Mingrone 		/*
6456f9cba8fSJoseph Mingrone 		 * Sort the structures to put the IPv4 addresses before the
6466f9cba8fSJoseph Mingrone 		 * IPv6 addresses; we will have to create an IPv4 socket
6476f9cba8fSJoseph Mingrone 		 * for the IPv4 addresses and an IPv6 socket for the IPv6
6486f9cba8fSJoseph Mingrone 		 * addresses (one of the arguments to socket() is the
6496f9cba8fSJoseph Mingrone 		 * address/protocol family to use, and IPv4 and IPv6 are
6506f9cba8fSJoseph Mingrone 		 * separate address/protocol families).
6516f9cba8fSJoseph Mingrone 		 */
6526f9cba8fSJoseph Mingrone 		qsort(addrs_to_try, numaddrinfos, sizeof *addrs_to_try,
6536f9cba8fSJoseph Mingrone 		    compare_addrs_to_try_by_address_family);
6546f9cba8fSJoseph Mingrone 
6556f9cba8fSJoseph Mingrone 		/* Start out with no socket. */
6566f9cba8fSJoseph Mingrone 		sock = INVALID_SOCKET;
6576f9cba8fSJoseph Mingrone 
6586f9cba8fSJoseph Mingrone 		/*
6596f9cba8fSJoseph Mingrone 		 * Now try them all.
6606f9cba8fSJoseph Mingrone 		 */
6616f9cba8fSJoseph Mingrone 		for (i = 0; i < numaddrinfos; i++)
6626f9cba8fSJoseph Mingrone 		{
6636f9cba8fSJoseph Mingrone 			tempaddrinfo = addrs_to_try[i].info;
6646f9cba8fSJoseph Mingrone #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
6656f9cba8fSJoseph Mingrone 			break;
6666f9cba8fSJoseph Mingrone #endif
6676f9cba8fSJoseph Mingrone 			/*
6686f9cba8fSJoseph Mingrone 			 * If we have a socket, but it's for a
6696f9cba8fSJoseph Mingrone 			 * different address family, close it.
6706f9cba8fSJoseph Mingrone 			 */
6716f9cba8fSJoseph Mingrone 			if (sock != INVALID_SOCKET &&
6726f9cba8fSJoseph Mingrone 			    current_af != tempaddrinfo->ai_family)
6736f9cba8fSJoseph Mingrone 			{
6746f9cba8fSJoseph Mingrone 				closesocket(sock);
6756f9cba8fSJoseph Mingrone 				sock = INVALID_SOCKET;
6766f9cba8fSJoseph Mingrone 			}
6776f9cba8fSJoseph Mingrone 
6786f9cba8fSJoseph Mingrone 			/*
6796f9cba8fSJoseph Mingrone 			 * If we don't have a socket, open one
6806f9cba8fSJoseph Mingrone 			 * for *this* address's address family.
6816f9cba8fSJoseph Mingrone 			 */
6826f9cba8fSJoseph Mingrone 			if (sock == INVALID_SOCKET)
6836f9cba8fSJoseph Mingrone 			{
6846f9cba8fSJoseph Mingrone 				sock = sock_create_socket(tempaddrinfo,
6856f9cba8fSJoseph Mingrone 				    errbuf, errbuflen);
6866f9cba8fSJoseph Mingrone 				if (sock == INVALID_SOCKET)
6876f9cba8fSJoseph Mingrone 				{
6886f9cba8fSJoseph Mingrone 					free(addrs_to_try);
6896f9cba8fSJoseph Mingrone 					return INVALID_SOCKET;
6906f9cba8fSJoseph Mingrone 				}
6916f9cba8fSJoseph Mingrone 			}
692ada6f083SXin LI 			if (connect(sock, tempaddrinfo->ai_addr, (int) tempaddrinfo->ai_addrlen) == -1)
693ada6f083SXin LI 			{
6946f9cba8fSJoseph Mingrone 				addrs_to_try[i].errcode = sock_geterrcode();
6956f9cba8fSJoseph Mingrone 				addrs_to_try[i].errtype =
6966f9cba8fSJoseph Mingrone 				   sock_geterrtype(addrs_to_try[i].errcode);
697ada6f083SXin LI 			}
698ada6f083SXin LI 			else
699ada6f083SXin LI 				break;
700ada6f083SXin LI 		}
701ada6f083SXin LI 
702ada6f083SXin LI 		/*
7036f9cba8fSJoseph Mingrone 		 * Check how we exited from the previous loop.
7046f9cba8fSJoseph Mingrone 		 * If tempaddrinfo is equal to NULL, it means that all
7056f9cba8fSJoseph Mingrone 		 * the connect() attempts failed.  Construct an
7066f9cba8fSJoseph Mingrone 		 * error message.
707ada6f083SXin LI 		 */
7086f9cba8fSJoseph Mingrone 		if (i == numaddrinfos)
709ada6f083SXin LI 		{
7106f9cba8fSJoseph Mingrone 			int same_error_for_all;
7116f9cba8fSJoseph Mingrone 			int first_error;
7126f9cba8fSJoseph Mingrone 
713ada6f083SXin LI 			closesocket(sock);
7146f9cba8fSJoseph Mingrone 
7156f9cba8fSJoseph Mingrone 			/*
7166f9cba8fSJoseph Mingrone 			 * Sort the statuses to group together categories
7176f9cba8fSJoseph Mingrone 			 * of errors, errors within categories, and
7186f9cba8fSJoseph Mingrone 			 * address families within error sets.
7196f9cba8fSJoseph Mingrone 			 */
7206f9cba8fSJoseph Mingrone 			qsort(addrs_to_try, numaddrinfos, sizeof *addrs_to_try,
7216f9cba8fSJoseph Mingrone 			    compare_addrs_to_try_by_status);
7226f9cba8fSJoseph Mingrone 
7236f9cba8fSJoseph Mingrone 			/*
7246f9cba8fSJoseph Mingrone 			 * Are all the errors the same?
7256f9cba8fSJoseph Mingrone 			 */
7266f9cba8fSJoseph Mingrone 			same_error_for_all = 1;
7276f9cba8fSJoseph Mingrone 			first_error = addrs_to_try[0].errcode;
7286f9cba8fSJoseph Mingrone 			for (i = 1; i < numaddrinfos; i++)
7296f9cba8fSJoseph Mingrone 			{
7306f9cba8fSJoseph Mingrone 				if (addrs_to_try[i].errcode != first_error)
7316f9cba8fSJoseph Mingrone 				{
7326f9cba8fSJoseph Mingrone 					same_error_for_all = 0;
7336f9cba8fSJoseph Mingrone 					break;
7346f9cba8fSJoseph Mingrone 				}
7356f9cba8fSJoseph Mingrone 			}
7366f9cba8fSJoseph Mingrone 
7376f9cba8fSJoseph Mingrone 			if (same_error_for_all) {
7386f9cba8fSJoseph Mingrone 				/*
7396f9cba8fSJoseph Mingrone 				 * Yes.  No need to show the IP
7406f9cba8fSJoseph Mingrone 				 * addresses.
7416f9cba8fSJoseph Mingrone 				 */
7426f9cba8fSJoseph Mingrone 				if (addrs_to_try[0].errtype == SOCK_CONNERR) {
7436f9cba8fSJoseph Mingrone 					/*
7446f9cba8fSJoseph Mingrone 					 * Connection error; note that
7456f9cba8fSJoseph Mingrone 					 * the daemon might not be set
7466f9cba8fSJoseph Mingrone 					 * up correctly, or set up at all.
7476f9cba8fSJoseph Mingrone 					 */
7486f9cba8fSJoseph Mingrone 					sock_fmterrmsg(errbuf, errbuflen,
7496f9cba8fSJoseph Mingrone 					    addrs_to_try[0].errcode,
7506f9cba8fSJoseph Mingrone 					    "Is the server properly installed? Cannot connect to %s",
7516f9cba8fSJoseph Mingrone 					    host);
7526f9cba8fSJoseph Mingrone 				} else {
7536f9cba8fSJoseph Mingrone 					sock_fmterrmsg(errbuf, errbuflen,
7546f9cba8fSJoseph Mingrone 					    addrs_to_try[0].errcode,
7556f9cba8fSJoseph Mingrone 					    "Cannot connect to %s", host);
7566f9cba8fSJoseph Mingrone 				}
7576f9cba8fSJoseph Mingrone 			} else {
7586f9cba8fSJoseph Mingrone 				/*
7596f9cba8fSJoseph Mingrone 				 * Show all the errors and the IP addresses
7606f9cba8fSJoseph Mingrone 				 * to which they apply.
7616f9cba8fSJoseph Mingrone 				 */
7626f9cba8fSJoseph Mingrone 				char *errbufptr;
7636f9cba8fSJoseph Mingrone 				size_t bufspaceleft;
7646f9cba8fSJoseph Mingrone 				size_t msglen;
7656f9cba8fSJoseph Mingrone 
7666f9cba8fSJoseph Mingrone 				snprintf(errbuf, errbuflen,
7676f9cba8fSJoseph Mingrone 				    "Connect to %s failed: ", host);
7686f9cba8fSJoseph Mingrone 
7696f9cba8fSJoseph Mingrone 				msglen = strlen(errbuf);
7706f9cba8fSJoseph Mingrone 				errbufptr = errbuf + msglen;
7716f9cba8fSJoseph Mingrone 				bufspaceleft = errbuflen - msglen;
7726f9cba8fSJoseph Mingrone 
7736f9cba8fSJoseph Mingrone 				for (i = 0; i < numaddrinfos &&
7746f9cba8fSJoseph Mingrone 				    addrs_to_try[i].errcode != SOCK_NOERR;
7756f9cba8fSJoseph Mingrone 				    i++)
7766f9cba8fSJoseph Mingrone 				{
7776f9cba8fSJoseph Mingrone 					/*
7786f9cba8fSJoseph Mingrone 					 * Get the string for the address
7796f9cba8fSJoseph Mingrone 					 * and port that got this error.
7806f9cba8fSJoseph Mingrone 					 */
7816f9cba8fSJoseph Mingrone 					sock_getascii_addrport((struct sockaddr_storage *) addrs_to_try[i].info->ai_addr,
7826f9cba8fSJoseph Mingrone 					    errbufptr, (int)bufspaceleft,
7836f9cba8fSJoseph Mingrone 					    NULL, 0, NI_NUMERICHOST, NULL, 0);
7846f9cba8fSJoseph Mingrone 					msglen = strlen(errbuf);
7856f9cba8fSJoseph Mingrone 					errbufptr = errbuf + msglen;
7866f9cba8fSJoseph Mingrone 					bufspaceleft = errbuflen - msglen;
7876f9cba8fSJoseph Mingrone 
7886f9cba8fSJoseph Mingrone 					if (i + 1 < numaddrinfos &&
7896f9cba8fSJoseph Mingrone 					    addrs_to_try[i + 1].errcode == addrs_to_try[i].errcode)
7906f9cba8fSJoseph Mingrone 					{
7916f9cba8fSJoseph Mingrone 						/*
7926f9cba8fSJoseph Mingrone 						 * There's another error
7936f9cba8fSJoseph Mingrone 						 * after this, and it has
7946f9cba8fSJoseph Mingrone 						 * the same error code.
7956f9cba8fSJoseph Mingrone 						 *
7966f9cba8fSJoseph Mingrone 						 * Append a comma, as the
7976f9cba8fSJoseph Mingrone 						 * list of addresses with
7986f9cba8fSJoseph Mingrone 						 * this error has another
7996f9cba8fSJoseph Mingrone 						 * entry.
8006f9cba8fSJoseph Mingrone 						 */
8016f9cba8fSJoseph Mingrone 						snprintf(errbufptr, bufspaceleft,
8026f9cba8fSJoseph Mingrone 						    ", ");
8036f9cba8fSJoseph Mingrone 					}
8046f9cba8fSJoseph Mingrone 					else
8056f9cba8fSJoseph Mingrone 					{
8066f9cba8fSJoseph Mingrone 						/*
8076f9cba8fSJoseph Mingrone 						 * Either there are no
8086f9cba8fSJoseph Mingrone 						 * more errors after this,
8096f9cba8fSJoseph Mingrone 						 * or the next error is
8106f9cba8fSJoseph Mingrone 						 * different.
8116f9cba8fSJoseph Mingrone 						 *
8126f9cba8fSJoseph Mingrone 						 * Append a colon and
8136f9cba8fSJoseph Mingrone 						 * the message for tis
8146f9cba8fSJoseph Mingrone 						 * error, followed by a
8156f9cba8fSJoseph Mingrone 						 * comma if there are
8166f9cba8fSJoseph Mingrone 						 * more errors.
8176f9cba8fSJoseph Mingrone 						 */
8186f9cba8fSJoseph Mingrone 						sock_fmterrmsg(errbufptr,
8196f9cba8fSJoseph Mingrone 						    bufspaceleft,
8206f9cba8fSJoseph Mingrone 						    addrs_to_try[i].errcode,
8216f9cba8fSJoseph Mingrone 						    "%s", "");
8226f9cba8fSJoseph Mingrone 						msglen = strlen(errbuf);
8236f9cba8fSJoseph Mingrone 						errbufptr = errbuf + msglen;
8246f9cba8fSJoseph Mingrone 						bufspaceleft = errbuflen - msglen;
8256f9cba8fSJoseph Mingrone 
8266f9cba8fSJoseph Mingrone 						if (i + 1 < numaddrinfos &&
8276f9cba8fSJoseph Mingrone 						    addrs_to_try[i + 1].errcode != SOCK_NOERR)
8286f9cba8fSJoseph Mingrone 						{
8296f9cba8fSJoseph Mingrone 							/*
8306f9cba8fSJoseph Mingrone 							 * More to come.
8316f9cba8fSJoseph Mingrone 							 */
8326f9cba8fSJoseph Mingrone 							snprintf(errbufptr,
8336f9cba8fSJoseph Mingrone 							    bufspaceleft,
8346f9cba8fSJoseph Mingrone 							    ", ");
8356f9cba8fSJoseph Mingrone 						}
8366f9cba8fSJoseph Mingrone 					}
8376f9cba8fSJoseph Mingrone 					msglen = strlen(errbuf);
8386f9cba8fSJoseph Mingrone 					errbufptr = errbuf + msglen;
8396f9cba8fSJoseph Mingrone 					bufspaceleft = errbuflen - msglen;
8406f9cba8fSJoseph Mingrone 				}
8416f9cba8fSJoseph Mingrone 			}
8426f9cba8fSJoseph Mingrone 			free(addrs_to_try);
843b00ab754SHans Petter Selasky 			return INVALID_SOCKET;
844ada6f083SXin LI 		}
845ada6f083SXin LI 		else
8466f9cba8fSJoseph Mingrone 		{
8476f9cba8fSJoseph Mingrone 			free(addrs_to_try);
848ada6f083SXin LI 			return sock;
849ada6f083SXin LI 		}
850ada6f083SXin LI 	}
8516f9cba8fSJoseph Mingrone }
852ada6f083SXin LI 
853ada6f083SXin LI /*
854ada6f083SXin LI  * \brief Closes the present (TCP and UDP) socket connection.
855ada6f083SXin LI  *
856ada6f083SXin LI  * This function sends a shutdown() on the socket in order to disable send() calls
857ada6f083SXin LI  * (while recv() ones are still allowed). Then, it closes the socket.
858ada6f083SXin LI  *
859ada6f083SXin LI  * \param sock: the socket identifier of the connection that has to be closed.
860ada6f083SXin LI  *
861ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
862ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
863ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
864ada6f083SXin LI  *
865ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
866ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
867ada6f083SXin LI  *
868ada6f083SXin LI  * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
869ada6f083SXin LI  * in the 'errbuf' variable.
870ada6f083SXin LI  */
sock_close(PCAP_SOCKET sock,char * errbuf,int errbuflen)871*afdbf109SJoseph Mingrone int sock_close(PCAP_SOCKET sock, char *errbuf, int errbuflen)
872ada6f083SXin LI {
873ada6f083SXin LI 	/*
874ada6f083SXin LI 	 * SHUT_WR: subsequent calls to the send function are disallowed.
875ada6f083SXin LI 	 * For TCP sockets, a FIN will be sent after all data is sent and
876ada6f083SXin LI 	 * acknowledged by the Server.
877ada6f083SXin LI 	 */
878ada6f083SXin LI 	if (shutdown(sock, SHUT_WR))
879ada6f083SXin LI 	{
880*afdbf109SJoseph Mingrone 		sock_geterrmsg(errbuf, errbuflen, "shutdown() failed");
881ada6f083SXin LI 		/* close the socket anyway */
882ada6f083SXin LI 		closesocket(sock);
883ada6f083SXin LI 		return -1;
884ada6f083SXin LI 	}
885ada6f083SXin LI 
886ada6f083SXin LI 	closesocket(sock);
887ada6f083SXin LI 	return 0;
888ada6f083SXin LI }
889ada6f083SXin LI 
890ada6f083SXin LI /*
8916f9cba8fSJoseph Mingrone  * gai_strerror() has some problems:
89257e22627SCy Schubert  *
89357e22627SCy Schubert  * 1) on Windows, Microsoft explicitly says it's not thread-safe;
89457e22627SCy Schubert  * 2) on UN*X, the Single UNIX Specification doesn't say it *is*
89557e22627SCy Schubert  *    thread-safe, so an implementation might use a static buffer
89657e22627SCy Schubert  *    for unknown error codes;
89757e22627SCy Schubert  * 3) the error message for the most likely error, EAI_NONAME, is
89857e22627SCy Schubert  *    truly horrible on several platforms ("nodename nor servname
89957e22627SCy Schubert  *    provided, or not known"?  It's typically going to be "not
90057e22627SCy Schubert  *    known", not "oopsie, I passed null pointers for the host name
90157e22627SCy Schubert  *    and service name", not to mention they forgot the "neither");
90257e22627SCy Schubert  *
90357e22627SCy Schubert  * so we roll our own.
90457e22627SCy Schubert  */
90557e22627SCy Schubert static void
get_gai_errstring(char * errbuf,int errbuflen,const char * prefix,int err,const char * hostname,const char * portname)90657e22627SCy Schubert get_gai_errstring(char *errbuf, int errbuflen, const char *prefix, int err,
90757e22627SCy Schubert     const char *hostname, const char *portname)
90857e22627SCy Schubert {
90957e22627SCy Schubert 	char hostport[PCAP_ERRBUF_SIZE];
91057e22627SCy Schubert 
91157e22627SCy Schubert 	if (hostname != NULL && portname != NULL)
9126f9cba8fSJoseph Mingrone 		snprintf(hostport, PCAP_ERRBUF_SIZE, "host and port %s:%s",
91357e22627SCy Schubert 		    hostname, portname);
91457e22627SCy Schubert 	else if (hostname != NULL)
9156f9cba8fSJoseph Mingrone 		snprintf(hostport, PCAP_ERRBUF_SIZE, "host %s",
91657e22627SCy Schubert 		    hostname);
91757e22627SCy Schubert 	else if (portname != NULL)
9186f9cba8fSJoseph Mingrone 		snprintf(hostport, PCAP_ERRBUF_SIZE, "port %s",
91957e22627SCy Schubert 		    portname);
92057e22627SCy Schubert 	else
9216f9cba8fSJoseph Mingrone 		snprintf(hostport, PCAP_ERRBUF_SIZE, "<no host or port!>");
92257e22627SCy Schubert 	switch (err)
92357e22627SCy Schubert 	{
92457e22627SCy Schubert #ifdef EAI_ADDRFAMILY
92557e22627SCy Schubert 		case EAI_ADDRFAMILY:
9266f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
92757e22627SCy Schubert 			    "%sAddress family for %s not supported",
92857e22627SCy Schubert 			    prefix, hostport);
92957e22627SCy Schubert 			break;
93057e22627SCy Schubert #endif
93157e22627SCy Schubert 
93257e22627SCy Schubert 		case EAI_AGAIN:
9336f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
93457e22627SCy Schubert 			    "%s%s could not be resolved at this time",
93557e22627SCy Schubert 			    prefix, hostport);
93657e22627SCy Schubert 			break;
93757e22627SCy Schubert 
93857e22627SCy Schubert 		case EAI_BADFLAGS:
9396f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
94057e22627SCy Schubert 			    "%sThe ai_flags parameter for looking up %s had an invalid value",
94157e22627SCy Schubert 			    prefix, hostport);
94257e22627SCy Schubert 			break;
94357e22627SCy Schubert 
94457e22627SCy Schubert 		case EAI_FAIL:
9456f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
94657e22627SCy Schubert 			    "%sA non-recoverable error occurred when attempting to resolve %s",
94757e22627SCy Schubert 			    prefix, hostport);
94857e22627SCy Schubert 			break;
94957e22627SCy Schubert 
95057e22627SCy Schubert 		case EAI_FAMILY:
9516f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
95257e22627SCy Schubert 			    "%sThe address family for looking up %s was not recognized",
95357e22627SCy Schubert 			    prefix, hostport);
95457e22627SCy Schubert 			break;
95557e22627SCy Schubert 
95657e22627SCy Schubert 		case EAI_MEMORY:
9576f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
95857e22627SCy Schubert 			    "%sOut of memory trying to allocate storage when looking up %s",
95957e22627SCy Schubert 			    prefix, hostport);
96057e22627SCy Schubert 			break;
96157e22627SCy Schubert 
96257e22627SCy Schubert 		/*
96357e22627SCy Schubert 		 * RFC 2553 had both EAI_NODATA and EAI_NONAME.
96457e22627SCy Schubert 		 *
96557e22627SCy Schubert 		 * RFC 3493 has only EAI_NONAME.
96657e22627SCy Schubert 		 *
96757e22627SCy Schubert 		 * Some implementations define EAI_NODATA and EAI_NONAME
96857e22627SCy Schubert 		 * to the same value, others don't.  If EAI_NODATA is
96957e22627SCy Schubert 		 * defined and isn't the same as EAI_NONAME, we handle
97057e22627SCy Schubert 		 * EAI_NODATA.
97157e22627SCy Schubert 		 */
97257e22627SCy Schubert #if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
97357e22627SCy Schubert 		case EAI_NODATA:
9746f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
97557e22627SCy Schubert 			    "%sNo address associated with %s",
97657e22627SCy Schubert 			    prefix, hostport);
97757e22627SCy Schubert 			break;
97857e22627SCy Schubert #endif
97957e22627SCy Schubert 
98057e22627SCy Schubert 		case EAI_NONAME:
9816f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
9826f9cba8fSJoseph Mingrone 			    "%sThe %s couldn't be resolved",
98357e22627SCy Schubert 			    prefix, hostport);
98457e22627SCy Schubert 			break;
98557e22627SCy Schubert 
98657e22627SCy Schubert 		case EAI_SERVICE:
9876f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
98857e22627SCy Schubert 			    "%sThe service value specified when looking up %s as not recognized for the socket type",
98957e22627SCy Schubert 			    prefix, hostport);
99057e22627SCy Schubert 			break;
99157e22627SCy Schubert 
99257e22627SCy Schubert 		case EAI_SOCKTYPE:
9936f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
99457e22627SCy Schubert 			    "%sThe socket type specified when looking up %s as not recognized",
99557e22627SCy Schubert 			    prefix, hostport);
99657e22627SCy Schubert 			break;
99757e22627SCy Schubert 
99857e22627SCy Schubert #ifdef EAI_SYSTEM
99957e22627SCy Schubert 		case EAI_SYSTEM:
100057e22627SCy Schubert 			/*
100157e22627SCy Schubert 			 * Assumed to be UN*X.
100257e22627SCy Schubert 			 */
1003*afdbf109SJoseph Mingrone 			pcapint_fmt_errmsg_for_errno(errbuf, errbuflen, errno,
10046f9cba8fSJoseph Mingrone 			    "%sAn error occurred when looking up %s",
10056f9cba8fSJoseph Mingrone 			    prefix, hostport);
100657e22627SCy Schubert 			break;
100757e22627SCy Schubert #endif
100857e22627SCy Schubert 
100957e22627SCy Schubert #ifdef EAI_BADHINTS
101057e22627SCy Schubert 		case EAI_BADHINTS:
10116f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
101257e22627SCy Schubert 			    "%sInvalid value for hints when looking up %s",
101357e22627SCy Schubert 			    prefix, hostport);
101457e22627SCy Schubert 			break;
101557e22627SCy Schubert #endif
101657e22627SCy Schubert 
101757e22627SCy Schubert #ifdef EAI_PROTOCOL
101857e22627SCy Schubert 		case EAI_PROTOCOL:
10196f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
102057e22627SCy Schubert 			    "%sResolved protocol when looking up %s is unknown",
102157e22627SCy Schubert 			    prefix, hostport);
102257e22627SCy Schubert 			break;
102357e22627SCy Schubert #endif
102457e22627SCy Schubert 
102557e22627SCy Schubert #ifdef EAI_OVERFLOW
102657e22627SCy Schubert 		case EAI_OVERFLOW:
10276f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
102857e22627SCy Schubert 			    "%sArgument buffer overflow when looking up %s",
102957e22627SCy Schubert 			    prefix, hostport);
103057e22627SCy Schubert 			break;
103157e22627SCy Schubert #endif
103257e22627SCy Schubert 
103357e22627SCy Schubert 		default:
10346f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
103557e22627SCy Schubert 			    "%sgetaddrinfo() error %d when looking up %s",
103657e22627SCy Schubert 			    prefix, err, hostport);
103757e22627SCy Schubert 			break;
103857e22627SCy Schubert 	}
103957e22627SCy Schubert }
104057e22627SCy Schubert 
104157e22627SCy Schubert /*
1042*afdbf109SJoseph Mingrone  * \brief Checks that the address, port and flags given are valid and it returns an 'addrinfo' structure.
1043ada6f083SXin LI  *
1044ada6f083SXin LI  * This function basically calls the getaddrinfo() calls, and it performs a set of sanity checks
1045ada6f083SXin LI  * to control that everything is fine (e.g. a TCP socket cannot have a mcast address, and such).
1046ada6f083SXin LI  * If an error occurs, it writes the error message into 'errbuf'.
1047ada6f083SXin LI  *
1048ada6f083SXin LI  * \param host: a pointer to a string identifying the host. It can be
1049ada6f083SXin LI  * a host name, a numeric literal address, or NULL or "" (useful
1050ada6f083SXin LI  * in case of a server socket which has to bind to all addresses).
1051ada6f083SXin LI  *
1052ada6f083SXin LI  * \param port: a pointer to a user-allocated buffer containing the network port to use.
1053ada6f083SXin LI  *
1054ada6f083SXin LI  * \param hints: an addrinfo variable (passed by reference) containing the flags needed to create the
1055ada6f083SXin LI  * addrinfo structure appropriately.
1056ada6f083SXin LI  *
1057ada6f083SXin LI  * \param addrinfo: it represents the true returning value. This is a pointer to an addrinfo variable
1058ada6f083SXin LI  * (passed by reference), which will be allocated by this function and returned back to the caller.
1059ada6f083SXin LI  * This variable will be used in the next sockets calls.
1060ada6f083SXin LI  *
1061ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1062ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1063ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1064ada6f083SXin LI  *
1065ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1066ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1067ada6f083SXin LI  *
1068*afdbf109SJoseph Mingrone  * \return a pointer to the first element in a list of addrinfo structures
1069*afdbf109SJoseph Mingrone  * if everything is fine, NULL if some errors occurred. The error message
1070*afdbf109SJoseph Mingrone  * is returned in the 'errbuf' variable.
1071ada6f083SXin LI  *
1072*afdbf109SJoseph Mingrone  * \warning The list of addrinfo structures returned has to be deleted by
1073*afdbf109SJoseph Mingrone  * the programmer by calling freeaddrinfo() when it is no longer needed.
1074ada6f083SXin LI  *
1075ada6f083SXin LI  * \warning This function requires the 'hints' variable as parameter. The semantic of this variable is the same
1076ada6f083SXin LI  * of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest
1077ada6f083SXin LI  * the programmer to look at that function in order to set the 'hints' variable appropriately.
1078ada6f083SXin LI  */
sock_initaddress(const char * host,const char * port,struct addrinfo * hints,char * errbuf,int errbuflen)1079*afdbf109SJoseph Mingrone struct addrinfo *sock_initaddress(const char *host, const char *port,
1080*afdbf109SJoseph Mingrone     struct addrinfo *hints, char *errbuf, int errbuflen)
1081ada6f083SXin LI {
1082*afdbf109SJoseph Mingrone 	struct addrinfo *addrinfo;
1083ada6f083SXin LI 	int retval;
1084ada6f083SXin LI 
10856f9cba8fSJoseph Mingrone 	/*
10866f9cba8fSJoseph Mingrone 	 * We allow both the host and port to be null, but getaddrinfo()
10876f9cba8fSJoseph Mingrone 	 * is not guaranteed to do so; to handle that, if port is null,
10886f9cba8fSJoseph Mingrone 	 * we provide "0" as the port number.
10896f9cba8fSJoseph Mingrone 	 *
10906f9cba8fSJoseph Mingrone 	 * This results in better error messages from get_gai_errstring(),
10916f9cba8fSJoseph Mingrone 	 * as those messages won't talk about a problem with the port if
10926f9cba8fSJoseph Mingrone 	 * no port was specified.
10936f9cba8fSJoseph Mingrone 	 */
1094*afdbf109SJoseph Mingrone 	retval = getaddrinfo(host, port == NULL ? "0" : port, hints, &addrinfo);
1095ada6f083SXin LI 	if (retval != 0)
1096ada6f083SXin LI 	{
1097*afdbf109SJoseph Mingrone 		/*
1098*afdbf109SJoseph Mingrone 		 * That call failed.
1099*afdbf109SJoseph Mingrone 		 * Determine whether the problem is that the host is bad.
1100*afdbf109SJoseph Mingrone 		 */
1101ada6f083SXin LI 		if (errbuf)
1102ada6f083SXin LI 		{
11036f9cba8fSJoseph Mingrone 			if (host != NULL && port != NULL) {
11046f9cba8fSJoseph Mingrone 				/*
11056f9cba8fSJoseph Mingrone 				 * Try with just a host, to distinguish
11066f9cba8fSJoseph Mingrone 				 * between "host is bad" and "port is
11076f9cba8fSJoseph Mingrone 				 * bad".
11086f9cba8fSJoseph Mingrone 				 */
11096f9cba8fSJoseph Mingrone 				int try_retval;
11106f9cba8fSJoseph Mingrone 
11116f9cba8fSJoseph Mingrone 				try_retval = getaddrinfo(host, NULL, hints,
1112*afdbf109SJoseph Mingrone 				    &addrinfo);
11136f9cba8fSJoseph Mingrone 				if (try_retval == 0) {
11146f9cba8fSJoseph Mingrone 					/*
11156f9cba8fSJoseph Mingrone 					 * Worked with just the host,
11166f9cba8fSJoseph Mingrone 					 * so assume the problem is
11176f9cba8fSJoseph Mingrone 					 * with the port.
11186f9cba8fSJoseph Mingrone 					 *
11196f9cba8fSJoseph Mingrone 					 * Free up the address info first.
11206f9cba8fSJoseph Mingrone 					 */
1121*afdbf109SJoseph Mingrone 					freeaddrinfo(addrinfo);
11226f9cba8fSJoseph Mingrone 					get_gai_errstring(errbuf, errbuflen,
11236f9cba8fSJoseph Mingrone 					    "", retval, NULL, port);
11246f9cba8fSJoseph Mingrone 				} else {
11256f9cba8fSJoseph Mingrone 					/*
11266f9cba8fSJoseph Mingrone 					 * Didn't work with just the host,
11276f9cba8fSJoseph Mingrone 					 * so assume the problem is
1128*afdbf109SJoseph Mingrone 					 * with the host; we assume
1129*afdbf109SJoseph Mingrone 					 * the original error indicates
1130*afdbf109SJoseph Mingrone 					 * the underlying problem.
11316f9cba8fSJoseph Mingrone 					 */
11326f9cba8fSJoseph Mingrone 					get_gai_errstring(errbuf, errbuflen,
11336f9cba8fSJoseph Mingrone 					    "", retval, host, NULL);
11346f9cba8fSJoseph Mingrone 				}
11356f9cba8fSJoseph Mingrone 			} else {
11366f9cba8fSJoseph Mingrone 				/*
11376f9cba8fSJoseph Mingrone 				 * Either the host or port was null, so
1138*afdbf109SJoseph Mingrone 				 * there's nothing to determine; report
1139*afdbf109SJoseph Mingrone 				 * the error from the original call.
11406f9cba8fSJoseph Mingrone 				 */
11416f9cba8fSJoseph Mingrone 				get_gai_errstring(errbuf, errbuflen, "",
11426f9cba8fSJoseph Mingrone 				    retval, host, port);
11436f9cba8fSJoseph Mingrone 			}
1144ada6f083SXin LI 		}
1145*afdbf109SJoseph Mingrone 		return NULL;
1146ada6f083SXin LI 	}
1147ada6f083SXin LI 	/*
1148ada6f083SXin LI 	 * \warning SOCKET: I should check all the accept() in order to bind to all addresses in case
1149ada6f083SXin LI 	 * addrinfo has more han one pointers
1150ada6f083SXin LI 	 */
1151ada6f083SXin LI 
1152ada6f083SXin LI 	/*
1153ada6f083SXin LI 	 * This software only supports PF_INET and PF_INET6.
1154ada6f083SXin LI 	 *
1155ada6f083SXin LI 	 * XXX - should we just check that at least *one* address is
1156ada6f083SXin LI 	 * either PF_INET or PF_INET6, and, when using the list,
1157ada6f083SXin LI 	 * ignore all addresses that are neither?  (What, no IPX
1158ada6f083SXin LI 	 * support? :-))
1159ada6f083SXin LI 	 */
1160*afdbf109SJoseph Mingrone 	if ((addrinfo->ai_family != PF_INET) &&
1161*afdbf109SJoseph Mingrone 	    (addrinfo->ai_family != PF_INET6))
1162ada6f083SXin LI 	{
1163ada6f083SXin LI 		if (errbuf)
11646f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported");
1165*afdbf109SJoseph Mingrone 		freeaddrinfo(addrinfo);
1166*afdbf109SJoseph Mingrone 		return NULL;
1167ada6f083SXin LI 	}
1168ada6f083SXin LI 
1169ada6f083SXin LI 	/*
1170ada6f083SXin LI 	 * You can't do multicast (or broadcast) TCP.
1171ada6f083SXin LI 	 */
1172*afdbf109SJoseph Mingrone 	if ((addrinfo->ai_socktype == SOCK_STREAM) &&
1173*afdbf109SJoseph Mingrone 	    (sock_ismcastaddr(addrinfo->ai_addr) == 0))
1174ada6f083SXin LI 	{
1175ada6f083SXin LI 		if (errbuf)
11766f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams");
1177*afdbf109SJoseph Mingrone 		freeaddrinfo(addrinfo);
1178*afdbf109SJoseph Mingrone 		return NULL;
1179ada6f083SXin LI 	}
1180ada6f083SXin LI 
1181*afdbf109SJoseph Mingrone 	return addrinfo;
1182ada6f083SXin LI }
1183ada6f083SXin LI 
1184ada6f083SXin LI /*
1185ada6f083SXin LI  * \brief It sends the amount of data contained into 'buffer' on the given socket.
1186ada6f083SXin LI  *
1187ada6f083SXin LI  * This function basically calls the send() socket function and it checks that all
1188ada6f083SXin LI  * the data specified in 'buffer' (of size 'size') will be sent. If an error occurs,
1189ada6f083SXin LI  * it writes the error message into 'errbuf'.
1190ada6f083SXin LI  * In case the socket buffer does not have enough space, it loops until all data
1191ada6f083SXin LI  * has been sent.
1192ada6f083SXin LI  *
1193ada6f083SXin LI  * \param socket: the connected socket currently opened.
1194ada6f083SXin LI  *
1195ada6f083SXin LI  * \param buffer: a char pointer to a user-allocated buffer in which data is contained.
1196ada6f083SXin LI  *
1197ada6f083SXin LI  * \param size: number of bytes that have to be sent.
1198ada6f083SXin LI  *
1199ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1200ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1201ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1202ada6f083SXin LI  *
1203ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1204ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1205ada6f083SXin LI  *
1206b00ab754SHans Petter Selasky  * \return '0' if everything is fine, '-1' if an error other than
1207b00ab754SHans Petter Selasky  * "connection reset" or "peer has closed the receive side" occurred,
1208b00ab754SHans Petter Selasky  * '-2' if we got one of those errors.
1209b00ab754SHans Petter Selasky  * For errors, an error message is returned in the 'errbuf' variable.
1210ada6f083SXin LI  */
sock_send(PCAP_SOCKET sock,SSL * ssl _U_NOSSL_,const char * buffer,size_t size,char * errbuf,int errbuflen)1211*afdbf109SJoseph Mingrone int sock_send(PCAP_SOCKET sock, SSL *ssl _U_NOSSL_, const char *buffer,
1212*afdbf109SJoseph Mingrone     size_t size, char *errbuf, int errbuflen)
1213ada6f083SXin LI {
1214b00ab754SHans Petter Selasky 	int remaining;
1215b00ab754SHans Petter Selasky 	ssize_t nsent;
1216ada6f083SXin LI 
1217b00ab754SHans Petter Selasky 	if (size > INT_MAX)
1218b00ab754SHans Petter Selasky 	{
1219b00ab754SHans Petter Selasky 		if (errbuf)
1220b00ab754SHans Petter Selasky 		{
12216f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
122257e22627SCy Schubert 			    "Can't send more than %u bytes with sock_send",
1223b00ab754SHans Petter Selasky 			    INT_MAX);
1224b00ab754SHans Petter Selasky 		}
1225b00ab754SHans Petter Selasky 		return -1;
1226b00ab754SHans Petter Selasky 	}
1227b00ab754SHans Petter Selasky 	remaining = (int)size;
1228b00ab754SHans Petter Selasky 
1229b00ab754SHans Petter Selasky 	do {
12306f9cba8fSJoseph Mingrone #ifdef HAVE_OPENSSL
12316f9cba8fSJoseph Mingrone 		if (ssl) return ssl_send(ssl, buffer, remaining, errbuf, errbuflen);
12326f9cba8fSJoseph Mingrone #endif
12336f9cba8fSJoseph Mingrone 
12346f9cba8fSJoseph Mingrone #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
12356f9cba8fSJoseph Mingrone 		nsent = remaining;
12366f9cba8fSJoseph Mingrone #else
1237b00ab754SHans Petter Selasky #ifdef MSG_NOSIGNAL
1238ada6f083SXin LI 		/*
1239b00ab754SHans Petter Selasky 		 * Send with MSG_NOSIGNAL, so that we don't get SIGPIPE
1240b00ab754SHans Petter Selasky 		 * on errors on stream-oriented sockets when the other
1241b00ab754SHans Petter Selasky 		 * end breaks the connection.
1242ada6f083SXin LI 		 * The EPIPE error is still returned.
1243ada6f083SXin LI 		 */
1244b00ab754SHans Petter Selasky 		nsent = send(sock, buffer, remaining, MSG_NOSIGNAL);
1245ada6f083SXin LI #else
1246b00ab754SHans Petter Selasky 		nsent = send(sock, buffer, remaining, 0);
1247ada6f083SXin LI #endif
12486f9cba8fSJoseph Mingrone #endif //FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1249ada6f083SXin LI 
1250ada6f083SXin LI 		if (nsent == -1)
1251ada6f083SXin LI 		{
1252b00ab754SHans Petter Selasky 			/*
1253b00ab754SHans Petter Selasky 			 * If the client closed the connection out from
1254b00ab754SHans Petter Selasky 			 * under us, there's no need to log that as an
1255b00ab754SHans Petter Selasky 			 * error.
1256b00ab754SHans Petter Selasky 			 */
1257b00ab754SHans Petter Selasky 			int errcode;
1258b00ab754SHans Petter Selasky 
1259b00ab754SHans Petter Selasky #ifdef _WIN32
1260b00ab754SHans Petter Selasky 			errcode = GetLastError();
1261b00ab754SHans Petter Selasky 			if (errcode == WSAECONNRESET ||
1262b00ab754SHans Petter Selasky 			    errcode == WSAECONNABORTED)
1263b00ab754SHans Petter Selasky 			{
1264b00ab754SHans Petter Selasky 				/*
1265b00ab754SHans Petter Selasky 				 * WSAECONNABORTED appears to be the error
1266b00ab754SHans Petter Selasky 				 * returned in Winsock when you try to send
1267b00ab754SHans Petter Selasky 				 * on a connection where the peer has closed
1268b00ab754SHans Petter Selasky 				 * the receive side.
1269b00ab754SHans Petter Selasky 				 */
1270b00ab754SHans Petter Selasky 				return -2;
1271b00ab754SHans Petter Selasky 			}
12726f9cba8fSJoseph Mingrone 			sock_fmterrmsg(errbuf, errbuflen, errcode,
12736f9cba8fSJoseph Mingrone 			    "send() failed");
1274b00ab754SHans Petter Selasky #else
1275b00ab754SHans Petter Selasky 			errcode = errno;
1276b00ab754SHans Petter Selasky 			if (errcode == ECONNRESET || errcode == EPIPE)
1277b00ab754SHans Petter Selasky 			{
1278b00ab754SHans Petter Selasky 				/*
1279b00ab754SHans Petter Selasky 				 * EPIPE is what's returned on UN*X when
1280b00ab754SHans Petter Selasky 				 * you try to send on a connection when
1281b00ab754SHans Petter Selasky 				 * the peer has closed the receive side.
1282b00ab754SHans Petter Selasky 				 */
1283b00ab754SHans Petter Selasky 				return -2;
1284b00ab754SHans Petter Selasky 			}
12856f9cba8fSJoseph Mingrone 			sock_fmterrmsg(errbuf, errbuflen, errcode,
12866f9cba8fSJoseph Mingrone 			    "send() failed");
1287b00ab754SHans Petter Selasky #endif
1288ada6f083SXin LI 			return -1;
1289ada6f083SXin LI 		}
1290ada6f083SXin LI 
1291b00ab754SHans Petter Selasky 		remaining -= nsent;
1292ada6f083SXin LI 		buffer += nsent;
1293b00ab754SHans Petter Selasky 	} while (remaining != 0);
1294ada6f083SXin LI 
1295ada6f083SXin LI 	return 0;
1296ada6f083SXin LI }
1297ada6f083SXin LI 
1298ada6f083SXin LI /*
12996f9cba8fSJoseph Mingrone  * \brief It copies the amount of data contained in 'data' into 'outbuf'.
1300ada6f083SXin LI  * and it checks for buffer overflows.
1301ada6f083SXin LI  *
13026f9cba8fSJoseph Mingrone  * This function basically copies 'size' bytes of data contained in 'data'
13036f9cba8fSJoseph Mingrone  * into 'outbuf', starting at offset 'offset'. Before that, it checks that the
1304ada6f083SXin LI  * resulting buffer will not be larger	than 'totsize'. Finally, it updates
1305ada6f083SXin LI  * the 'offset' variable in order to point to the first empty location of the buffer.
1306ada6f083SXin LI  *
1307ada6f083SXin LI  * In case the function is called with 'checkonly' equal to 1, it does not copy
1308ada6f083SXin LI  * the data into the buffer. It only checks for buffer overflows and it updates the
1309ada6f083SXin LI  * 'offset' variable. This mode can be useful when the buffer already contains the
1310ada6f083SXin LI  * data (maybe because the producer writes directly into the target buffer), so
1311ada6f083SXin LI  * only the buffer overflow check has to be made.
13126f9cba8fSJoseph Mingrone  * In this case, both 'data' and 'outbuf' can be NULL values.
1313ada6f083SXin LI  *
1314ada6f083SXin LI  * This function is useful in case the userland application does not know immediately
1315ada6f083SXin LI  * all the data it has to write into the socket. This function provides a way to create
1316ada6f083SXin LI  * the "stream" step by step, appending the new data to the old one. Then, when all the
1317ada6f083SXin LI  * data has been bufferized, the application can call the sock_send() function.
1318ada6f083SXin LI  *
13196f9cba8fSJoseph Mingrone  * \param data: a void pointer to the data that has to be copied.
1320ada6f083SXin LI  *
1321ada6f083SXin LI  * \param size: number of bytes that have to be copied.
1322ada6f083SXin LI  *
13236f9cba8fSJoseph Mingrone  * \param outbuf: user-allocated buffer (of size 'totsize') into which data
1324ada6f083SXin LI  * has to be copied.
1325ada6f083SXin LI  *
13266f9cba8fSJoseph Mingrone  * \param offset: an index into 'outbuf' which keeps the location of its first
1327ada6f083SXin LI  * empty location.
1328ada6f083SXin LI  *
13296f9cba8fSJoseph Mingrone  * \param totsize: total size of the buffer into which data is being copied.
1330ada6f083SXin LI  *
1331ada6f083SXin LI  * \param checkonly: '1' if we do not want to copy data into the buffer and we
1332*afdbf109SJoseph Mingrone  * want just do a buffer overflow control, '0' if data has to be copied as well.
1333ada6f083SXin LI  *
1334ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1335ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1336ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1337ada6f083SXin LI  *
1338ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1339ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1340ada6f083SXin LI  *
1341ada6f083SXin LI  * \return '0' if everything is fine, '-1' if some errors occurred. The error message
13426f9cba8fSJoseph Mingrone  * is returned in the 'errbuf' variable. When the function returns, 'outbuf' will
1343ada6f083SXin LI  * have the new string appended, and 'offset' will keep the length of that buffer.
1344ada6f083SXin LI  * In case of 'checkonly == 1', data is not copied, but 'offset' is updated in any case.
1345ada6f083SXin LI  *
1346ada6f083SXin LI  * \warning This function assumes that the buffer in which data has to be stored is
1347ada6f083SXin LI  * large 'totbuf' bytes.
1348ada6f083SXin LI  *
1349ada6f083SXin LI  * \warning In case of 'checkonly', be carefully to call this function *before* copying
1350ada6f083SXin LI  * the data into the buffer. Otherwise, the control about the buffer overflow is useless.
1351ada6f083SXin LI  */
sock_bufferize(const void * data,int size,char * outbuf,int * offset,int totsize,int checkonly,char * errbuf,int errbuflen)13526f9cba8fSJoseph Mingrone int sock_bufferize(const void *data, int size, char *outbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen)
1353ada6f083SXin LI {
1354ada6f083SXin LI 	if ((*offset + size) > totsize)
1355ada6f083SXin LI 	{
1356ada6f083SXin LI 		if (errbuf)
13576f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen, "Not enough space in the temporary send buffer.");
1358ada6f083SXin LI 		return -1;
1359ada6f083SXin LI 	}
1360ada6f083SXin LI 
1361ada6f083SXin LI 	if (!checkonly)
13626f9cba8fSJoseph Mingrone 		memcpy(outbuf + (*offset), data, size);
1363ada6f083SXin LI 
1364ada6f083SXin LI 	(*offset) += size;
1365ada6f083SXin LI 
1366ada6f083SXin LI 	return 0;
1367ada6f083SXin LI }
1368ada6f083SXin LI 
1369ada6f083SXin LI /*
1370ada6f083SXin LI  * \brief It waits on a connected socket and it manages to receive data.
1371ada6f083SXin LI  *
1372ada6f083SXin LI  * This function basically calls the recv() socket function and it checks that no
1373ada6f083SXin LI  * error occurred. If that happens, it writes the error message into 'errbuf'.
1374ada6f083SXin LI  *
1375ada6f083SXin LI  * This function changes its behavior according to the 'receiveall' flag: if we
1376ada6f083SXin LI  * want to receive exactly 'size' byte, it loops on the recv()	until all the requested
1377ada6f083SXin LI  * data is arrived. Otherwise, it returns the data currently available.
1378ada6f083SXin LI  *
1379ada6f083SXin LI  * In case the socket does not have enough data available, it cycles on the recv()
1380ada6f083SXin LI  * until the requested data (of size 'size') is arrived.
1381ada6f083SXin LI  * In this case, it blocks until the number of bytes read is equal to 'size'.
1382ada6f083SXin LI  *
1383ada6f083SXin LI  * \param sock: the connected socket currently opened.
1384ada6f083SXin LI  *
1385ada6f083SXin LI  * \param buffer: a char pointer to a user-allocated buffer in which data has to be stored
1386ada6f083SXin LI  *
1387ada6f083SXin LI  * \param size: size of the allocated buffer. WARNING: this indicates the number of bytes
1388ada6f083SXin LI  * that we are expecting to be read.
1389ada6f083SXin LI  *
1390b00ab754SHans Petter Selasky  * \param flags:
1391b00ab754SHans Petter Selasky  *
1392b00ab754SHans Petter Selasky  *   SOCK_RECEIVALL_XXX:
1393b00ab754SHans Petter Selasky  *
1394b00ab754SHans Petter Selasky  *	if SOCK_RECEIVEALL_NO, return as soon as some data is ready
1395b00ab754SHans Petter Selasky  *	if SOCK_RECEIVALL_YES, wait until 'size' data has been
1396ada6f083SXin LI  *	    received (in case the socket does not have enough data available).
1397ada6f083SXin LI  *
1398b00ab754SHans Petter Selasky  *   SOCK_EOF_XXX:
1399b00ab754SHans Petter Selasky  *
1400b00ab754SHans Petter Selasky  *	if SOCK_EOF_ISNT_ERROR, if the first read returns 0, just return 0,
1401b00ab754SHans Petter Selasky  *	    and return an error on any subsequent read that returns 0;
1402b00ab754SHans Petter Selasky  *	if SOCK_EOF_IS_ERROR, if any read returns 0, return an error.
1403b00ab754SHans Petter Selasky  *
1404ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1405ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1406ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1407ada6f083SXin LI  *
1408ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1409ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1410ada6f083SXin LI  *
1411ada6f083SXin LI  * \return the number of bytes read if everything is fine, '-1' if some errors occurred.
1412ada6f083SXin LI  * The error message is returned in the 'errbuf' variable.
1413ada6f083SXin LI  */
1414ada6f083SXin LI 
sock_recv(PCAP_SOCKET sock,SSL * ssl _U_NOSSL_,void * buffer,size_t size,int flags,char * errbuf,int errbuflen)1415*afdbf109SJoseph Mingrone int sock_recv(PCAP_SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer, size_t size,
14166f9cba8fSJoseph Mingrone     int flags, char *errbuf, int errbuflen)
1417ada6f083SXin LI {
14186f9cba8fSJoseph Mingrone 	int recv_flags = 0;
1419ada6f083SXin LI 	char *bufp = buffer;
1420ada6f083SXin LI 	int remaining;
1421ada6f083SXin LI 	ssize_t nread;
1422ada6f083SXin LI 
1423ada6f083SXin LI 	if (size == 0)
1424ada6f083SXin LI 	{
1425ada6f083SXin LI 		return 0;
1426ada6f083SXin LI 	}
1427ada6f083SXin LI 	if (size > INT_MAX)
1428ada6f083SXin LI 	{
1429b00ab754SHans Petter Selasky 		if (errbuf)
1430b00ab754SHans Petter Selasky 		{
14316f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
1432b00ab754SHans Petter Selasky 			    "Can't read more than %u bytes with sock_recv",
1433ada6f083SXin LI 			    INT_MAX);
1434b00ab754SHans Petter Selasky 		}
1435ada6f083SXin LI 		return -1;
1436ada6f083SXin LI 	}
1437ada6f083SXin LI 
14386f9cba8fSJoseph Mingrone 	if (flags & SOCK_MSG_PEEK)
14396f9cba8fSJoseph Mingrone 		recv_flags |= MSG_PEEK;
14406f9cba8fSJoseph Mingrone 
1441ada6f083SXin LI 	bufp = (char *) buffer;
1442ada6f083SXin LI 	remaining = (int) size;
1443ada6f083SXin LI 
1444ada6f083SXin LI 	/*
1445ada6f083SXin LI 	 * We don't use MSG_WAITALL because it's not supported in
1446ada6f083SXin LI 	 * Win32.
1447ada6f083SXin LI 	 */
1448ada6f083SXin LI 	for (;;) {
14496f9cba8fSJoseph Mingrone #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
14506f9cba8fSJoseph Mingrone 		nread = fuzz_recv(bufp, remaining);
14516f9cba8fSJoseph Mingrone #elif defined(HAVE_OPENSSL)
14526f9cba8fSJoseph Mingrone 		if (ssl)
14536f9cba8fSJoseph Mingrone 		{
14546f9cba8fSJoseph Mingrone 			/*
14556f9cba8fSJoseph Mingrone 			 * XXX - what about MSG_PEEK?
14566f9cba8fSJoseph Mingrone 			 */
14576f9cba8fSJoseph Mingrone 			nread = ssl_recv(ssl, bufp, remaining, errbuf, errbuflen);
14586f9cba8fSJoseph Mingrone 			if (nread == -2) return -1;
14596f9cba8fSJoseph Mingrone 		}
14606f9cba8fSJoseph Mingrone 		else
14616f9cba8fSJoseph Mingrone 			nread = recv(sock, bufp, remaining, recv_flags);
14626f9cba8fSJoseph Mingrone #else
14636f9cba8fSJoseph Mingrone 		nread = recv(sock, bufp, remaining, recv_flags);
14646f9cba8fSJoseph Mingrone #endif
1465ada6f083SXin LI 
1466ada6f083SXin LI 		if (nread == -1)
1467ada6f083SXin LI 		{
1468ada6f083SXin LI #ifndef _WIN32
1469ada6f083SXin LI 			if (errno == EINTR)
1470ada6f083SXin LI 				return -3;
1471ada6f083SXin LI #endif
14726f9cba8fSJoseph Mingrone 			sock_geterrmsg(errbuf, errbuflen, "recv() failed");
1473ada6f083SXin LI 			return -1;
1474ada6f083SXin LI 		}
1475ada6f083SXin LI 
1476ada6f083SXin LI 		if (nread == 0)
1477ada6f083SXin LI 		{
1478b00ab754SHans Petter Selasky 			if ((flags & SOCK_EOF_IS_ERROR) ||
1479b00ab754SHans Petter Selasky 			    (remaining != (int) size))
1480b00ab754SHans Petter Selasky 			{
1481b00ab754SHans Petter Selasky 				/*
1482b00ab754SHans Petter Selasky 				 * Either we've already read some data,
1483b00ab754SHans Petter Selasky 				 * or we're always supposed to return
1484b00ab754SHans Petter Selasky 				 * an error on EOF.
1485b00ab754SHans Petter Selasky 				 */
1486ada6f083SXin LI 				if (errbuf)
1487ada6f083SXin LI 				{
14886f9cba8fSJoseph Mingrone 					snprintf(errbuf, errbuflen,
1489ada6f083SXin LI 					    "The other host terminated the connection.");
1490ada6f083SXin LI 				}
1491ada6f083SXin LI 				return -1;
1492ada6f083SXin LI 			}
1493b00ab754SHans Petter Selasky 			else
1494b00ab754SHans Petter Selasky 				return 0;
1495b00ab754SHans Petter Selasky 		}
1496ada6f083SXin LI 
1497ada6f083SXin LI 		/*
1498ada6f083SXin LI 		 * Do we want to read the amount requested, or just return
1499ada6f083SXin LI 		 * what we got?
1500ada6f083SXin LI 		 */
1501b00ab754SHans Petter Selasky 		if (!(flags & SOCK_RECEIVEALL_YES))
1502ada6f083SXin LI 		{
1503ada6f083SXin LI 			/*
1504ada6f083SXin LI 			 * Just return what we got.
1505ada6f083SXin LI 			 */
1506ada6f083SXin LI 			return (int) nread;
1507ada6f083SXin LI 		}
1508ada6f083SXin LI 
1509ada6f083SXin LI 		bufp += nread;
1510ada6f083SXin LI 		remaining -= nread;
1511ada6f083SXin LI 
1512ada6f083SXin LI 		if (remaining == 0)
1513ada6f083SXin LI 			return (int) size;
1514ada6f083SXin LI 	}
1515ada6f083SXin LI }
1516ada6f083SXin LI 
1517ada6f083SXin LI /*
1518b00ab754SHans Petter Selasky  * Receives a datagram from a socket.
1519b00ab754SHans Petter Selasky  *
1520b00ab754SHans Petter Selasky  * Returns the size of the datagram on success or -1 on error.
1521b00ab754SHans Petter Selasky  */
sock_recv_dgram(PCAP_SOCKET sock,SSL * ssl _U_NOSSL_,void * buffer,size_t size,char * errbuf,int errbuflen)1522*afdbf109SJoseph Mingrone int sock_recv_dgram(PCAP_SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer,
1523*afdbf109SJoseph Mingrone     size_t size, char *errbuf, int errbuflen)
1524b00ab754SHans Petter Selasky {
1525b00ab754SHans Petter Selasky 	ssize_t nread;
1526b00ab754SHans Petter Selasky #ifndef _WIN32
1527b00ab754SHans Petter Selasky 	struct msghdr message;
1528b00ab754SHans Petter Selasky 	struct iovec iov;
1529b00ab754SHans Petter Selasky #endif
1530b00ab754SHans Petter Selasky 
1531b00ab754SHans Petter Selasky 	if (size == 0)
1532b00ab754SHans Petter Selasky 	{
1533b00ab754SHans Petter Selasky 		return 0;
1534b00ab754SHans Petter Selasky 	}
1535b00ab754SHans Petter Selasky 	if (size > INT_MAX)
1536b00ab754SHans Petter Selasky 	{
1537b00ab754SHans Petter Selasky 		if (errbuf)
1538b00ab754SHans Petter Selasky 		{
15396f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen,
1540b00ab754SHans Petter Selasky 			    "Can't read more than %u bytes with sock_recv_dgram",
1541b00ab754SHans Petter Selasky 			    INT_MAX);
1542b00ab754SHans Petter Selasky 		}
1543b00ab754SHans Petter Selasky 		return -1;
1544b00ab754SHans Petter Selasky 	}
1545b00ab754SHans Petter Selasky 
15466f9cba8fSJoseph Mingrone #ifdef HAVE_OPENSSL
15476f9cba8fSJoseph Mingrone 	// TODO: DTLS
15486f9cba8fSJoseph Mingrone 	if (ssl)
15496f9cba8fSJoseph Mingrone 	{
15506f9cba8fSJoseph Mingrone 		snprintf(errbuf, errbuflen, "DTLS not implemented yet");
15516f9cba8fSJoseph Mingrone 		return -1;
15526f9cba8fSJoseph Mingrone 	}
15536f9cba8fSJoseph Mingrone #endif
15546f9cba8fSJoseph Mingrone 
1555b00ab754SHans Petter Selasky 	/*
1556b00ab754SHans Petter Selasky 	 * This should be a datagram socket, so we should get the
1557b00ab754SHans Petter Selasky 	 * entire datagram in one recv() or recvmsg() call, and
1558b00ab754SHans Petter Selasky 	 * don't need to loop.
1559b00ab754SHans Petter Selasky 	 */
1560b00ab754SHans Petter Selasky #ifdef _WIN32
15616f9cba8fSJoseph Mingrone 	nread = recv(sock, buffer, (int)size, 0);
1562b00ab754SHans Petter Selasky 	if (nread == SOCKET_ERROR)
1563b00ab754SHans Petter Selasky 	{
1564b00ab754SHans Petter Selasky 		/*
1565b00ab754SHans Petter Selasky 		 * To quote the MSDN documentation for recv(),
1566b00ab754SHans Petter Selasky 		 * "If the datagram or message is larger than
1567b00ab754SHans Petter Selasky 		 * the buffer specified, the buffer is filled
1568b00ab754SHans Petter Selasky 		 * with the first part of the datagram, and recv
1569b00ab754SHans Petter Selasky 		 * generates the error WSAEMSGSIZE. For unreliable
1570b00ab754SHans Petter Selasky 		 * protocols (for example, UDP) the excess data is
1571b00ab754SHans Petter Selasky 		 * lost..."
1572b00ab754SHans Petter Selasky 		 *
1573b00ab754SHans Petter Selasky 		 * So if the message is bigger than the buffer
1574b00ab754SHans Petter Selasky 		 * supplied to us, the excess data is discarded,
1575b00ab754SHans Petter Selasky 		 * and we'll report an error.
1576b00ab754SHans Petter Selasky 		 */
15776f9cba8fSJoseph Mingrone 		sock_fmterrmsg(errbuf, errbuflen, sock_geterrcode(),
15786f9cba8fSJoseph Mingrone 		    "recv() failed");
1579b00ab754SHans Petter Selasky 		return -1;
1580b00ab754SHans Petter Selasky 	}
1581b00ab754SHans Petter Selasky #else /* _WIN32 */
1582b00ab754SHans Petter Selasky 	/*
1583b00ab754SHans Petter Selasky 	 * The Single UNIX Specification says that a recv() on
1584b00ab754SHans Petter Selasky 	 * a socket for a message-oriented protocol will discard
1585b00ab754SHans Petter Selasky 	 * the excess data.  It does *not* indicate that the
1586b00ab754SHans Petter Selasky 	 * receive will fail with, for example, EMSGSIZE.
1587b00ab754SHans Petter Selasky 	 *
1588b00ab754SHans Petter Selasky 	 * Therefore, we use recvmsg(), which appears to be
1589b00ab754SHans Petter Selasky 	 * the only way to get a "message truncated" indication
1590b00ab754SHans Petter Selasky 	 * when receiving a message for a message-oriented
1591b00ab754SHans Petter Selasky 	 * protocol.
1592b00ab754SHans Petter Selasky 	 */
1593b00ab754SHans Petter Selasky 	message.msg_name = NULL;	/* we don't care who it's from */
1594b00ab754SHans Petter Selasky 	message.msg_namelen = 0;
1595b00ab754SHans Petter Selasky 	iov.iov_base = buffer;
1596b00ab754SHans Petter Selasky 	iov.iov_len = size;
1597b00ab754SHans Petter Selasky 	message.msg_iov = &iov;
1598b00ab754SHans Petter Selasky 	message.msg_iovlen = 1;
1599b00ab754SHans Petter Selasky #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
1600b00ab754SHans Petter Selasky 	message.msg_control = NULL;	/* we don't care about control information */
1601b00ab754SHans Petter Selasky 	message.msg_controllen = 0;
1602b00ab754SHans Petter Selasky #endif
1603b00ab754SHans Petter Selasky #ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
1604b00ab754SHans Petter Selasky 	message.msg_flags = 0;
1605b00ab754SHans Petter Selasky #endif
16066f9cba8fSJoseph Mingrone #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
16076f9cba8fSJoseph Mingrone 	nread = fuzz_recv(buffer, size);
16086f9cba8fSJoseph Mingrone #else
1609b00ab754SHans Petter Selasky 	nread = recvmsg(sock, &message, 0);
16106f9cba8fSJoseph Mingrone #endif
1611b00ab754SHans Petter Selasky 	if (nread == -1)
1612b00ab754SHans Petter Selasky 	{
1613b00ab754SHans Petter Selasky 		if (errno == EINTR)
1614b00ab754SHans Petter Selasky 			return -3;
16156f9cba8fSJoseph Mingrone 		sock_geterrmsg(errbuf, errbuflen, "recv() failed");
1616b00ab754SHans Petter Selasky 		return -1;
1617b00ab754SHans Petter Selasky 	}
1618b00ab754SHans Petter Selasky #ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
1619b00ab754SHans Petter Selasky 	/*
1620b00ab754SHans Petter Selasky 	 * XXX - Solaris supports this, but only if you ask for the
1621b00ab754SHans Petter Selasky 	 * X/Open version of recvmsg(); should we use that, or will
1622b00ab754SHans Petter Selasky 	 * that cause other problems?
1623b00ab754SHans Petter Selasky 	 */
1624b00ab754SHans Petter Selasky 	if (message.msg_flags & MSG_TRUNC)
1625b00ab754SHans Petter Selasky 	{
1626b00ab754SHans Petter Selasky 		/*
1627b00ab754SHans Petter Selasky 		 * Message was bigger than the specified buffer size.
1628b00ab754SHans Petter Selasky 		 *
1629b00ab754SHans Petter Selasky 		 * Report this as an error, as the Microsoft documentation
1630b00ab754SHans Petter Selasky 		 * implies we'd do in a similar case on Windows.
1631b00ab754SHans Petter Selasky 		 */
16326f9cba8fSJoseph Mingrone 		snprintf(errbuf, errbuflen, "recv(): Message too long");
1633b00ab754SHans Petter Selasky 		return -1;
1634b00ab754SHans Petter Selasky 	}
1635b00ab754SHans Petter Selasky #endif /* HAVE_STRUCT_MSGHDR_MSG_FLAGS */
1636b00ab754SHans Petter Selasky #endif /* _WIN32 */
1637b00ab754SHans Petter Selasky 
1638b00ab754SHans Petter Selasky 	/*
1639b00ab754SHans Petter Selasky 	 * The size we're reading fits in an int, so the return value
1640b00ab754SHans Petter Selasky 	 * will fit in an int.
1641b00ab754SHans Petter Selasky 	 */
1642b00ab754SHans Petter Selasky 	return (int)nread;
1643b00ab754SHans Petter Selasky }
1644b00ab754SHans Petter Selasky 
1645b00ab754SHans Petter Selasky /*
1646ada6f083SXin LI  * \brief It discards N bytes that are currently waiting to be read on the current socket.
1647ada6f083SXin LI  *
1648ada6f083SXin LI  * This function is useful in case we receive a message we cannot understand (e.g.
1649ada6f083SXin LI  * wrong version number when receiving a network packet), so that we have to discard all
1650ada6f083SXin LI  * data before reading a new message.
1651ada6f083SXin LI  *
1652ada6f083SXin LI  * This function will read 'size' bytes from the socket and discard them.
1653ada6f083SXin LI  * It defines an internal buffer in which data will be copied; however, in case
1654ada6f083SXin LI  * this buffer is not large enough, it will cycle in order to read everything as well.
1655ada6f083SXin LI  *
1656ada6f083SXin LI  * \param sock: the connected socket currently opened.
1657ada6f083SXin LI  *
1658ada6f083SXin LI  * \param size: number of bytes that have to be discarded.
1659ada6f083SXin LI  *
1660ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1661ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1662ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1663ada6f083SXin LI  *
1664ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1665ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1666ada6f083SXin LI  *
1667ada6f083SXin LI  * \return '0' if everything is fine, '-1' if some errors occurred.
1668ada6f083SXin LI  * The error message is returned in the 'errbuf' variable.
1669ada6f083SXin LI  */
sock_discard(PCAP_SOCKET sock,SSL * ssl,int size,char * errbuf,int errbuflen)1670*afdbf109SJoseph Mingrone int sock_discard(PCAP_SOCKET sock, SSL *ssl, int size, char *errbuf,
1671*afdbf109SJoseph Mingrone     int errbuflen)
1672ada6f083SXin LI {
1673ada6f083SXin LI #define TEMP_BUF_SIZE 32768
1674ada6f083SXin LI 
1675ada6f083SXin LI 	char buffer[TEMP_BUF_SIZE];		/* network buffer, to be used when the message is discarded */
1676ada6f083SXin LI 
1677ada6f083SXin LI 	/*
1678ada6f083SXin LI 	 * A static allocation avoids the need of a 'malloc()' each time we want to discard a message
1679ada6f083SXin LI 	 * Our feeling is that a buffer if 32KB is enough for most of the application;
1680ada6f083SXin LI 	 * in case this is not enough, the "while" loop discards the message by calling the
1681ada6f083SXin LI 	 * sockrecv() several times.
1682ada6f083SXin LI 	 * We do not want to create a bigger variable because this causes the program to exit on
1683ada6f083SXin LI 	 * some platforms (e.g. BSD)
1684ada6f083SXin LI 	 */
1685ada6f083SXin LI 	while (size > TEMP_BUF_SIZE)
1686ada6f083SXin LI 	{
16876f9cba8fSJoseph Mingrone 		if (sock_recv(sock, ssl, buffer, TEMP_BUF_SIZE, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
1688ada6f083SXin LI 			return -1;
1689ada6f083SXin LI 
1690ada6f083SXin LI 		size -= TEMP_BUF_SIZE;
1691ada6f083SXin LI 	}
1692ada6f083SXin LI 
1693ada6f083SXin LI 	/*
1694ada6f083SXin LI 	 * If there is still data to be discarded
1695ada6f083SXin LI 	 * In this case, the data can fit into the temporary buffer
1696ada6f083SXin LI 	 */
1697ada6f083SXin LI 	if (size)
1698ada6f083SXin LI 	{
16996f9cba8fSJoseph Mingrone 		if (sock_recv(sock, ssl, buffer, size, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
1700ada6f083SXin LI 			return -1;
1701ada6f083SXin LI 	}
1702ada6f083SXin LI 
1703ada6f083SXin LI 	return 0;
1704ada6f083SXin LI }
1705ada6f083SXin LI 
1706ada6f083SXin LI /*
1707ada6f083SXin LI  * \brief Checks that one host (identified by the sockaddr_storage structure) belongs to an 'allowed list'.
1708ada6f083SXin LI  *
1709ada6f083SXin LI  * This function is useful after an accept() call in order to check if the connecting
1710ada6f083SXin LI  * host is allowed to connect to me. To do that, we have a buffer that keeps the list of the
1711ada6f083SXin LI  * allowed host; this function checks the sockaddr_storage structure of the connecting host
1712ada6f083SXin LI  * against this host list, and it returns '0' is the host is included in this list.
1713ada6f083SXin LI  *
1714ada6f083SXin LI  * \param hostlist: pointer to a string that contains the list of the allowed host.
1715ada6f083SXin LI  *
1716ada6f083SXin LI  * \param sep: a string that keeps the separators used between the hosts (for example the
1717ada6f083SXin LI  * space character) in the host list.
1718ada6f083SXin LI  *
1719ada6f083SXin LI  * \param from: a sockaddr_storage structure, as it is returned by the accept() call.
1720ada6f083SXin LI  *
1721ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1722ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1723ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1724ada6f083SXin LI  *
1725ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1726ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1727ada6f083SXin LI  *
1728ada6f083SXin LI  * \return It returns:
1729ada6f083SXin LI  * - '1' if the host list is empty
1730ada6f083SXin LI  * - '0' if the host belongs to the host list (and therefore it is allowed to connect)
1731ada6f083SXin LI  * - '-1' in case the host does not belong to the host list (and therefore it is not allowed to connect
1732ada6f083SXin LI  * - '-2' in case or error. The error message is returned in the 'errbuf' variable.
1733ada6f083SXin LI  */
sock_check_hostlist(const char * hostlist,const char * sep,struct sockaddr_storage * from,char * errbuf,int errbuflen)1734*afdbf109SJoseph Mingrone int sock_check_hostlist(const char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen)
1735ada6f083SXin LI {
1736ada6f083SXin LI 	/* checks if the connecting host is among the ones allowed */
1737ada6f083SXin LI 	if ((hostlist) && (hostlist[0]))
1738ada6f083SXin LI 	{
1739ada6f083SXin LI 		char *token;					/* temp, needed to separate items into the hostlist */
1740ada6f083SXin LI 		struct addrinfo *addrinfo, *ai_next;
1741ada6f083SXin LI 		char *temphostlist;
1742ada6f083SXin LI 		char *lasts;
174357e22627SCy Schubert 		int getaddrinfo_failed = 0;
1744ada6f083SXin LI 
1745ada6f083SXin LI 		/*
1746ada6f083SXin LI 		 * The problem is that strtok modifies the original variable by putting '0' at the end of each token
1747ada6f083SXin LI 		 * So, we have to create a new temporary string in which the original content is kept
1748ada6f083SXin LI 		 */
1749ada6f083SXin LI 		temphostlist = strdup(hostlist);
1750ada6f083SXin LI 		if (temphostlist == NULL)
1751ada6f083SXin LI 		{
17526f9cba8fSJoseph Mingrone 			sock_geterrmsg(errbuf, errbuflen,
17536f9cba8fSJoseph Mingrone 			    "sock_check_hostlist(), malloc() failed");
1754ada6f083SXin LI 			return -2;
1755ada6f083SXin LI 		}
1756ada6f083SXin LI 
1757*afdbf109SJoseph Mingrone 		token = pcapint_strtok_r(temphostlist, sep, &lasts);
1758ada6f083SXin LI 
1759ada6f083SXin LI 		/* it avoids a warning in the compilation ('addrinfo used but not initialized') */
1760ada6f083SXin LI 		addrinfo = NULL;
1761ada6f083SXin LI 
1762ada6f083SXin LI 		while (token != NULL)
1763ada6f083SXin LI 		{
1764ada6f083SXin LI 			struct addrinfo hints;
1765ada6f083SXin LI 			int retval;
1766ada6f083SXin LI 
1767ada6f083SXin LI 			addrinfo = NULL;
1768ada6f083SXin LI 			memset(&hints, 0, sizeof(struct addrinfo));
1769ada6f083SXin LI 			hints.ai_family = PF_UNSPEC;
1770ada6f083SXin LI 			hints.ai_socktype = SOCK_STREAM;
1771ada6f083SXin LI 
177257e22627SCy Schubert 			retval = getaddrinfo(token, NULL, &hints, &addrinfo);
1773ada6f083SXin LI 			if (retval != 0)
1774ada6f083SXin LI 			{
1775ada6f083SXin LI 				if (errbuf)
177657e22627SCy Schubert 					get_gai_errstring(errbuf, errbuflen,
177757e22627SCy Schubert 					    "Allowed host list error: ",
177857e22627SCy Schubert 					    retval, token, NULL);
1779ada6f083SXin LI 
178057e22627SCy Schubert 				/*
178157e22627SCy Schubert 				 * Note that at least one call to getaddrinfo()
178257e22627SCy Schubert 				 * failed.
178357e22627SCy Schubert 				 */
178457e22627SCy Schubert 				getaddrinfo_failed = 1;
1785ada6f083SXin LI 
1786ada6f083SXin LI 				/* Get next token */
1787*afdbf109SJoseph Mingrone 				token = pcapint_strtok_r(NULL, sep, &lasts);
1788ada6f083SXin LI 				continue;
1789ada6f083SXin LI 			}
1790ada6f083SXin LI 
1791ada6f083SXin LI 			/* ai_next is required to preserve the content of addrinfo, in order to deallocate it properly */
1792ada6f083SXin LI 			ai_next = addrinfo;
1793ada6f083SXin LI 			while (ai_next)
1794ada6f083SXin LI 			{
1795ada6f083SXin LI 				if (sock_cmpaddr(from, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
1796ada6f083SXin LI 				{
1797ada6f083SXin LI 					free(temphostlist);
1798b00ab754SHans Petter Selasky 					freeaddrinfo(addrinfo);
1799ada6f083SXin LI 					return 0;
1800ada6f083SXin LI 				}
1801ada6f083SXin LI 
1802ada6f083SXin LI 				/*
1803ada6f083SXin LI 				 * If we are here, it means that the current address does not matches
1804ada6f083SXin LI 				 * Let's try with the next one in the header chain
1805ada6f083SXin LI 				 */
1806ada6f083SXin LI 				ai_next = ai_next->ai_next;
1807ada6f083SXin LI 			}
1808ada6f083SXin LI 
1809ada6f083SXin LI 			freeaddrinfo(addrinfo);
1810ada6f083SXin LI 			addrinfo = NULL;
1811ada6f083SXin LI 
1812ada6f083SXin LI 			/* Get next token */
1813*afdbf109SJoseph Mingrone 			token = pcapint_strtok_r(NULL, sep, &lasts);
1814ada6f083SXin LI 		}
1815ada6f083SXin LI 
1816ada6f083SXin LI 		if (addrinfo)
1817ada6f083SXin LI 		{
1818ada6f083SXin LI 			freeaddrinfo(addrinfo);
1819ada6f083SXin LI 			addrinfo = NULL;
1820ada6f083SXin LI 		}
1821ada6f083SXin LI 
182257e22627SCy Schubert 		free(temphostlist);
182357e22627SCy Schubert 
182457e22627SCy Schubert 		if (getaddrinfo_failed) {
182557e22627SCy Schubert 			/*
182657e22627SCy Schubert 			 * At least one getaddrinfo() call failed;
182757e22627SCy Schubert 			 * treat that as an error, so rpcapd knows
182857e22627SCy Schubert 			 * that it should log it locally as well
182957e22627SCy Schubert 			 * as telling the client about it.
183057e22627SCy Schubert 			 */
183157e22627SCy Schubert 			return -2;
183257e22627SCy Schubert 		} else {
183357e22627SCy Schubert 			/*
183457e22627SCy Schubert 			 * All getaddrinfo() calls succeeded, but
183557e22627SCy Schubert 			 * the host wasn't in the list.
183657e22627SCy Schubert 			 */
1837ada6f083SXin LI 			if (errbuf)
18386f9cba8fSJoseph Mingrone 				snprintf(errbuf, errbuflen, "The host is not in the allowed host list. Connection refused.");
1839ada6f083SXin LI 			return -1;
1840ada6f083SXin LI 		}
184157e22627SCy Schubert 	}
1842ada6f083SXin LI 
1843ada6f083SXin LI 	/* No hostlist, so we have to return 'empty list' */
1844ada6f083SXin LI 	return 1;
1845ada6f083SXin LI }
1846ada6f083SXin LI 
1847ada6f083SXin LI /*
1848ada6f083SXin LI  * \brief Compares two addresses contained into two sockaddr_storage structures.
1849ada6f083SXin LI  *
1850ada6f083SXin LI  * This function is useful to compare two addresses, given their internal representation,
1851ada6f083SXin LI  * i.e. an sockaddr_storage structure.
1852ada6f083SXin LI  *
1853ada6f083SXin LI  * The two structures do not need to be sockaddr_storage; you can have both 'sockaddr_in' and
1854*afdbf109SJoseph Mingrone  * sockaddr_in6, properly casted in order to be compliant to the function interface.
1855ada6f083SXin LI  *
1856ada6f083SXin LI  * This function will return '0' if the two addresses matches, '-1' if not.
1857ada6f083SXin LI  *
1858ada6f083SXin LI  * \param first: a sockaddr_storage structure, (for example the one that is returned by an
1859ada6f083SXin LI  * accept() call), containing the first address to compare.
1860ada6f083SXin LI  *
1861ada6f083SXin LI  * \param second: a sockaddr_storage structure containing the second address to compare.
1862ada6f083SXin LI  *
1863ada6f083SXin LI  * \return '0' if the addresses are equal, '-1' if they are different.
1864ada6f083SXin LI  */
sock_cmpaddr(struct sockaddr_storage * first,struct sockaddr_storage * second)1865ada6f083SXin LI int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second)
1866ada6f083SXin LI {
1867ada6f083SXin LI 	if (first->ss_family == second->ss_family)
1868ada6f083SXin LI 	{
1869ada6f083SXin LI 		if (first->ss_family == AF_INET)
1870ada6f083SXin LI 		{
1871ada6f083SXin LI 			if (memcmp(&(((struct sockaddr_in *) first)->sin_addr),
1872ada6f083SXin LI 				&(((struct sockaddr_in *) second)->sin_addr),
1873ada6f083SXin LI 				sizeof(struct in_addr)) == 0)
1874ada6f083SXin LI 				return 0;
1875ada6f083SXin LI 		}
1876ada6f083SXin LI 		else /* address family is AF_INET6 */
1877ada6f083SXin LI 		{
1878ada6f083SXin LI 			if (memcmp(&(((struct sockaddr_in6 *) first)->sin6_addr),
1879ada6f083SXin LI 				&(((struct sockaddr_in6 *) second)->sin6_addr),
1880ada6f083SXin LI 				sizeof(struct in6_addr)) == 0)
1881ada6f083SXin LI 				return 0;
1882ada6f083SXin LI 		}
1883ada6f083SXin LI 	}
1884ada6f083SXin LI 
1885ada6f083SXin LI 	return -1;
1886ada6f083SXin LI }
1887ada6f083SXin LI 
1888ada6f083SXin LI /*
1889ada6f083SXin LI  * \brief It gets the address/port the system picked for this socket (on connected sockets).
1890ada6f083SXin LI  *
1891ada6f083SXin LI  * It is used to return the address and port the server picked for our socket on the local machine.
1892ada6f083SXin LI  * It works only on:
1893ada6f083SXin LI  * - connected sockets
1894ada6f083SXin LI  * - server sockets
1895ada6f083SXin LI  *
1896ada6f083SXin LI  * On unconnected client sockets it does not work because the system dynamically chooses a port
1897ada6f083SXin LI  * only when the socket calls a send() call.
1898ada6f083SXin LI  *
1899ada6f083SXin LI  * \param sock: the connected socket currently opened.
1900ada6f083SXin LI  *
1901ada6f083SXin LI  * \param address: it contains the address that will be returned by the function. This buffer
1902ada6f083SXin LI  * must be properly allocated by the user. The address can be either literal or numeric depending
1903ada6f083SXin LI  * on the value of 'Flags'.
1904ada6f083SXin LI  *
1905ada6f083SXin LI  * \param addrlen: the length of the 'address' buffer.
1906ada6f083SXin LI  *
1907ada6f083SXin LI  * \param port: it contains the port that will be returned by the function. This buffer
1908ada6f083SXin LI  * must be properly allocated by the user.
1909ada6f083SXin LI  *
1910ada6f083SXin LI  * \param portlen: the length of the 'port' buffer.
1911ada6f083SXin LI  *
1912ada6f083SXin LI  * \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function)
1913ada6f083SXin LI  * that determine if the resulting address must be in numeric / literal form, and so on.
1914ada6f083SXin LI  *
1915ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1916ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1917ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1918ada6f083SXin LI  *
1919ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1920ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1921ada6f083SXin LI  *
1922ada6f083SXin LI  * \return It returns '-1' if this function succeeds, '0' otherwise.
1923ada6f083SXin LI  * The address and port corresponding are returned back in the buffers 'address' and 'port'.
1924ada6f083SXin LI  * In any case, the returned strings are '0' terminated.
1925ada6f083SXin LI  *
1926ada6f083SXin LI  * \warning If the socket is using a connectionless protocol, the address may not be available
1927ada6f083SXin LI  * until I/O occurs on the socket.
1928ada6f083SXin LI  */
sock_getmyinfo(PCAP_SOCKET sock,char * address,int addrlen,char * port,int portlen,int flags,char * errbuf,int errbuflen)1929*afdbf109SJoseph Mingrone int sock_getmyinfo(PCAP_SOCKET sock, char *address, int addrlen, char *port,
1930*afdbf109SJoseph Mingrone     int portlen, int flags, char *errbuf, int errbuflen)
1931ada6f083SXin LI {
1932ada6f083SXin LI 	struct sockaddr_storage mysockaddr;
1933ada6f083SXin LI 	socklen_t sockaddrlen;
1934ada6f083SXin LI 
1935ada6f083SXin LI 
1936ada6f083SXin LI 	sockaddrlen = sizeof(struct sockaddr_storage);
1937ada6f083SXin LI 
1938ada6f083SXin LI 	if (getsockname(sock, (struct sockaddr *) &mysockaddr, &sockaddrlen) == -1)
1939ada6f083SXin LI 	{
19406f9cba8fSJoseph Mingrone 		sock_geterrmsg(errbuf, errbuflen, "getsockname() failed");
1941ada6f083SXin LI 		return 0;
1942ada6f083SXin LI 	}
1943b00ab754SHans Petter Selasky 
1944ada6f083SXin LI 	/* Returns the numeric address of the host that triggered the error */
1945ada6f083SXin LI 	return sock_getascii_addrport(&mysockaddr, address, addrlen, port, portlen, flags, errbuf, errbuflen);
1946ada6f083SXin LI }
1947ada6f083SXin LI 
1948ada6f083SXin LI /*
1949ada6f083SXin LI  * \brief It retrieves two strings containing the address and the port of a given 'sockaddr' variable.
1950ada6f083SXin LI  *
1951ada6f083SXin LI  * This function is basically an extended version of the inet_ntop(), which does not exist in
1952ada6f083SXin LI  * Winsock because the same result can be obtained by using the getnameinfo().
1953ada6f083SXin LI  * However, differently from inet_ntop(), this function is able to return also literal names
1954ada6f083SXin LI  * (e.g. 'localhost') dependently from the 'Flags' parameter.
1955ada6f083SXin LI  *
1956ada6f083SXin LI  * The function accepts a sockaddr_storage variable (which can be returned by several functions
1957ada6f083SXin LI  * like bind(), connect(), accept(), and more) and it transforms its content into a 'human'
1958ada6f083SXin LI  * form. So, for instance, it is able to translate an hex address (stored in binary form) into
1959ada6f083SXin LI  * a standard IPv6 address like "::1".
1960ada6f083SXin LI  *
1961ada6f083SXin LI  * The behavior of this function depends on the parameters we have in the 'Flags' variable, which
1962ada6f083SXin LI  * are the ones allowed in the standard getnameinfo() socket function.
1963ada6f083SXin LI  *
1964ada6f083SXin LI  * \param sockaddr: a 'sockaddr_in' or 'sockaddr_in6' structure containing the address that
1965ada6f083SXin LI  * need to be translated from network form into the presentation form. This structure must be
1966ada6f083SXin LI  * zero-ed prior using it, and the address family field must be filled with the proper value.
1967ada6f083SXin LI  * The user must cast any 'sockaddr_in' or 'sockaddr_in6' structures to 'sockaddr_storage' before
1968ada6f083SXin LI  * calling this function.
1969ada6f083SXin LI  *
1970ada6f083SXin LI  * \param address: it contains the address that will be returned by the function. This buffer
1971ada6f083SXin LI  * must be properly allocated by the user. The address can be either literal or numeric depending
1972ada6f083SXin LI  * on the value of 'Flags'.
1973ada6f083SXin LI  *
1974ada6f083SXin LI  * \param addrlen: the length of the 'address' buffer.
1975ada6f083SXin LI  *
1976ada6f083SXin LI  * \param port: it contains the port that will be returned by the function. This buffer
1977ada6f083SXin LI  * must be properly allocated by the user.
1978ada6f083SXin LI  *
1979ada6f083SXin LI  * \param portlen: the length of the 'port' buffer.
1980ada6f083SXin LI  *
1981ada6f083SXin LI  * \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function)
1982ada6f083SXin LI  * that determine if the resulting address must be in numeric / literal form, and so on.
1983ada6f083SXin LI  *
1984ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
1985ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
1986ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
1987ada6f083SXin LI  *
1988ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
1989ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
1990ada6f083SXin LI  *
1991ada6f083SXin LI  * \return It returns '-1' if this function succeeds, '0' otherwise.
1992ada6f083SXin LI  * The address and port corresponding to the given SockAddr are returned back in the buffers 'address'
1993ada6f083SXin LI  * and 'port'.
1994ada6f083SXin LI  * In any case, the returned strings are '0' terminated.
1995ada6f083SXin LI  */
sock_getascii_addrport(const struct sockaddr_storage * sockaddr,char * address,int addrlen,char * port,int portlen,int flags,char * errbuf,size_t errbuflen)19966f9cba8fSJoseph Mingrone int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, size_t errbuflen)
1997ada6f083SXin LI {
1998ada6f083SXin LI 	socklen_t sockaddrlen;
1999ada6f083SXin LI 	int retval;					/* Variable that keeps the return value; */
2000ada6f083SXin LI 
2001ada6f083SXin LI 	retval = -1;
2002ada6f083SXin LI 
2003ada6f083SXin LI #ifdef _WIN32
2004ada6f083SXin LI 	if (sockaddr->ss_family == AF_INET)
2005ada6f083SXin LI 		sockaddrlen = sizeof(struct sockaddr_in);
2006ada6f083SXin LI 	else
2007ada6f083SXin LI 		sockaddrlen = sizeof(struct sockaddr_in6);
2008ada6f083SXin LI #else
2009ada6f083SXin LI 	sockaddrlen = sizeof(struct sockaddr_storage);
2010ada6f083SXin LI #endif
2011ada6f083SXin LI 
2012ada6f083SXin LI 	if ((flags & NI_NUMERICHOST) == 0)	/* Check that we want literal names */
2013ada6f083SXin LI 	{
2014ada6f083SXin LI 		if ((sockaddr->ss_family == AF_INET6) &&
2015ada6f083SXin LI 			(memcmp(&((struct sockaddr_in6 *) sockaddr)->sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(struct in6_addr)) == 0))
2016ada6f083SXin LI 		{
2017ada6f083SXin LI 			if (address)
2018*afdbf109SJoseph Mingrone 				pcapint_strlcpy(address, SOCKET_NAME_NULL_DAD, addrlen);
2019ada6f083SXin LI 			return retval;
2020ada6f083SXin LI 		}
2021ada6f083SXin LI 	}
2022ada6f083SXin LI 
2023ada6f083SXin LI 	if (getnameinfo((struct sockaddr *) sockaddr, sockaddrlen, address, addrlen, port, portlen, flags) != 0)
2024ada6f083SXin LI 	{
2025ada6f083SXin LI 		/* If the user wants to receive an error message */
2026ada6f083SXin LI 		if (errbuf)
2027ada6f083SXin LI 		{
20286f9cba8fSJoseph Mingrone 			sock_geterrmsg(errbuf, errbuflen,
20296f9cba8fSJoseph Mingrone 			    "getnameinfo() failed");
2030ada6f083SXin LI 			errbuf[errbuflen - 1] = 0;
2031ada6f083SXin LI 		}
2032ada6f083SXin LI 
2033ada6f083SXin LI 		if (address)
2034ada6f083SXin LI 		{
2035*afdbf109SJoseph Mingrone 			pcapint_strlcpy(address, SOCKET_NO_NAME_AVAILABLE, addrlen);
2036ada6f083SXin LI 			address[addrlen - 1] = 0;
2037ada6f083SXin LI 		}
2038ada6f083SXin LI 
2039ada6f083SXin LI 		if (port)
2040ada6f083SXin LI 		{
2041*afdbf109SJoseph Mingrone 			pcapint_strlcpy(port, SOCKET_NO_PORT_AVAILABLE, portlen);
2042ada6f083SXin LI 			port[portlen - 1] = 0;
2043ada6f083SXin LI 		}
2044ada6f083SXin LI 
2045ada6f083SXin LI 		retval = 0;
2046ada6f083SXin LI 	}
2047ada6f083SXin LI 
2048ada6f083SXin LI 	return retval;
2049ada6f083SXin LI }
2050ada6f083SXin LI 
2051ada6f083SXin LI /*
2052ada6f083SXin LI  * \brief It translates an address from the 'presentation' form into the 'network' form.
2053ada6f083SXin LI  *
2054ada6f083SXin LI  * This function basically replaces inet_pton(), which does not exist in Winsock because
2055ada6f083SXin LI  * the same result can be obtained by using the getaddrinfo().
2056ada6f083SXin LI  * An additional advantage is that 'Address' can be both a numeric address (e.g. '127.0.0.1',
2057ada6f083SXin LI  * like in inet_pton() ) and a literal name (e.g. 'localhost').
2058ada6f083SXin LI  *
2059ada6f083SXin LI  * This function does the reverse job of sock_getascii_addrport().
2060ada6f083SXin LI  *
2061ada6f083SXin LI  * \param address: a zero-terminated string which contains the name you have to
2062ada6f083SXin LI  * translate. The name can be either literal (e.g. 'localhost') or numeric (e.g. '::1').
2063ada6f083SXin LI  *
2064ada6f083SXin LI  * \param sockaddr: a user-allocated sockaddr_storage structure which will contains the
2065ada6f083SXin LI  * 'network' form of the requested address.
2066ada6f083SXin LI  *
2067ada6f083SXin LI  * \param addr_family: a constant which can assume the following values:
2068ada6f083SXin LI  * - 'AF_INET' if we want to ping an IPv4 host
2069ada6f083SXin LI  * - 'AF_INET6' if we want to ping an IPv6 host
2070ada6f083SXin LI  * - 'AF_UNSPEC' if we do not have preferences about the protocol used to ping the host
2071ada6f083SXin LI  *
2072ada6f083SXin LI  * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
2073ada6f083SXin LI  * error message. This buffer has to be at least 'errbuflen' in length.
2074ada6f083SXin LI  * It can be NULL; in this case the error cannot be printed.
2075ada6f083SXin LI  *
2076ada6f083SXin LI  * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
2077ada6f083SXin LI  * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
2078ada6f083SXin LI  *
2079ada6f083SXin LI  * \return '-1' if the translation succeeded, '-2' if there was some non critical error, '0'
2080ada6f083SXin LI  * otherwise. In case it fails, the content of the SockAddr variable remains unchanged.
2081ada6f083SXin LI  * A 'non critical error' can occur in case the 'Address' is a literal name, which can be mapped
2082ada6f083SXin LI  * to several network addresses (e.g. 'foo.bar.com' => '10.2.2.2' and '10.2.2.3'). In this case
2083ada6f083SXin LI  * the content of the SockAddr parameter will be the address corresponding to the first mapping.
2084ada6f083SXin LI  *
2085ada6f083SXin LI  * \warning The sockaddr_storage structure MUST be allocated by the user.
2086ada6f083SXin LI  */
sock_present2network(const char * address,struct sockaddr_storage * sockaddr,int addr_family,char * errbuf,int errbuflen)2087ada6f083SXin LI int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen)
2088ada6f083SXin LI {
2089ada6f083SXin LI 	struct addrinfo *addrinfo;
2090ada6f083SXin LI 	struct addrinfo hints;
2091ada6f083SXin LI 
2092ada6f083SXin LI 	memset(&hints, 0, sizeof(hints));
2093ada6f083SXin LI 
2094ada6f083SXin LI 	hints.ai_family = addr_family;
2095ada6f083SXin LI 
2096*afdbf109SJoseph Mingrone 	addrinfo = sock_initaddress(address, "22222" /* fake port */, &hints,
2097*afdbf109SJoseph Mingrone 	    errbuf, errbuflen);
2098*afdbf109SJoseph Mingrone 	if (addrinfo == NULL)
2099ada6f083SXin LI 		return 0;
2100ada6f083SXin LI 
2101ada6f083SXin LI 	if (addrinfo->ai_family == PF_INET)
2102ada6f083SXin LI 		memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in));
2103ada6f083SXin LI 	else
2104ada6f083SXin LI 		memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in6));
2105ada6f083SXin LI 
2106ada6f083SXin LI 	if (addrinfo->ai_next != NULL)
2107ada6f083SXin LI 	{
2108ada6f083SXin LI 		freeaddrinfo(addrinfo);
2109ada6f083SXin LI 
2110ada6f083SXin LI 		if (errbuf)
21116f9cba8fSJoseph Mingrone 			snprintf(errbuf, errbuflen, "More than one socket requested; using the first one returned");
2112ada6f083SXin LI 		return -2;
2113ada6f083SXin LI 	}
2114ada6f083SXin LI 
2115ada6f083SXin LI 	freeaddrinfo(addrinfo);
2116ada6f083SXin LI 	return -1;
2117ada6f083SXin LI }
2118