33 #if ( defined( sun ) && OSVERSION > 4 )
44 #if defined( _MSC_VER ) && defined( _PREFAST_ )
45 #define OUT_STRING_OPT __out_bcount_z
47 #define OUT_STRING_OPT( size )
50 typedef void ( SOCKET_API *FREEADDRINFO )(
INOUT struct addrinfo *ai ) \
55 const struct addrinfo *hints,
56 OUT_PTR struct addrinfo **res );
57 typedef CHECK_RETVAL struct hostent
FAR * ( SOCKET_API *GETHOSTBYNAME )\
59 STDC_NONNULL_ARG( ( 1 ) );
65 OUT_STRING_OPT( servicelen )
char *service,
66 IN SIZE_TYPE servicelen,
int flags ) \
68 typedef
CHECK_RETVAL u_long ( SOCKET_API *HTONL )( u_long hostlong );
69 typedef
CHECK_RETVAL u_short ( SOCKET_API *HTONS )( u_short hostshort );
70 typedef
CHECK_RETVAL unsigned long ( SOCKET_API *INET_ADDR )\
72 STDC_NONNULL_ARG( ( 1 ) );
73 typedef
CHECK_RETVAL char FAR * ( SOCKET_API *INET_NTOA )( struct in_addr in );
74 typedef
CHECK_RETVAL u_long ( SOCKET_API *NTOHL )( u_long netlong );
75 typedef
CHECK_RETVAL u_short ( SOCKET_API *NTOHS )( u_short netshort );
76 typedef
int ( SOCKET_API *WSAGETLASTERROR )(
void );
78 static FREEADDRINFO pfreeaddrinfo = NULL;
79 static GETADDRINFO pgetaddrinfo = NULL;
80 static GETHOSTBYNAME pgethostbyname = NULL;
81 static GETNAMEINFO pgetnameinfo = NULL;
82 static HTONL phtonl = NULL;
83 static HTONS phtons = NULL;
84 static INET_ADDR pinet_addr = NULL;
85 static INET_NTOA pinet_ntoa = NULL;
86 static NTOHL pntohl = NULL;
87 static NTOHS pntohs = NULL;
88 static WSAGETLASTERROR pWSAGetLastError = NULL;
90 #define freeaddrinfo pfreeaddrinfo
91 #define getaddrinfo pgetaddrinfo
92 #define gethostbyname pgethostbyname
93 #define getnameinfo pgetnameinfo
96 #define inet_addr pinet_addr
97 #define inet_ntoa pinet_ntoa
100 #ifndef WSAGetLastError
103 #define WSAGetLastError pWSAGetLastError
104 #define DYNLOAD_WSAGETLASTERROR
108 static
int SOCKET_API my_getaddrinfo(
IN_STRING const char *nodename,
110 const struct addrinfo *hints,
111 OUT_PTR struct addrinfo **res );
113 static
void SOCKET_API my_freeaddrinfo(
IN struct addrinfo *ai );
115 static
int SOCKET_API my_getnameinfo(
IN_BUFFER( salen ) \
116 const struct sockaddr *sa,
119 IN SIZE_TYPE nodelen,
122 IN SIZE_TYPE servicelen,
IN int flags );
125 int initDNS(
const INSTANCE_HANDLE hTCP,
const INSTANCE_HANDLE hAddr )
128 gethostbyname = ( GETHOSTBYNAME ) DynamicBind( hTCP,
TEXT(
"gethostbyname" ) );
129 htonl = ( HTONL ) DynamicBind( hTCP,
TEXT(
"htonl" ) );
130 htons = ( HTONS ) DynamicBind( hTCP,
TEXT(
"htons" ) );
131 inet_addr = ( INET_ADDR ) DynamicBind( hTCP,
TEXT(
"inet_addr" ) );
132 inet_ntoa = ( INET_NTOA ) DynamicBind( hTCP,
TEXT(
"inet_ntoa" ) );
133 ntohl = ( NTOHL ) DynamicBind( hTCP,
TEXT(
"ntohl" ) );
134 ntohs = ( NTOHS ) DynamicBind( hTCP,
TEXT(
"ntohs" ) );
135 #ifdef DYNLOAD_WSAGETLASTERROR
136 WSAGetLastError = ( WSAGETLASTERROR ) DynamicBind( hTCP,
TEXT(
"WSAGetLastError" ) );
138 if( gethostbyname == NULL || htonl == NULL || htons == NULL || \
139 inet_addr == NULL || inet_ntoa == NULL || ntohl == NULL || \
144 if( hAddr != NULL_INSTANCE )
146 freeaddrinfo = ( FREEADDRINFO ) DynamicBind( hAddr,
TEXT(
"freeaddrinfo" ) );
147 getaddrinfo = ( GETADDRINFO ) DynamicBind( hAddr,
TEXT(
"getaddrinfo" ) );
148 getnameinfo = ( GETNAMEINFO ) DynamicBind( hAddr,
TEXT(
"getnameinfo" ) );
149 if( freeaddrinfo == NULL || getaddrinfo == NULL || \
150 getnameinfo == NULL )
157 getaddrinfo = my_getaddrinfo;
158 freeaddrinfo = my_freeaddrinfo;
159 getnameinfo = my_getnameinfo;
164 ( void ) initDNSSRV( hTCP );
169 void endDNS(
const INSTANCE_HANDLE hTCP )
185 #if !defined( IPv6 ) || defined( __WINDOWS__ )
188 static
int addAddrInfo(
INOUT_OPT struct addrinfo *prevAddrInfoPtr,
189 OUT_PTR struct addrinfo **addrInfoPtrPtr,
190 IN_BUFFER( addrLen )
const void *address,
191 IN_RANGE( IP_ADDR_SIZE, IP_ADDR_SIZE ) \
192 const int addrLen,
IN_PORT const int port )
194 struct addrinfo *addrInfoPtr;
195 struct sockaddr_in *sockAddrPtr;
197 assert( prevAddrInfoPtr == NULL || \
198 isWritePtr( prevAddrInfoPtr,
sizeof(
struct addrinfo ) ) );
199 assert(
isWritePtr( addrInfoPtrPtr,
sizeof(
struct addrinfo * ) ) );
202 REQUIRES( addrLen == IP_ADDR_SIZE );
203 REQUIRES( port >= 22 && port < 65536L );
206 *addrInfoPtrPtr = NULL;
209 addrInfoPtr =
clAlloc(
"addAddrInfo",
sizeof(
struct addrinfo ) );
210 sockAddrPtr =
clAlloc(
"addAddrInfo",
sizeof(
struct sockaddr_in ) );
211 if( addrInfoPtr == NULL || sockAddrPtr == NULL )
213 if( addrInfoPtr != NULL )
214 clFree(
"addAddrInfo", addrInfoPtr );
215 if( sockAddrPtr != NULL )
216 clFree(
"addAddrInfo", sockAddrPtr );
219 memset( addrInfoPtr, 0,
sizeof(
struct addrinfo ) );
220 memset( sockAddrPtr, 0,
sizeof(
struct sockaddr_in ) );
221 if( prevAddrInfoPtr != NULL )
222 prevAddrInfoPtr->ai_next = addrInfoPtr;
223 addrInfoPtr->ai_family = PF_INET;
224 addrInfoPtr->ai_socktype = SOCK_STREAM;
225 addrInfoPtr->ai_protocol = IPPROTO_TCP;
226 addrInfoPtr->ai_addrlen =
sizeof(
struct sockaddr_in );
227 addrInfoPtr->ai_addr = (
struct sockaddr * ) sockAddrPtr;
233 sockAddrPtr->sin_family = AF_INET;
234 sockAddrPtr->sin_port = htons( ( in_port_t ) port );
235 memcpy( &sockAddrPtr->sin_addr, address, addrLen );
236 *addrInfoPtrPtr = addrInfoPtr;
241 static
int SOCKET_API my_getaddrinfo(
IN_STRING const char *nodename,
243 const struct addrinfo *hints,
244 OUT_PTR struct addrinfo **res )
246 struct hostent *pHostent;
247 struct addrinfo *currentAddrInfoPtr = NULL;
248 int port, hostErrno, i,
status;
249 gethostbyname_vars();
251 assert(
isReadPtr( hints,
sizeof(
struct addrinfo ) ) );
252 assert(
isWritePtr( res,
sizeof(
struct addrinfo * ) ) );
257 REQUIRES( nodename != NULL || ( hints->ai_flags & AI_PASSIVE ) );
267 if( ( nodename == NULL && !( hints->ai_flags & AI_PASSIVE ) ) || \
268 servname == NULL || hints == NULL || res == NULL )
272 status = strGetNumeric( servname, strlen( servname ), &port, 1, 65535 );
280 if( nodename == NULL && ( hints->ai_flags & AI_PASSIVE ) )
282 const in_addr_t address = INADDR_ANY;
284 return( addAddrInfo( NULL, res, &address,
sizeof( in_addr_t ),
292 if( isdigit( *nodename ) )
294 const in_addr_t address = inet_addr( nodename );
296 if( isBadAddress( address ) )
298 return( addAddrInfo( NULL, res, &address,
sizeof( in_addr_t ),
303 gethostbyname_threadsafe( nodename, pHostent, hostErrno );
304 if( pHostent == NULL )
306 ENSURES( pHostent->h_length == IP_ADDR_SIZE );
307 for( i = 0; i < IP_ADDR_COUNT && \
308 pHostent->h_addr_list[ i ] != NULL; i++ )
312 if( currentAddrInfoPtr == NULL )
314 status = addAddrInfo( NULL, res, pHostent->h_addr_list[ i ],
315 pHostent->h_length, port );
316 currentAddrInfoPtr = *res;
319 status = addAddrInfo( currentAddrInfoPtr, ¤tAddrInfoPtr,
320 pHostent->h_addr_list[ i ],
321 pHostent->h_length, port );
324 freeaddrinfo( *res );
332 static
void SOCKET_API my_freeaddrinfo(
INOUT struct addrinfo *ai )
336 assert(
isWritePtr( ai,
sizeof(
struct addrinfo ) ) );
345 for( i = 0; ai != NULL && i < IP_ADDR_COUNT; i++ )
347 struct addrinfo *addrInfoCursor = ai;
350 if( addrInfoCursor->ai_addr != NULL )
351 clFree(
"my_freeaddrinfo", addrInfoCursor->ai_addr );
352 clFree(
"my_freeaddrinfo", addrInfoCursor );
357 static
int SOCKET_API my_getnameinfo(
IN_BUFFER( salen ) \
358 const struct sockaddr *sa,
367 const struct sockaddr_in *sockAddr = (
struct sockaddr_in * ) sa;
368 const char *ipAddress;
370 assert(
isReadPtr( sa, salen ) && salen >=
sizeof(
struct sockaddr_in ) );
371 assert(
isReadPtr( node, nodelen ) && nodelen >= 10 );
372 assert(
isReadPtr( service, servicelen ) && servicelen >= 8 );
379 salen <
sizeof(
struct sockaddr_in ) || \
392 if( ( ipAddress = inet_ntoa( sockAddr->sin_addr ) ) == NULL )
394 memcpy( node, ipAddress, nodelen );
395 node[ nodelen - 1 ] =
'\0';
396 if(
sprintf_s( service, servicelen,
"%d",
397 ntohs( sockAddr->sin_port ) ) < 0 )
414 OUT_PTR struct addrinfo **addrInfoPtrPtr,
419 struct addrinfo hints;
420 char nameBuffer[
MAX_DNS_SIZE + 8 ], portBuffer[ 16 + 8 ];
423 assert(
isWritePtr( addrInfoPtrPtr,
sizeof(
struct addrinfo * ) ) );
424 assert( isServer || name != NULL );
426 REQUIRES( port >= 22 && port < 65536L );
428 ( !isServer && name != NULL ) );
429 REQUIRES( ( name == NULL && nameLen == 0 ) || \
444 memcpy( nameBuffer, name, nameLen );
452 if( !isServer && name != NULL && nameLen == 12 && \
453 ( !memcmp( name,
"[Autodetect]", 12 ) || *name ==
'_' ) )
457 status = findHostInfo( netStream, nameBuffer,
MAX_DNS_SIZE,
458 &localPort, name, nameLen );
462 sprintf_s( portBuffer, 8,
"%d", localPort );
469 bufferToEbcdic( nameBuffer, nameBuffer );
470 bufferToEbcdic( portBuffer, portBuffer );
517 memset( &hints, 0,
sizeof(
struct addrinfo ) );
518 hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
524 hints.ai_flags |= AI_PASSIVE;
527 hints.ai_family = PF_UNSPEC;
534 CRYPT_OPTION_PREFERIPV4 );
540 hints.ai_family = PF_INET;
546 hints.ai_family = PF_UNSPEC;
549 hints.ai_socktype = SOCK_STREAM;
550 if( getaddrinfo( name, portBuffer, &hints, addrInfoPtrPtr ) )
559 hints.ai_family = PF_UNSPEC;
560 if( getaddrinfo( name, portBuffer, &hints, addrInfoPtrPtr ) )
570 void freeAddressInfo(
struct addrinfo *addrInfoPtr )
572 assert(
isWritePtr( addrInfoPtr,
sizeof(
struct addrinfo ) ) );
574 freeaddrinfo( addrInfoPtr );
578 void getNameInfo(
IN_BUFFER( sockAddrLen )
const void *sockAddr,
580 OUT_BUFFER( addressMaxLen, *addressLen )
char *address,
586 char portBuffer[ 32 + 8 ];
587 int nameLength, portLength, localPort,
status;
589 assert(
isReadPtr( sockAddr, sockAddrLen ) );
590 assert(
isWritePtr( address, addressMaxLen ) );
593 REQUIRES_V( sockAddrLen >= 8 && sockAddrLen < MAX_INTLENGTH_SHORT );
598 memcpy( address,
"<Unknown>", 9 );
609 if( getnameinfo( sockAddr, sockAddrLen, nameBuffer,
MAX_DNS_SIZE,
610 portBuffer, 32, NI_NUMERICHOST | NI_NUMERICSERV ) != 0 )
612 DEBUG_DIAG((
"Couldn't get host name for socket" ));
616 nameLength = strlen( nameBuffer );
617 portLength = strlen( portBuffer );
618 if( nameLength <= 0 || nameLength > addressMaxLen || \
619 portLength <= 0 || portLength > 8 )
621 DEBUG_DIAG((
"Returned host name data is invalid" ));
626 ebcdicToAscii( nameBuffer, nameBuffer, nameLength );
627 ebcdicToAscii( portBuffer, portBuffer, portLength );
629 memcpy( address, nameBuffer, nameLength );
630 *addressLen = nameLength;
631 status = strGetNumeric( portBuffer, portLength, &localPort, 1, 65536 );
634 DEBUG_DIAG((
"Returned host port is invalid" ));