Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2002 - 2003 |
| 3 | * NetGroup, Politecnico di Torino (Italy) |
| 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: |
| 9 | * |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. Neither the name of the Politecnico di Torino nor the names of its |
| 16 | * contributors may be used to endorse or promote products derived from |
| 17 | * this software without specific prior written permission. |
| 18 | * |
| 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | * |
| 31 | */ |
| 32 | |
| 33 | #ifndef __SOCKUTILS_H__ |
| 34 | #define __SOCKUTILS_H__ |
| 35 | |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 36 | #ifdef _MSC_VER |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 37 | #pragma once |
| 38 | #endif |
| 39 | |
| 40 | #ifdef _WIN32 |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 41 | /* Need windef.h for defines used in winsock2.h under MingW32 */ |
| 42 | #ifdef __MINGW32__ |
| 43 | #include <windef.h> |
| 44 | #endif |
| 45 | #include <winsock2.h> |
| 46 | #include <ws2tcpip.h> |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 47 | |
| 48 | /* |
| 49 | * Winsock doesn't have this UN*X type; it's used in the UN*X |
| 50 | * sockets API. |
| 51 | * |
| 52 | * XXX - do we need to worry about UN*Xes so old that *they* |
| 53 | * don't have it, either? |
| 54 | */ |
| 55 | typedef int socklen_t; |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 56 | #else |
| 57 | /* UN*X */ |
| 58 | #include <stdio.h> |
| 59 | #include <string.h> /* for memset() */ |
| 60 | #include <sys/types.h> |
| 61 | #include <sys/socket.h> |
| 62 | #include <netdb.h> /* DNS lookup */ |
| 63 | #include <unistd.h> /* close() */ |
| 64 | #include <errno.h> /* errno() */ |
| 65 | #include <netinet/in.h> /* for sockaddr_in, in BSD at least */ |
| 66 | #include <arpa/inet.h> |
| 67 | #include <net/if.h> |
| 68 | |
| 69 | /*! |
| 70 | * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's |
| 71 | * a file descriptor, and therefore a signed integer. |
| 72 | * We define SOCKET to be a signed integer on UN*X, so that it can |
| 73 | * be used on both platforms. |
| 74 | */ |
| 75 | #ifndef SOCKET |
| 76 | #define SOCKET int |
| 77 | #endif |
| 78 | |
| 79 | /*! |
| 80 | * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET; |
| 81 | * in UN*X, it's -1. |
| 82 | * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on |
| 83 | * both platforms. |
| 84 | */ |
| 85 | #ifndef INVALID_SOCKET |
| 86 | #define INVALID_SOCKET -1 |
| 87 | #endif |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 88 | |
| 89 | /*! |
| 90 | * \brief In Winsock, the close() call cannot be used on a socket; |
| 91 | * closesocket() must be used. |
| 92 | * We define closesocket() to be a wrapper around close() on UN*X, |
| 93 | * so that it can be used on both platforms. |
| 94 | */ |
| 95 | #define closesocket(a) close(a) |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 96 | #endif |
| 97 | |
| 98 | /* |
| 99 | * MingW headers include this definition, but only for Windows XP and above. |
| 100 | * MSDN states that this function is available for most versions on Windows. |
| 101 | */ |
| 102 | #if ((defined(__MINGW32__)) && (_WIN32_WINNT < 0x0501)) |
| 103 | int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, |
| 104 | char*,DWORD,int); |
| 105 | #endif |
| 106 | |
| 107 | /* |
| 108 | * \defgroup SockUtils Cross-platform socket utilities (IPv4-IPv6) |
| 109 | */ |
| 110 | |
| 111 | /* |
| 112 | * \addtogroup SockUtils |
| 113 | * \{ |
| 114 | */ |
| 115 | |
| 116 | /* |
| 117 | * \defgroup ExportedStruct Exported Structures and Definitions |
| 118 | */ |
| 119 | |
| 120 | /* |
| 121 | * \addtogroup ExportedStruct |
| 122 | * \{ |
| 123 | */ |
| 124 | |
| 125 | /* |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 126 | * \brief DEBUG facility: it prints an error message on the screen (stderr) |
| 127 | * |
| 128 | * This macro prints the error on the standard error stream (stderr); |
| 129 | * if we are working in debug mode (i.e. there is no NDEBUG defined) and we are in |
| 130 | * Microsoft Visual C++, the error message will appear on the MSVC console as well. |
| 131 | * |
| 132 | * When NDEBUG is defined, this macro is empty. |
| 133 | * |
| 134 | * \param msg: the message you want to print. |
| 135 | * |
| 136 | * \param expr: 'false' if you want to abort the program, 'true' it you want |
| 137 | * to print the message and continue. |
| 138 | * |
| 139 | * \return No return values. |
| 140 | */ |
| 141 | #ifdef NDEBUG |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 142 | #define SOCK_DEBUG_MESSAGE(msg) ((void)0) |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 143 | #else |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 144 | #if (defined(_WIN32) && defined(_MSC_VER)) |
| 145 | #include <crtdbg.h> /* for _CrtDbgReport */ |
| 146 | /* Use MessageBox(NULL, msg, "warning", MB_OK)' instead of the other calls if you want to debug a Win32 service */ |
| 147 | /* Remember to activate the 'allow service to interact with desktop' flag of the service */ |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 148 | #define SOCK_DEBUG_MESSAGE(msg) { _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s\n", msg); fprintf(stderr, "%s\n", msg); } |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 149 | #else |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 150 | #define SOCK_DEBUG_MESSAGE(msg) { fprintf(stderr, "%s\n", msg); } |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 151 | #endif |
| 152 | #endif |
| 153 | |
| 154 | /**************************************************** |
| 155 | * * |
| 156 | * Exported functions / definitions * |
| 157 | * * |
| 158 | ****************************************************/ |
| 159 | |
| 160 | /* 'checkonly' flag, into the rpsock_bufferize() */ |
| 161 | #define SOCKBUF_CHECKONLY 1 |
| 162 | /* no 'checkonly' flag, into the rpsock_bufferize() */ |
| 163 | #define SOCKBUF_BUFFERIZE 0 |
| 164 | |
| 165 | /* no 'server' flag; it opens a client socket */ |
| 166 | #define SOCKOPEN_CLIENT 0 |
| 167 | /* 'server' flag; it opens a server socket */ |
| 168 | #define SOCKOPEN_SERVER 1 |
| 169 | |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 170 | /* |
| 171 | * Flags for sock_recv(). |
| 172 | */ |
| 173 | #define SOCK_RECEIVEALL_NO 0x00000000 /* Don't wait to receive all data */ |
| 174 | #define SOCK_RECEIVEALL_YES 0x00000001 /* Wait to receive all data */ |
| 175 | |
| 176 | #define SOCK_EOF_ISNT_ERROR 0x00000000 /* Return 0 on EOF */ |
| 177 | #define SOCK_EOF_IS_ERROR 0x00000002 /* Return an error on EOF */ |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 178 | |
| 179 | /* |
| 180 | * \} |
| 181 | */ |
| 182 | |
| 183 | #ifdef __cplusplus |
| 184 | extern "C" { |
| 185 | #endif |
| 186 | |
| 187 | /* |
| 188 | * \defgroup ExportedFunc Exported Functions |
| 189 | */ |
| 190 | |
| 191 | /* |
| 192 | * \addtogroup ExportedFunc |
| 193 | * \{ |
| 194 | */ |
| 195 | |
| 196 | int sock_init(char *errbuf, int errbuflen); |
| 197 | void sock_cleanup(void); |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 198 | void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen); |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 199 | void sock_geterror(const char *caller, char *errbuf, int errbufsize); |
| 200 | int sock_initaddress(const char *address, const char *port, |
| 201 | struct addrinfo *hints, struct addrinfo **addrinfo, |
| 202 | char *errbuf, int errbuflen); |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 203 | int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall, |
| 204 | char *errbuf, int errbuflen); |
| 205 | int sock_recv_dgram(SOCKET sock, void *buffer, size_t size, |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 206 | char *errbuf, int errbuflen); |
| 207 | SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen); |
| 208 | int sock_close(SOCKET sock, char *errbuf, int errbuflen); |
| 209 | |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 210 | int sock_send(SOCKET sock, const char *buffer, size_t size, |
| 211 | char *errbuf, int errbuflen); |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 212 | int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen); |
Haibo Huang | 165065a | 2018-07-23 17:26:52 -0700 | [diff] [blame] | 213 | int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen); |
Elliott Hughes | 965a4b5 | 2017-05-15 10:37:39 -0700 | [diff] [blame] | 214 | int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen); |
| 215 | int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second); |
| 216 | |
| 217 | int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); |
| 218 | |
| 219 | int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); |
| 220 | int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen); |
| 221 | |
| 222 | #ifdef __cplusplus |
| 223 | } |
| 224 | #endif |
| 225 | |
| 226 | /* |
| 227 | * \} |
| 228 | */ |
| 229 | |
| 230 | /* |
| 231 | * \} |
| 232 | */ |
| 233 | |
| 234 | #endif |