old_win_sdk_compat.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. //
  2. // old_win_sdk_compat.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP
  11. #define BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <boost/config.hpp>
  18. #include <boost/asio/detail/pop_options.hpp>
  19. #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
  20. // Guess whether we are building against on old Platform SDK.
  21. #if !defined(IN6ADDR_ANY_INIT)
  22. #define BOOST_ASIO_HAS_OLD_WIN_SDK 1
  23. #endif // !defined(IN6ADDR_ANY_INIT)
  24. #if defined(BOOST_ASIO_HAS_OLD_WIN_SDK)
  25. // Emulation of types that are missing from old Platform SDKs.
  26. //
  27. // N.B. this emulation is also used if building for a Windows 2000 target with
  28. // a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support
  29. // in that case.
  30. namespace boost {
  31. namespace asio {
  32. namespace detail {
  33. enum
  34. {
  35. sockaddr_storage_maxsize = 128, // Maximum size.
  36. sockaddr_storage_alignsize = (sizeof(__int64)), // Desired alignment.
  37. sockaddr_storage_pad1size = (sockaddr_storage_alignsize - sizeof(short)),
  38. sockaddr_storage_pad2size = (sockaddr_storage_maxsize -
  39. (sizeof(short) + sockaddr_storage_pad1size + sockaddr_storage_alignsize))
  40. };
  41. struct sockaddr_storage_emulation
  42. {
  43. short ss_family;
  44. char __ss_pad1[sockaddr_storage_pad1size];
  45. __int64 __ss_align;
  46. char __ss_pad2[sockaddr_storage_pad2size];
  47. };
  48. struct in6_addr_emulation
  49. {
  50. union
  51. {
  52. u_char Byte[16];
  53. u_short Word[8];
  54. } u;
  55. };
  56. #if !defined(s6_addr)
  57. # define _S6_un u
  58. # define _S6_u8 Byte
  59. # define s6_addr _S6_un._S6_u8
  60. #endif // !defined(s6_addr)
  61. struct sockaddr_in6_emulation
  62. {
  63. short sin6_family;
  64. u_short sin6_port;
  65. u_long sin6_flowinfo;
  66. in6_addr_emulation sin6_addr;
  67. u_long sin6_scope_id;
  68. };
  69. struct ipv6_mreq_emulation
  70. {
  71. in6_addr_emulation ipv6mr_multiaddr;
  72. unsigned int ipv6mr_interface;
  73. };
  74. #if !defined(IN6ADDR_ANY_INIT)
  75. # define IN6ADDR_ANY_INIT { 0 }
  76. #endif
  77. #if !defined(IN6ADDR_LOOPBACK_INIT)
  78. # define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
  79. #endif
  80. struct addrinfo_emulation
  81. {
  82. int ai_flags;
  83. int ai_family;
  84. int ai_socktype;
  85. int ai_protocol;
  86. size_t ai_addrlen;
  87. char* ai_canonname;
  88. sockaddr* ai_addr;
  89. addrinfo_emulation* ai_next;
  90. };
  91. #if !defined(AI_PASSIVE)
  92. # define AI_PASSIVE 0x1
  93. #endif
  94. #if !defined(AI_CANONNAME)
  95. # define AI_CANONNAME 0x2
  96. #endif
  97. #if !defined(AI_NUMERICHOST)
  98. # define AI_NUMERICHOST 0x4
  99. #endif
  100. #if !defined(EAI_AGAIN)
  101. # define EAI_AGAIN WSATRY_AGAIN
  102. #endif
  103. #if !defined(EAI_BADFLAGS)
  104. # define EAI_BADFLAGS WSAEINVAL
  105. #endif
  106. #if !defined(EAI_FAIL)
  107. # define EAI_FAIL WSANO_RECOVERY
  108. #endif
  109. #if !defined(EAI_FAMILY)
  110. # define EAI_FAMILY WSAEAFNOSUPPORT
  111. #endif
  112. #if !defined(EAI_MEMORY)
  113. # define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
  114. #endif
  115. #if !defined(EAI_NODATA)
  116. # define EAI_NODATA WSANO_DATA
  117. #endif
  118. #if !defined(EAI_NONAME)
  119. # define EAI_NONAME WSAHOST_NOT_FOUND
  120. #endif
  121. #if !defined(EAI_SERVICE)
  122. # define EAI_SERVICE WSATYPE_NOT_FOUND
  123. #endif
  124. #if !defined(EAI_SOCKTYPE)
  125. # define EAI_SOCKTYPE WSAESOCKTNOSUPPORT
  126. #endif
  127. #if !defined(NI_NOFQDN)
  128. # define NI_NOFQDN 0x01
  129. #endif
  130. #if !defined(NI_NUMERICHOST)
  131. # define NI_NUMERICHOST 0x02
  132. #endif
  133. #if !defined(NI_NAMEREQD)
  134. # define NI_NAMEREQD 0x04
  135. #endif
  136. #if !defined(NI_NUMERICSERV)
  137. # define NI_NUMERICSERV 0x08
  138. #endif
  139. #if !defined(NI_DGRAM)
  140. # define NI_DGRAM 0x10
  141. #endif
  142. #if !defined(IPPROTO_IPV6)
  143. # define IPPROTO_IPV6 41
  144. #endif
  145. #if !defined(IPV6_UNICAST_HOPS)
  146. # define IPV6_UNICAST_HOPS 4
  147. #endif
  148. #if !defined(IPV6_MULTICAST_IF)
  149. # define IPV6_MULTICAST_IF 9
  150. #endif
  151. #if !defined(IPV6_MULTICAST_HOPS)
  152. # define IPV6_MULTICAST_HOPS 10
  153. #endif
  154. #if !defined(IPV6_MULTICAST_LOOP)
  155. # define IPV6_MULTICAST_LOOP 11
  156. #endif
  157. #if !defined(IPV6_JOIN_GROUP)
  158. # define IPV6_JOIN_GROUP 12
  159. #endif
  160. #if !defined(IPV6_LEAVE_GROUP)
  161. # define IPV6_LEAVE_GROUP 13
  162. #endif
  163. inline int IN6_IS_ADDR_UNSPECIFIED(const in6_addr_emulation* a)
  164. {
  165. return ((a->s6_addr[0] == 0)
  166. && (a->s6_addr[1] == 0)
  167. && (a->s6_addr[2] == 0)
  168. && (a->s6_addr[3] == 0)
  169. && (a->s6_addr[4] == 0)
  170. && (a->s6_addr[5] == 0)
  171. && (a->s6_addr[6] == 0)
  172. && (a->s6_addr[7] == 0)
  173. && (a->s6_addr[8] == 0)
  174. && (a->s6_addr[9] == 0)
  175. && (a->s6_addr[10] == 0)
  176. && (a->s6_addr[11] == 0)
  177. && (a->s6_addr[12] == 0)
  178. && (a->s6_addr[13] == 0)
  179. && (a->s6_addr[14] == 0)
  180. && (a->s6_addr[15] == 0));
  181. }
  182. inline int IN6_IS_ADDR_LOOPBACK(const in6_addr_emulation* a)
  183. {
  184. return ((a->s6_addr[0] == 0)
  185. && (a->s6_addr[1] == 0)
  186. && (a->s6_addr[2] == 0)
  187. && (a->s6_addr[3] == 0)
  188. && (a->s6_addr[4] == 0)
  189. && (a->s6_addr[5] == 0)
  190. && (a->s6_addr[6] == 0)
  191. && (a->s6_addr[7] == 0)
  192. && (a->s6_addr[8] == 0)
  193. && (a->s6_addr[9] == 0)
  194. && (a->s6_addr[10] == 0)
  195. && (a->s6_addr[11] == 0)
  196. && (a->s6_addr[12] == 0)
  197. && (a->s6_addr[13] == 0)
  198. && (a->s6_addr[14] == 0)
  199. && (a->s6_addr[15] == 1));
  200. }
  201. inline int IN6_IS_ADDR_MULTICAST(const in6_addr_emulation* a)
  202. {
  203. return (a->s6_addr[0] == 0xff);
  204. }
  205. inline int IN6_IS_ADDR_LINKLOCAL(const in6_addr_emulation* a)
  206. {
  207. return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0x80));
  208. }
  209. inline int IN6_IS_ADDR_SITELOCAL(const in6_addr_emulation* a)
  210. {
  211. return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0xc0));
  212. }
  213. inline int IN6_IS_ADDR_V4MAPPED(const in6_addr_emulation* a)
  214. {
  215. return ((a->s6_addr[0] == 0)
  216. && (a->s6_addr[1] == 0)
  217. && (a->s6_addr[2] == 0)
  218. && (a->s6_addr[3] == 0)
  219. && (a->s6_addr[4] == 0)
  220. && (a->s6_addr[5] == 0)
  221. && (a->s6_addr[6] == 0)
  222. && (a->s6_addr[7] == 0)
  223. && (a->s6_addr[8] == 0)
  224. && (a->s6_addr[9] == 0)
  225. && (a->s6_addr[10] == 0xff)
  226. && (a->s6_addr[11] == 0xff));
  227. }
  228. inline int IN6_IS_ADDR_V4COMPAT(const in6_addr_emulation* a)
  229. {
  230. return ((a->s6_addr[0] == 0)
  231. && (a->s6_addr[1] == 0)
  232. && (a->s6_addr[2] == 0)
  233. && (a->s6_addr[3] == 0)
  234. && (a->s6_addr[4] == 0)
  235. && (a->s6_addr[5] == 0)
  236. && (a->s6_addr[6] == 0)
  237. && (a->s6_addr[7] == 0)
  238. && (a->s6_addr[8] == 0)
  239. && (a->s6_addr[9] == 0)
  240. && (a->s6_addr[10] == 0xff)
  241. && (a->s6_addr[11] == 0xff)
  242. && !((a->s6_addr[12] == 0)
  243. && (a->s6_addr[13] == 0)
  244. && (a->s6_addr[14] == 0)
  245. && ((a->s6_addr[15] == 0) || (a->s6_addr[15] == 1))));
  246. }
  247. inline int IN6_IS_ADDR_MC_NODELOCAL(const in6_addr_emulation* a)
  248. {
  249. return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 1);
  250. }
  251. inline int IN6_IS_ADDR_MC_LINKLOCAL(const in6_addr_emulation* a)
  252. {
  253. return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 2);
  254. }
  255. inline int IN6_IS_ADDR_MC_SITELOCAL(const in6_addr_emulation* a)
  256. {
  257. return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 5);
  258. }
  259. inline int IN6_IS_ADDR_MC_ORGLOCAL(const in6_addr_emulation* a)
  260. {
  261. return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 8);
  262. }
  263. inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a)
  264. {
  265. return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 0xe);
  266. }
  267. } // namespace detail
  268. } // namespace asio
  269. } // namespace boost
  270. #endif // defined(BOOST_ASIO_HAS_OLD_WIN_SDK)
  271. // Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY.
  272. #if !defined(IPV6_V6ONLY)
  273. # define IPV6_V6ONLY 27
  274. #endif
  275. // Some SDKs (e.g. Windows CE) don't define IPPROTO_ICMPV6.
  276. #if !defined(IPPROTO_ICMPV6)
  277. # define IPPROTO_ICMPV6 58
  278. #endif
  279. #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
  280. #include <boost/asio/detail/pop_options.hpp>
  281. #endif // BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP