jwaws2tcpip.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. {******************************************************************************}
  2. { }
  3. { Winsock2 TCP/IP Extensions API interface Unit for Object Pascal }
  4. { }
  5. { Portions created by Microsoft are Copyright (C) 1995-2001 Microsoft }
  6. { Corporation. All Rights Reserved. }
  7. { }
  8. { The original file is: ws2tcpip.h, released June 2000. The original Pascal }
  9. { code is: WS2tcpip.pas, released December 2000. The initial developer of the }
  10. { Pascal code is Marcel van Brakel (brakelm att chello dott nl). }
  11. { }
  12. { Portions created by Marcel van Brakel are Copyright (C) 1999-2001 }
  13. { Marcel van Brakel. All Rights Reserved. }
  14. { }
  15. { Obtained through: Joint Endeavour of Delphi Innovators (Project JEDI) }
  16. { }
  17. { You may retrieve the latest version of this file at the Project JEDI }
  18. { APILIB home page, located at http://jedi-apilib.sourceforge.net }
  19. { }
  20. { The contents of this file are used with permission, subject to the Mozilla }
  21. { Public License Version 1.1 (the "License"); you may not use this file except }
  22. { in compliance with the License. You may obtain a copy of the License at }
  23. { http://www.mozilla.org/MPL/MPL-1.1.html }
  24. { }
  25. { Software distributed under the License is distributed on an "AS IS" basis, }
  26. { WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
  27. { the specific language governing rights and limitations under the License. }
  28. { }
  29. { Alternatively, the contents of this file may be used under the terms of the }
  30. { GNU Lesser General Public License (the "LGPL License"), in which case the }
  31. { provisions of the LGPL License are applicable instead of those above. }
  32. { If you wish to allow use of your version of this file only under the terms }
  33. { of the LGPL License and not to allow others to use your version of this file }
  34. { under the MPL, indicate your decision by deleting the provisions above and }
  35. { replace them with the notice and other provisions required by the LGPL }
  36. { License. If you do not delete the provisions above, a recipient may use }
  37. { your version of this file under either the MPL or the LGPL License. }
  38. { }
  39. { For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
  40. { }
  41. {******************************************************************************}
  42. // $Id: JwaWS2tcpip.pas,v 1.10 2005/09/08 07:49:25 marquardt Exp $
  43. unit JwaWS2tcpip;
  44. {$WEAKPACKAGEUNIT}
  45. {$HPPEMIT ''}
  46. {$HPPEMIT '#include "ws2tcpip.h"'}
  47. {$HPPEMIT ''}
  48. {$I jediapilib.inc}
  49. interface
  50. uses
  51. JwaWinSock2, JwaWindows;
  52. //
  53. // WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols
  54. //
  55. // This file contains TCP/IP specific information for use
  56. // by WinSock2 compatible applications.
  57. //
  58. // Copyright (c) 1995-1999 Microsoft Corporation
  59. //
  60. // To provide the backward compatibility, all the TCP/IP
  61. // specific definitions that were included in the WINSOCK.H
  62. // file are now included in WINSOCK2.H file. WS2TCPIP.H
  63. // file includes only the definitions introduced in the
  64. // "WinSock 2 Protocol-Specific Annex" document.
  65. //
  66. // Rev 0.3 Nov 13, 1995
  67. // Rev 0.4 Dec 15, 1996
  68. //
  69. // Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP
  70. type
  71. ip_mreq = record
  72. imr_multiaddr: in_addr; // IP multicast address of group
  73. imr_interface: in_addr; // local IP address of interface
  74. end;
  75. {$EXTERNALSYM ip_mreq}
  76. TIPMReq = ip_mreq;
  77. PIPMReq = ^ip_mreq;
  78. // Argument structure for IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP,
  79. // IP_BLOCK_SOURCE, and IP_UNBLOCK_SOURCE
  80. //
  81. ip_mreq_source = record
  82. imr_multiaddr: in_addr; // IP multicast address of group
  83. imr_sourceaddr: in_addr; // IP address of source
  84. imr_interface: in_addr; // local IP address of interface
  85. end;
  86. {$EXTERNALSYM ip_mreq_source}
  87. TIpMreqSource = ip_mreq_source;
  88. PIpMreqSource = ^ip_mreq_source;
  89. // Argument structure for SIO_{GET,SET}_MULTICAST_FILTER
  90. ip_msfilter = record
  91. imsf_multiaddr: in_addr; // IP multicast address of group
  92. imsf_interface: in_addr; // local IP address of interface
  93. imsf_fmode: u_long; // filter mode - INCLUDE or EXCLUDE
  94. imsf_numsrc: u_long; // number of sources in src_list
  95. imsf_slist: array [0..0] of in_addr;
  96. end;
  97. {$EXTERNALSYM ip_msfilter}
  98. TIpMsFilter = ip_msfilter;
  99. PIpMsFilter = ^ip_msfilter;
  100. function IP_MSFILTER_SIZE(numsrc: Integer): Integer;
  101. {$EXTERNALSYM IP_MSFILTER_SIZE(numsrc)}
  102. const
  103. MCAST_INCLUDE = 0;
  104. {$EXTERNALSYM MCAST_INCLUDE}
  105. MCAST_EXCLUDE = 1;
  106. {$EXTERNALSYM MCAST_EXCLUDE}
  107. // TCP/IP specific Ioctl codes
  108. const
  109. SIO_GET_INTERFACE_LIST = IOC_OUT or ((4 and IOCPARM_MASK) shl 16) or ((Ord('t')) shl 8) or (127);
  110. {$EXTERNALSYM SIO_GET_INTERFACE_LIST}
  111. // New IOCTL with address size independent address array
  112. SIO_GET_INTERFACE_LIST_EX = IOC_OUT or ((4 and IOCPARM_MASK) shl 16) or ((Ord('t')) shl 8) or (126);
  113. {$EXTERNALSYM SIO_GET_INTERFACE_LIST_EX}
  114. SIO_SET_MULTICAST_FILTER = DWORD(IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 125);
  115. {$EXTERNALSYM SIO_SET_MULTICAST_FILTER}
  116. SIO_GET_MULTICAST_FILTER = DWORD(IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 124 or IOC_IN);
  117. {$EXTERNALSYM SIO_GET_MULTICAST_FILTER}
  118. // Option to use with [gs]etsockopt at the IPPROTO_IP level
  119. const
  120. IP_OPTIONS = 1; // set/get IP options
  121. {$EXTERNALSYM IP_OPTIONS}
  122. IP_HDRINCL = 2; // header is included with data
  123. {$EXTERNALSYM IP_HDRINCL}
  124. IP_TOS = 3; // IP type of service and preced
  125. {$EXTERNALSYM IP_TOS}
  126. IP_TTL = 4; // IP time to live
  127. {$EXTERNALSYM IP_TTL}
  128. IP_MULTICAST_IF = 9; // set/get IP multicast i/f
  129. {$EXTERNALSYM IP_MULTICAST_IF}
  130. IP_MULTICAST_TTL = 10; // set/get IP multicast ttl
  131. {$EXTERNALSYM IP_MULTICAST_TTL}
  132. IP_MULTICAST_LOOP = 11; // set/get IP multicast loopback
  133. {$EXTERNALSYM IP_MULTICAST_LOOP}
  134. IP_ADD_MEMBERSHIP = 12; // add an IP group membership
  135. {$EXTERNALSYM IP_ADD_MEMBERSHIP}
  136. IP_DROP_MEMBERSHIP = 13; // drop an IP group membership
  137. {$EXTERNALSYM IP_DROP_MEMBERSHIP}
  138. IP_DONTFRAGMENT = 14; // don't fragment IP datagrams
  139. {$EXTERNALSYM IP_DONTFRAGMENT}
  140. IP_ADD_SOURCE_MEMBERSHIP = 15; // join IP group/source
  141. {$EXTERNALSYM IP_ADD_SOURCE_MEMBERSHIP}
  142. IP_DROP_SOURCE_MEMBERSHIP = 16; // leave IP group/source
  143. {$EXTERNALSYM IP_DROP_SOURCE_MEMBERSHIP}
  144. IP_BLOCK_SOURCE = 17; // block IP group/source
  145. {$EXTERNALSYM IP_BLOCK_SOURCE}
  146. IP_UNBLOCK_SOURCE = 18; // unblock IP group/source
  147. {$EXTERNALSYM IP_UNBLOCK_SOURCE}
  148. IP_PKTINFO = 19; // receive packet information for ipv4
  149. {$EXTERNALSYM IP_PKTINFO}
  150. // Option to use with [gs]etsockopt at the IPPROTO_IPV6 level
  151. IPV6_HDRINCL = 2; // Header is included with data
  152. {$EXTERNALSYM IPV6_HDRINCL}
  153. IPV6_UNICAST_HOPS = 4; // Set/get IP unicast hop limit
  154. {$EXTERNALSYM IPV6_UNICAST_HOPS}
  155. IPV6_MULTICAST_IF = 9; // Set/get IP multicast interface
  156. {$EXTERNALSYM IPV6_MULTICAST_IF}
  157. IPV6_MULTICAST_HOPS = 10; // Set/get IP multicast ttl
  158. {$EXTERNALSYM IPV6_MULTICAST_HOPS}
  159. IPV6_MULTICAST_LOOP = 11; // Set/get IP multicast loopback
  160. {$EXTERNALSYM IPV6_MULTICAST_LOOP}
  161. IPV6_ADD_MEMBERSHIP = 12; // Add an IP group membership
  162. {$EXTERNALSYM IPV6_ADD_MEMBERSHIP}
  163. IPV6_DROP_MEMBERSHIP = 13; // Drop an IP group membership
  164. {$EXTERNALSYM IPV6_DROP_MEMBERSHIP}
  165. IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP;
  166. {$EXTERNALSYM IPV6_JOIN_GROUP}
  167. IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP;
  168. {$EXTERNALSYM IPV6_LEAVE_GROUP}
  169. IPV6_PKTINFO = 19; // Receive packet information for ipv6
  170. {$EXTERNALSYM IPV6_PKTINFO}
  171. // Option to use with [gs]etsockopt at the IPPROTO_UDP level
  172. UDP_NOCHECKSUM = 1;
  173. {$EXTERNALSYM UDP_NOCHECKSUM}
  174. UDP_CHECKSUM_COVERAGE = 20; // Set/get UDP-Lite checksum coverage
  175. {$EXTERNALSYM UDP_CHECKSUM_COVERAGE}
  176. // Option to use with [gs]etsockopt at the IPPROTO_TCP level
  177. TCP_EXPEDITED_1122 = $0002;
  178. {$EXTERNALSYM TCP_EXPEDITED_1122}
  179. // IPv6 definitions
  180. type
  181. in6_addr = record
  182. case Integer of
  183. 0: (Byte: array [0..15] of u_char);
  184. 1: (Word: array[0..7] of u_short);
  185. 2: (s6_bytes: array [0..15] of u_char);
  186. 3: (s6_addr: array [0..15] of u_char);
  187. 4: (s6_words: array[0..7] of u_short);
  188. end;
  189. {$EXTERNALSYM in6_addr}
  190. TIn6Addr = in6_addr;
  191. PIn6Addr = ^in6_addr;
  192. //
  193. // Defines to match RFC 2553.
  194. //
  195. //#define _S6_un u
  196. //#define _S6_u8 Byte
  197. // Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP
  198. type
  199. ipv6_mreq = record
  200. ipv6mr_multiaddr: in6_addr; // IPv6 multicast address
  201. ipv6mr_interface: Cardinal; // Interface index
  202. end;
  203. {$EXTERNALSYM ipv6_mreq}
  204. TIpV6MReq = ipv6_mreq;
  205. PIpV6MReq = ^ipv6_mreq;
  206. type
  207. in_addr6 = record
  208. s6_addr: array [0..15] of u_char; // IPv6 address
  209. end;
  210. {$EXTERNALSYM in_addr6}
  211. TInAddr6 = in_addr6;
  212. PInAddr6 = ^in_addr6;
  213. // Old IPv6 socket address structure (retained for sockaddr_gen definition below)
  214. type
  215. sockaddr_in6_old = record
  216. sin6_family: short; // AF_INET6
  217. sin6_port: u_short; // Transport level port number
  218. sin6_flowinfo: u_long; // IPv6 flow information
  219. sin6_addr: in6_addr; // IPv6 address
  220. end;
  221. {$EXTERNALSYM sockaddr_in6_old}
  222. TSockAddrIn6Old = sockaddr_in6_old;
  223. PSockAddrIn6Old = ^sockaddr_in6_old;
  224. // IPv6 socket address structure, RFC 2553
  225. SOCKADDR_IN6 = record
  226. sin6_family: short; // AF_INET6
  227. sin6_port: u_short; // Transport level port number
  228. sin6_flowinfo: u_long; // IPv6 flow information
  229. sin6_addr: in6_addr; // IPv6 address
  230. sin6_scope_id: u_long; // set of interfaces for a scope
  231. end;
  232. {$EXTERNALSYM SOCKADDR_IN6}
  233. PSOCKADDR_IN6 = ^SOCKADDR_IN6;
  234. {$EXTERNALSYM PSOCKADDR_IN6}
  235. LPSOCKADDR_IN6 = ^SOCKADDR_IN6;
  236. {$EXTERNALSYM LPSOCKADDR_IN6}
  237. TSockAddrIn6 = SOCKADDR_IN6;
  238. PSockAddrIn6 = LPSOCKADDR_IN6;
  239. // Macro that works for both IPv4 and IPv6
  240. function SS_PORT(ssp: Pointer): u_short;
  241. {$EXTERNALSYM SS_PORT}
  242. const
  243. IN6ADDR_ANY_INIT: in6_addr = (Word: (0, 0, 0, 0, 0, 0, 0, 0));
  244. {$EXTERNALSYM IN6ADDR_ANY_INIT}
  245. IN6ADDR_LOOPBACK_INIT: in6_addr = (Byte: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1));
  246. {$EXTERNALSYM IN6ADDR_LOOPBACK_INIT}
  247. in6addr_any: in6_addr = (Word: (0, 0, 0, 0, 0, 0, 0, 0));
  248. {$EXTERNALSYM in6addr_any}
  249. in6addr_loopback: in6_addr = (Byte: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1));
  250. {$EXTERNALSYM in6addr_loopback}
  251. procedure IN6ADDR_SETANY(var x: TSockAddrIn6);
  252. {$EXTERNALSYM IN6ADDR_SETANY}
  253. procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6);
  254. {$EXTERNALSYM IN6ADDR_SETLOOPBACK}
  255. function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean;
  256. {$EXTERNALSYM IN6ADDR_ISANY}
  257. function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean;
  258. {$EXTERNALSYM IN6ADDR_ISLOOPBACK}
  259. function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean;
  260. {$EXTERNALSYM IN6_ADDR_EQUAL}
  261. function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean;
  262. {$EXTERNALSYM IN6_IS_ADDR_UNSPECIFIED}
  263. function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean;
  264. {$EXTERNALSYM IN6_IS_ADDR_LOOPBACK}
  265. function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean;
  266. {$EXTERNALSYM IN6_IS_ADDR_MULTICAST}
  267. function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean;
  268. {$EXTERNALSYM IN6_IS_ADDR_LINKLOCAL}
  269. function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean;
  270. {$EXTERNALSYM IN6_IS_ADDR_SITELOCAL}
  271. function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean;
  272. {$EXTERNALSYM IN6_IS_ADDR_V4MAPPED}
  273. function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean;
  274. {$EXTERNALSYM IN6_IS_ADDR_V4COMPAT}
  275. function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean;
  276. {$EXTERNALSYM IN6_IS_ADDR_MC_NODELOCAL}
  277. function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean;
  278. {$EXTERNALSYM IN6_IS_ADDR_MC_LINKLOCAL}
  279. function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean;
  280. {$EXTERNALSYM IN6_IS_ADDR_MC_SITELOCAL}
  281. function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean;
  282. {$EXTERNALSYM IN6_IS_ADDR_MC_ORGLOCAL}
  283. function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean;
  284. {$EXTERNALSYM IN6_IS_ADDR_MC_GLOBAL}
  285. type
  286. sockaddr_gen = record
  287. case Integer of
  288. 0: (Address: sockaddr);
  289. 1: (AddressIn: sockaddr_in);
  290. 2: (AddressIn6: sockaddr_in6_old);
  291. end;
  292. {$EXTERNALSYM sockaddr_gen}
  293. TSockAddrGen = sockaddr_gen;
  294. PSockAddrGen = ^sockaddr_gen;
  295. // Structure to keep interface specific information
  296. _INTERFACE_INFO = record
  297. iiFlags: u_long; // Interface flags
  298. iiAddress: sockaddr_gen; // Interface address
  299. iiBroadcastAddress: sockaddr_gen; // Broadcast address
  300. iiNetmask: sockaddr_gen; // Network mask
  301. end;
  302. {$EXTERNALSYM _INTERFACE_INFO}
  303. INTERFACE_INFO = _INTERFACE_INFO;
  304. {$EXTERNALSYM INTERFACE_INFO}
  305. LPINTERFACE_INFO = ^INTERFACE_INFO;
  306. {$EXTERNALSYM LPINTERFACE_INFO}
  307. TInterfaceInfo = INTERFACE_INFO;
  308. PInterfaceInfo = LPINTERFACE_INFO;
  309. // New structure that does not have dependency on the address size
  310. _INTERFACE_INFO_EX = record
  311. iiFlags: u_long; // Interface flags
  312. iiAddress: SOCKET_ADDRESS; // Interface address
  313. iiBroadcastAddress: SOCKET_ADDRESS; // Broadcast address
  314. iiNetmask: SOCKET_ADDRESS; // Network mask
  315. end;
  316. {$EXTERNALSYM _INTERFACE_INFO_EX}
  317. INTERFACE_INFO_EX = _INTERFACE_INFO_EX;
  318. {$EXTERNALSYM INTERFACE_INFO_EX}
  319. LPINTERFACE_INFO_EX = ^INTERFACE_INFO_EX;
  320. {$EXTERNALSYM LPINTERFACE_INFO_EX}
  321. TInterfaceInfoEx = INTERFACE_INFO_EX;
  322. PInterfaceInfoEx = LPINTERFACE_INFO_EX;
  323. // Possible flags for the iiFlags - bitmask
  324. const
  325. IFF_UP = $00000001; // Interface is up
  326. {$EXTERNALSYM IFF_UP}
  327. IFF_BROADCAST = $00000002; // Broadcast is supported
  328. {$EXTERNALSYM IFF_BROADCAST}
  329. IFF_LOOPBACK = $00000004; // this is loopback interface
  330. {$EXTERNALSYM IFF_LOOPBACK}
  331. IFF_POINTTOPOINT = $00000008; //this is point-to-point interface
  332. {$EXTERNALSYM IFF_POINTTOPOINT}
  333. IFF_MULTICAST = $00000010; // multicast is supported
  334. {$EXTERNALSYM IFF_MULTICAST}
  335. // structure for IP_PKTINFO option
  336. //
  337. type
  338. in_pktinfo = record
  339. ipi_addr: IN_ADDR; // destination IPv4 address
  340. ipi_ifindex: UINT; // received interface index
  341. end;
  342. {$EXTERNALSYM in_pktinfo}
  343. TInPktInfo = in_pktinfo;
  344. PInPktInfo = ^in_pktinfo;
  345. // C_ASSERT(sizeof(IN_PKTINFO) == 8);
  346. // structure for IPV6_PKTINFO option
  347. //
  348. in6_pktinfo = record
  349. ipi6_addr: IN6_ADDR; // destination IPv6 address
  350. ipi6_ifindex: UINT; // received interface index
  351. end;
  352. {$EXTERNALSYM in6_pktinfo}
  353. TIn6PktInfo = in6_pktinfo;
  354. PIn6PktInfo = ^in6_pktinfo;
  355. // C_ASSERT(sizeof(IN6_PKTINFO) == 20);
  356. // Error codes from getaddrinfo()
  357. const
  358. EAI_AGAIN = WSATRY_AGAIN;
  359. {$EXTERNALSYM EAI_AGAIN}
  360. EAI_BADFLAGS = WSAEINVAL;
  361. {$EXTERNALSYM EAI_BADFLAGS}
  362. EAI_FAIL = WSANO_RECOVERY;
  363. {$EXTERNALSYM EAI_FAIL}
  364. EAI_FAMILY = WSAEAFNOSUPPORT;
  365. {$EXTERNALSYM EAI_FAMILY}
  366. EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY;
  367. {$EXTERNALSYM EAI_MEMORY}
  368. //#define EAI_NODATA WSANO_DATA
  369. EAI_NONAME = WSAHOST_NOT_FOUND;
  370. {$EXTERNALSYM EAI_NONAME}
  371. EAI_SERVICE = WSATYPE_NOT_FOUND;
  372. {$EXTERNALSYM EAI_SERVICE}
  373. EAI_SOCKTYPE = WSAESOCKTNOSUPPORT;
  374. {$EXTERNALSYM EAI_SOCKTYPE}
  375. //
  376. // DCR_FIX: EAI_NODATA remove or fix
  377. //
  378. // EAI_NODATA was removed from rfc2553bis
  379. // need to find out from the authors why and
  380. // determine the error for "no records of this type"
  381. // temporarily, we'll keep #define to avoid changing
  382. // code that could change back; use NONAME
  383. //
  384. EAI_NODATA = EAI_NONAME;
  385. {$EXTERNALSYM EAI_NODATA}
  386. // Structure used in getaddrinfo() call
  387. type
  388. LPADDRINFO = ^addrinfo;
  389. {$EXTERNALSYM LPADDRINFO}
  390. addrinfo = record
  391. ai_flags: Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
  392. ai_family: Integer; // PF_xxx
  393. ai_socktype: Integer; // SOCK_xxx
  394. ai_protocol: Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6
  395. ai_addrlen: size_t; // Length of ai_addr
  396. ai_canonname: PChar; // Canonical name for nodename
  397. ai_addr: PSockAddr; // Binary address
  398. ai_next: LPADDRINFO; // Next structure in linked list
  399. end;
  400. {$EXTERNALSYM addrinfo}
  401. TAddrInfo = addrinfo;
  402. PAddrInfo = LPADDRINFO;
  403. // Flags used in "hints" argument to getaddrinfo()
  404. const
  405. AI_PASSIVE = $1; // Socket address will be used in bind() call
  406. {$EXTERNALSYM AI_PASSIVE}
  407. AI_CANONNAME = $2; // Return canonical name in first ai_canonname
  408. {$EXTERNALSYM AI_CANONNAME}
  409. AI_NUMERICHOST = $4; // Nodename must be a numeric address string
  410. {$EXTERNALSYM AI_NUMERICHOST}
  411. function getaddrinfo(nodename, servname: PChar; hints: PAddrInfo; var res: PAddrInfo): Integer; stdcall;
  412. {$EXTERNALSYM getaddrinfo}
  413. procedure freeaddrinfo(ai: PAddrInfo); stdcall;
  414. {$EXTERNALSYM freeaddrinfo}
  415. // WARNING: The gai_strerror inline functions below use static buffers,
  416. // and hence are not thread-safe. We'll use buffers long enough to hold
  417. // 1k characters. Any system error messages longer than this will be
  418. // returned as empty strings. However 1k should work for the error codes
  419. // used by getaddrinfo().
  420. const
  421. GAI_STRERROR_BUFFER_SIZE = 1024;
  422. {$EXTERNALSYM GAI_STRERROR_BUFFER_SIZE}
  423. function gai_strerrorA(ecode: Integer): PChar;
  424. {$EXTERNALSYM gai_strerrorA}
  425. function gai_strerrorW(ecode: Integer): PWideChar;
  426. {$EXTERNALSYM gai_strerrorW}
  427. function gai_strerror(ecode: Integer): PTCHAR;
  428. {$EXTERNALSYM gai_strerror}
  429. type
  430. socklen_t = Integer;
  431. {$EXTERNALSYM socklen_t}
  432. function getnameinfo(sa: PSockAddr; salen: socklen_t; host: PChar; hostlen: DWORD; serv: PChar; servlen: DWORD; flags: Integer): Integer; stdcall;
  433. {$EXTERNALSYM getnameinfo}
  434. const
  435. NI_MAXHOST = 1025; // Max size of a fully-qualified domain name
  436. {$EXTERNALSYM NI_MAXHOST}
  437. NI_MAXSERV = 32; // Max size of a service name
  438. {$EXTERNALSYM NI_MAXSERV}
  439. INET_ADDRSTRLEN = 16; // Max size of numeric form of IPv4 address
  440. {$EXTERNALSYM INET_ADDRSTRLEN}
  441. INET6_ADDRSTRLEN = 46; // Max size of numeric form of IPv6 address
  442. {$EXTERNALSYM INET6_ADDRSTRLEN}
  443. // Flags for getnameinfo()
  444. NI_NOFQDN = $01; // Only return nodename portion for local hosts
  445. {$EXTERNALSYM NI_NOFQDN}
  446. NI_NUMERICHOST = $02; // Return numeric form of the host's address
  447. {$EXTERNALSYM NI_NUMERICHOST}
  448. NI_NAMEREQD = $04; // Error if the host's name not in DNS
  449. {$EXTERNALSYM NI_NAMEREQD}
  450. NI_NUMERICSERV = $08; // Return numeric form of the service (port #)
  451. {$EXTERNALSYM NI_NUMERICSERV}
  452. NI_DGRAM = $10; // Service is a datagram service
  453. {$EXTERNALSYM NI_DGRAM}
  454. implementation
  455. function IP_MSFILTER_SIZE(numsrc: Integer): Integer;
  456. begin
  457. Result := SizeOf(ip_msfilter) - SizeOf(in_addr) + (numsrc * SizeOf(in_addr));
  458. end;
  459. function SS_PORT(ssp: Pointer): u_short;
  460. begin
  461. Result := PSockAddrIn(ssp)^.sin_port;
  462. end;
  463. procedure IN6ADDR_SETANY(var x: TSockAddrIn6);
  464. var
  465. I: Integer;
  466. begin
  467. x.sin6_family := AF_INET6;
  468. x.sin6_port := 0;
  469. x.sin6_flowinfo := 0;
  470. for I := 0 to 15 do
  471. x.sin6_addr.s6_addr[I] := 0;
  472. end;
  473. procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6);
  474. var
  475. I: Integer;
  476. begin
  477. x.sin6_family := AF_INET6;
  478. x.sin6_port := 0;
  479. x.sin6_flowinfo := 0;
  480. for I := 0 to 14 do
  481. x.sin6_addr.s6_addr[I] := 0;
  482. x.sin6_addr.s6_addr[15] := 1;
  483. end;
  484. function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean;
  485. var
  486. I: Integer;
  487. begin
  488. Result := x.sin6_family = AF_INET6;
  489. for I := 0 to 15 do
  490. Result := Result and (x.sin6_addr.s6_addr[I] = 0);
  491. end;
  492. function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean;
  493. var
  494. I: Integer;
  495. begin
  496. Result := x.sin6_family = AF_INET6;
  497. for I := 0 to 14 do
  498. Result := Result and (x.sin6_addr.s6_addr[I] = 0);
  499. Result := Result and (x.sin6_addr.s6_addr[15] = 1);
  500. end;
  501. function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean;
  502. var
  503. I: Integer;
  504. begin
  505. Result := True;
  506. for I := Low(a.Word) to High(a.Word) do
  507. Result := (a.Word[I] = b.Word[I]) and Result;
  508. end;
  509. function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean;
  510. begin
  511. Result := IN6_ADDR_EQUAL(a, in6addr_any);
  512. end;
  513. function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean;
  514. begin
  515. Result := IN6_ADDR_EQUAL(a, in6addr_loopback);
  516. end;
  517. function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean;
  518. begin
  519. Result := (a.s6_bytes[0] = $ff);
  520. end;
  521. function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean;
  522. begin
  523. Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $80));
  524. end;
  525. function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean;
  526. begin
  527. Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $c0));
  528. end;
  529. function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean;
  530. begin
  531. Result := ((a.s6_words[0] = 0) and (a.s6_words[1] = 0) and (a.s6_words[2] = 0) and
  532. (a.s6_words[3] = 0) and (a.s6_words[4] = 0) and (a.s6_words[5] = $ffff));
  533. end;
  534. function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean;
  535. begin
  536. Result :=
  537. ((a.s6_words[0] = 0) and
  538. (a.s6_words[1] = 0) and
  539. (a.s6_words[2] = 0) and
  540. (a.s6_words[3] = 0) and
  541. (a.s6_words[4] = 0) and
  542. (a.s6_words[5] = 0) and
  543. not ((a.s6_words[6] = 0) and
  544. (a.s6_addr[14] = 0) and
  545. ((a.s6_addr[15] = 0) or (a.s6_addr[15] = 1))));
  546. end;
  547. function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean;
  548. begin
  549. Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 1);
  550. end;
  551. function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean;
  552. begin
  553. Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 2);
  554. end;
  555. function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean;
  556. begin
  557. Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 5);
  558. end;
  559. function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean;
  560. begin
  561. Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 8);
  562. end;
  563. function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean;
  564. begin
  565. Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = $e);
  566. end;
  567. var
  568. gai_strerror_buffA: array [0..GAI_STRERROR_BUFFER_SIZE-1] of Char;
  569. gai_strerror_buffW: array [0..GAI_STRERROR_BUFFER_SIZE-1] of WideChar;
  570. function gai_strerrorA(ecode: Integer): PChar;
  571. var
  572. dwMsgLen: DWORD;
  573. begin
  574. dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  575. nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(@gai_strerror_buffA[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  576. if dwMsgLen = 0 then
  577. Result := nil
  578. else
  579. Result := PChar(@gai_strerror_buffA[0]);
  580. end;
  581. function gai_strerrorW(ecode: Integer): PWideChar;
  582. var
  583. dwMsgLen: DWORD;
  584. begin
  585. dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  586. nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(@gai_strerror_buffW[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  587. if dwMsgLen = 0 then
  588. Result := nil
  589. else
  590. Result := PWideChar(@gai_strerror_buffW[0]);
  591. end;
  592. function gai_strerror(ecode: Integer): PTCHAR;
  593. begin
  594. {$IFDEF UNICODE}
  595. Result := PTCHAR(gai_strerrorW(ecode));
  596. {$ELSE}
  597. Result := PTCHAR(gai_strerrorA(ecode));
  598. {$ENDIF UNICODE}
  599. end;
  600. const
  601. ws2tcpip = 'ws2_32.dll';
  602. {$IFDEF DYNAMIC_LINK}
  603. var
  604. _getaddrinfo: Pointer;
  605. function getaddrinfo;
  606. begin
  607. GetProcedureAddress(_getaddrinfo, ws2tcpip, 'getaddrinfo');
  608. asm
  609. MOV ESP, EBP
  610. POP EBP
  611. JMP [_getaddrinfo]
  612. end;
  613. end;
  614. var
  615. _freeaddrinfo: Pointer;
  616. procedure freeaddrinfo;
  617. begin
  618. GetProcedureAddress(_freeaddrinfo, ws2tcpip, 'freeaddrinfo');
  619. asm
  620. MOV ESP, EBP
  621. POP EBP
  622. JMP [_freeaddrinfo]
  623. end;
  624. end;
  625. var
  626. _getnameinfo: Pointer;
  627. function getnameinfo;
  628. begin
  629. GetProcedureAddress(_getnameinfo, ws2tcpip, 'getnameinfo');
  630. asm
  631. MOV ESP, EBP
  632. POP EBP
  633. JMP [_getnameinfo]
  634. end;
  635. end;
  636. {$ELSE}
  637. function getaddrinfo; external ws2tcpip name 'getaddrinfo';
  638. procedure freeaddrinfo; external ws2tcpip name 'freeaddrinfo';
  639. function getnameinfo; external ws2tcpip name 'getnameinfo';
  640. {$ENDIF DYNAMIC_LINK}
  641. end.