Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

451 lines
9.5 KiB

/*++
Module Name:
dgipxs.c
Abstract:
All IPX-specific code goes here.
This file is #included by winsock.c.
Author:
Jeff Roberts (jroberts) 3-Dec-1994
Revision History:
3-Dec-1994 jroberts
Created this module.
--*/
static char
HexDigits[16] =
{
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
extern unsigned int IPX_NumNetworkCard();
#if defined(NTENV) || defined(WIN96)
extern void ConstructIpxAddress(char *,
ADDRESS_TYPE *);
#endif // defined (NTENV) || defined(WIN96)
RPC_STATUS RPC_ENTRY
IPX_RegisterEndpoint(
IN void * pServerAddress,
IN RPC_CHAR * pEndpoint,
OUT PDG_SERVER_TRANS_ADDRESS * ppTransAddress,
OUT RPC_CHAR PAPI * lNetworkAddress,
OUT unsigned int PAPI * NumNetworkAddress,
IN unsigned int NetworkAddressLength,
IN unsigned long EndpointFlags,
IN unsigned long NICFlags
)
/*++
Routine Description:
Registers an endpoint for sending and receiving.
Arguments:
pServerAddress - Pointer to the DG_ADDRESS object that this transport
address is to be associated with. This is a 'void *' instead of
a 'PDG_ADDRESS' because we don't want to include or link in all
sorts of garbage associated with DG_ADDRESS.
pEndpoint - name of the endpoint to create.
ppTransAddress - Where to place a pointer to the newly created transport
address structure.
Return Value:
RPC_S_OUT_OF_MEMORY
Revision History:
--*/
{
RPC_STATUS Status = RPC_S_OK;
ADDRESS_TYPE Server;
char hostname[MAX_HOSTNAME_LEN];
int length = sizeof(Server);
SOCKET Socket;
#ifdef NTENV
UNICODE_STRING UnicodeHostName;
ANSI_STRING AsciiHostName;
NTSTATUS NtStatus;
#endif
struct ENDPOINT_INFO * pInfo;
char * PAPI * tmpPtr;
int NumCard;
NumCard = IPX_NumNetworkCard();
/* The first part is pointers,
the second part is the actual
networkaddress */
if ( NetworkAddressLength < ( NumCard * sizeof(RPC_CHAR *) +
(NETADDR_LEN) * NumCard) )
return( RPC_P_NETWORK_ADDRESS_TOO_SMALL );
*ppTransAddress = (PDG_SERVER_TRANS_ADDRESS) CreateTransAddress(
pServerAddress,
pEndpoint,
&Status
);
if (Status != RPC_S_OK)
{
return Status;
}
pInfo = (struct ENDPOINT_INFO *) (*ppTransAddress)->pTsap;
if (getsockname( pInfo->Socket,
(struct sockaddr *) &Server,
&length ))
{
DeleteTransAddress( ppTransAddress );
return RPC_S_CANT_CREATE_ENDPOINT;
}
//
// BUGBUG
//
// This needs to be fixed for WIN96. There should be an equivalent function defined.
//
#ifdef NTENV
ConstructIpxAddress(hostname, &Server);
#endif // NTENV
#ifdef NTENV
RtlInitAnsiString ( &AsciiHostName, hostname );
//
// Covert NetworkAddress to Unicode
//
NtStatus = RtlAnsiStringToUnicodeString ( &UnicodeHostName,
&AsciiHostName, TRUE
);
if (!NT_SUCCESS(NtStatus))
{
DeleteTransAddress( ppTransAddress );
return (RPC_S_OUT_OF_MEMORY) ;
}
#endif // NTENV
//
// Now copy it to where the caller said to
//
tmpPtr = (char * PAPI *) lNetworkAddress;
tmpPtr[0] = (char *) lNetworkAddress +
sizeof(RPC_CHAR * ) * IPX_NumNetworkCard();
#ifdef NTENV
memcpy ( tmpPtr[0],
UnicodeHostName.Buffer,
UnicodeHostName.Length + sizeof (UNICODE_NULL));
//
// Free string overhead
//
RtlFreeUnicodeString ( &UnicodeHostName );
#else // !NTENV
strcpy (tmpPtr[0], hostname);
#endif // NTENV
*NumNetworkAddress = 1; /* IPX hack for now */
if (PrimaryAddress.ThreadListening)
{
return RPC_P_THREAD_LISTENING;
}
return RPC_S_OK;
}
RPC_STATUS RPC_ENTRY
IPX_DeregisterEndpoint(
IN OUT PDG_SERVER_TRANS_ADDRESS * pServerTransAddress
)
/*++
Routine Description:
Deregisters an endpoint. This serves as a psuedo-destructor for a
DG_UDP_SERVER_TRANS_ADDRESS.
Arguments:
pServerTransAddress - transport address to delete.
Return Value:
RPC_S_OK
--*/
{
ASSERT(0 && "this fn is never used");
return RPC_S_INTERNAL_ERROR;
}
RPC_STATUS
IPX_CreateServerEndpoint(
IN char * pEndpoint,
IN void * pServerAddr
)
/*++
Routine Description:
Given an endpoint name make a sockaddr using 'this' host's hostname.
Arguments:
pTransAddress - Server's transport address information.
pNcaPacketHeader - Pointer to buffer to place incoming pkt into.
pDataLength - Number of bytes read in.
pEndpoint - Pointer to the server port num to forward to.
This is in string format.
Return Value:
<return from MapStatusCode>
Revision History:
Connie Hoppe (CLH) (connieh) 23-Feb-94 Created.
--*/
{
char * pCharServerName;
int Endpoint;
int EndpointLength;
int i;
int length;
ADDRESS_TYPE * pServerAddress = (ADDRESS_TYPE *) pServerAddr;
SOCKET dummy;
int zero_success;
ADDRESS_TYPE dummy_address;
//
// convert the endpoint to a number.
//
EndpointLength = strlen(pEndpoint);
for (i=0, Endpoint=0 ; i< EndpointLength ; i++)
{
if ( ((char)pEndpoint[i] >= '0') && ((char)pEndpoint[i] <= '9'))
{
Endpoint *= 10;
Endpoint += (char)pEndpoint[i]-'0';
}
}
pServerAddress->s.sa_family = ADDRESS_FAMILY;
pServerAddress->s.sa_socket = htons((unsigned short) Endpoint);
memset( &dummy_address, 0, sizeof(dummy_address) );
dummy_address.s.sa_family = ADDRESS_FAMILY;
zero_success = 0;
dummy = socket( ADDRESS_FAMILY, SOCK_DGRAM, PROTOCOL );
if (dummy != INVALID_SOCKET)
{
length = sizeof ( *pServerAddress );
zero_success = bind( dummy, &dummy_address.unused,
length );
if (zero_success == 0)
zero_success = getsockname ( dummy, (struct sockaddr *) pServerAddress,
&length );
closesocket( dummy );
pServerAddress->s.sa_socket = htons((unsigned short) Endpoint);
}
else
zero_success = 1;
if (zero_success != 0)
{
return RPC_S_CANT_CREATE_ENDPOINT;
}
return RPC_S_OK;
}
RPC_STATUS
IPX_QueryClientAddress
(
IN void * pOriginalEndpoint,
OUT RPC_CHAR * pClientAddress
)
{
int i;
RPC_CHAR * pString;
SOCKADDR_IPX * pSockAddr = (SOCKADDR_IPX *) pOriginalEndpoint;
//
// address looks like "~11111111222222222222".
//
pString = pClientAddress;
*(pString++) = '~';
for (i=0; i < 4; i++)
{
unsigned char Byte = pSockAddr->sa_netnum[i];
*(pString++) = HexDigits[Byte / 16];
*(pString++) = HexDigits[Byte % 16];
}
for (i=0; i < 6; i++)
{
unsigned char Byte = pSockAddr->sa_nodenum[i];
*(pString++) = HexDigits[Byte / 16];
*(pString++) = HexDigits[Byte % 16];
}
*pString = '\0';
return RPC_S_OK;
}
RPC_STATUS
IPX_QueryClientEndpoint
(
IN void * pOriginalEndpoint,
OUT RPC_CHAR * pClientEndpoint
)
{
SOCKADDR_IPX * pSockAddr = (SOCKADDR_IPX *) pOriginalEndpoint;
unsigned NativeSocket = ntohs(pSockAddr->sa_socket);
char AnsiBuffer[6];
char * pAnsi = AnsiBuffer;
RPC_CHAR * pUni = pClientEndpoint;
//
// Convert endpoint to an ASCII string, and thence to Unicode.
//
_ultoa(NativeSocket, AnsiBuffer, 10);
do
{
*pUni++ = *pAnsi;
}
while ( *pAnsi++ );
return RPC_S_OK;
}
int
IPX_SetTransportSpecificSocketOptions(
SOCKET Socket
)
{
unsigned PacketType;
PacketType = 4;
if (setsockopt(
Socket,
NSPROTO_IPX,
IPX_PTYPE,
(char *) &PacketType,
sizeof(PacketType)) != 0)
{
return WSAGetLastError();
}
}
#ifdef NTENV
enum IP_INTERFACE_TYPE
{
IT_UNKNOWN,
IT_WINSOCK,
IT_TDI
};
extern enum IP_INTERFACE_TYPE IpInterfaceType;
DWORD
GetIpInterfaceType(
);
#endif
extern DG_RPC_SERVER_TRANSPORT_INFO IPX_TransportInformation ;
RPC_SERVER_TRANSPORT_INFO *
IPX_TransportLoad(
INT protocolId
)
{
#if 1
if (!initialized)
{
if (0 == SPX_CreateSyncSocket())
{
return 0;
}
initialized = 1;
}
#endif
IPX_TransportInformation.BaselinePduSize = 1024;
IPX_TransportInformation.PreferredPduSize = 1464;
IPX_TransportInformation.MaxPduSize = 1464;
IPX_TransportInformation.MaxPacketSize = 1464;
#ifdef NTENV
GetIpInterfaceType();
if (IT_WINSOCK == IpInterfaceType)
{
IPX_TransportInformation.SendPacketBack = SendPacketViaWinsock;
IPX_TransportInformation.ReceivePacket = ReceivePacketViaWinsock;
}
else
{
IPX_TransportInformation.SendPacketBack = SendPacketViaTdi;
IPX_TransportInformation.ReceivePacket = ReceivePacketViaTdi;
}
#endif
return (RPC_SERVER_TRANSPORT_INFO *) &IPX_TransportInformation ;
}