From: Amine Khaldi Date: Fri, 2 Apr 2010 09:14:55 +0000 (+0000) Subject: [PSDK] X-Git-Tag: backups/header-work@57446~69 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=e998dec47746963e76568de2e61fca2e33bf8700 [PSDK] - Add missing mstcpip.h, wsipv6ok.h and wspiapi.h definitions. svn path=/branches/header-work/; revision=46666 --- diff --git a/include/psdk/mstcpip.h b/include/psdk/mstcpip.h new file mode 100644 index 00000000000..2d25e70f506 --- /dev/null +++ b/include/psdk/mstcpip.h @@ -0,0 +1,1525 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ASSERT +#define MSTCPIP_ASSERT_UNDEFINED +#define ASSERT(exp) ((VOID) 0) +#endif + +#ifdef _MSC_VER +#define MSTCPIP_INLINE __inline +#else +#define MSTCPIP_INLINE extern inline +#endif + +/* FIXME : +#include +*/ + +struct tcp_keepalive { + ULONG onoff; + ULONG keepalivetime; + ULONG keepaliveinterval; +}; + +#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) +#define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2) +#define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3) +#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) +#define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5) +#define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6) +#define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7) +#define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8) +#define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9) +#define SIO_INDEX_ADD_MCAST _WSAIOW(IOC_VENDOR,10) +#define SIO_INDEX_DEL_MCAST _WSAIOW(IOC_VENDOR,11) +#define SIO_RCVALL_MCAST_IF _WSAIOW(IOC_VENDOR,13) +#define SIO_RCVALL_IF _WSAIOW(IOC_VENDOR,14) + +typedef enum { + RCVALL_OFF = 0, + RCVALL_ON = 1, + RCVALL_SOCKETLEVELONLY = 2, + RCVALL_IPLEVEL = 3, +} RCVALL_VALUE, *PRCVALL_VALUE; + +#define RCVALL_MAX RCVALL_IPLEVEL + +typedef struct { + RCVALL_VALUE Mode; + ULONG Interface; +} RCVALL_IF, *PRCVALL_IF; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +DEFINE_GUID(SOCKET_DEFAULT2_QM_POLICY, 0xaec2ef9c, 0x3a4d, 0x4d3e, 0x88, 0x42, 0x23, 0x99, 0x42, 0xe3, 0x9a, 0x47); +#endif + +#define SIO_ACQUIRE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 100) +#define SIO_RELEASE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 101) +#define SIO_ASSOCIATE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 102) + +typedef struct _INET_PORT_RANGE { + USHORT StartPort; + USHORT NumberOfPorts; +} INET_PORT_RANGE, *PINET_PORT_RANGE; +typedef struct _INET_PORT_RANGE INET_PORT_RESERVATION, *PINET_PORT_RESERVATION; + +typedef struct { + ULONG64 Token; +} INET_PORT_RESERVATION_TOKEN, *PINET_PORT_RESERVATION_TOKEN; + +#define INVALID_PORT_RESERVATION_TOKEN ((ULONG64)0) + +typedef struct { +#ifdef __cplusplus + INET_PORT_RESERVATION Reservation; + INET_PORT_RESERVATION_TOKEN Token; +#else + INET_PORT_RESERVATION; + INET_PORT_RESERVATION_TOKEN; +#endif +} INET_PORT_RESERVATION_INSTANCE, *PINET_PORT_RESERVATION_INSTANCE; + +typedef struct { + ULONG AssignmentCount; + ULONG OwningPid; +} INET_PORT_RESERVATION_INFORMATION, *PINET_PORT_RESERVATION_INFORMATION; + +#ifdef _WS2DEF_ + +#if (NTDDI_VERSION >= NTDDI_VISTA) + +#define _SECURE_SOCKET_TYPES_DEFINED_ + +#define SIO_SET_SECURITY _WSAIOW(IOC_VENDOR, 200) +#define SIO_QUERY_SECURITY _WSAIORW(IOC_VENDOR, 201) +#define SIO_SET_PEER_TARGET_NAME _WSAIOW(IOC_VENDOR, 202) +#define SIO_DELETE_PEER_TARGET_NAME _WSAIOW(IOC_VENDOR, 203) + +#define SIO_SOCKET_USAGE_NOTIFICATION _WSAIOW(IOC_VENDOR, 204) + +typedef enum _SOCKET_USAGE_TYPE { + SYSTEM_CRITICAL_SOCKET = 1 +}SOCKET_USAGE_TYPE; + +typedef enum _SOCKET_SECURITY_PROTOCOL { + SOCKET_SECURITY_PROTOCOL_DEFAULT, + SOCKET_SECURITY_PROTOCOL_IPSEC, +#if (NTDDI_VERSION >= NTDDI_WIN7) + SOCKET_SECURITY_PROTOCOL_IPSEC2, +#endif + SOCKET_SECURITY_PROTOCOL_INVALID +} SOCKET_SECURITY_PROTOCOL; + +#define SOCKET_SETTINGS_GUARANTEE_ENCRYPTION 0x1 +#define SOCKET_SETTINGS_ALLOW_INSECURE 0x2 + +typedef struct _SOCKET_SECURITY_SETTINGS { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + ULONG SecurityFlags; +} SOCKET_SECURITY_SETTINGS; + +#define SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION 0x1 + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +#define SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION 0x2 +#define SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED 0x4 +#define SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT 0x8 + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + +typedef struct _SOCKET_SECURITY_SETTINGS_IPSEC { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + ULONG SecurityFlags; + ULONG IpsecFlags; + GUID AuthipMMPolicyKey; + GUID AuthipQMPolicyKey; + GUID Reserved; + UINT64 Reserved2; + ULONG UserNameStringLen; + ULONG DomainNameStringLen; + ULONG PasswordStringLen; + wchar_t AllStrings[0]; +} SOCKET_SECURITY_SETTINGS_IPSEC; + +typedef struct _SOCKET_PEER_TARGET_NAME { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + SOCKADDR_STORAGE PeerAddress; + ULONG PeerTargetNameStringLen; + wchar_t AllStrings[0]; +} SOCKET_PEER_TARGET_NAME; + +typedef struct _SOCKET_SECURITY_QUERY_TEMPLATE { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + SOCKADDR_STORAGE PeerAddress; + ULONG PeerTokenAccessMask; +} SOCKET_SECURITY_QUERY_TEMPLATE; + +#if (NTDDI_VERSION >= NTDDI_WIN7) + +#define SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE 0x1 + +#define SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID 0x1 +#define SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID 0x2 + +typedef struct _SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2 { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + SOCKADDR_STORAGE PeerAddress; + ULONG PeerTokenAccessMask; + ULONG Flags; + ULONG FieldMask; +} SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2; + +#endif /* (NTDDI_VERSION >= NTDDI_WIN7) */ + +#define SOCKET_INFO_CONNECTION_SECURED 0x1 +#define SOCKET_INFO_CONNECTION_ENCRYPTED 0x2 +#define SOCKET_INFO_CONNECTION_IMPERSONATED 0x4 + +typedef struct _SOCKET_SECURITY_QUERY_INFO { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + ULONG Flags; + UINT64 PeerApplicationAccessTokenHandle; + UINT64 PeerMachineAccessTokenHandle; +} SOCKET_SECURITY_QUERY_INFO; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +typedef struct _SOCKET_SECURITY_QUERY_INFO_IPSEC2 { + SOCKET_SECURITY_PROTOCOL SecurityProtocol; + ULONG Flags; + UINT64 PeerApplicationAccessTokenHandle; + UINT64 PeerMachineAccessTokenHandle; + UINT64 MmSaId; + UINT64 QmSaId; + UINT32 NegotiationWinerr; + GUID SaLookupContext; +} SOCKET_SECURITY_QUERY_INFO_IPSEC2; +#endif + +#define SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE _WSAIOR(IOC_VENDOR, 205) +#define SIO_QUERY_RSS_SCALABILITY_INFO _WSAIOR(IOC_VENDOR, 210) + +typedef struct _RSS_SCALABILITY_INFO { + BOOLEAN RssEnabled; +} RSS_SCALABILITY_INFO, *PRSS_SCALABILITY_INFO; + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + +#define IN4_CLASSA(i) (((LONG)(i) & 0x00000080) == 0) +#define IN4_CLASSB(i) (((LONG)(i) & 0x000000c0) == 0x00000080) +#define IN4_CLASSC(i) (((LONG)(i) & 0x000000e0) == 0x000000c0) +#define IN4_CLASSD(i) (((LONG)(i) & 0x000000f0) == 0x000000e0) +#define IN4_MULTICAST(i) IN4_CLASSD(i) + +#define IN4ADDR_ANY INADDR_ANY +#define IN4ADDR_LOOPBACK 0x0100007f +#define IN4ADDR_BROADCAST INADDR_BROADCAST +#define IN4ADDR_NONE INADDR_NONE +#define IN4ADDR_ANY_INIT { 0 } +#define IN4ADDR_LOOPBACK_INIT { 0x7f, 0, 0, 1 } +#define IN4ADDR_BROADCAST_INIT { 0xff, 0xff, 0xff, 0xff } +#define IN4ADDR_ALLNODESONLINK_INIT { 0xe0, 0, 0, 1 } +#define IN4ADDR_ALLROUTERSONLINK_INIT { 0xe0, 0, 0, 2 } +#define IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT { 0xe0, 0, 0, 0x16 } +#define IN4ADDR_ALLTEREDONODESONLINK_INIT { 0xe0, 0, 0, 0xfd } +#define IN4ADDR_LINKLOCALPREFIX_INIT { 0xa9, 0xfe, } +#define IN4ADDR_MULTICASTPREFIX_INIT { 0xe0, } + +#define IN4ADDR_LOOPBACKPREFIX_LENGTH 8 +#define IN4ADDR_LINKLOCALPREFIX_LENGTH 16 +#define IN4ADDR_MULTICASTPREFIX_LENGTH 4 + +#if (NTDDI_VERSION >= NTDDI_WIN2KSP1) + +MSTCPIP_INLINE +BOOLEAN +IN4_ADDR_EQUAL( + IN CONST IN_ADDR *a, + IN CONST IN_ADDR *b) +{ + return (BOOLEAN)(a->s_addr == b->s_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_UNALIGNED_ADDR_EQUAL( + IN CONST IN_ADDR UNALIGNED *a, + IN CONST IN_ADDR UNALIGNED *b) +{ + return (BOOLEAN)(a->s_addr == b->s_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_UNSPECIFIED( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)(a->s_addr == IN4ADDR_ANY); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_UNSPECIFIED( + IN CONST IN_ADDR UNALIGNED *a) +{ + return (BOOLEAN)(a->s_addr == IN4ADDR_ANY); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_LOOPBACK( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)(*((PUCHAR) a) == 0x7f); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_LOOPBACK( + IN CONST IN_ADDR UNALIGNED *a) +{ + return (BOOLEAN)(*((PUCHAR) a) == 0x7f); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_BROADCAST( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)(a->s_addr == IN4ADDR_BROADCAST); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_BROADCAST( + IN CONST IN_ADDR UNALIGNED *a) +{ + return (BOOLEAN)(a->s_addr == IN4ADDR_BROADCAST); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_MULTICAST( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)IN4_MULTICAST(a->s_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_MULTICAST( + IN CONST IN_ADDR UNALIGNED *a) +{ + return (BOOLEAN)IN4_MULTICAST(a->s_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_LINKLOCAL( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)((a->s_addr & 0xffff) == 0xfea9); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_LINKLOCAL( + IN CONST IN_ADDR UNALIGNED *a) +{ + return (BOOLEAN)((a->s_addr & 0xffff) == 0xfea9); // 169.254/16 +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_SITELOCAL( + IN CONST IN_ADDR *a) +{ + UNREFERENCED_PARAMETER(a); + return FALSE; +} +#define IN4_IS_UNALIGNED_ADDR_SITELOCAL IN4_IS_ADDR_SITELOCAL + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_RFC1918( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)(((a->s_addr & 0x00ff) == 0x0a) || + ((a->s_addr & 0xf0ff) == 0x10ac) || + ((a->s_addr & 0xffff) == 0xa8c0)); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_RFC1918( + IN CONST IN_ADDR UNALIGNED *a) +{ + IN_ADDR Ipv4Address = *a; + return IN4_IS_ADDR_RFC1918(&Ipv4Address); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_MC_LINKLOCAL( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)((a->s_addr & 0xffffff) == 0xe0); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_MC_ADMINLOCAL( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)((a->s_addr & 0xffff) == 0xffef); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_MC_SITELOCAL( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)((a->s_addr & 0xff) == 0xef) && + !IN4_IS_ADDR_MC_ADMINLOCAL(a); +} + +MSTCPIP_INLINE +VOID +IN4ADDR_SETSOCKADDR( + OUT PSOCKADDR_IN a, + IN CONST IN_ADDR *addr, + IN USHORT port) +{ + a->sin_family = AF_INET; + a->sin_port = port; + a->sin_addr = *addr; + memset(a->sin_zero, 0, sizeof(a->sin_zero)); +} + +MSTCPIP_INLINE +VOID +IN4ADDR_SETANY( + OUT PSOCKADDR_IN a) +{ + a->sin_family = AF_INET; + a->sin_port = 0; + a->sin_addr.s_addr = IN4ADDR_ANY; + memset(a->sin_zero, 0, sizeof(a->sin_zero)); +} + +MSTCPIP_INLINE +VOID +IN4ADDR_SETLOOPBACK( + OUT PSOCKADDR_IN a) +{ + a->sin_family = AF_INET; + a->sin_port = 0; + a->sin_addr.s_addr = IN4ADDR_LOOPBACK; + memset(a->sin_zero, 0, sizeof(a->sin_zero)); +} + +MSTCPIP_INLINE +BOOLEAN +IN4ADDR_ISANY( + IN CONST SOCKADDR_IN *a) +{ + ASSERT(a->sin_family == AF_INET); + return IN4_IS_ADDR_UNSPECIFIED(&a->sin_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN4ADDR_ISLOOPBACK( + IN CONST SOCKADDR_IN *a) +{ + ASSERT(a->sin_family == AF_INET); + return IN4_IS_ADDR_LOOPBACK(&a->sin_addr); +} + +MSTCPIP_INLINE +SCOPE_ID +IN4ADDR_SCOPE_ID( + IN CONST SOCKADDR_IN *a) +{ + SCOPE_ID UnspecifiedScopeId = {0}; + UNREFERENCED_PARAMETER(a); + return UnspecifiedScopeId; +} + +MSTCPIP_INLINE +BOOLEAN +IN4ADDR_ISEQUAL( + IN CONST SOCKADDR_IN *a, + IN CONST SOCKADDR_IN *b) +{ + ASSERT(a->sin_family == AF_INET); + return (BOOLEAN)(IN4ADDR_SCOPE_ID(a).Value == IN4ADDR_SCOPE_ID(b).Value && + IN4_ADDR_EQUAL(&a->sin_addr, &b->sin_addr)); +} + +MSTCPIP_INLINE +BOOLEAN +IN4ADDR_ISUNSPECIFIED( + IN CONST SOCKADDR_IN *a) +{ + ASSERT(a->sin_family == AF_INET); + return (BOOLEAN)(IN4ADDR_SCOPE_ID(a).Value == 0 && + IN4_IS_ADDR_UNSPECIFIED(&a->sin_addr)); +} + +#define INET_IS_ALIGNED(Pointer, Type) \ + (((ULONG_PTR)Pointer & (__builtin_alignof(Type)-1)) == 0) + +MSTCPIP_INLINE +SCOPE_LEVEL +Ipv4UnicastAddressScope( + IN CONST UCHAR *Address) +{ + IN_ADDR Ipv4Address; + + if (!INET_IS_ALIGNED(Address, IN_ADDR)) { + Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address; + Address = (CONST UCHAR *) &Ipv4Address; + } + if (IN4_IS_ADDR_LINKLOCAL((PIN_ADDR) Address) || + IN4_IS_ADDR_LOOPBACK((PIN_ADDR) Address)) { + return ScopeLevelLink; + } + return ScopeLevelGlobal; +} + +MSTCPIP_INLINE +SCOPE_LEVEL +Ipv4MulticastAddressScope( + IN CONST UCHAR *Address) +{ + IN_ADDR Ipv4Address; + + if (!INET_IS_ALIGNED(Address, IN_ADDR)) { + Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address; + Address = (CONST UCHAR *) &Ipv4Address; + } + if (IN4_IS_ADDR_MC_LINKLOCAL((PIN_ADDR) Address)) { + return ScopeLevelLink; + } else if (IN4_IS_ADDR_MC_ADMINLOCAL((PIN_ADDR) Address)) { + return ScopeLevelAdmin; + } else if (IN4_IS_ADDR_MC_SITELOCAL((PIN_ADDR) Address)) { + return ScopeLevelSite; + } else { + return ScopeLevelGlobal; + } +} + +MSTCPIP_INLINE +SCOPE_LEVEL +Ipv4AddressScope( + IN CONST UCHAR *Address) +{ + IN CONST IN_ADDR Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address; + + if (IN4_IS_ADDR_BROADCAST(&Ipv4Address)) { + return ScopeLevelLink; + } else if (IN4_IS_ADDR_MULTICAST(&Ipv4Address)) { + return Ipv4MulticastAddressScope((UCHAR *) &Ipv4Address); + } else { + return Ipv4UnicastAddressScope((UCHAR *) &Ipv4Address); + } +} + +MSTCPIP_INLINE +NL_ADDRESS_TYPE +Ipv4AddressType( + IN CONST UCHAR *Address) +{ + IN_ADDR Ipv4Address = *(CONST IN_ADDR UNALIGNED *) Address; + + if (IN4_IS_ADDR_MULTICAST(&Ipv4Address)) { + return NlatMulticast; + } + if (IN4_IS_ADDR_BROADCAST(&Ipv4Address)) { + return NlatBroadcast; + } + if (IN4_IS_ADDR_UNSPECIFIED(&Ipv4Address)) { + return NlatUnspecified; + } + if (((Ipv4Address.s_addr & 0x000000ff) == 0) || + ((Ipv4Address.s_addr & 0x000000f0) == 240)) { + return NlatInvalid; + } + return NlatUnicast; +} + +MSTCPIP_INLINE +VOID +IN4_UNCANONICALIZE_SCOPE_ID( + IN CONST IN_ADDR *Address, + IN OUT SCOPE_ID *ScopeId) +{ + SCOPE_LEVEL ScopeLevel = Ipv4AddressScope((CONST UCHAR *)Address); + + if ((IN4_IS_ADDR_LOOPBACK(Address)) || (ScopeLevel == ScopeLevelGlobal)) { + ScopeId->Value = 0; + } + if ((SCOPE_LEVEL)ScopeId->Level == ScopeLevel) { + ScopeId->Level = 0; + } +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_ADDR_6TO4ELIGIBLE( + IN CONST IN_ADDR *a) +{ + return (BOOLEAN)((Ipv4AddressType((CONST UCHAR *) a) == NlatUnicast) && + !(IN4_IS_ADDR_LOOPBACK(a) || + IN4_IS_ADDR_LINKLOCAL(a) || + IN4_IS_ADDR_SITELOCAL(a) || + IN4_IS_ADDR_RFC1918(a))); +} + +MSTCPIP_INLINE +BOOLEAN +IN4_IS_UNALIGNED_ADDR_6TO4ELIGIBLE( + IN CONST IN_ADDR UNALIGNED *a) +{ + IN_ADDR Ipv4Address = *a; + return IN4_IS_ADDR_6TO4ELIGIBLE(&Ipv4Address); +} + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2KSP1) */ + +#endif /* _WS2DEF_ */ + +#ifdef _WS2IPDEF_ + +MSTCPIP_INLINE +BOOLEAN +IN6_PREFIX_EQUAL( + IN CONST IN6_ADDR *a, + IN CONST IN6_ADDR *b, + IN UINT8 len) +{ + UINT8 Bytes = len / 8; + UINT8 Bits = len % 8; + UINT8 Mask = 0xff << (8 - Bits); + + ASSERT(len <= (sizeof(IN6_ADDR) * 8)); + return (BOOLEAN) (((memcmp(a, b, Bytes)) == 0) && ((Bits == 0) || + ((a->s6_bytes[Bytes] | Mask) == (b->s6_bytes[Bytes] | Mask)))); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_ALLNODESONNODE( + IN CONST IN6_ADDR *a) +{ + return IN6_ADDR_EQUAL(a, &in6addr_allnodesonnode); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_ALLNODESONLINK( + IN CONST IN6_ADDR *a) +{ + return IN6_ADDR_EQUAL(a, &in6addr_allnodesonlink); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_ALLROUTERSONLINK( + IN CONST IN6_ADDR *a) +{ + return IN6_ADDR_EQUAL(a, &in6addr_allroutersonlink); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_SOLICITEDNODE( + IN CONST IN6_ADDR *a) +{ + return IN6_PREFIX_EQUAL(a, &in6addr_solicitednodemulticastprefix, + IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_ISATAP( + IN CONST IN6_ADDR *a) +{ + return (BOOLEAN)(((a->s6_words[4] & 0xfffd) == 0x0000) && + (a->s6_words[5] == 0xfe5e)); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_6TO4( + IN CONST IN6_ADDR *a) +{ + C_ASSERT(IN6ADDR_6TO4PREFIX_LENGTH == RTL_BITS_OF(USHORT)); + return (BOOLEAN)(a->s6_words[0] == in6addr_6to4prefix.s6_words[0]); +} + +MSTCPIP_INLINE +BOOLEAN +IN6_IS_ADDR_TEREDO( + IN CONST IN6_ADDR *a) +{ + C_ASSERT(IN6ADDR_TEREDOPREFIX_LENGTH == 2 * RTL_BITS_OF(USHORT)); + return (BOOLEAN) + (((a->s6_words[0] == in6addr_teredoprefix.s6_words[0]) && + (a->s6_words[1] == in6addr_teredoprefix.s6_words[1])) || + ((a->s6_words[0] == in6addr_teredoprefix_old.s6_words[0]) && + (a->s6_words[1] == in6addr_teredoprefix_old.s6_words[1]))); +} + +MSTCPIP_INLINE +BOOLEAN +IN6ADDR_ISV4MAPPED( + IN CONST SOCKADDR_IN6 *a) +{ + ASSERT(a->sin6_family == AF_INET6); + return IN6_IS_ADDR_V4MAPPED(&a->sin6_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN6ADDR_ISISATAP( + IN CONST SOCKADDR_IN6 *a) +{ + ASSERT(a->sin6_family == AF_INET6); + return IN6_IS_ADDR_ISATAP(&a->sin6_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN6ADDR_IS6TO4( + IN CONST SOCKADDR_IN6 *a) +{ + ASSERT(a->sin6_family == AF_INET6); + return IN6_IS_ADDR_6TO4(&a->sin6_addr); +} + +MSTCPIP_INLINE +BOOLEAN +IN6ADDR_ISTEREDO( + IN CONST SOCKADDR_IN6 *a) +{ + ASSERT(a->sin6_family == AF_INET6); + return IN6_IS_ADDR_TEREDO(&a->sin6_addr); +} + +MSTCPIP_INLINE +CONST UCHAR* +IN6_GET_ADDR_V4MAPPED( + IN CONST IN6_ADDR *Ipv6Address) +{ + return (CONST UCHAR *) (Ipv6Address->s6_words + 6); +} + +MSTCPIP_INLINE +CONST UCHAR* +IN6_GET_ADDR_V4COMPAT( + IN CONST IN6_ADDR *Ipv6Address) +{ + return (CONST UCHAR *) (Ipv6Address->s6_words + 6); +} + +MSTCPIP_INLINE +CONST UCHAR* +IN6_EXTRACT_V4ADDR_FROM_ISATAP( + IN CONST IN6_ADDR *Ipv6Address) +{ + return (CONST UCHAR *) (Ipv6Address->s6_words + 6); +} + +MSTCPIP_INLINE +CONST UCHAR* +IN6_EXTRACT_V4ADDR_FROM_6TO4( + IN CONST IN6_ADDR *Ipv6Address) +{ + return (CONST UCHAR *) (Ipv6Address->s6_words + 1); +} + +MSTCPIP_INLINE +VOID +IN6_SET_ADDR_V4MAPPED( + OUT PIN6_ADDR a6, + IN CONST IN_ADDR* a4) +{ + *a6 = in6addr_v4mappedprefix; + a6->s6_bytes[12] = ((CONST UCHAR *) a4)[0]; + a6->s6_bytes[13] = ((CONST UCHAR *) a4)[1]; + a6->s6_bytes[14] = ((CONST UCHAR *) a4)[2]; + a6->s6_bytes[15] = ((CONST UCHAR *) a4)[3]; +} + +MSTCPIP_INLINE +VOID +IN6_SET_ADDR_V4COMPAT( + OUT PIN6_ADDR a6, + IN CONST IN_ADDR* a4) +{ + *a6 = in6addr_any; + a6->s6_bytes[12] = ((CONST UCHAR *) a4)[0]; + a6->s6_bytes[13] = ((CONST UCHAR *) a4)[1]; + a6->s6_bytes[14] = ((CONST UCHAR *) a4)[2]; + a6->s6_bytes[15] = ((CONST UCHAR *) a4)[3]; +} + +MSTCPIP_INLINE +VOID +IN6_SET_ADDR_SOLICITEDNODE( + OUT PIN6_ADDR Multicast, + IN CONST IN6_ADDR *Unicast) +{ + *Multicast = in6addr_solicitednodemulticastprefix; + Multicast->s6_bytes[13] = Unicast->s6_bytes[13]; + Multicast->s6_bytes[14] = Unicast->s6_bytes[14]; + Multicast->s6_bytes[15] = Unicast->s6_bytes[15]; +} + +MSTCPIP_INLINE +VOID +IN6_SET_ISATAP_IDENTIFIER( + IN OUT IN6_ADDR *Ipv6Address, + IN CONST IN_ADDR *Ipv4Address) +{ + if (IN4_IS_ADDR_6TO4ELIGIBLE(Ipv4Address)) { + Ipv6Address->s6_words[4] = 0x0002; + } else { + Ipv6Address->s6_words[4] = 0x0000; + } + Ipv6Address->s6_words[5] = 0xFE5E; + *((UNALIGNED IN_ADDR *) (Ipv6Address->s6_words + 6)) = *Ipv4Address; +} + +MSTCPIP_INLINE +VOID +IN6_SET_6TO4_PREFIX( + IN OUT IN6_ADDR *Ipv6Address, + IN CONST IN_ADDR *Ipv4Address) +{ + Ipv6Address->s6_words[0] = 0x0220; + *((UNALIGNED IN_ADDR *) (Ipv6Address->s6_words + 1)) = *Ipv4Address; + Ipv6Address->s6_words[3] = 0x0000; +} + +MSTCPIP_INLINE +SCOPE_LEVEL +Ipv6UnicastAddressScope( + IN CONST UCHAR *Address) +{ + IN6_ADDR Ipv6Address; + + if (!INET_IS_ALIGNED(Address, IN6_ADDR)) { + Ipv6Address = *(CONST IN6_ADDR UNALIGNED *)Address; + Address = (CONST UCHAR *) &Ipv6Address; + } + if (IN6_IS_ADDR_LINKLOCAL((PIN6_ADDR) Address) || + IN6_IS_ADDR_LOOPBACK((PIN6_ADDR) Address)) { + return ScopeLevelLink; + } else if (IN6_IS_ADDR_SITELOCAL((PIN6_ADDR) Address)) { + return ScopeLevelSite; + } else { + return ScopeLevelGlobal; + } +} + +MSTCPIP_INLINE +SCOPE_LEVEL +IN6_MULTICAST_SCOPE( + IN CONST UCHAR *Address) +{ + PIN6_ADDR Ipv6Address = (PIN6_ADDR) Address; + return (SCOPE_LEVEL)(Ipv6Address->s6_bytes[1] & 0xf); +} + +MSTCPIP_INLINE +SCOPE_LEVEL +Ipv6AddressScope( + IN CONST UCHAR *Address) +{ + if (IN6_IS_ADDR_MULTICAST((CONST IN6_ADDR *) Address)) { + return IN6_MULTICAST_SCOPE(Address); + } else { + return Ipv6UnicastAddressScope(Address); + } +} + +MSTCPIP_INLINE +NL_ADDRESS_TYPE +Ipv6AddressType( + IN CONST UCHAR *Address) +{ + CONST IN6_ADDR *Ipv6Address = (CONST IN6_ADDR *) Address; + CONST UCHAR *Ipv4Address; + + if (IN6_IS_ADDR_MULTICAST(Ipv6Address)) { + return NlatMulticast; + } + if (IN6_IS_ADDR_UNSPECIFIED(Ipv6Address)) { + return NlatUnspecified; + } + if (IN6_IS_ADDR_ISATAP(Ipv6Address) || IN6_IS_ADDR_V4COMPAT(Ipv6Address) || + IN6_IS_ADDR_V4MAPPED(Ipv6Address) || IN6_IS_ADDR_V4TRANSLATED(Ipv6Address)) { + Ipv4Address = IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address); + } else if (IN6_IS_ADDR_6TO4(Ipv6Address)) { + Ipv4Address = IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address); + } else { + return NlatUnicast; + } + if (Ipv4AddressType(Ipv4Address) != NlatUnicast) { + return NlatInvalid; + } + return NlatUnicast; +} + +MSTCPIP_INLINE +VOID +IN6_UNCANONICALIZE_SCOPE_ID( + IN CONST IN6_ADDR *Address, + IN OUT SCOPE_ID *ScopeId) +{ + SCOPE_LEVEL ScopeLevel = Ipv6AddressScope((CONST UCHAR *)Address); + + if ((IN6_IS_ADDR_LOOPBACK(Address)) || (ScopeLevel == ScopeLevelGlobal)) { + ScopeId->Value = 0; + } + if ((SCOPE_LEVEL)ScopeId->Level == ScopeLevel) { + ScopeId->Level = 0; + } +} + +#if (NTDDI_VERSION >= NTDDI_VISTA) + +MSTCPIP_INLINE +VOID +IN6ADDR_SETSOCKADDR( + OUT PSOCKADDR_IN6 a, + IN CONST IN6_ADDR *addr, + IN SCOPE_ID scope, + IN USHORT port) +{ + a->sin6_family = AF_INET6; + a->sin6_port = port; + a->sin6_flowinfo = 0; + RtlCopyMemory(&a->sin6_addr, addr, sizeof(IN6_ADDR)); + a->sin6_scope_struct = scope; + IN6_UNCANONICALIZE_SCOPE_ID(&a->sin6_addr, &a->sin6_scope_struct); +} + +MSTCPIP_INLINE +VOID +IN6ADDR_SETV4MAPPED( + OUT PSOCKADDR_IN6 a6, + IN CONST IN_ADDR* a4, + IN SCOPE_ID scope, + IN USHORT port) +{ + a6->sin6_family = AF_INET6; + a6->sin6_port = port; + a6->sin6_flowinfo = 0; + IN6_SET_ADDR_V4MAPPED(&a6->sin6_addr, a4); + a6->sin6_scope_struct = scope; + IN4_UNCANONICALIZE_SCOPE_ID(a4, &a6->sin6_scope_struct); +} + +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + +MSTCPIP_INLINE +BOOLEAN +INET_ADDR_EQUAL( + IN ADDRESS_FAMILY af, + IN CONST VOID* a, + IN CONST VOID* b) +{ + if (af == AF_INET6) { + return IN6_ADDR_EQUAL((CONST IN6_ADDR*)a, (CONST IN6_ADDR*)b); + } else { + ASSERT(af == AF_INET); + return IN4_ADDR_EQUAL((CONST IN_ADDR*)a, (CONST IN_ADDR*)b); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_UNALIGNED_ADDR_EQUAL( + IN ADDRESS_FAMILY af, + IN CONST VOID* a, + IN CONST VOID* b) +{ + if (af == AF_INET6) { + return IN6_ADDR_EQUAL((CONST IN6_ADDR*)a, (CONST IN6_ADDR*)b); + } else { + ASSERT(af == AF_INET); + return IN4_UNALIGNED_ADDR_EQUAL((CONST IN_ADDR*)a, (CONST IN_ADDR*)b); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_IS_ADDR_UNSPECIFIED( + IN ADDRESS_FAMILY af, + IN CONST VOID* a) +{ + if (af == AF_INET6) { + return IN6_IS_ADDR_UNSPECIFIED((CONST IN6_ADDR*)a); + } else { + ASSERT(af == AF_INET); + return IN4_IS_ADDR_UNSPECIFIED((CONST IN_ADDR*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_IS_UNALIGNED_ADDR_UNSPECIFIED( + IN ADDRESS_FAMILY af, + IN CONST VOID* a) +{ + if (af == AF_INET6) { + return IN6_IS_ADDR_UNSPECIFIED((CONST IN6_ADDR*)a); + } else { + ASSERT(af == AF_INET); + return IN4_IS_UNALIGNED_ADDR_UNSPECIFIED((CONST IN_ADDR UNALIGNED*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_IS_ADDR_LOOPBACK( + IN ADDRESS_FAMILY af, + IN CONST VOID* a) +{ + if (af == AF_INET6) { + return IN6_IS_ADDR_LOOPBACK((CONST IN6_ADDR*)a); + } else { + ASSERT(af == AF_INET); + return IN4_IS_ADDR_LOOPBACK((CONST IN_ADDR*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_IS_ADDR_BROADCAST( + IN ADDRESS_FAMILY af, + IN CONST VOID* a) +{ + if (af == AF_INET6) { + return FALSE; + } else { + ASSERT(af == AF_INET); + return IN4_IS_ADDR_BROADCAST((CONST IN_ADDR*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INET_IS_ADDR_MULTICAST( + IN ADDRESS_FAMILY af, + IN CONST VOID* a) +{ + if (af == AF_INET6) { + return IN6_IS_ADDR_MULTICAST((CONST IN6_ADDR*)a); + } else { + ASSERT(af == AF_INET); + return IN4_IS_ADDR_MULTICAST((CONST IN_ADDR*)a); + } +} + +MSTCPIP_INLINE +CONST UCHAR* +INET_ADDR_UNSPECIFIED( + IN ADDRESS_FAMILY af) +{ + if (af == AF_INET6) { + return (CONST UCHAR*)&in6addr_any; + } else { + ASSERT(af == AF_INET); + return (CONST UCHAR*)&in4addr_any; + } +} + +MSTCPIP_INLINE +VOID +INET_SET_ADDRESS( + IN ADDRESS_FAMILY Family, + OUT PUCHAR Address, + IN CONST UCHAR *Value) +{ + if (Family == AF_INET6) { + *((PIN6_ADDR)Address) = *((PIN6_ADDR)Value); + } else { + ASSERT(Family == AF_INET); + *((PIN_ADDR)Address) = *((PIN_ADDR)Value); + } +} + +MSTCPIP_INLINE +SIZE_T +INET_ADDR_LENGTH( + IN ADDRESS_FAMILY af) +{ + if (af == AF_INET6) { + return sizeof(IN6_ADDR); + } else { + ASSERT(af == AF_INET); + return sizeof(IN_ADDR); + } +} + +MSTCPIP_INLINE +SIZE_T +INET_SOCKADDR_LENGTH( + IN ADDRESS_FAMILY af) +{ + if (af == AF_INET6) { + return sizeof(SOCKADDR_IN6); + } else { + ASSERT(af == AF_INET); + return sizeof(SOCKADDR_IN); + } +} + +#if (NTDDI_VERSION >= NTDDI_VISTA) +MSTCPIP_INLINE +VOID +INETADDR_SETSOCKADDR( + IN ADDRESS_FAMILY af, + OUT PSOCKADDR a, + IN CONST VOID* addr, + IN SCOPE_ID scope, + IN USHORT port) +{ + if (af == AF_INET6) { + IN6ADDR_SETSOCKADDR((PSOCKADDR_IN6) a, (CONST IN6_ADDR *) addr, scope, port); + } else { + CONST IN_ADDR addr4 = *((IN_ADDR UNALIGNED *) addr); + ASSERT(af == AF_INET); + IN4ADDR_SETSOCKADDR((PSOCKADDR_IN) a, (CONST IN_ADDR *) &addr4, port); + } +} +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ + +MSTCPIP_INLINE +VOID +INETADDR_SETANY( + OUT PSOCKADDR a) +{ + if (a->sa_family == AF_INET6) { + IN6ADDR_SETANY((PSOCKADDR_IN6)a); + } else { + ASSERT(a->sa_family == AF_INET); + IN4ADDR_SETANY((PSOCKADDR_IN)a); + } +} + +MSTCPIP_INLINE +VOID +INETADDR_SETLOOPBACK( + OUT PSOCKADDR a) +{ + if (a->sa_family == AF_INET6) { + IN6ADDR_SETLOOPBACK((PSOCKADDR_IN6)a); + } else { + ASSERT(a->sa_family == AF_INET); + IN4ADDR_SETLOOPBACK((PSOCKADDR_IN)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INETADDR_ISANY( + IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return IN6ADDR_ISANY((CONST SOCKADDR_IN6*)a); + } else { + ASSERT(a->sa_family == AF_INET); + return IN4ADDR_ISANY((CONST SOCKADDR_IN*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INETADDR_ISLOOPBACK( + IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return IN6ADDR_ISLOOPBACK((CONST SOCKADDR_IN6*)a); + } else { + ASSERT(a->sa_family == AF_INET); + return IN4ADDR_ISLOOPBACK((CONST SOCKADDR_IN*)a); + } +} + +MSTCPIP_INLINE +BOOLEAN +INETADDR_ISV4MAPPED(IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return IN6ADDR_ISV4MAPPED((CONST SOCKADDR_IN6*)a); + } else { + return FALSE; + } +} + +MSTCPIP_INLINE +BOOLEAN +NL_ADDR_EQUAL( + IN ADDRESS_FAMILY af, + IN SCOPE_ID sa, + IN CONST UCHAR* aa, + IN SCOPE_ID sb, + IN CONST UCHAR* ab) +{ + return (BOOLEAN)((sa.Value == sb.Value) && INET_ADDR_EQUAL(af, aa, ab)); +} + +MSTCPIP_INLINE +BOOLEAN +NL_IS_ADDR_UNSPECIFIED( + IN ADDRESS_FAMILY af, + IN SCOPE_ID s, + IN CONST UCHAR* a) +{ + return (BOOLEAN)((s.Value == 0) && INET_IS_ADDR_UNSPECIFIED(af, a)); +} + +MSTCPIP_INLINE +BOOLEAN +INETADDR_ISEQUAL( + IN CONST SOCKADDR *a, + IN CONST SOCKADDR *b) +{ + if (a->sa_family == AF_INET6) { + return (BOOLEAN) (b->sa_family == AF_INET6 && + IN6ADDR_ISEQUAL((CONST SOCKADDR_IN6*)a, (CONST SOCKADDR_IN6*)b)); + } else { + ASSERT(a->sa_family == AF_INET); + return (BOOLEAN) (b->sa_family == AF_INET && + IN4ADDR_ISEQUAL((CONST SOCKADDR_IN*)a, (CONST SOCKADDR_IN*)b)); + } +} + +MSTCPIP_INLINE +BOOLEAN +INETADDR_ISUNSPECIFIED( + IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return IN6ADDR_ISUNSPECIFIED((CONST SOCKADDR_IN6*)a); + } else { + ASSERT(a->sa_family == AF_INET); + return IN4ADDR_ISUNSPECIFIED((CONST SOCKADDR_IN*)a); + } +} + +#if (NTDDI_VERSION >= NTDDI_VISTA) +MSTCPIP_INLINE +SCOPE_ID +INETADDR_SCOPE_ID( + IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return ((CONST SOCKADDR_IN6*)a)->sin6_scope_struct; + } else { + ASSERT(a->sa_family == AF_INET); + return IN4ADDR_SCOPE_ID((CONST SOCKADDR_IN*)a); + } +} +#endif + +MSTCPIP_INLINE +USHORT +INETADDR_PORT( + IN CONST SOCKADDR *a) +{ + if (a->sa_family == AF_INET6) { + return ((CONST SOCKADDR_IN6*)a)->sin6_port; + } else { + ASSERT(a->sa_family == AF_INET); + return ((CONST SOCKADDR_IN*)a)->sin_port; + } +} + +MSTCPIP_INLINE +PUCHAR +INETADDR_ADDRESS( + IN CONST SOCKADDR* a) +{ + if (a->sa_family == AF_INET6) { + return (PUCHAR)&((PSOCKADDR_IN6)a)->sin6_addr; + } else { + ASSERT(a->sa_family == AF_INET); + return (PUCHAR)&((PSOCKADDR_IN)a)->sin_addr; + } +} + +MSTCPIP_INLINE +VOID +INETADDR_SET_PORT( + IN OUT PSOCKADDR a, + IN USHORT Port) +{ + SS_PORT(a) = Port; +} + +MSTCPIP_INLINE +VOID +INETADDR_SET_ADDRESS( + IN OUT PSOCKADDR a, + IN CONST UCHAR *Address) +{ + if (a->sa_family == AF_INET6) { + ((PSOCKADDR_IN6)a)->sin6_addr = *((CONST IN6_ADDR*)Address); + } else { + ASSERT(a->sa_family == AF_INET); + ((PSOCKADDR_IN)a)->sin_addr = *((CONST IN_ADDR*)Address); + } +} + +MSTCPIP_INLINE +VOID +INET_UNCANONICALIZE_SCOPE_ID( + IN ADDRESS_FAMILY AddressFamily, + IN CONST UCHAR *Address, + IN OUT SCOPE_ID *ScopeId) +{ + if (AddressFamily == AF_INET6) { + IN6_UNCANONICALIZE_SCOPE_ID((CONST IN6_ADDR*) Address, ScopeId); + } else { + IN4_UNCANONICALIZE_SCOPE_ID((CONST IN_ADDR*) Address, ScopeId); + } +} + +#endif /* _WS2IPDEF_ */ + +#ifndef __IP2STRING__ +#define __IP2STRING__ + +#if (NTDDI_VERSION >= NTDDI_VISTA) + +#ifdef _WS2DEF_ + +NTSYSAPI +PSTR +NTAPI +RtlIpv4AddressToStringA( + IN const struct in_addr *Addr, + OUT PSTR S); + +NTSYSAPI +LONG +NTAPI +RtlIpv4AddressToStringExA( + IN const struct in_addr *Address, + IN USHORT Port, + OUT PSTR AddressString, + IN OUT PULONG AddressStringLength); + +NTSYSAPI +PWSTR +NTAPI +RtlIpv4AddressToStringW( + IN const struct in_addr *Addr, + OUT PWSTR S); + +NTSYSAPI +LONG +NTAPI +RtlIpv4AddressToStringExW( + IN const struct in_addr *Address, + IN USHORT Port, + OUT PWSTR AddressString, + IN OUT PULONG AddressStringLength); + +NTSYSAPI +LONG +NTAPI +RtlIpv4StringToAddressA( + IN PCSTR S, + IN BOOLEAN Strict, + OUT PCSTR *Terminator, + OUT struct in_addr *Addr); + +NTSYSAPI +LONG +NTAPI +RtlIpv4StringToAddressExA( + IN PCSTR AddressString, + IN BOOLEAN Strict, + OUT struct in_addr *Address, + OUT PUSHORT Port); + +NTSYSAPI +LONG +NTAPI +RtlIpv4StringToAddressW( + IN PCWSTR S, + IN BOOLEAN Strict, + OUT LPCWSTR *Terminator, + OUT struct in_addr *Addr); + +NTSYSAPI +LONG +NTAPI +RtlIpv4StringToAddressExW( + IN PCWSTR AddressString, + IN BOOLEAN Strict, + OUT struct in_addr *Address, + OUT PUSHORT Port); + +#ifdef UNICODE +#define RtlIpv4AddressToString RtlIpv4AddressToStringW +#define RtlIpv4StringToAddress RtlIpv4StringToAddressW +#define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExW +#define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExW +#else +#define RtlIpv4AddressToString RtlIpv4AddressToStringA +#define RtlIpv4StringToAddress RtlIpv4StringToAddressA +#define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExA +#define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExA +#endif + +#endif /* _WS2DEF_ */ + +#ifdef _WS2IPDEF_ + +NTSYSAPI +PSTR +NTAPI +RtlIpv6AddressToStringA( + IN const struct in6_addr *Addr, + OUT PSTR S); + +NTSYSAPI +LONG +NTAPI +RtlIpv6AddressToStringExA( + IN const struct in6_addr *Address, + IN ULONG ScopeId, + IN USHORT Port, + OUT PSTR AddressString, + IN OUT PULONG AddressStringLength); + +NTSYSAPI +PWSTR +NTAPI +RtlIpv6AddressToStringW( + IN const struct in6_addr *Addr, + OUT PWSTR S); + +NTSYSAPI +LONG +NTAPI +RtlIpv6AddressToStringExW( + IN const struct in6_addr *Address, + IN ULONG ScopeId, + IN USHORT Port, + OUT PWSTR AddressString, + IN OUT PULONG AddressStringLength); + +NTSYSAPI +LONG +NTAPI +RtlIpv6StringToAddressA( + IN PCSTR S, + OUT PCSTR *Terminator, + OUT struct in6_addr *Addr); + +NTSYSAPI +LONG +NTAPI +RtlIpv6StringToAddressExA( + IN PCSTR AddressString, + OUT struct in6_addr *Address, + OUT PULONG ScopeId, + OUT PUSHORT Port); + +NTSYSAPI +LONG +NTAPI +RtlIpv6StringToAddressW( + IN PCWSTR S, + OUT PCWSTR *Terminator, + OUT struct in6_addr *Addr); + +NTSYSAPI +LONG +NTAPI +RtlIpv6StringToAddressExW( + IN PCWSTR AddressString, + OUT struct in6_addr *Address, + OUT PULONG ScopeId, + OUT PUSHORT Port); + +#ifdef UNICODE +#define RtlIpv6AddressToString RtlIpv6AddressToStringW +#define RtlIpv6StringToAddress RtlIpv6StringToAddressW +#define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExW +#define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExW +#else +#define RtlIpv6AddressToString RtlIpv6AddressToStringA +#define RtlIpv6StringToAddress RtlIpv6StringToAddressA +#define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExA +#define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExA +#endif + +#endif /* __WS2IPDEF__ */ + +#ifdef _WS2DEF_ + +union _DL_EUI48; +typedef union _DL_EUI48 DL_EUI48, *PDL_EUI48; + +NTSYSAPI +PSTR +NTAPI +RtlEthernetAddressToStringA( + IN const DL_EUI48 *Addr, + OUT PSTR S); + +NTSYSAPI +PWSTR +NTAPI +RtlEthernetAddressToStringW( + IN const DL_EUI48 *Addr, + OUT PWSTR S); + +NTSYSAPI +LONG +NTAPI +RtlEthernetStringToAddressA( + IN PCSTR S, + OUT PCSTR *Terminator, + OUT DL_EUI48 *Addr); + +NTSYSAPI +LONG +NTAPI +RtlEthernetStringToAddressW( + IN PCWSTR S, + OUT LPCWSTR *Terminator, + OUT DL_EUI48 *Addr); + +#ifdef UNICODE +#define RtlEthernetAddressToString RtlEthernetAddressToStringW +#define RtlEthernetStringToAddress RtlEthernetStringToAddressW +#else +#define RtlEthernetAddressToString RtlEthernetAddressToStringA +#define RtlEthernetStringToAddress RtlEthernetStringToAddressA +#endif + +#endif /* _WS2DEF_ */ + +#endif /* (NTDDI >= NTDDI_VISTA) */ + +#endif /* __IP2STRING__ */ + +#ifdef __cplusplus +} +#endif diff --git a/include/psdk/wsipv6ok.h b/include/psdk/wsipv6ok.h new file mode 100644 index 00000000000..b9950254e66 --- /dev/null +++ b/include/psdk/wsipv6ok.h @@ -0,0 +1,83 @@ +#pragma once + +#ifdef IPV6STRICT + +#include +#include + +#undef AF_INET +#define AF_INET AF_INET_IPV6INCOMPATIBLE +#undef PF_INET +#define PF_INET PF_INET_IPV6INCOMPATIBLE +#undef in_addr +#define in_addr in_addr_IPV6INCOMPATIBLE +#undef IN_ADDR +#define IN_ADDR IN_ADDR_IPV6INCOMPATIBLE +#undef PIN_ADDR +#define PIN_ADDR PIN_ADDR_IPV6INCOMPATIBLE +#undef LPIN_ADDR +#define LPIN_ADDR LPIN_ADDR_IPV6INCOMPATIBLE +#undef IPAddr +#define IPAddr IPAddr_IPV6INCOMPATIBLE +#undef sockaddr_in +#define sockaddr_in sockaddr_in_IPV6INCOMPATIBLE +#undef SOCKADDR_IN +#define SOCKADDR_IN SOCKADDR_IN_IPV6INCOMPATIBLE +#undef PSOCKADDR_IN +#define PSOCKADDR_IN PSOCKADDR_IN_IPV6INCOMPATIBLE +#undef LPSOCKADDR_IN +#define LPSOCKADDR_IN LPSOCKADDR_IN_IPV6INCOMPATIBLE +#undef INADDR_ANY +#define INADDR_ANY INADDR_ANY_IPV6INCOMPATIBLE +#undef INADDR_LOOPBACK +#define INADDR_LOOPBACK INADDR_LOOPBACK_IPV6INCOMPATIBLE +#undef IPPROTO_IP +#define IPPROTO_IP IPPROTO_IP_IPV6INCOMPATIBLE +#undef IP_MULTICAST_IF +#define IP_MULTICAST_IF IP_MULTICAST_IF_IPV6INCOMPATIBLE +#undef IP_MULTICAST_TTL +#define IP_MULTICAST_TTL IP_MULTICAST_TTL_IPV6INCOMPATIBLE +#undef IP_MULTICAST_LOOP +#define IP_MULTICAST_LOOP IP_MULTICAST_LOOP_IPV6INCOMPATIBLE +#undef IP_ADD_MEMBERSHIP +#define IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP_IPV6INCOMPATIBLE +#undef IP_DROP_MEMBERSHIP +#define IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP_IPV6INCOMPATIBLE +#undef ip_mreq +#define ip_mreq ip_mreq_IPV6INCOMPATIBLE +#undef gethostbyname +#define gethostbyname(a) gethostbyname_IPV6INCOMPATIBLE +#undef hostent +#define hostent hostent_IPV6INCOMPATIBLE +#undef HOSTENT +#define HOSTENT HOSTENT_IPV6INCOMPATIBLE +#undef PHOSTENT +#define PHOSTENT PHOSTENT_IPV6INCOMPATIBLE +#undef LPHOSTENT +#define LPHOSTENT LPHOSTENT_IPV6INCOMPATIBLE +#undef inet_addr +#define inet_addr(a) inet_addr_IPV6INCOMPATIBLE +#undef gethostbyaddr +#define gethostbyaddr(a,b,c) gethostbyaddr_IPV6INCOMPATIBLE +#undef inet_ntoa +#define inet_ntoa(a) inet_ntoa_IPV6INCOMPATIBLE +#undef IN_MULTICAST +#define IN_MULTICAST(a) IN_MULTICAST_IPV6INCOMPATIBLE +#undef IN_CLASSD +#define IN_CLASSD(a) IN_CLASSD_IPV6INCOMPATIBLE +#undef IP_TTL +#define IP_TTL IP_TTL_IPV6INCOMPATIBLE +#undef IN_CLASSA +#define IN_CLASSA(a) IN_CLASSA_IPV6INCOMPATIBLE +#undef IN_CLASSB +#define IN_CLASSB(a) IN_CLASSB_IPV6INCOMPATIBLE +#undef IN_CLASSC +#define IN_CLASSC(a) IN_CLASSC_IPV6INCOMPATIBLE +#undef INADDR_BROADCAST +#define INADDR_BROADCAST(a) INADDR_BROADCAST_IPV6INCOMPATIBLE +#undef WSAAsyncGetHostByAddr +#define WSAAsyncGetHostByAddr(a,b,c,d,e,f,g) WSAAsyncGetHostByAddr_IPV6INCOMPATIBLE +#undef WSAAsyncGetHostByName +#define WSAAsyncGetHostByName(a,b,c,d,e) WSAAsyncGetHostByName_IPV6INCOMPATIBLE + +#endif \ No newline at end of file diff --git a/include/psdk/wspiapi.h b/include/psdk/wspiapi.h new file mode 100644 index 00000000000..12c8ac4f2c4 --- /dev/null +++ b/include/psdk/wspiapi.h @@ -0,0 +1,564 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +#include +#include +#include +#include + +#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L + +#define _WSPIAPI_STRCPY_S strcpy_s +#define _WSPIAPI_STRCAT_S strcat_s +#define _WSPIAPI_STRNCPY_S strncpy_s +#define _WSPIAPI_SPRINTF_S_1 sprintf_s + +#else + +#define _WSPIAPI_STRCPY_S(_Dst, _Size, _Src) strcpy((_Dst), (_Src)) +#define _WSPIAPI_STRCAT_S(_Dst, _Size, _Src) strcat((_Dst), (_Src)) +#define _WSPIAPI_STRNCPY_S(_Dst, _Size, _Src, _Count) strncpy((_Dst), (_Src), (_Count)); (_Dst)[(_Size) - 1] = 0 +#define _WSPIAPI_SPRINTF_S_1(_Dst, _Size, _Format, _Arg1) sprintf((_Dst), (_Format), (_Arg1)) + +#endif /* #if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L */ + +#if !defined(_WSPIAPI_COUNTOF) + +#if !defined(__cplusplus) +#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#else +template +char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N]; +#define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array)) +#endif + +#endif /* !defined(_WSPIAPI_COUNTOF) */ + +#define WspiapiMalloc(tSize) calloc(1, (tSize)) +#define WspiapiFree(p) free(p) +#define WspiapiSwap(a, b, c) {(c) = (a); (a) = (b); (b) = (c);} +#define getaddrinfo WspiapiGetAddrInfo +#define getnameinfo WspiapiGetNameInfo +#define freeaddrinfo WspiapiFreeAddrInfo + +typedef int +(WINAPI *WSPIAPI_PGETADDRINFO)( + IN const char *nodename, + IN const char *servname, + IN const struct addrinfo *hints, + OUT struct addrinfo **res); + +typedef int +(WINAPI *WSPIAPI_PGETNAMEINFO)( + IN const struct sockaddr *sa, + IN socklen_t salen, + OUT char *host, + IN size_t hostlen, + OUT char *serv, + IN size_t servlen, + IN int flags); + +typedef void +(WINAPI *WSPIAPI_PFREEADDRINFO)( + IN struct addrinfo *ai); + +__inline +char * +WINAPI +WspiapiStrdup( + IN const char *pszString) +{ + char *pszMemory; + size_t cchMemory; + + if (!pszString) return(NULL); + cchMemory = strlen(pszString) + 1; + pszMemory = (char *) WspiapiMalloc(cchMemory); + if (!pszMemory) return(NULL); + _WSPIAPI_STRCPY_S(pszMemory, cchMemory, pszString); + return pszMemory; +} + +__inline +BOOL +WINAPI +WspiapiParseV4Address( + IN const char *pszAddress, + OUT PDWORD pdwAddress) +{ + DWORD dwAddress = 0; + const char *pcNext = NULL; + int iCount = 0; + + for (pcNext = pszAddress; *pcNext != '\0'; pcNext++) + if (*pcNext == '.') iCount++; + if (iCount != 3) return FALSE; + dwAddress = inet_addr(pszAddress); + if (dwAddress == INADDR_NONE) return FALSE; + *pdwAddress = dwAddress; + return TRUE; +} + +__inline +struct addrinfo * +WINAPI +WspiapiNewAddrInfo( + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + IN DWORD dwAddress) +{ + struct addrinfo *ptNew; + struct sockaddr_in *ptAddress; + + ptNew = (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo)); + if (!ptNew) return NULL; + ptAddress = (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in)); + if (!ptAddress) { + WspiapiFree(ptNew); + return NULL; + } + ptAddress->sin_family = AF_INET; + ptAddress->sin_port = wPort; + ptAddress->sin_addr.s_addr = dwAddress; + ptNew->ai_family = PF_INET; + ptNew->ai_socktype = iSocketType; + ptNew->ai_protocol = iProtocol; + ptNew->ai_addrlen = sizeof(struct sockaddr_in); + ptNew->ai_addr = (struct sockaddr *) ptAddress; + + return ptNew; +} + +__inline +int +WINAPI +WspiapiQueryDNS( + IN const char *pszNodeName, + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + OUT char pszAlias[NI_MAXHOST], + OUT struct addrinfo **pptResult) +{ + struct addrinfo **pptNext = pptResult; + struct hostent *ptHost = NULL; + char **ppAddresses; + + *pptNext = NULL; + pszAlias[0] = '\0'; + + ptHost = gethostbyname(pszNodeName); + if (ptHost) { + if ((ptHost->h_addrtype == AF_INET) && (ptHost->h_length == sizeof(struct in_addr))) { + for (ppAddresses = ptHost->h_addr_list; *ppAddresses != NULL; ppAddresses++) { + *pptNext = WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, ((struct in_addr *) *ppAddresses)->s_addr); + if (!*pptNext) return EAI_MEMORY; + pptNext = &((*pptNext)->ai_next); + } + } + _WSPIAPI_STRNCPY_S(pszAlias, NI_MAXHOST, ptHost->h_name, NI_MAXHOST - 1); + return 0; + } + switch (WSAGetLastError()) { + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSANO_RECOVERY: return EAI_FAIL; + case WSANO_DATA: return EAI_NODATA; + default: return EAI_NONAME; + } +} + +__inline +int +WINAPI +WspiapiLookupNode( + IN const char *pszNodeName, + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + IN BOOL bAI_CANONNAME, + OUT struct addrinfo **pptResult) +{ + int iError = 0; + int iAliasCount = 0; + char szFQDN1[NI_MAXHOST] = ""; + char szFQDN2[NI_MAXHOST] = ""; + char *pszName = szFQDN1; + char *pszAlias = szFQDN2; + char *pszScratch = NULL; + + _WSPIAPI_STRNCPY_S(pszName, NI_MAXHOST, pszNodeName, NI_MAXHOST - 1); + for (;;) { + iError = WspiapiQueryDNS(pszNodeName, iSocketType, iProtocol, wPort, pszAlias, pptResult); + if (iError) break; + if (*pptResult) break; + if ((!strlen(pszAlias)) || (!strcmp(pszName, pszAlias)) || (++iAliasCount == 16)) { + iError = EAI_FAIL; + break; + } + WspiapiSwap(pszName, pszAlias, pszScratch); + } + if (!iError && bAI_CANONNAME) { + (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias); + if (!(*pptResult)->ai_canonname) iError = EAI_MEMORY; + } + + return iError; +} + + + +__inline +int +WINAPI +WspiapiClone( + IN WORD wPort, + IN struct addrinfo *ptResult) +{ + struct addrinfo *ptNext = NULL; + struct addrinfo *ptNew = NULL; + + for (ptNext = ptResult; ptNext != NULL; ) { + ptNew = WspiapiNewAddrInfo(SOCK_DGRAM, ptNext->ai_protocol, wPort, + ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr); + if (!ptNew) break; + ptNew->ai_next = ptNext->ai_next; + ptNext->ai_next = ptNew; + ptNext = ptNew->ai_next; + } + if (ptNext != NULL) return EAI_MEMORY; + + return 0; +} + +__inline +void +WINAPI +WspiapiLegacyFreeAddrInfo( + IN struct addrinfo *ptHead) +{ + struct addrinfo *ptNext; + + for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead) { + if (ptNext->ai_canonname) WspiapiFree(ptNext->ai_canonname); + if (ptNext->ai_addr) WspiapiFree(ptNext->ai_addr); + ptHead = ptNext->ai_next; + WspiapiFree(ptNext); + } +} + +__inline +int +WINAPI +WspiapiLegacyGetAddrInfo( + IN const char *pszNodeName, + IN const char *pszServiceName, + IN const struct addrinfo *ptHints, + OUT struct addrinfo **pptResult) +{ + int iError = 0; + int iFlags = 0; + int iFamily = PF_UNSPEC; + int iSocketType = 0; + int iProtocol = 0; + WORD wPort = 0; + DWORD dwAddress = 0; + struct servent *ptService = NULL; + char *pc = NULL; + BOOL bClone = FALSE; + WORD wTcpPort = 0; + WORD wUdpPort = 0; + *pptResult = NULL; + + if ((!pszNodeName) && (!pszServiceName)) return EAI_NONAME; + if (ptHints) { + if ((ptHints->ai_addrlen != 0) || + (ptHints->ai_canonname != NULL) || + (ptHints->ai_addr != NULL) || + (ptHints->ai_next != NULL)) { + return EAI_FAIL; + } + iFlags = ptHints->ai_flags; + if ((iFlags & AI_CANONNAME) && !pszNodeName) return EAI_BADFLAGS; + iFamily = ptHints->ai_family; + if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET)) return EAI_FAMILY; + iSocketType = ptHints->ai_socktype; + if ((iSocketType != 0) && + (iSocketType != SOCK_STREAM) && + (iSocketType != SOCK_DGRAM) && + (iSocketType != SOCK_RAW)) + return EAI_SOCKTYPE; + iProtocol = ptHints->ai_protocol; + } + if (pszServiceName) { + wPort = (WORD) strtoul(pszServiceName, &pc, 10); + if (*pc == '\0') { + wPort = wTcpPort = wUdpPort = htons(wPort); + if (iSocketType == 0) { + bClone = TRUE; + iSocketType = SOCK_STREAM; + } + } + else { + if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM)) { + ptService = getservbyname(pszServiceName, "udp"); + if (ptService) wPort = wUdpPort = ptService->s_port; + } + if ((iSocketType == 0) || (iSocketType == SOCK_STREAM)) { + ptService = getservbyname(pszServiceName, "tcp"); + if (ptService) wPort = wTcpPort = ptService->s_port; + } + if (wPort == 0) return (iSocketType ? EAI_SERVICE : EAI_NONAME); + if (iSocketType == 0) { + iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM; + bClone = (wTcpPort && wUdpPort); + } + } + } + if ((!pszNodeName) || (WspiapiParseV4Address(pszNodeName, &dwAddress))) { + if (!pszNodeName) dwAddress = htonl((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK); + *pptResult = WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); + if (!(*pptResult)) iError = EAI_MEMORY; + if (!iError && pszNodeName) { + (*pptResult)->ai_flags |= AI_NUMERICHOST; + if (iFlags & AI_CANONNAME) { + (*pptResult)->ai_canonname = WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress))); + if (!(*pptResult)->ai_canonname) iError = EAI_MEMORY; + } + } + } + else if (iFlags & AI_NUMERICHOST) { + iError = EAI_NONAME; + } + else { + iError = WspiapiLookupNode(pszNodeName, iSocketType, + iProtocol, wPort, + (iFlags & AI_CANONNAME), + pptResult); + } + if (!iError && bClone) { + iError = WspiapiClone(wUdpPort, *pptResult); + } + if (iError) { + WspiapiLegacyFreeAddrInfo(*pptResult); + *pptResult = NULL; + } + + return (iError); +} + +__inline +int +WINAPI +WspiapiLegacyGetNameInfo( + IN const struct sockaddr *ptSocketAddress, + IN socklen_t tSocketLength, + OUT char *pszNodeName, + IN size_t tNodeLength, + OUT char *pszServiceName, + IN size_t tServiceLength, + IN int iFlags) +{ + struct servent *ptService; + WORD wPort; + char szBuffer[] = "65535"; + char *pszService = szBuffer; + struct hostent *ptHost; + struct in_addr tAddress; + char *pszNode = NULL; + char *pc = NULL; + + if ((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) return EAI_FAIL; + if (ptSocketAddress->sa_family != AF_INET) return EAI_FAMILY; + if (tSocketLength < sizeof(struct sockaddr_in)) return EAI_FAIL; + if (!(pszNodeName && tNodeLength) && !(pszServiceName && tServiceLength)) { + return EAI_NONAME; + } + if ((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) { + return EAI_BADFLAGS; + } + if (pszServiceName && tServiceLength) { + wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port; + if (iFlags & NI_NUMERICSERV) { + _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); + } + else { + ptService = getservbyport(wPort, (iFlags & NI_DGRAM) ? "udp" : NULL); + if (ptService && ptService->s_name) { + pszService = ptService->s_name; + } + else { + _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); + } + } + if (tServiceLength > strlen(pszService)) + _WSPIAPI_STRCPY_S(pszServiceName, tServiceLength, pszService); + else return EAI_FAIL; + } + if (pszNodeName && tNodeLength) { + tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr; + if (iFlags & NI_NUMERICHOST) { + pszNode = inet_ntoa(tAddress); + } + else { + ptHost = gethostbyaddr((char *) &tAddress, sizeof(struct in_addr), AF_INET); + if (ptHost && ptHost->h_name) { + pszNode = ptHost->h_name; + if ((iFlags & NI_NOFQDN) && ((pc = strchr(pszNode, '.')) != NULL)) *pc = '\0'; + } + else { + if (iFlags & NI_NAMEREQD) { + switch (WSAGetLastError()) { + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSANO_RECOVERY: return EAI_FAIL; + default: return EAI_NONAME; + } + } + else pszNode = inet_ntoa(tAddress); + } + } + if (tNodeLength > strlen(pszNode)) _WSPIAPI_STRCPY_S(pszNodeName, tNodeLength, pszNode); + else return EAI_FAIL; + } + + return 0; +} + +typedef struct { + char const *pszName; + FARPROC pfAddress; +} WSPIAPI_FUNCTION; + +#define WSPIAPI_FUNCTION_ARRAY { \ + "getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo, \ + "getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo, \ + "freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo, \ +} + +__inline +FARPROC +WINAPI +WspiapiLoad( + IN WORD wFunction) +{ + HMODULE hLibrary = NULL; + + static BOOL bInitialized = FALSE; + static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY; + static const int iNumGlobal = (sizeof(rgtGlobal) / sizeof(WSPIAPI_FUNCTION)); + WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY; + FARPROC fScratch = NULL; + int i = 0; + + if (bInitialized) return (rgtGlobal[wFunction].pfAddress); + for (;;) { + CHAR SystemDir[MAX_PATH + 1]; + CHAR Path[MAX_PATH + 8]; + if (GetSystemDirectoryA(SystemDir, MAX_PATH) == 0) break; + _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); + _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\ws2_32"); + hLibrary = LoadLibraryA(Path); + if (hLibrary != NULL) { + fScratch = GetProcAddress(hLibrary, "getaddrinfo"); + if (fScratch == NULL) { + FreeLibrary(hLibrary); + hLibrary = NULL; + } + } + if (hLibrary != NULL) break; + _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); + _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\wship6"); + hLibrary = LoadLibraryA(Path); + if (hLibrary != NULL) { + fScratch = GetProcAddress(hLibrary, "getaddrinfo"); + if (fScratch == NULL) { + FreeLibrary(hLibrary); + hLibrary = NULL; + } + } + break; + } + if (hLibrary != NULL) { + for (i = 0; i < iNumGlobal; i++) { + rgtLocal[i].pfAddress = GetProcAddress(hLibrary, rgtLocal[i].pszName); + if (rgtLocal[i].pfAddress == NULL) { + FreeLibrary(hLibrary); + hLibrary = NULL; + break; + } + } + if (hLibrary != NULL) { + for (i = 0; i < iNumGlobal; i++) + rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress; + } + } + bInitialized = TRUE; + + return (rgtGlobal[wFunction].pfAddress); +} + +__inline +int +WINAPI +WspiapiGetAddrInfo( + IN const char *nodename OPTIONAL, + IN const char *servname OPTIONAL, + IN const struct addrinfo *hints OPTIONAL, + OUT struct addrinfo **res) +{ + int iError; + static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL; + + if (!pfGetAddrInfo) pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0); + iError = (*pfGetAddrInfo)(nodename, servname, hints, res); + WSASetLastError(iError); + + return iError; +} + +__inline +int +WINAPI +WspiapiGetNameInfo( + IN const struct sockaddr *sa, + IN socklen_t salen, + OUT char *host, + IN size_t hostlen, + OUT char *serv, + IN size_t servlen, + IN int flags) +{ + int iError; + static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL; + + if (!pfGetNameInfo) pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1); + iError = (*pfGetNameInfo)(sa, salen, host, hostlen, serv, servlen, flags); + WSASetLastError(iError); + + return iError; +} + +__inline +void +WINAPI +WspiapiFreeAddrInfo( + IN struct addrinfo *ai) +{ + static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL; + + if (!pfFreeAddrInfo) pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2); + (*pfFreeAddrInfo)(ai); +} + +#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ + +#ifdef __cplusplus +} +#endif