⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*						cryptlib TCP/IP Interface Routines					*
*						Copyright Peter Gutmann 1998-2007					*
*																			*
****************************************************************************/

#include <ctype.h>
#if defined( INC_ALL )
  #include "crypt.h"
  #include "stream_int.h"
  #include "tcp.h"
#else
  #include "crypt.h"
  #include "io/stream_int.h"
  #include "io/tcp.h"
#endif /* Compiler-specific includes */

#ifdef USE_TCP

/****************************************************************************
*																			*
*						 		Init/Shutdown Routines						*
*																			*
****************************************************************************/

/* Forward declarations for socket pool functions */

CHECK_RETVAL \
static int initSocketPool( void );
static void endSocketPool( void );

#ifdef __WINDOWS__

#ifndef TEXT
  #define TEXT		/* Win32 windows.h defines this, but not the Win16 one */
#endif /* TEXT */

/* Global function pointers.  These are necessary because the functions need
   to be dynamically linked since not all systems contain the necessary
   libraries */

static INSTANCE_HANDLE hTCP, hIPv6;

typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
		SOCKET ( SOCKET_API *ACCEPT )( IN SOCKET s, OUT struct sockaddr *addr,
									   INOUT int *addrlen );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
		int ( SOCKET_API *BIND )( IN SOCKET s, 
								  const struct sockaddr FAR *addr, 
								  IN_LENGTH_DNS int namelen );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
		int ( SOCKET_API *CONNECT )( IN SOCKET s, IN_BUFFER( namelen ) \
									 const struct sockaddr *name, 
									 IN_LENGTH_DNS int namelen );
typedef STDC_NONNULL_ARG( ( 4, 5 ) ) \
		int ( SOCKET_API *GETSOCKOPT )( IN SOCKET s, IN int level, 
										IN int optname, 
										OUT_BUFFER_FIXED( *optlen ) char *optval, 
										INOUT int FAR *optlen );
typedef CHECK_RETVAL \
		int ( SOCKET_API *LISTEN )( IN SOCKET s, IN int backlog );
typedef CHECK_RETVAL RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
		int ( SOCKET_API *RECV )( IN SOCKET s, 
								  OUT_BUFFER( len, return ) char *buf, 
								  IN_LENGTH int len, IN int flags );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 4, 5 ) ) \
		int ( SOCKET_API *SELECT )( IN int nfds, INOUT_OPT fd_set *readfds, 
									INOUT_OPT fd_set *writefds, 
									INOUT fd_set *exceptfds, 
									const struct timeval *timeout );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
		int ( SOCKET_API *SEND )( IN SOCKET s, 
								  IN_BUFFER( len ) const char *buf, 
								  IN_LENGTH int len, IN int flags );
typedef STDC_NONNULL_ARG( ( 4 ) ) \
		int ( SOCKET_API *SETSOCKOPT )( IN SOCKET s, IN int level, \
										IN int optname,
										IN_BUFFER( optlen ) char *optval, 
										IN int optlen );
typedef int ( SOCKET_API *SHUTDOWN )( IN SOCKET s, IN int how );
typedef CHECK_RETVAL \
		SOCKET ( SOCKET_API *SOCKETFN )( IN int af, IN int type, 
										 IN int protocol );
#ifdef __WINDOWS__
typedef int ( SOCKET_API *CLOSESOCKET )( IN SOCKET s );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
		int ( SOCKET_API *FDISSETFN )( IN SOCKET s, fd_set *fds );
typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
		int ( SOCKET_API *IOCTLSOCKET )( IN SOCKET s, IN long cmd, 
										 INOUT u_long FAR *argp );
typedef int ( SOCKET_API *WSACLEANUP )( void );
typedef CHECK_RETVAL \
		int ( SOCKET_API *WSAGETLASTERROR )( void );
typedef CHECK_RETVAL \
		int ( SOCKET_API *WSASTARTUP )( IN WORD wVersionRequested, 
										OUT LPWSADATA lpWSAData );
#endif /* __WINDOWS__ */
static ACCEPT paccept = NULL;
static BIND pbind = NULL;
static CONNECT pconnect = NULL;
static GETSOCKOPT pgetsockopt = NULL;
static LISTEN plisten = NULL;
static RECV precv = NULL;
static SELECT pselect = NULL;
static SEND psend = NULL;
static SETSOCKOPT psetsockopt = NULL;
static SHUTDOWN pshutdown = NULL;
static SOCKETFN psocket = NULL;
#ifdef __WINDOWS__
static CLOSESOCKET pclosesocket = NULL;
static FDISSETFN pFDISSETfn = NULL;
static IOCTLSOCKET pioctlsocket = NULL;
static WSACLEANUP pWSACleanup = NULL;
static WSAGETLASTERROR pWSAGetLastError = NULL;
static WSASTARTUP pWSAStartup = NULL;
#endif /* __WINDOWS__ */
#if ( defined( sun ) && OSVERSION > 4 )
  static int *h_errnoPtr;

  #undef getHostErrorCode
  #define getHostErrorCode()	*h_errnoPtr
