sockutils.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #ifndef __SOCKUTILS_H__
  33. #define __SOCKUTILS_H__
  34. #ifdef _MSC_VER
  35. #pragma once
  36. #endif
  37. #ifdef _WIN32
  38. /* Need windef.h for defines used in winsock2.h under MingW32 */
  39. #ifdef __MINGW32__
  40. #include <windef.h>
  41. #endif
  42. #include <winsock2.h>
  43. #include <ws2tcpip.h>
  44. /*
  45. * Winsock doesn't have this UN*X type; it's used in the UN*X
  46. * sockets API.
  47. *
  48. * XXX - do we need to worry about UN*Xes so old that *they*
  49. * don't have it, either?
  50. */
  51. typedef int socklen_t;
  52. #else
  53. /* UN*X */
  54. #include <stdio.h>
  55. #include <string.h> /* for memset() */
  56. #include <sys/types.h>
  57. #include <sys/socket.h>
  58. #include <netdb.h> /* DNS lookup */
  59. #include <unistd.h> /* close() */
  60. #include <errno.h> /* errno() */
  61. #include <netinet/in.h> /* for sockaddr_in, in BSD at least */
  62. #include <arpa/inet.h>
  63. #include <net/if.h>
  64. /*!
  65. * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
  66. * a file descriptor, and therefore a signed integer.
  67. * We define SOCKET to be a signed integer on UN*X, so that it can
  68. * be used on both platforms.
  69. */
  70. #ifndef SOCKET
  71. #define SOCKET int
  72. #endif
  73. /*!
  74. * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
  75. * in UN*X, it's -1.
  76. * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
  77. * both platforms.
  78. */
  79. #ifndef INVALID_SOCKET
  80. #define INVALID_SOCKET -1
  81. #endif
  82. /*!
  83. * \brief In Winsock, the close() call cannot be used on a socket;
  84. * closesocket() must be used.
  85. * We define closesocket() to be a wrapper around close() on UN*X,
  86. * so that it can be used on both platforms.
  87. */
  88. #define closesocket(a) close(a)
  89. #endif
  90. /*
  91. * MingW headers include this definition, but only for Windows XP and above.
  92. * MSDN states that this function is available for most versions on Windows.
  93. */
  94. #if ((defined(__MINGW32__)) && (_WIN32_WINNT < 0x0501))
  95. int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
  96. char*,DWORD,int);
  97. #endif
  98. /*
  99. * \defgroup SockUtils Cross-platform socket utilities (IPv4-IPv6)
  100. */
  101. /*
  102. * \addtogroup SockUtils
  103. * \{
  104. */
  105. /*
  106. * \defgroup ExportedStruct Exported Structures and Definitions
  107. */
  108. /*
  109. * \addtogroup ExportedStruct
  110. * \{
  111. */
  112. /*
  113. * \brief DEBUG facility: it prints an error message on the screen (stderr)
  114. *
  115. * This macro prints the error on the standard error stream (stderr);
  116. * if we are working in debug mode (i.e. there is no NDEBUG defined) and we are in
  117. * Microsoft Visual C++, the error message will appear on the MSVC console as well.
  118. *
  119. * When NDEBUG is defined, this macro is empty.
  120. *
  121. * \param msg: the message you want to print.
  122. *
  123. * \param expr: 'false' if you want to abort the program, 'true' it you want
  124. * to print the message and continue.
  125. *
  126. * \return No return values.
  127. */
  128. #ifdef NDEBUG
  129. #define SOCK_DEBUG_MESSAGE(msg) ((void)0)
  130. #else
  131. #if (defined(_WIN32) && defined(_MSC_VER))
  132. #include <crtdbg.h> /* for _CrtDbgReport */
  133. /* Use MessageBox(NULL, msg, "warning", MB_OK)' instead of the other calls if you want to debug a Win32 service */
  134. /* Remember to activate the 'allow service to interact with desktop' flag of the service */
  135. #define SOCK_DEBUG_MESSAGE(msg) { _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s\n", msg); fprintf(stderr, "%s\n", msg); }
  136. #else
  137. #define SOCK_DEBUG_MESSAGE(msg) { fprintf(stderr, "%s\n", msg); }
  138. #endif
  139. #endif
  140. /****************************************************
  141. * *
  142. * Exported functions / definitions *
  143. * *
  144. ****************************************************/
  145. /* 'checkonly' flag, into the rpsock_bufferize() */
  146. #define SOCKBUF_CHECKONLY 1
  147. /* no 'checkonly' flag, into the rpsock_bufferize() */
  148. #define SOCKBUF_BUFFERIZE 0
  149. /* no 'server' flag; it opens a client socket */
  150. #define SOCKOPEN_CLIENT 0
  151. /* 'server' flag; it opens a server socket */
  152. #define SOCKOPEN_SERVER 1
  153. /*
  154. * Flags for sock_recv().
  155. */
  156. #define SOCK_RECEIVEALL_NO 0x00000000 /* Don't wait to receive all data */
  157. #define SOCK_RECEIVEALL_YES 0x00000001 /* Wait to receive all data */
  158. #define SOCK_EOF_ISNT_ERROR 0x00000000 /* Return 0 on EOF */
  159. #define SOCK_EOF_IS_ERROR 0x00000002 /* Return an error on EOF */
  160. /*
  161. * \}
  162. */
  163. #ifdef __cplusplus
  164. extern "C" {
  165. #endif
  166. /*
  167. * \defgroup ExportedFunc Exported Functions
  168. */
  169. /*
  170. * \addtogroup ExportedFunc
  171. * \{
  172. */
  173. int sock_init(char *errbuf, int errbuflen);
  174. void sock_cleanup(void);
  175. void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen);
  176. void sock_geterror(const char *caller, char *errbuf, int errbufsize);
  177. int sock_initaddress(const char *address, const char *port,
  178. struct addrinfo *hints, struct addrinfo **addrinfo,
  179. char *errbuf, int errbuflen);
  180. int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
  181. char *errbuf, int errbuflen);
  182. int sock_recv_dgram(SOCKET sock, void *buffer, size_t size,
  183. char *errbuf, int errbuflen);
  184. SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen);
  185. int sock_close(SOCKET sock, char *errbuf, int errbuflen);
  186. int sock_send(SOCKET sock, const char *buffer, size_t size,
  187. char *errbuf, int errbuflen);
  188. int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen);
  189. int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen);
  190. int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen);
  191. int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second);
  192. int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen);
  193. int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen);
  194. int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen);
  195. #ifdef __cplusplus
  196. }
  197. #endif
  198. /*
  199. * \}
  200. */
  201. /*
  202. * \}
  203. */
  204. #endif