summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/tcpip/tcp/init.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/tdi/tcpip/tcp/init.c597
1 files changed, 597 insertions, 0 deletions
diff --git a/private/ntos/tdi/tcpip/tcp/init.c b/private/ntos/tdi/tcpip/tcp/init.c
new file mode 100644
index 000000000..2a889d88a
--- /dev/null
+++ b/private/ntos/tdi/tcpip/tcp/init.c
@@ -0,0 +1,597 @@
+/********************************************************************/
+/** Microsoft LAN Manager **/
+/** Copyright(c) Microsoft Corp., 1990-1993 **/
+/********************************************************************/
+/* :ts=4 */
+
+//** INIT.C - TCP/UDP init code.
+//
+// This file contain init code for the TCP/UDP driver. Some things
+// here are ifdef'ed for building a UDP only version.
+//
+
+#include "oscfg.h"
+#include "ndis.h"
+#include "cxport.h"
+#include "ip.h"
+#include "tdi.h"
+#ifdef NT
+#include <tdikrnl.h>
+#endif
+#ifdef VXD
+#include "tdivxd.h"
+#include "tdistat.h"
+#endif
+#ifdef NT
+#include "tdint.h"
+#include "tdistat.h"
+#endif
+#include "queue.h"
+#include "addr.h"
+#include "udp.h"
+#include "raw.h"
+#include "info.h"
+#ifndef UDP_ONLY
+#include "tcp.h"
+#include "tcpsend.h"
+#include "tcb.h"
+#include "tcpconn.h"
+#include "tcpdeliv.h"
+#include "tlcommon.h"
+
+extern int InitTCPRcv(void);
+extern void UnInitTCPRcv(void);
+#endif // UDP_ONLY
+
+#include "tdiinfo.h"
+#include "tcpcfg.h"
+
+
+//* Definitions of global variables.
+IPInfo LocalNetInfo;
+
+uint DeadGWDetect;
+uint PMTUDiscovery;
+uint PMTUBHDetect;
+uint KeepAliveTime;
+uint KAInterval;
+uint DefaultRcvWin;
+uint MaxConnections;
+uint MaxConnectRexmitCount;
+uint MaxConnectResponseRexmitCount;
+#ifdef SYN_ATTACK
+uint MaxConnectResponseRexmitCountTmp;
+#endif
+uint MaxDataRexmitCount;
+uint BSDUrgent;
+uint FinWait2TO;
+uint NTWMaxConnectCount;
+uint NTWMaxConnectTime;
+uint MaxUserPort;
+
+#ifdef SECFLTR
+uint SecurityFilteringEnabled;
+#endif // SECFLTR
+
+#ifdef VXD
+uint PreloadCount;
+#endif
+
+#ifdef _PNP_POWER
+HANDLE AddressChangeHandle;
+#endif
+
+#ifdef VXD
+TDIDispatchTable TLDispatch;
+
+#ifndef CHICAGO
+char TransportName[] = "MSTCP";
+#else
+char TransportName[] = TCP_NAME;
+#endif
+
+#ifdef CHICAGO
+extern int RegisterAddrChangeHndlr(void *Handler, uint Add);
+#endif
+
+#endif
+
+uint StartTime;
+
+extern void *UDPProtInfo;
+extern void *RawProtInfo;
+
+extern int InitTCPConn(void);
+extern void UnInitTCPConn(void);
+extern IP_STATUS TLGetIPInfo(IPInfo *Buffer, int Size);
+
+
+
+//
+// All of the init code can be discarded.
+//
+#ifdef NT
+#ifdef ALLOC_PRAGMA
+
+int tlinit();
+
+#pragma alloc_text(INIT, tlinit)
+
+#endif // ALLOC_PRAGMA
+#endif
+
+//* Dummy routines for UDP only version. All of these routines return
+// 'Invalid Request'.
+
+#ifdef UDP_ONLY
+TDI_STATUS
+TdiOpenConnection(PTDI_REQUEST Request, PVOID Context)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS
+TdiCloseConnection(PTDI_REQUEST Request)
+{
+ return TDI_INVALID_REQUEST;
+}
+
+TDI_STATUS
+TdiAssociateAddress(PTDI_REQUEST Request, HANDLE AddrHandle)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS TdiDisAssociateAddress(PTDI_REQUEST Request)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS TdiConnect(PTDI_REQUEST Request, void *Timeout,
+ PTDI_CONNECTION_INFORMATION RequestAddr,
+ PTDI_CONNECTION_INFORMATION ReturnAddr)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS TdiListen(PTDI_REQUEST Request, ushort Flags,
+ PTDI_CONNECTION_INFORMATION AcceptableAddr,
+ PTDI_CONNECTION_INFORMATION ConnectedAddr)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS TdiAccept(PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION AcceptInfo,
+ PTDI_CONNECTION_INFORMATION ConnectedInfo)
+{
+ return TDI_INVALID_REQUEST;
+}
+TDI_STATUS TdiReceive(PTDI_REQUEST Request, ushort *Flags,
+ uint *RcvLength, PNDIS_BUFFER Buffer)
+{
+ return TDI_INVALID_REQUEST;
+}
+
+TDI_STATUS TdiSend(PTDI_REQUEST Request, ushort Flags, uint SendLength,
+ PNDIS_BUFFER Buffer)
+{
+ return TDI_INVALID_REQUEST;
+}
+
+TDI_STATUS TdiDisconnect(PTDI_REQUEST Request, PVOID Timeout, ushort Flags,
+ PTDI_CONNECTION_INFORMATION DisconnectInfo,
+ PTDI_CONNECTION_INFORMATION ReturnInfo)
+{
+ return TDI_INVALID_REQUEST;
+}
+
+#endif
+
+#ifdef VXD
+
+extern void *ConvertPtr(void *Ptr);
+
+//** Routines to handle incoming QueryInformation requests, and dispatch
+//** them.
+
+struct ClientReq {
+ ushort cr_opcode;
+ void *cr_ID;
+ void *cr_buffer;
+ void *cr_length;
+ void *cr_context;
+};
+
+//* VxDQueryInfo - VxD thunk to query information.
+//
+// The VxD thunk to TdiQueryInformationEx. All we do it convert the pointers
+// and call in.
+//
+// Input: Req - A pointer to a ClientReq structure.
+//
+// Returns: Status of command.
+//
+TDI_STATUS
+VxDQueryInfo(struct ClientReq *Req)
+{
+ NDIS_BUFFER Buffer;
+ TDI_REQUEST Request;
+ uint *Size;
+ TDIObjectID *ID;
+ void *Context;
+
+ CTEAssert(Req->cr_opcode == 0);
+
+ CTEMemSet(&Request, 0, sizeof(TDI_REQUEST));
+
+ ID = (TDIObjectID *)ConvertPtr(Req->cr_ID);
+ Size = (uint *)ConvertPtr(Req->cr_length);
+
+#ifdef DEBUG
+ Buffer.Signature = BUFFER_SIGN;
+#endif
+
+ Buffer.VirtualAddress = ConvertPtr(Req->cr_buffer);
+ Buffer.Length = *Size;
+ Buffer.Next = NULL;
+
+ return TdiQueryInformationEx(&Request, ID, &Buffer, Size,
+ ConvertPtr(Req->cr_context));
+
+}
+
+//* VxDSetInfo - VxD thunk to set information.
+//
+// The VxD thunk to TdiSetInformationEx. All we do it convert the pointers
+// and call in.
+//
+// Input: Req - A pointer to a ClientReq structure.
+//
+// Returns: Status of command.
+//
+TDI_STATUS
+VxDSetInfo(struct ClientReq *Req)
+{
+ TDIObjectID *ID;
+ uint *Size;
+ void *Buffer;
+ TDI_REQUEST Request;
+
+ CTEAssert(Req->cr_opcode == 1);
+
+ CTEMemSet(&Request, 0, sizeof(TDI_REQUEST));
+
+ ID = (TDIObjectID *)ConvertPtr(Req->cr_ID);
+ Size = (uint *)ConvertPtr(Req->cr_length);
+ Buffer = ConvertPtr(Req->cr_buffer);
+
+ return TdiSetInformationEx(&Request, ID, Buffer, *Size);
+
+}
+#endif
+
+#ifdef CHICAGO
+//* AddrChange - Receive notification of an IP address change.
+//
+// Called by IP when an address comes or goes. We get the address
+// and mask, and depending on what's actually happened we may close address
+// and connections.
+//
+// Input: Addr - IP address that's coming or going.
+// Mask - Mask for Addr.
+// Context - PNP context (unused)
+// IPContext - IP context (unused)
+// Added - True if the address is coming, False if it's going.
+//
+// Returns: Nothing.
+//
+void
+AddrChange(IPAddr Addr, IPMask Mask, void *Context, ushort IPContext,
+ uint Added)
+{
+ if (Added) {
+ // He's adding an address. Re-query the entity list now.
+ EntityList[0].tei_entity = CO_TL_ENTITY;
+ EntityList[0].tei_instance = 0;
+ EntityList[1].tei_entity = CL_TL_ENTITY;
+ EntityList[1].tei_instance = 0;
+ EntityCount = 2;
+
+ // When we have multiple networks under us, we'll want to loop through
+ // here calling them all. For now just call the one we have.
+ (*LocalNetInfo.ipi_getelist)(EntityList, &EntityCount);
+ } else {
+ // He's deleting an address.
+ if (!IP_ADDR_EQUAL(Addr, NULL_IP_ADDR)) {
+#ifndef UDP_ONLY
+ TCBWalk(DeleteTCBWithSrc, &Addr, NULL, NULL);
+#endif
+ InvalidateAddrs(Addr);
+ }
+
+ }
+}
+#endif
+
+#ifdef NT
+#ifdef _PNP_POWER
+
+//* AddressArrival - Handle an IP address arriving
+//
+// Called by TDI when an address arrives. All we do is query the
+// EntityList.
+//
+// Input: Addr - IP address that's coming.
+//
+// Returns: Nothing.
+//
+void
+AddressArrival(PTA_ADDRESS Addr)
+{
+ if (Addr->AddressType == TDI_ADDRESS_TYPE_IP) {
+ // He's adding an address. Re-query the entity list now.
+ EntityList[0].tei_entity = CO_TL_ENTITY;
+ EntityList[0].tei_instance = 0;
+ EntityList[1].tei_entity = CL_TL_ENTITY;
+ EntityList[1].tei_instance = 0;
+ EntityCount = 2;
+
+ // When we have multiple networks under us, we'll want to loop through
+ // here calling them all. For now just call the one we have.
+ (*LocalNetInfo.ipi_getelist)(EntityList, &EntityCount);
+ }
+}
+
+//* AddressDeletion - Handle an IP address going away.
+//
+// Called by TDI when an address is deleted. If it's an address we
+// care about we'll clean up appropriately.
+//
+// Input: Addr - IP address that's going.
+//
+// Returns: Nothing.
+//
+void
+AddressDeletion(PTA_ADDRESS Addr)
+{
+ PTDI_ADDRESS_IP MyAddress;
+ IPAddr LocalAddress;
+
+ if (Addr->AddressType == TDI_ADDRESS_TYPE_IP) {
+ // He's deleting an address.
+
+ MyAddress = (PTDI_ADDRESS_IP)Addr->Address;
+ LocalAddress = MyAddress->in_addr;
+
+ if (!IP_ADDR_EQUAL(LocalAddress, NULL_IP_ADDR)) {
+#ifndef UDP_ONLY
+ TCBWalk(DeleteTCBWithSrc, &LocalAddress, NULL, NULL);
+#endif
+ InvalidateAddrs(LocalAddress);
+ }
+ }
+}
+
+#endif // _PNP_POWER
+#endif // NT
+
+#pragma BEGIN_INIT
+
+extern uchar TCPGetConfigInfo(void);
+
+extern uchar IPPresent(void);
+
+//** tlinit - Initialize the transport layer.
+//
+// The main transport layer initialize routine. We get whatever config
+// info we need, initialize some data structures, get information
+// from IP, do some more initialization, and finally register our
+// protocol values with IP.
+//
+// Input: Nothing
+//
+// Returns: True is we succeeded, False if we fail to initialize.
+//
+int
+tlinit()
+{
+#ifdef VXD
+ void *PreloadPtrs[MAX_PRELOAD_COUNT];
+ uint i;
+#endif
+
+ uint TCBInitialized = 0;
+
+ if (!CTEInitialize())
+ return FALSE;
+
+#ifdef VXD
+ if (!IPPresent())
+ return FALSE;
+#endif
+
+ if (!TCPGetConfigInfo())
+ return FALSE;
+
+ StartTime = CTESystemUpTime();
+
+#ifndef UDP_ONLY
+ KeepAliveTime = MS_TO_TICKS(KeepAliveTime);
+ KAInterval = MS_TO_TICKS(KAInterval);
+
+#endif
+
+ CTERefillMem();
+
+ // Get net information from IP.
+ if (TLGetIPInfo(&LocalNetInfo, sizeof(IPInfo)) != IP_SUCCESS)
+ goto failure;
+
+ if (LocalNetInfo.ipi_version != IP_DRIVER_VERSION)
+ goto failure; // Wrong version of IP.
+
+#ifdef CHICAGO
+ if (!RegisterAddrChangeHndlr(AddrChange, TRUE))
+ goto failure;
+#endif
+
+#ifdef NT
+#ifdef _PNP_POWER
+
+ (void)TdiRegisterAddressChangeHandler(
+ AddressArrival,
+ AddressDeletion,
+ &AddressChangeHandle
+ );
+
+#endif // _PNP_POWER
+#endif // NT
+
+ //* Initialize addr obj management code.
+ if (!InitAddr())
+ goto failure;
+
+ CTERefillMem();
+ if (!InitDG(sizeof(UDPHeader)))
+ goto failure;
+
+#ifndef UDP_ONLY
+ MaxConnections = MIN(MaxConnections, INVALID_CONN_INDEX - 1);
+ CTERefillMem();
+ if (!InitTCPConn())
+ goto failure;
+
+ CTERefillMem();
+ if (!InitTCB())
+ goto failure;
+
+ TCBInitialized = 1;
+
+ CTERefillMem();
+ if (!InitTCPRcv())
+ goto failure;
+
+ CTERefillMem();
+ if (!InitTCPSend())
+ goto failure;
+
+ CTEMemSet(&TStats, 0, sizeof(TCPStats));
+
+ TStats.ts_rtoalgorithm = TCP_RTO_VANJ;
+ TStats.ts_rtomin = MIN_RETRAN_TICKS * MS_PER_TICK;
+ TStats.ts_rtomax = MAX_REXMIT_TO * MS_PER_TICK;
+ TStats.ts_maxconn = (ulong) TCP_MAXCONN_DYNAMIC;
+
+#endif
+
+ CTEMemSet(&UStats,0, sizeof(UDPStats));
+
+
+ // Register our UDP protocol handler.
+ UDPProtInfo = TLRegisterProtocol(PROTOCOL_UDP, UDPRcv, DGSendComplete,
+ UDPStatus, NULL);
+
+ if (UDPProtInfo == NULL)
+ goto failure; // Failed to register!
+
+ // Register the Raw IP (wildcard) protocol handler.
+ RawProtInfo = TLRegisterProtocol(PROTOCOL_ANY, RawRcv, DGSendComplete,
+ RawStatus, NULL);
+
+ if (RawProtInfo == NULL) {
+ CTEPrint(("failed to register raw prot with IP\n"));
+ goto failure; // Failed to register!
+ }
+
+#ifdef VXD
+ TLDispatch.TdiOpenAddressEntry = TdiOpenAddress;
+ TLDispatch.TdiCloseAddressEntry = TdiCloseAddress;
+ TLDispatch.TdiSendDatagramEntry = TdiSendDatagram;
+ TLDispatch.TdiReceiveDatagramEntry = TdiReceiveDatagram;
+ TLDispatch.TdiSetEventEntry = TdiSetEvent;
+
+ TLDispatch.TdiOpenConnectionEntry = TdiOpenConnection;
+ TLDispatch.TdiCloseConnectionEntry = TdiCloseConnection;
+ TLDispatch.TdiAssociateAddressEntry = TdiAssociateAddress;
+ TLDispatch.TdiDisAssociateAddressEntry = TdiDisAssociateAddress;
+ TLDispatch.TdiConnectEntry = TdiConnect;
+ TLDispatch.TdiDisconnectEntry = TdiDisconnect;
+ TLDispatch.TdiListenEntry = TdiListen;
+ TLDispatch.TdiAcceptEntry = TdiAccept;
+ TLDispatch.TdiReceiveEntry = TdiReceive;
+ TLDispatch.TdiSendEntry = TdiSend;
+ TLDispatch.TdiQueryInformationEntry = TdiQueryInformation;
+ TLDispatch.TdiSetInformationEntry = TdiSetInformation;
+ TLDispatch.TdiActionEntry = TdiAction;
+ TLDispatch.TdiQueryInformationExEntry = TdiQueryInformationEx;
+ TLDispatch.TdiSetInformationExEntry = TdiSetInformationEx;
+
+ if (!TLRegisterDispatch(TransportName, &TLDispatch))
+ goto failure;
+
+#endif
+
+ CTERefillMem();
+
+ // Now query the lower layer entities, and save the information.
+ EntityList = CTEAllocMem(sizeof(TDIEntityID) * MAX_TDI_ENTITIES);
+ if (EntityList == NULL)
+ goto failure;
+
+ EntityList[0].tei_entity = CO_TL_ENTITY;
+ EntityList[0].tei_instance = 0;
+ EntityList[1].tei_entity = CL_TL_ENTITY;
+ EntityList[1].tei_instance = 0;
+ EntityCount = 2;
+
+ // When we have multiple networks under us, we'll want to loop through
+ // here calling them all. For now just call the one we have.
+ (*LocalNetInfo.ipi_getelist)(EntityList, &EntityCount);
+
+ CTERefillMem();
+
+#ifdef VXD
+ // Allocate memory as needed to satisfy the heap preload requirements. We'll
+ // allocate a bunch of memory from the IFSMgr and then free it, so
+ // hopefully it'll be there later when we need it.
+ PreloadCount = MIN(PreloadCount, MAX_PRELOAD_COUNT);
+ for (i = 0; i < PreloadCount; i++) {
+ void *Temp;
+
+ Temp = CTEAllocMem(PRELOAD_BLOCK_SIZE);
+ if (Temp != NULL)
+ PreloadPtrs[i] = Temp;
+ else
+ break;
+ CTERefillMem();
+ }
+
+ PreloadCount = i;
+ for (i = 0; i < PreloadCount; i++) {
+ CTEFreeMem(PreloadPtrs[i]);
+ }
+
+#endif
+
+ return TRUE;
+
+ // Come here to handle all failure cases.
+failure:
+
+ // If we've registered Raw IP, unregister it now.
+ if (RawProtInfo != NULL)
+ TLRegisterProtocol(PROTOCOL_ANY, NULL, NULL, NULL, NULL);
+
+ // If we've registered UDP, unregister it now.
+ if (UDPProtInfo != NULL)
+ TLRegisterProtocol(PROTOCOL_UDP, NULL, NULL, NULL, NULL);
+#ifndef UDP_ONLY
+ UnInitTCPSend();
+ UnInitTCPRcv();
+ if (TCBInitialized) {
+ UnInitTCB();
+ }
+ UnInitTCPConn();
+#endif
+
+ CTERefillMem();
+ return FALSE;
+}
+
+#pragma END_INIT