{******************************************************************************} { } { Winsock2 TCP/IP Extensions API interface Unit for Object Pascal } { } { Portions created by Microsoft are Copyright (C) 1995-2001 Microsoft } { Corporation. All Rights Reserved. } { } { The original file is: ws2tcpip.h, released June 2000. The original Pascal } { code is: WS2tcpip.pas, released December 2000. The initial developer of the } { Pascal code is Marcel van Brakel (brakelm att chello dott nl). } { } { Portions created by Marcel van Brakel are Copyright (C) 1999-2001 } { Marcel van Brakel. All Rights Reserved. } { } { Obtained through: Joint Endeavour of Delphi Innovators (Project JEDI) } { } { You may retrieve the latest version of this file at the Project JEDI } { APILIB home page, located at http://jedi-apilib.sourceforge.net } { } { The contents of this file are used with permission, subject to the Mozilla } { Public License Version 1.1 (the "License"); you may not use this file except } { in compliance with the License. You may obtain a copy of the License at } { http://www.mozilla.org/MPL/MPL-1.1.html } { } { Software distributed under the License is distributed on an "AS IS" basis, } { WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for } { the specific language governing rights and limitations under the License. } { } { Alternatively, the contents of this file may be used under the terms of the } { GNU Lesser General Public License (the "LGPL License"), in which case the } { provisions of the LGPL License are applicable instead of those above. } { If you wish to allow use of your version of this file only under the terms } { of the LGPL License and not to allow others to use your version of this file } { under the MPL, indicate your decision by deleting the provisions above and } { replace them with the notice and other provisions required by the LGPL } { License. If you do not delete the provisions above, a recipient may use } { your version of this file under either the MPL or the LGPL License. } { } { For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html } { } {******************************************************************************} // $Id: JwaWS2tcpip.pas,v 1.12 2007/09/05 11:58:53 dezipaitor Exp $ {$IFNDEF JWA_OMIT_SECTIONS} unit JwaWS2tcpip; {$WEAKPACKAGEUNIT} {$ENDIF JWA_OMIT_SECTIONS} {$HPPEMIT ''} {$HPPEMIT '#include "ws2tcpip.h"'} {$HPPEMIT ''} {$IFNDEF JWA_OMIT_SECTIONS} {$I jediapilib.inc} interface uses JwaWinSock2, JwaWinType; {$ENDIF JWA_OMIT_SECTIONS} {$IFNDEF JWA_IMPLEMENTATIONSECTION} // // WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols // // This file contains TCP/IP specific information for use // by WinSock2 compatible applications. // // Copyright (c) 1995-1999 Microsoft Corporation // // To provide the backward compatibility, all the TCP/IP // specific definitions that were included in the WINSOCK.H // file are now included in WINSOCK2.H file. WS2TCPIP.H // file includes only the definitions introduced in the // "WinSock 2 Protocol-Specific Annex" document. // // Rev 0.3 Nov 13, 1995 // Rev 0.4 Dec 15, 1996 // // Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP type ip_mreq = record imr_multiaddr: in_addr; // IP multicast address of group imr_interface: in_addr; // local IP address of interface end; {$EXTERNALSYM ip_mreq} TIPMReq = ip_mreq; PIPMReq = ^ip_mreq; // Argument structure for IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, // IP_BLOCK_SOURCE, and IP_UNBLOCK_SOURCE // ip_mreq_source = record imr_multiaddr: in_addr; // IP multicast address of group imr_sourceaddr: in_addr; // IP address of source imr_interface: in_addr; // local IP address of interface end; {$EXTERNALSYM ip_mreq_source} TIpMreqSource = ip_mreq_source; PIpMreqSource = ^ip_mreq_source; // Argument structure for SIO_{GET,SET}_MULTICAST_FILTER ip_msfilter = record imsf_multiaddr: in_addr; // IP multicast address of group imsf_interface: in_addr; // local IP address of interface imsf_fmode: u_long; // filter mode - INCLUDE or EXCLUDE imsf_numsrc: u_long; // number of sources in src_list imsf_slist: array [0..0] of in_addr; end; {$EXTERNALSYM ip_msfilter} TIpMsFilter = ip_msfilter; PIpMsFilter = ^ip_msfilter; function IP_MSFILTER_SIZE(numsrc: Integer): Integer; {$EXTERNALSYM IP_MSFILTER_SIZE(numsrc)} const MCAST_INCLUDE = 0; {$EXTERNALSYM MCAST_INCLUDE} MCAST_EXCLUDE = 1; {$EXTERNALSYM MCAST_EXCLUDE} // TCP/IP specific Ioctl codes const SIO_GET_INTERFACE_LIST = IOC_OUT or ((4 and IOCPARM_MASK) shl 16) or ((Ord('t')) shl 8) or (127); {$EXTERNALSYM SIO_GET_INTERFACE_LIST} // New IOCTL with address size independent address array SIO_GET_INTERFACE_LIST_EX = IOC_OUT or ((4 and IOCPARM_MASK) shl 16) or ((Ord('t')) shl 8) or (126); {$EXTERNALSYM SIO_GET_INTERFACE_LIST_EX} SIO_SET_MULTICAST_FILTER = DWORD(IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 125); {$EXTERNALSYM SIO_SET_MULTICAST_FILTER} 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); {$EXTERNALSYM SIO_GET_MULTICAST_FILTER} // Option to use with [gs]etsockopt at the IPPROTO_IP level const IP_OPTIONS = 1; // set/get IP options {$EXTERNALSYM IP_OPTIONS} IP_HDRINCL = 2; // header is included with data {$EXTERNALSYM IP_HDRINCL} IP_TOS = 3; // IP type of service and preced {$EXTERNALSYM IP_TOS} IP_TTL = 4; // IP time to live {$EXTERNALSYM IP_TTL} IP_MULTICAST_IF = 9; // set/get IP multicast i/f {$EXTERNALSYM IP_MULTICAST_IF} IP_MULTICAST_TTL = 10; // set/get IP multicast ttl {$EXTERNALSYM IP_MULTICAST_TTL} IP_MULTICAST_LOOP = 11; // set/get IP multicast loopback {$EXTERNALSYM IP_MULTICAST_LOOP} IP_ADD_MEMBERSHIP = 12; // add an IP group membership {$EXTERNALSYM IP_ADD_MEMBERSHIP} IP_DROP_MEMBERSHIP = 13; // drop an IP group membership {$EXTERNALSYM IP_DROP_MEMBERSHIP} IP_DONTFRAGMENT = 14; // don't fragment IP datagrams {$EXTERNALSYM IP_DONTFRAGMENT} IP_ADD_SOURCE_MEMBERSHIP = 15; // join IP group/source {$EXTERNALSYM IP_ADD_SOURCE_MEMBERSHIP} IP_DROP_SOURCE_MEMBERSHIP = 16; // leave IP group/source {$EXTERNALSYM IP_DROP_SOURCE_MEMBERSHIP} IP_BLOCK_SOURCE = 17; // block IP group/source {$EXTERNALSYM IP_BLOCK_SOURCE} IP_UNBLOCK_SOURCE = 18; // unblock IP group/source {$EXTERNALSYM IP_UNBLOCK_SOURCE} IP_PKTINFO = 19; // receive packet information for ipv4 {$EXTERNALSYM IP_PKTINFO} // Option to use with [gs]etsockopt at the IPPROTO_IPV6 level IPV6_HDRINCL = 2; // Header is included with data {$EXTERNALSYM IPV6_HDRINCL} IPV6_UNICAST_HOPS = 4; // Set/get IP unicast hop limit {$EXTERNALSYM IPV6_UNICAST_HOPS} IPV6_MULTICAST_IF = 9; // Set/get IP multicast interface {$EXTERNALSYM IPV6_MULTICAST_IF} IPV6_MULTICAST_HOPS = 10; // Set/get IP multicast ttl {$EXTERNALSYM IPV6_MULTICAST_HOPS} IPV6_MULTICAST_LOOP = 11; // Set/get IP multicast loopback {$EXTERNALSYM IPV6_MULTICAST_LOOP} IPV6_ADD_MEMBERSHIP = 12; // Add an IP group membership {$EXTERNALSYM IPV6_ADD_MEMBERSHIP} IPV6_DROP_MEMBERSHIP = 13; // Drop an IP group membership {$EXTERNALSYM IPV6_DROP_MEMBERSHIP} IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP; {$EXTERNALSYM IPV6_JOIN_GROUP} IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP; {$EXTERNALSYM IPV6_LEAVE_GROUP} IPV6_PKTINFO = 19; // Receive packet information for ipv6 {$EXTERNALSYM IPV6_PKTINFO} // Option to use with [gs]etsockopt at the IPPROTO_UDP level UDP_NOCHECKSUM = 1; {$EXTERNALSYM UDP_NOCHECKSUM} UDP_CHECKSUM_COVERAGE = 20; // Set/get UDP-Lite checksum coverage {$EXTERNALSYM UDP_CHECKSUM_COVERAGE} // Option to use with [gs]etsockopt at the IPPROTO_TCP level TCP_EXPEDITED_1122 = $0002; {$EXTERNALSYM TCP_EXPEDITED_1122} // IPv6 definitions type in6_addr = record case Integer of 0: (Byte: array [0..15] of u_char); 1: (Word: array[0..7] of u_short); 2: (s6_bytes: array [0..15] of u_char); 3: (s6_addr: array [0..15] of u_char); 4: (s6_words: array[0..7] of u_short); end; {$EXTERNALSYM in6_addr} TIn6Addr = in6_addr; PIn6Addr = ^in6_addr; // // Defines to match RFC 2553. // //#define _S6_un u //#define _S6_u8 Byte // Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP type ipv6_mreq = record ipv6mr_multiaddr: in6_addr; // IPv6 multicast address ipv6mr_interface: Cardinal; // Interface index end; {$EXTERNALSYM ipv6_mreq} TIpV6MReq = ipv6_mreq; PIpV6MReq = ^ipv6_mreq; type in_addr6 = record s6_addr: array [0..15] of u_char; // IPv6 address end; {$EXTERNALSYM in_addr6} TInAddr6 = in_addr6; PInAddr6 = ^in_addr6; // Old IPv6 socket address structure (retained for sockaddr_gen definition below) type sockaddr_in6_old = record sin6_family: short; // AF_INET6 sin6_port: u_short; // Transport level port number sin6_flowinfo: u_long; // IPv6 flow information sin6_addr: in6_addr; // IPv6 address end; {$EXTERNALSYM sockaddr_in6_old} TSockAddrIn6Old = sockaddr_in6_old; PSockAddrIn6Old = ^sockaddr_in6_old; // IPv6 socket address structure, RFC 2553 SOCKADDR_IN6 = record sin6_family: short; // AF_INET6 sin6_port: u_short; // Transport level port number sin6_flowinfo: u_long; // IPv6 flow information sin6_addr: in6_addr; // IPv6 address sin6_scope_id: u_long; // set of interfaces for a scope end; {$EXTERNALSYM SOCKADDR_IN6} PSOCKADDR_IN6 = ^SOCKADDR_IN6; {$EXTERNALSYM PSOCKADDR_IN6} LPSOCKADDR_IN6 = ^SOCKADDR_IN6; {$EXTERNALSYM LPSOCKADDR_IN6} TSockAddrIn6 = SOCKADDR_IN6; PSockAddrIn6 = LPSOCKADDR_IN6; // Macro that works for both IPv4 and IPv6 function SS_PORT(ssp: Pointer): u_short; {$EXTERNALSYM SS_PORT} const IN6ADDR_ANY_INIT: in6_addr = (Word: (0, 0, 0, 0, 0, 0, 0, 0)); {$EXTERNALSYM IN6ADDR_ANY_INIT} IN6ADDR_LOOPBACK_INIT: in6_addr = (Byte: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)); {$EXTERNALSYM IN6ADDR_LOOPBACK_INIT} in6addr_any: in6_addr = (Word: (0, 0, 0, 0, 0, 0, 0, 0)); {$EXTERNALSYM in6addr_any} in6addr_loopback: in6_addr = (Byte: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)); {$EXTERNALSYM in6addr_loopback} procedure IN6ADDR_SETANY(var x: TSockAddrIn6); {$EXTERNALSYM IN6ADDR_SETANY} procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6); {$EXTERNALSYM IN6ADDR_SETLOOPBACK} function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean; {$EXTERNALSYM IN6ADDR_ISANY} function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean; {$EXTERNALSYM IN6ADDR_ISLOOPBACK} function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean; {$EXTERNALSYM IN6_ADDR_EQUAL} function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean; {$EXTERNALSYM IN6_IS_ADDR_UNSPECIFIED} function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_LOOPBACK} function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MULTICAST} function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_LINKLOCAL} function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_SITELOCAL} function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_V4MAPPED} function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_V4COMPAT} function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MC_NODELOCAL} function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MC_LINKLOCAL} function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MC_SITELOCAL} function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MC_ORGLOCAL} function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean; {$EXTERNALSYM IN6_IS_ADDR_MC_GLOBAL} type sockaddr_gen = record case Integer of 0: (Address: sockaddr); 1: (AddressIn: sockaddr_in); 2: (AddressIn6: sockaddr_in6_old); end; {$EXTERNALSYM sockaddr_gen} TSockAddrGen = sockaddr_gen; PSockAddrGen = ^sockaddr_gen; // Structure to keep interface specific information _INTERFACE_INFO = record iiFlags: u_long; // Interface flags iiAddress: sockaddr_gen; // Interface address iiBroadcastAddress: sockaddr_gen; // Broadcast address iiNetmask: sockaddr_gen; // Network mask end; {$EXTERNALSYM _INTERFACE_INFO} INTERFACE_INFO = _INTERFACE_INFO; {$EXTERNALSYM INTERFACE_INFO} LPINTERFACE_INFO = ^INTERFACE_INFO; {$EXTERNALSYM LPINTERFACE_INFO} TInterfaceInfo = INTERFACE_INFO; PInterfaceInfo = LPINTERFACE_INFO; // New structure that does not have dependency on the address size _INTERFACE_INFO_EX = record iiFlags: u_long; // Interface flags iiAddress: SOCKET_ADDRESS; // Interface address iiBroadcastAddress: SOCKET_ADDRESS; // Broadcast address iiNetmask: SOCKET_ADDRESS; // Network mask end; {$EXTERNALSYM _INTERFACE_INFO_EX} INTERFACE_INFO_EX = _INTERFACE_INFO_EX; {$EXTERNALSYM INTERFACE_INFO_EX} LPINTERFACE_INFO_EX = ^INTERFACE_INFO_EX; {$EXTERNALSYM LPINTERFACE_INFO_EX} TInterfaceInfoEx = INTERFACE_INFO_EX; PInterfaceInfoEx = LPINTERFACE_INFO_EX; // Possible flags for the iiFlags - bitmask const IFF_UP = $00000001; // Interface is up {$EXTERNALSYM IFF_UP} IFF_BROADCAST = $00000002; // Broadcast is supported {$EXTERNALSYM IFF_BROADCAST} IFF_LOOPBACK = $00000004; // this is loopback interface {$EXTERNALSYM IFF_LOOPBACK} IFF_POINTTOPOINT = $00000008; //this is point-to-point interface {$EXTERNALSYM IFF_POINTTOPOINT} IFF_MULTICAST = $00000010; // multicast is supported {$EXTERNALSYM IFF_MULTICAST} // structure for IP_PKTINFO option // type in_pktinfo = record ipi_addr: IN_ADDR; // destination IPv4 address ipi_ifindex: UINT; // received interface index end; {$EXTERNALSYM in_pktinfo} TInPktInfo = in_pktinfo; PInPktInfo = ^in_pktinfo; // C_ASSERT(sizeof(IN_PKTINFO) == 8); // structure for IPV6_PKTINFO option // in6_pktinfo = record ipi6_addr: IN6_ADDR; // destination IPv6 address ipi6_ifindex: UINT; // received interface index end; {$EXTERNALSYM in6_pktinfo} TIn6PktInfo = in6_pktinfo; PIn6PktInfo = ^in6_pktinfo; // C_ASSERT(sizeof(IN6_PKTINFO) == 20); // Error codes from getaddrinfo() const EAI_AGAIN = WSATRY_AGAIN; {$EXTERNALSYM EAI_AGAIN} EAI_BADFLAGS = WSAEINVAL; {$EXTERNALSYM EAI_BADFLAGS} EAI_FAIL = WSANO_RECOVERY; {$EXTERNALSYM EAI_FAIL} EAI_FAMILY = WSAEAFNOSUPPORT; {$EXTERNALSYM EAI_FAMILY} EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY; {$EXTERNALSYM EAI_MEMORY} //#define EAI_NODATA WSANO_DATA EAI_NONAME = WSAHOST_NOT_FOUND; {$EXTERNALSYM EAI_NONAME} EAI_SERVICE = WSATYPE_NOT_FOUND; {$EXTERNALSYM EAI_SERVICE} EAI_SOCKTYPE = WSAESOCKTNOSUPPORT; {$EXTERNALSYM EAI_SOCKTYPE} // // DCR_FIX: EAI_NODATA remove or fix // // EAI_NODATA was removed from rfc2553bis // need to find out from the authors why and // determine the error for "no records of this type" // temporarily, we'll keep #define to avoid changing // code that could change back; use NONAME // EAI_NODATA = EAI_NONAME; {$EXTERNALSYM EAI_NODATA} // Structure used in getaddrinfo() call type LPADDRINFO = ^addrinfo; {$EXTERNALSYM LPADDRINFO} addrinfo = record ai_flags: Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST ai_family: Integer; // PF_xxx ai_socktype: Integer; // SOCK_xxx ai_protocol: Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 ai_addrlen: size_t; // Length of ai_addr ai_canonname: PChar; // Canonical name for nodename ai_addr: PSockAddr; // Binary address ai_next: LPADDRINFO; // Next structure in linked list end; {$EXTERNALSYM addrinfo} TAddrInfo = addrinfo; PAddrInfo = LPADDRINFO; // Flags used in "hints" argument to getaddrinfo() const AI_PASSIVE = $1; // Socket address will be used in bind() call {$EXTERNALSYM AI_PASSIVE} AI_CANONNAME = $2; // Return canonical name in first ai_canonname {$EXTERNALSYM AI_CANONNAME} AI_NUMERICHOST = $4; // Nodename must be a numeric address string {$EXTERNALSYM AI_NUMERICHOST} function getaddrinfo(nodename, servname: PChar; hints: PAddrInfo; var res: PAddrInfo): Integer; stdcall; {$EXTERNALSYM getaddrinfo} procedure freeaddrinfo(ai: PAddrInfo); stdcall; {$EXTERNALSYM freeaddrinfo} // WARNING: The gai_strerror inline functions below use static buffers, // and hence are not thread-safe. We'll use buffers long enough to hold // 1k characters. Any system error messages longer than this will be // returned as empty strings. However 1k should work for the error codes // used by getaddrinfo(). const GAI_STRERROR_BUFFER_SIZE = 1024; {$EXTERNALSYM GAI_STRERROR_BUFFER_SIZE} function gai_strerrorA(ecode: Integer): PChar; {$EXTERNALSYM gai_strerrorA} function gai_strerrorW(ecode: Integer): PWideChar; {$EXTERNALSYM gai_strerrorW} function gai_strerror(ecode: Integer): PTCHAR; {$EXTERNALSYM gai_strerror} type socklen_t = Integer; {$EXTERNALSYM socklen_t} function getnameinfo(sa: PSockAddr; salen: socklen_t; host: PChar; hostlen: DWORD; serv: PChar; servlen: DWORD; flags: Integer): Integer; stdcall; {$EXTERNALSYM getnameinfo} const NI_MAXHOST = 1025; // Max size of a fully-qualified domain name {$EXTERNALSYM NI_MAXHOST} NI_MAXSERV = 32; // Max size of a service name {$EXTERNALSYM NI_MAXSERV} INET_ADDRSTRLEN = 16; // Max size of numeric form of IPv4 address {$EXTERNALSYM INET_ADDRSTRLEN} INET6_ADDRSTRLEN = 46; // Max size of numeric form of IPv6 address {$EXTERNALSYM INET6_ADDRSTRLEN} // Flags for getnameinfo() NI_NOFQDN = $01; // Only return nodename portion for local hosts {$EXTERNALSYM NI_NOFQDN} NI_NUMERICHOST = $02; // Return numeric form of the host's address {$EXTERNALSYM NI_NUMERICHOST} NI_NAMEREQD = $04; // Error if the host's name not in DNS {$EXTERNALSYM NI_NAMEREQD} NI_NUMERICSERV = $08; // Return numeric form of the service (port #) {$EXTERNALSYM NI_NUMERICSERV} NI_DGRAM = $10; // Service is a datagram service {$EXTERNALSYM NI_DGRAM} {$ENDIF JWA_IMPLEMENTATIONSECTION} {$IFNDEF JWA_OMIT_SECTIONS} implementation uses SysUtils, JwaWinBase, JwaWinNT; {$ENDIF JWA_OMIT_SECTIONS} {$IFNDEF JWA_INTERFACESECTION} function IP_MSFILTER_SIZE(numsrc: Integer): Integer; begin Result := SizeOf(ip_msfilter) - SizeOf(in_addr) + (numsrc * SizeOf(in_addr)); end; function SS_PORT(ssp: Pointer): u_short; begin Result := PSockAddrIn(ssp)^.sin_port; end; procedure IN6ADDR_SETANY(var x: TSockAddrIn6); var I: Integer; begin x.sin6_family := AF_INET6; x.sin6_port := 0; x.sin6_flowinfo := 0; for I := 0 to 15 do x.sin6_addr.s6_addr[I] := 0; end; procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6); var I: Integer; begin x.sin6_family := AF_INET6; x.sin6_port := 0; x.sin6_flowinfo := 0; for I := 0 to 14 do x.sin6_addr.s6_addr[I] := 0; x.sin6_addr.s6_addr[15] := 1; end; function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean; var I: Integer; begin Result := x.sin6_family = AF_INET6; for I := 0 to 15 do Result := Result and (x.sin6_addr.s6_addr[I] = 0); end; function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean; var I: Integer; begin Result := x.sin6_family = AF_INET6; for I := 0 to 14 do Result := Result and (x.sin6_addr.s6_addr[I] = 0); Result := Result and (x.sin6_addr.s6_addr[15] = 1); end; function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean; var I: Integer; begin Result := True; for I := Low(a.Word) to High(a.Word) do Result := (a.Word[I] = b.Word[I]) and Result; end; function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean; begin Result := IN6_ADDR_EQUAL(a, in6addr_any); end; function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean; begin Result := IN6_ADDR_EQUAL(a, in6addr_loopback); end; function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean; begin Result := (a.s6_bytes[0] = $ff); end; function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean; begin Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $80)); end; function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean; begin Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $c0)); end; function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean; begin Result := ((a.s6_words[0] = 0) and (a.s6_words[1] = 0) and (a.s6_words[2] = 0) and (a.s6_words[3] = 0) and (a.s6_words[4] = 0) and (a.s6_words[5] = $ffff)); end; function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean; begin Result := ((a.s6_words[0] = 0) and (a.s6_words[1] = 0) and (a.s6_words[2] = 0) and (a.s6_words[3] = 0) and (a.s6_words[4] = 0) and (a.s6_words[5] = 0) and not ((a.s6_words[6] = 0) and (a.s6_addr[14] = 0) and ((a.s6_addr[15] = 0) or (a.s6_addr[15] = 1)))); end; function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean; begin Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 1); end; function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean; begin Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 2); end; function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean; begin Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 5); end; function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean; begin Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 8); end; function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean; begin Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = $e); end; var gai_strerror_buffA: array [0..GAI_STRERROR_BUFFER_SIZE-1] of Char; gai_strerror_buffW: array [0..GAI_STRERROR_BUFFER_SIZE-1] of WideChar; function gai_strerrorA(ecode: Integer): PChar; var dwMsgLen: DWORD; begin dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK, nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(@gai_strerror_buffA[0]), GAI_STRERROR_BUFFER_SIZE, nil); if dwMsgLen = 0 then Result := nil else Result := PChar(@gai_strerror_buffA[0]); end; function gai_strerrorW(ecode: Integer): PWideChar; var dwMsgLen: DWORD; begin dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK, nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(@gai_strerror_buffW[0]), GAI_STRERROR_BUFFER_SIZE, nil); if dwMsgLen = 0 then Result := nil else Result := PWideChar(@gai_strerror_buffW[0]); end; function gai_strerror(ecode: Integer): PTCHAR; begin {$IFDEF UNICODE} Result := PTCHAR(gai_strerrorW(ecode)); {$ELSE} Result := PTCHAR(gai_strerrorA(ecode)); {$ENDIF UNICODE} end; const ws2tcpip = 'ws2_32.dll'; {$IFDEF DYNAMIC_LINK} var _getaddrinfo: Pointer; function getaddrinfo; begin GetProcedureAddress(_getaddrinfo, ws2tcpip, 'getaddrinfo'); asm MOV ESP, EBP POP EBP JMP [_getaddrinfo] end; end; var _freeaddrinfo: Pointer; procedure freeaddrinfo; begin GetProcedureAddress(_freeaddrinfo, ws2tcpip, 'freeaddrinfo'); asm MOV ESP, EBP POP EBP JMP [_freeaddrinfo] end; end; var _getnameinfo: Pointer; function getnameinfo; begin GetProcedureAddress(_getnameinfo, ws2tcpip, 'getnameinfo'); asm MOV ESP, EBP POP EBP JMP [_getnameinfo] end; end; {$ELSE} function getaddrinfo; external ws2tcpip name 'getaddrinfo'; procedure freeaddrinfo; external ws2tcpip name 'freeaddrinfo'; function getnameinfo; external ws2tcpip name 'getnameinfo'; {$ENDIF DYNAMIC_LINK} {$ENDIF JWA_INTERFACESECTION} {$IFNDEF JWA_OMIT_SECTIONS} end. {$ENDIF JWA_OMIT_SECTIONS}