#endif /* Slowaris */

#define accept				paccept
#define bind				pbind
#define connect				pconnect
#define getsockopt			pgetsockopt
#define listen				plisten
#define recv				precv
#define select				pselect
#define send				psend
#define setsockopt			psetsockopt
#define shutdown			pshutdown
#define socket				psocket
#ifdef __WINDOWS__
#define closesocket			pclosesocket
#define __WSAFDIsSet		pFDISSETfn
#define ioctlsocket			pioctlsocket
#define WSACleanup			pWSACleanup
#ifndef WSAGetLastError
  /* In some environments WSAGetLastError() is a macro that maps to
     GetLastError() */
  #define WSAGetLastError	pWSAGetLastError
  #define DYNLOAD_WSAGETLASTERROR
#endif /* WSAGetLastError */
#define WSAStartup			pWSAStartup
#endif /* __WINDOWS__ */

/* Dynamically load and unload any necessary TCP/IP libraries.  Under Windows
   the dynamic loading is complicated by the existence of Winsock 1 vs.
   Winsock 2, all recent systems use Winsock 2 but we allow for Winsock 1 as
   well just in case */

#ifdef __WINDOWS__
  #ifdef __WIN16__
	#define TCP_LIBNAME			"winsock.dll"
  #elif defined( __WIN32__ )
	#define TCP_LIBNAME			TEXT( "ws2_32.dll" )
	#define WINSOCK_OLD_LIBNAME	TEXT( "wsock32.dll" )
  #elif defined( __WINCE__ )
	#define TCP_LIBNAME			TEXT( "ws2.dll" )
  #else
	#error Unknown Windows variant encountered
  #endif /* Win16/Win32/WinCE */
#else
  #define TCP_LIBNAME			"libsocket.so"
  #define TEXT( x )				x
#endif /* OS-specific TCP/IP library naming */

RETVAL \
int netInitTCP( void )
	{
#ifdef __WINDOWS__
	WSADATA wsaData;
  #ifdef __WIN16__
	UINT errorMode;
  #endif /* __WIN16__ */
	BOOLEAN ip6inWinsock = FALSE;
	int status;
#endif /* __WINDOWS__ */

	/* Obtain a handle to the modules containing the TCP/IP functions */
#ifdef __WINDOWS__
	hTCP = hIPv6 = NULL_INSTANCE;
  #if defined( __WIN16__ )
	errorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX );
	hTCP = DynamicLoad( TCP_LIBNAME );
	SetErrorMode( errorMode );
	if( hTCP < HINSTANCE_ERROR )
		{
		hTCP = NULL_INSTANCE;
		return( CRYPT_ERROR );
		}
  #elif defined( __WIN32__ )
	if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE && \
		( hTCP = DynamicLoad( WINSOCK_OLD_LIBNAME ) ) == NULL_INSTANCE )
		return( CRYPT_ERROR );
	if( DynamicBind( hTCP, "getaddrinfo" ) != NULL )
		ip6inWinsock = TRUE;
	else
		{
		/* Newer releases of Windows put the IPv6 functions in the Winsock 2
		   library, older (non-IPv6-enabled) releases had it available as an
		   experimental add-on using the IPv6 Technology Preview library */
		hIPv6 = DynamicLoad( "wship6.dll" );
		}
  #elif defined( __WINCE__ )
	if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE )
		return( CRYPT_ERROR );
	if( DynamicBind( hTCP, TEXT( "getaddrinfo" ) ) != NULL )
		ip6inWinsock = TRUE;
  #endif /* Win16/Win32/WinCE */
#else
	if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE )
		return( CRYPT_ERROR );
#endif /* OS-specific dynamic load */

	/* Now get pointers to the functions */
	accept = ( ACCEPT ) DynamicBind( hTCP, TEXT( "accept" ) );
	bind = ( BIND ) DynamicBind( hTCP, TEXT( "bind" ) );
	connect = ( CONNECT ) DynamicBind( hTCP, TEXT( "connect" ) );
	getsockopt = ( GETSOCKOPT ) DynamicBind( hTCP, TEXT( "getsockopt" ) );
	listen = ( LISTEN ) DynamicBind( hTCP, TEXT( "listen" ) );
	recv = ( RECV ) DynamicBind( hTCP, TEXT( "recv" ) );
	select = ( SELECT ) DynamicBind( hTCP, TEXT( "select" ) );
	send = ( SEND ) DynamicBind( hTCP, TEXT( "send" ) );
	setsockopt = ( SETSOCKOPT ) DynamicBind( hTCP, TEXT( "setsockopt" ) );
	shutdown = ( SHUTDOWN ) DynamicBind( hTCP, TEXT( "shutdown" ) );
	socket = ( SOCKETFN ) DynamicBind( hTCP, TEXT( "socket" ) );
