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