Retail products


Traffic interception SDK

Control every TCP/IP network connection

  • Route connections via proxy
  • Redirect connections and modify the data
  • Block connections and applications
SSL interception SDK

View SSL in plaintext and modify it

  • View the SSL stream decrypted in plaintext
  • Redirect SSL connection and modify decrypted data
  • Browser shows "SSL lock" without warnings

Documentation


lspdef.h File Reference

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ws2spi.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#include <lspcommon.h>

Include dependency graph for lspdef.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.


Classes

struct  _SOCKET_CONTEXT

Typedefs

typedef struct _SOCKET_CONTEXT SOCKET_CONTEXT

Functions

void FreeLspProviders (PROVIDER *lspProvider, int lspProviderCount, int *lpErrno)
void FindDestinationAddress (SOCKET_CONTEXT *context, const SOCKADDR *destAddr, int destLen, SOCKADDR **proxyAddr, int *proxyLen)
int WSPAPI WSPCloseSocket (SOCKET s, LPINT lpErrno)
int WSPAPI WSPConnect (SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
int WSPAPI WSPGetPeerName (SOCKET s, struct sockaddr FAR *name, LPINT namelen, LPINT lpErrno)
int WSPAPI WSPIoctl (SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
SOCKET WSPAPI WSPSocket (int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
SOCKET_CONTEXTFindSocketContext (SOCKET s, BOOL Remove=FALSE)
SOCKET_CONTEXTCreateSocketContext (PROVIDER *Provider, SOCKET Socket, int *lpErrno)
void FreeSocketContext (PROVIDER *Provider, SOCKET_CONTEXT *Context)
void FreeSocketContextList (PROVIDER *Provider)
BOOL PASCAL FAR ExtConnectEx (IN SOCKET s, IN const struct sockaddr FAR *name, IN int namelen, IN PVOID lpSendBuffer OPTIONAL, IN DWORD dwSendDataLength, OUT LPDWORD lpdwBytesSent, IN LPOVERLAPPED lpOverlapped)

Variables

CRITICAL_SECTION gCriticalSection
INT gLayerCount
PROVIDERgLayerInfo
WSPUPCALLTABLE gMainUpCallTable
GUID gProviderGuid

Typedef Documentation


Function Documentation

SOCKET_CONTEXT* CreateSocketContext ( PROVIDER Provider,
SOCKET  Socket,
int *  lpErrno 
)

Definition at line 94 of file sockinfo.cpp.

00099 {
00100     SOCKET_CONTEXT   *newContext = NULL;
00101 
00102     newContext = (SOCKET_CONTEXT *) LspAlloc(
00103             sizeof( SOCKET_CONTEXT ),
00104             lpErrno
00105             );
00106     if ( NULL == newContext )
00107     {
00108         dbgprint("CreateSocketContext: LspAlloc failed: %d", *lpErrno );
00109         goto cleanup;
00110     }
00111 
00112     newContext->Socket     = Socket;
00113     newContext->Provider   = Provider;
00114     newContext->Proxied    = FALSE;
00115 
00116     EnterCriticalSection( &Provider->ProviderCritSec );
00117 
00118     InsertHeadList( &Provider->SocketList, &newContext->Link );
00119 
00120     LeaveCriticalSection( &Provider->ProviderCritSec );
00121 
00122     return newContext;
00123 
00124 cleanup:
00125 
00126     return NULL;
00127 }

BOOL PASCAL FAR ExtConnectEx ( IN SOCKET  s,
IN const struct sockaddr FAR *  name,
IN int  namelen,
IN PVOID lpSendBuffer  OPTIONAL,
IN DWORD  dwSendDataLength,
OUT LPDWORD  lpdwBytesSent,
IN LPOVERLAPPED  lpOverlapped 
)

Definition at line 83 of file extension.cpp.

00092 {
00093     SOCKET_CONTEXT *sockContext = NULL;
00094     SOCKADDR       *proxyAddr = NULL;
00095     int             Errno = NO_ERROR,
00096                     proxyLen = 0,
00097                     rc = FALSE;
00098 
00099     sockContext = FindSocketContext( s );
00100     if ( NULL == sockContext )
00101     {
00102         dbgprint("ExtConnectEx: FindSocketContext failed!");
00103         Errno = WSAENOTSOCK;
00104         goto cleanup;
00105     }
00106 
00107     // Make sure we already have the extension function
00108     if ( NULL == sockContext->Provider->NextProcTableExt.lpfnConnectEx )
00109     {
00110         GUID    guidConnectEx = WSAID_CONNECTEX;
00111 
00112         rc = LoadExtensionFunction(
00113                 (FARPROC **)&sockContext->Provider->NextProcTableExt.lpfnConnectEx,
00114                 guidConnectEx,
00115                 sockContext->Provider->NextProcTable.lpWSPIoctl,
00116                 s
00117                 );
00118         if ( FALSE == rc )
00119         {
00120             dbgprint("Next proc table ConnectEx == NULL!");
00121             Errno = WSAEFAULT;
00122             goto cleanup;
00123         }
00124     }
00125 
00126     // See if the connect needs to be proxied
00127     FindDestinationAddress( sockContext, name, namelen, &proxyAddr, &proxyLen );
00128 
00129     rc = sockContext->Provider->NextProcTableExt.lpfnConnectEx(
00130             s,
00131             proxyAddr,
00132             proxyLen,
00133             lpSendBuffer,
00134             dwSendDataLength,
00135             lpdwBytesSent,
00136             lpOverlapped
00137             );
00138 
00139 cleanup:
00140 
00141     return rc;
00142 }

void FindDestinationAddress ( SOCKET_CONTEXT context,
const SOCKADDR *  destAddr,
int  destLen,
SOCKADDR **  proxyAddr,
int *  proxyLen 
)

Definition at line 1049 of file spi.cpp.

01056 {
01057     UNREFERENCED_PARAMETER( context );
01058     UNREFERENCED_PARAMETER( destLen );
01059     UNREFERENCED_PARAMETER( proxyAddr );
01060     UNREFERENCED_PARAMETER( proxyLen );
01061 
01062     context->AddressLength = destLen;
01063 
01064     // Save destination address
01065     memcpy( &context->OriginalAddress, destAddr, context->AddressLength );
01066 
01067     *proxyAddr = (SOCKADDR *) &context->OriginalAddress;
01068     *proxyLen  = context->AddressLength;
01069 
01070     if ( destAddr->sa_family == AF_INET )
01071     {
01072         // Redirect one destination to another
01073         if ( ( (SOCKADDR_IN *)destAddr )->sin_addr.s_addr == inet_addr("157.56.236.201") )
01074         {
01075             memcpy( &context->ProxiedAddress, destAddr, context->AddressLength );
01076             ( (SOCKADDR_IN *)&context->ProxiedAddress )->sin_addr.s_addr = inet_addr(
01077                     "157.56.237.9"
01078                     );
01079 
01080             *proxyAddr = (SOCKADDR *) &context->ProxiedAddress;
01081 
01082             context->Proxied = TRUE;
01083         }
01084     }
01085     else if ( destAddr->sa_family == AF_INET6 )
01086     {
01087         // Perform redirection here
01088     }
01089 }

SOCKET_CONTEXT* FindSocketContext ( SOCKET  s,
BOOL  Remove = FALSE 
)

Definition at line 32 of file sockinfo.cpp.

00036 {
00037     SOCKET_CONTEXT  *SocketContext = NULL,
00038                *info = NULL;
00039     LIST_ENTRY *lptr = NULL;
00040     int         i;
00041 
00042     EnterCriticalSection( &gCriticalSection );
00043 
00044     for(i=0; i < gLayerCount ;i++)
00045     {
00046         EnterCriticalSection( &gLayerInfo[ i ].ProviderCritSec );
00047 
00048         for(lptr = gLayerInfo[ i ].SocketList.Flink ;
00049             lptr != &gLayerInfo[ i ].SocketList ;
00050             lptr = lptr->Flink )
00051         {
00052             info = CONTAINING_RECORD( lptr, SOCKET_CONTEXT, Link );
00053 
00054             if ( s == info->Socket )
00055             {
00056                 SocketContext = info;
00057                 
00058                 if ( TRUE == Remove )
00059                 {
00060                     RemoveEntryList( &info->Link );
00061                 }
00062                 break;
00063             }
00064         }
00065 
00066         LeaveCriticalSection( &gLayerInfo[ i ].ProviderCritSec );
00067 
00068         if ( NULL != SocketContext )
00069             break;
00070     }
00071 
00072     LeaveCriticalSection( &gCriticalSection );
00073 
00074     return SocketContext;
00075 }

void FreeLspProviders ( PROVIDER lspProvider,
int  lspProviderCount,
int *  lpErrno 
)

Definition at line 1098 of file spi.cpp.

01103 {
01104     int     i;
01105 
01106     if ( NULL == lspProvider )
01107         return;
01108 
01109     // Need to iterate through the LSP providers and call WSPCleanup accordingly
01110     for(i=0; i < lspProviderCount ;i++)
01111     {
01112         while( 0 != lspProvider[ i ].StartupCount )
01113         {
01114             lspProvider[ i ].StartupCount--;
01115 
01116             lspProvider[ i ].NextProcTable.lpWSPCleanup( lpErrno );
01117         }
01118 
01119         if ( NULL != lspProvider[ i ].Module )
01120         {
01121             FreeLibrary( lspProvider[ i ].Module );
01122             lspProvider[ i ].Module = NULL;
01123         }
01124     }
01125 
01126     for(i=0; i < lspProviderCount ;i++)
01127     {
01128         FreeSocketContextList( &lspProvider[ i ] );
01129         
01130         DeleteCriticalSection( &lspProvider[ i ].ProviderCritSec );
01131     }
01132 
01133     LspFree( lspProvider );
01134 }

void FreeSocketContext ( PROVIDER Provider,
SOCKET_CONTEXT Context 
)

Definition at line 136 of file sockinfo.cpp.

00140 {
00141     EnterCriticalSection( &Provider->ProviderCritSec );
00142 
00143     RemoveEntryList( &Context->Link );
00144     LspFree( Context );
00145 
00146     LeaveCriticalSection( &Provider->ProviderCritSec );
00147 
00148     return;
00149 }

void FreeSocketContextList ( PROVIDER Provider  ) 

Definition at line 160 of file sockinfo.cpp.

00163 {
00164     LIST_ENTRY     *lptr = NULL;
00165     SOCKET_CONTEXT *context = NULL;
00166 
00167     ASSERT( provider );
00168 
00169     // Walk the list of sockets
00170     while ( !IsListEmpty( &provider->SocketList ) )
00171     {
00172         lptr = RemoveHeadList( &provider->SocketList );
00173 
00174         ASSERT( lptr );
00175 
00176         context = CONTAINING_RECORD( lptr, SOCKET_CONTEXT, Link );
00177 
00178         // Context is already removed so just free it
00179         LspFree( context );
00180     }
00181 
00182     return;
00183 }

int WSPAPI WSPCloseSocket ( SOCKET  s,
LPINT  lpErrno 
)

Definition at line 204 of file spi.cpp.

00208 {
00209     SOCKET_CONTEXT *sockContext = NULL;
00210     int             rc = SOCKET_ERROR;
00211 
00212     // Find the socket context and remove it from the provider's list of sockets
00213     sockContext = FindSocketContext( s, TRUE );
00214     if ( NULL == sockContext )
00215     {
00216         *lpErrno = WSAENOTSOCK;
00217         goto cleanup;
00218     }
00219 
00220     ASSERT( sockContext->Provider->NextProcTable.lpWSPCloseSocket );
00221 
00222     // Pass the socket down to close it
00223     rc = sockContext->Provider->NextProcTable.lpWSPCloseSocket(
00224             s,
00225             lpErrno
00226             );
00227 
00228     // Just free the structure as its alreayd removed from the provider's list
00229     LspFree( sockContext );
00230 
00231 cleanup:
00232 
00233     return rc;
00234 }

int WSPAPI WSPConnect ( SOCKET  s,
const struct sockaddr FAR *  name,
int  namelen,
LPWSABUF  lpCallerData,
LPWSABUF  lpCalleeData,
LPQOS  lpSQOS,
LPQOS  lpGQOS,
LPINT  lpErrno 
)

Definition at line 246 of file spi.cpp.

00256 {
00257     SOCKET_CONTEXT *sockContext = NULL;
00258     SOCKADDR       *proxyAddr = NULL;
00259     int             proxyLen = 0,
00260                     rc = SOCKET_ERROR;
00261 
00262     // Find the socket context
00263     sockContext = FindSocketContext( s );
00264     if ( NULL == sockContext )
00265     {
00266         *lpErrno = WSAENOTSOCK;
00267         goto cleanup;
00268     }
00269 
00270     ASSERT( sockContext->Provider->NextProcTable.lpWSPConnect );
00271 
00272     FindDestinationAddress( sockContext, name, namelen, &proxyAddr, &proxyLen );
00273 
00274     rc = sockContext->Provider->NextProcTable.lpWSPConnect(
00275             s,
00276             proxyAddr, 
00277             proxyLen, 
00278             lpCallerData, 
00279             lpCalleeData,
00280             lpSQOS, 
00281             lpGQOS, 
00282             lpErrno
00283             );
00284 
00285 cleanup:
00286 
00287     return rc;
00288 }

int WSPAPI WSPGetPeerName ( SOCKET  s,
struct sockaddr FAR *  name,
LPINT  namelen,
LPINT  lpErrno 
)

Definition at line 299 of file spi.cpp.

00305 {
00306     SOCKET_CONTEXT *sockContext = NULL;
00307     int             rc = SOCKET_ERROR;
00308 
00309     //
00310     // Find our provider socket corresponding to this one
00311     //
00312     sockContext = FindSocketContext( s );
00313     if ( NULL == sockContext )
00314     {
00315         *lpErrno = WSAENOTSOCK;
00316         goto cleanup;
00317     }
00318 
00319     // If the connection has been proxied, return the address the application
00320     //    originally tried to connect to.
00321     if ( TRUE == sockContext->Proxied )
00322     {
00323         __try
00324         {
00325             // Verify buffer is large enough for underlying address structure
00326             if ( *namelen < sockContext->AddressLength )
00327             {
00328                 *namelen = sockContext->AddressLength;
00329                 *lpErrno = WSAEFAULT;
00330                 goto cleanup;
00331             }
00332 
00333             memcpy( name, &sockContext->OriginalAddress, *namelen );
00334             *namelen = sockContext->AddressLength;
00335         } 
00336         __except( EXCEPTION_EXECUTE_HANDLER )
00337         {
00338             *lpErrno = WSAEFAULT;
00339             goto cleanup;
00340         }
00341 
00342         return NO_ERROR;
00343     }
00344 
00345     ASSERT( sockContext->Provider->NextProcTable.lpWSPGetPeerName );
00346 
00347     rc = sockContext->Provider->NextProcTable.lpWSPGetPeerName(
00348             s,
00349             name,
00350             namelen, 
00351             lpErrno
00352             );
00353 
00354 cleanup:
00355 
00356     return rc;
00357 }

int WSPAPI WSPIoctl ( SOCKET  s,
DWORD  dwIoControlCode,
LPVOID  lpvInBuffer,
DWORD  cbInBuffer,
LPVOID  lpvOutBuffer,
DWORD  cbOutBuffer,
LPDWORD  lpcbBytesReturned,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 478 of file spi.cpp.

00491 {
00492     SOCKET_CONTEXT *sockContext = NULL;
00493     GUID            ConnectExGuid = WSAID_CONNECTEX;
00494     int             rc = NO_ERROR;
00495 
00496     // If loading an extension function, check for ConnectEx
00497     if ( SIO_GET_EXTENSION_FUNCTION_POINTER == dwIoControlCode )
00498     {
00499         if ( 0 == memcmp( lpvInBuffer, &ConnectExGuid, sizeof( GUID ) ) )
00500         {
00501             // Return a pointer to our intermediate extension function
00502             __try 
00503             {
00504                 if ( cbOutBuffer < sizeof( LPFN_CONNECTEX ) )
00505                 {
00506                     *lpcbBytesReturned = sizeof( LPFN_CONNECTEX );
00507                     *lpErrno = WSAEFAULT;
00508                     rc = SOCKET_ERROR;
00509                     goto cleanup;
00510                 }
00511                 *lpcbBytesReturned = sizeof( LPFN_CONNECTEX );
00512                 *((DWORD_PTR *)lpvOutBuffer) = (DWORD_PTR) ExtConnectEx;
00513             }
00514             __except( EXCEPTION_EXECUTE_HANDLER )
00515             {
00516                 *lpErrno = WSAEFAULT;
00517                 rc = SOCKET_ERROR;
00518             }
00519             return rc;
00520         }
00521     }
00522 
00523     // Retrieve the socket context
00524     sockContext = FindSocketContext( s );
00525     if ( NULL == sockContext )
00526     {
00527         *lpErrno = WSAENOTSOCK;
00528         rc = SOCKET_ERROR;
00529         goto cleanup;
00530     }
00531 
00532     ASSERT( sockContext->Provider->NextProcTable.lpWSPIoctl );
00533 
00534     // Pass the call to the lower layer
00535     rc = sockContext->Provider->NextProcTable.lpWSPIoctl(
00536             s,
00537             dwIoControlCode, 
00538             lpvInBuffer,
00539             cbInBuffer, 
00540             lpvOutBuffer, 
00541             cbOutBuffer, 
00542             lpcbBytesReturned, 
00543             lpOverlapped, 
00544             lpCompletionRoutine, 
00545             lpThreadId, 
00546             lpErrno
00547             );
00548 
00549 cleanup:
00550 
00551     return rc;
00552 }

SOCKET WSPAPI WSPSocket ( int  af,
int  type,
int  protocol,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
GROUP  g,
DWORD  dwFlags,
LPINT  lpErrno 
)

Definition at line 665 of file spi.cpp.

00674 {
00675     WSAPROTOCOL_INFOW   InfoCopy = {0};
00676     SOCKET_CONTEXT     *sockContext = NULL;
00677     PROVIDER           *lowerProvider = NULL;
00678     SOCKET              nextProviderSocket = INVALID_SOCKET,
00679                         sret = INVALID_SOCKET;
00680     int                 rc;
00681 
00682     // Find the LSP entry which matches the given provider info
00683     lowerProvider = FindMatchingLspEntryForProtocolInfo(
00684             lpProtocolInfo,
00685             gLayerInfo,
00686             gLayerCount
00687             );
00688     if ( NULL == lowerProvider )
00689     {
00690         dbgprint("WSPSocket: FindMatchingLspEntryForProtocolInfo failed!" );
00691         goto cleanup;
00692     }
00693 
00694     if ( 0 == lowerProvider->StartupCount ) 
00695     {
00696         rc = InitializeProvider( lowerProvider, MAKEWORD(2,2), lpProtocolInfo, 
00697                gMainUpCallTable, lpErrno );
00698         if ( SOCKET_ERROR == rc )
00699         {
00700             dbgprint("WSPSocket: InitializeProvider failed: %d", *lpErrno);
00701             goto cleanup;
00702         }
00703     }
00704 
00705     // If the next layer is a base, substitute the provider structure with the
00706     //    base provider's
00707     if ( BASE_PROTOCOL == lowerProvider->NextProvider.ProtocolChain.ChainLen )
00708     {
00709         memcpy( &InfoCopy, &lowerProvider->NextProvider, sizeof( InfoCopy ) );
00710         InfoCopy.dwProviderReserved = lpProtocolInfo->dwProviderReserved;
00711         lpProtocolInfo = &InfoCopy;
00712     }
00713 
00714     ASSERT( lowerProvider->NextProcTable.lpWSPSocket );
00715 
00716     //
00717     // Create the socket from the lower layer
00718     //
00719     nextProviderSocket = lowerProvider->NextProcTable.lpWSPSocket(
00720             af, 
00721             type, 
00722             protocol, 
00723             lpProtocolInfo,
00724             g, 
00725             dwFlags,
00726             lpErrno
00727             );
00728     if ( INVALID_SOCKET == nextProviderSocket )
00729     {
00730         dbgprint("WSPSocket: NextProcTable.WSPSocket failed: %d", *lpErrno);
00731         goto cleanup;
00732     }
00733 
00734     //
00735     // Create the context information to be associated with this socket
00736     //
00737     sockContext = CreateSocketContext(
00738             lowerProvider,
00739             nextProviderSocket,
00740             lpErrno
00741             );
00742     if ( NULL == sockContext )
00743     {
00744         dbgprint( "WSPSocket: CreateSocketContext failed: %d", *lpErrno );
00745         goto cleanup;
00746     }
00747 
00748     //
00749     // Associate ownership of this handle with our LSP
00750     //
00751     sret = gMainUpCallTable.lpWPUModifyIFSHandle(
00752             lowerProvider->LayerProvider.dwCatalogEntryId,
00753             nextProviderSocket,
00754             lpErrno
00755             );
00756     if ( INVALID_SOCKET == sret )
00757     {
00758         dbgprint( "WSPSocket: WPUModifyIFSHandle failed: %d", *lpErrno );
00759         goto cleanup;
00760     }
00761 
00762     ASSERT( sret == nextProviderSocket );
00763 
00764     return nextProviderSocket;
00765 
00766 cleanup:
00767 
00768     // If an error occured close the socket if it was already created
00769     if ( ( NULL != sockContext ) && ( NULL != lowerProvider ) &&
00770          ( INVALID_SOCKET != nextProviderSocket ) )
00771     {
00772         rc = lowerProvider->NextProcTable.lpWSPCloseSocket(
00773                 nextProviderSocket,
00774                 lpErrno
00775                 );
00776         if ( SOCKET_ERROR == rc )
00777         {
00778             dbgprint( "WSPSocket: WSPCloseSocket failed: %d", *lpErrno );
00779         }
00780 
00781     }
00782     if ( ( NULL != sockContext ) && ( NULL != lowerProvider ) )
00783         FreeSocketContext( lowerProvider, sockContext );
00784 
00785     return INVALID_SOCKET;
00786 }


Variable Documentation

CRITICAL_SECTION gCriticalSection

Definition at line 45 of file spi.cpp.

Definition at line 48 of file spi.cpp.

Definition at line 47 of file spi.cpp.

WSPUPCALLTABLE gMainUpCallTable

Definition at line 46 of file spi.cpp.

Definition at line 37 of file lspguid.cpp.