#ifdef __WINDOWS__
	closesocket = ( CLOSESOCKET ) DynamicBind( hTCP, TEXT( "closesocket" ) );
	__WSAFDIsSet = ( FDISSETFN ) DynamicBind( hTCP, TEXT( "__WSAFDIsSet" ) );
	ioctlsocket = ( IOCTLSOCKET ) DynamicBind( hTCP, TEXT( "ioctlsocket" ) );
	WSACleanup = ( WSACLEANUP ) DynamicBind( hTCP, TEXT( "WSACleanup" ) );
  #ifdef DYNLOAD_WSAGETLASTERROR
	WSAGetLastError = ( WSAGETLASTERROR ) DynamicBind( hTCP, TEXT( "WSAGetLastError" ) );
  #endif /* DYNLOAD_WSAGETLASTERROR */
	WSAStartup = ( WSASTARTUP ) DynamicBind( hTCP, TEXT( "WSAStartup" ) );
	if( ip6inWinsock || hIPv6 != NULL_INSTANCE )
		status = initDNS( hTCP, ip6inWinsock ? hTCP : hIPv6 );
	else
		status = initDNS( hTCP, NULL_INSTANCE );
	if( cryptStatusError( status ) )
		{
		if( hIPv6 != NULL_INSTANCE )
			{
			DynamicUnload( hIPv6 );
			hIPv6 = NULL_INSTANCE;
			}
		DynamicUnload( hTCP );
		hTCP = NULL_INSTANCE;
		return( CRYPT_ERROR );
		}
#endif /* __WINDOWS__ */
#if ( defined( sun ) && OSVERSION > 4 )
	h_errnoPtr = ( int * ) DynamicBind( hTCP, "h_errno" );
	if( h_errnoPtr == NULL )
		{
		DynamicUnload( hTCP );
		hTCP = NULL_INSTANCE;
		return( CRYPT_ERROR );
		}
#endif /* Slowaris */

	/* Make sure that we got valid pointers for every TCP/IP function */
	if( accept == NULL || bind == NULL || connect == NULL || \
		getsockopt == NULL || listen == NULL || recv == NULL || \
		select == NULL || send == NULL || setsockopt == NULL || \
		shutdown == NULL || socket == NULL )
		{
		endDNS( hTCP );
		DynamicUnload( hTCP );
		hTCP = NULL_INSTANCE;
		if( hIPv6 != NULL_INSTANCE )
			{
			DynamicUnload( hIPv6 );
			hIPv6 = NULL_INSTANCE;
			}
		return( CRYPT_ERROR );
		}

#ifdef __WINDOWS__
	if( closesocket == NULL || __WSAFDIsSet == NULL || \
		ioctlsocket == NULL || WSACleanup == NULL ||
  #ifdef DYNLOAD_WSAGETLASTERROR
		WSAGetLastError == NULL ||
  #endif /* DYNLOAD_WSAGETLASTERROR */
		WSAStartup == NULL || \
		( WSAStartup( 2, &wsaData ) && WSAStartup( 1, &wsaData ) ) )
		{
		endDNS( hTCP );
		DynamicUnload( hTCP );
		hTCP = NULL_INSTANCE;
		if( hIPv6 != NULL_INSTANCE )
			{
			DynamicUnload( hIPv6 );
			hIPv6 = NULL_INSTANCE;
			}
		return( CRYPT_ERROR );
		}
#endif /* __WINDOWS__ */

	/* Set up the socket pool state information */
	return( initSocketPool() );
	}

void netEndTCP( void )
	{
	/* Clean up the socket pool state information */
	endSocketPool();

	endDNS( hTCP );
	if( hIPv6 != NULL_INSTANCE )
		DynamicUnload( hIPv6 );
	if( hTCP != NULL_INSTANCE )
		{
#ifdef __WINDOWS__
		/* Wipe the Sheets Afterwards and Cleanup */
		WSACleanup();
#endif /* __WINDOWS__ */
		DynamicUnload( hTCP );
		}
	hTCP = hIPv6 = NULL_INSTANCE;
	}

/* Return the status of the network interface */

CHECK_RETVAL_BOOL \
static BOOLEAN transportOKFunction( void )
	{
	return( hTCP != NULL_INSTANCE ? TRUE : FALSE );
	}
#else

RETVAL \
int netInitTCP( void )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -