JwaWS2tcpip.pas
上传用户:davidchvip
上传日期:2009-07-28
资源大小:1749k
文件大小:25k
源码类别:

Windows编程

开发平台:

Delphi

  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@chello.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 home    }
  18. { page, located at http://delphi-jedi.org or my personal homepage located at   }
  19. { http://members.chello.nl/m.vanbrakel2                                        }
  20. {                }
  21. { The contents of this file are used with permission, subject to the Mozilla   }
  22. { Public License Version 1.1 (the "License"); you may not use this file except }
  23. { in compliance with the License. You may obtain a copy of the License at      }
  24. { http://www.mozilla.org/MPL/MPL-1.1.html                                      }
  25. {                                                                              }
  26. { Software distributed under the License is distributed on an "AS IS" basis,   }
  27. { WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
  28. { the specific language governing rights and limitations under the License.    }
  29. {                                                                              }
  30. { Alternatively, the contents of this file may be used under the terms of the  }
  31. { GNU Lesser General Public License (the  "LGPL License"), in which case the   }
  32. { provisions of the LGPL License are applicable instead of those above.        }
  33. { If you wish to allow use of your version of this file only under the terms   }
  34. { of the LGPL License and not to allow others to use your version of this file }
  35. { under the MPL, indicate your decision by deleting  the provisions above and  }
  36. { replace  them with the notice and other provisions required by the LGPL      }
  37. { License.  If you do not delete the provisions above, a recipient may use     }
  38. { your version of this file under either the MPL or the LGPL License.          }
  39. {                 }
  40. { For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
  41. {                 }
  42. {******************************************************************************}
  43. unit JwaWS2tcpip;
  44. {$WEAKPACKAGEUNIT}
  45. {$HPPEMIT ''}
  46. {$HPPEMIT '#include "ws2tcpip.h"'}
  47. {$HPPEMIT ''}
  48. {$I WINDEFINES.INC}
  49. interface
  50. uses
  51.   JwaWinSock2, JwaWinType;
  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. {$IFDEF UNICODE}
  428. function gai_strerror(ecode: Integer): PWideChar;
  429. {$EXTERNALSYM gai_strerror}
  430. {$ELSE}
  431. function gai_strerror(ecode: Integer): PChar;
  432. {$EXTERNALSYM gai_strerror}
  433. {$ENDIF}
  434. type
  435.   socklen_t = Integer;
  436.   {$EXTERNALSYM socklen_t}
  437. function getnameinfo(sa: PSockAddr; salen: socklen_t; host: PChar; hostlen: DWORD; serv: PChar; servlen: DWORD; flags: Integer): Integer; stdcall;
  438. {$EXTERNALSYM getnameinfo}
  439. const
  440.   NI_MAXHOST = 1025; // Max size of a fully-qualified domain name
  441.   {$EXTERNALSYM NI_MAXHOST}
  442.   NI_MAXSERV = 32; // Max size of a service name
  443.   {$EXTERNALSYM NI_MAXSERV}
  444.   INET_ADDRSTRLEN  = 16; // Max size of numeric form of IPv4 address
  445.   {$EXTERNALSYM INET_ADDRSTRLEN}
  446.   INET6_ADDRSTRLEN = 46; // Max size of numeric form of IPv6 address
  447.   {$EXTERNALSYM INET6_ADDRSTRLEN}
  448. // Flags for getnameinfo()
  449.   NI_NOFQDN      = $01; // Only return nodename portion for local hosts
  450.   {$EXTERNALSYM NI_NOFQDN}
  451.   NI_NUMERICHOST = $02; // Return numeric form of the host's address
  452.   {$EXTERNALSYM NI_NUMERICHOST}
  453.   NI_NAMEREQD    = $04; // Error if the host's name not in DNS
  454.   {$EXTERNALSYM NI_NAMEREQD}
  455.   NI_NUMERICSERV = $08; // Return numeric form of the service (port #)
  456.   {$EXTERNALSYM NI_NUMERICSERV}
  457.   NI_DGRAM       = $10; // Service is a datagram service
  458.   {$EXTERNALSYM NI_DGRAM}
  459. implementation
  460. uses
  461.   SysUtils, JwaWinBase, JwaWinNT;
  462. function IP_MSFILTER_SIZE(numsrc: Integer): Integer;
  463. begin
  464.   Result := SizeOf(ip_msfilter) - SizeOf(in_addr) + (numsrc * SizeOf(in_addr));
  465. end;
  466. function SS_PORT(ssp: Pointer): u_short;
  467. begin
  468.   Result := PSockAddrIn(ssp)^.sin_port;
  469. end;
  470. procedure IN6ADDR_SETANY(var x: TSockAddrIn6);
  471. var
  472.   I: Integer;
  473. begin
  474.   x.sin6_family := AF_INET6;
  475.   x.sin6_port := 0;
  476.   x.sin6_flowinfo := 0;
  477.   for I := 0 to 15 do x.sin6_addr.s6_addr[I] := 0;
  478. end;
  479. procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6);
  480. var
  481.   I: Integer;
  482. begin
  483.   x.sin6_family := AF_INET6;
  484.   x.sin6_port := 0;
  485.   x.sin6_flowinfo := 0;
  486.   for I := 0 to 14 do x.sin6_addr.s6_addr[I] := 0;
  487.   x.sin6_addr.s6_addr[15] := 1;
  488. end;
  489. function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean;
  490. var
  491.   I: Integer;
  492. begin
  493.   Result := x.sin6_family = AF_INET6;
  494.   for I := 0 to 15 do Result := Result and (x.sin6_addr.s6_addr[I] = 0);
  495. end;
  496. function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean;
  497. var
  498.   I: Integer;
  499. begin
  500.   Result := x.sin6_family = AF_INET6;
  501.   for I := 0 to 14 do Result := Result and (x.sin6_addr.s6_addr[I] = 0);
  502.   Result := Result and (x.sin6_addr.s6_addr[15] = 1);
  503. end;
  504. function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean;
  505. begin
  506.   Result := CompareMem(@a, @b, SizeOf(in6_addr));
  507. end;
  508. function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean;
  509. begin
  510.   Result := IN6_ADDR_EQUAL(a, in6addr_any);
  511. end;
  512. function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean;
  513. begin
  514.   Result := IN6_ADDR_EQUAL(a, in6addr_loopback);
  515. end;
  516. function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean;
  517. begin
  518.   Result := (a.s6_bytes[0] = $ff);
  519. end;
  520. function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean;
  521. begin
  522.   Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $80));
  523. end;
  524. function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean;
  525. begin
  526.   Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $c0));
  527. end;
  528. function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean;
  529. begin
  530.   Result := ((a.s6_words[0] = 0) and (a.s6_words[1] = 0) and (a.s6_words[2] = 0) and
  531.              (a.s6_words[3] = 0) and (a.s6_words[4] = 0) and (a.s6_words[5] = $ffff));
  532. end;
  533. function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean;
  534. begin
  535.   Result :=
  536.    ((a.s6_words[0] = 0) and
  537.     (a.s6_words[1] = 0) and
  538.     (a.s6_words[2] = 0) and
  539.     (a.s6_words[3] = 0) and
  540.     (a.s6_words[4] = 0) and
  541.     (a.s6_words[5] = 0) and
  542.     not ((a.s6_words[6] = 0) and
  543.          (a.s6_addr[14] = 0) and
  544.          ((a.s6_addr[15] = 0) or (a.s6_addr[15] = 1))));
  545. end;
  546. function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean;
  547. begin
  548.   Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 1);
  549. end;
  550. function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean;
  551. begin
  552.   Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 2);
  553. end;
  554. function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean;
  555. begin
  556.   Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 5);
  557. end;
  558. function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean;
  559. begin
  560.   Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 8);
  561. end;
  562. function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean;
  563. begin
  564.   Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = $e);
  565. end;
  566. const
  567.   ws2tcpip = 'ws2_32.dll';
  568. function getaddrinfo; external ws2tcpip name 'getaddrinfo';
  569. procedure freeaddrinfo; external ws2tcpip name 'freeaddrinfo';
  570. function gai_strerrorA(ecode: Integer): PChar;
  571. var
  572.   dwMsgLen: DWORD;
  573.   buff: array [0..GAI_STRERROR_BUFFER_SIZE] of Char;
  574. begin
  575.   dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  576.     nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  577.   if dwMsgLen = 0 then
  578.     Result := nil
  579.   else
  580.     Result := PChar(buff[0]);
  581. end;
  582. function gai_strerrorW(ecode: Integer): PWideChar;
  583. var
  584.   dwMsgLen: DWORD;
  585.   buff: array [0..GAI_STRERROR_BUFFER_SIZE] of WideChar;
  586. begin
  587.   dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  588.     nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  589.   if dwMsgLen = 0 then
  590.     Result := nil
  591.   else
  592.     Result := PWideChar(buff[0]);
  593. end;
  594. {$IFDEF UNICODE}
  595. function gai_strerror(ecode: Integer): PWideChar;
  596. var
  597.   dwMsgLen: DWORD;
  598.   buff: array [0..GAI_STRERROR_BUFFER_SIZE] of WideChar;
  599. begin
  600.   dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  601.     nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  602.   if dwMsgLen = 0 then
  603.     Result := nil
  604.   else
  605.     Result := PWideChar(buff[0]);
  606. end;
  607. {$ELSE}
  608. function gai_strerror(ecode: Integer): PChar;
  609. var
  610.   dwMsgLen: DWORD;
  611.   buff: array [0..GAI_STRERROR_BUFFER_SIZE] of Char;
  612. begin
  613.   dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
  614.     nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
  615.   if dwMsgLen = 0 then
  616.     Result := nil
  617.   else
  618.     Result := PChar(buff[0]);
  619. end;
  620. {$ENDIF}
  621. function getnameinfo; external ws2tcpip name 'getnameinfo';
  622. end.