* REVISIONS:
* CSH 01/08-2000 Created
*/
-#include <roscfg.h>
-#include <tcpip.h>
-#include <dispatch.h>
-#include <fileobjs.h>
-#include <datagram.h>
-#include <loopback.h>
-#include <rawip.h>
-#include <udp.h>
-#include <tcp.h>
-#include <rosrtl/string.h>
-#include <info.h>
-#include <memtrack.h>
+#include "precomp.h"
#define NDEBUG
#ifndef NDEBUG
-DWORD DebugTraceLevel = 0x7fffffff;
+DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER);
#else
DWORD DebugTraceLevel = 0;
#endif /* NDEBUG */
ULONG EntityMax = 0;
UDP_STATISTICS UDPStats;
+/* Network timers */
+KTIMER IPTimer;
+KDPC IPTimeoutDpc;
+KSPIN_LOCK IpWorkLock;
+WORK_QUEUE_ITEM IpWorkItem;
VOID TiWriteErrorLog(
PDRIVER_OBJECT DriverContext,
* ErrorCode = An error code to put in the log entry
* UniqueErrorValue = UniqueErrorValue in the error log packet
* FinalStatus = FinalStatus in the error log packet
- * String = If not NULL, a pointer to a string to put in log entry
+ * String = If not NULL, a pointer to a string to put in log
+ * entry
* DumpDataCount = Number of ULONGs of dump data
* DumpData = Pointer to dump data for the log entry
*/
PUCHAR pString;
static WCHAR DriverName[] = L"TCP/IP";
- EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
+ EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
(DumpDataCount * sizeof(ULONG)) + sizeof(DriverName);
if (String) {
#endif
}
-
-NTSTATUS TiGetProtocolNumber(
- PUNICODE_STRING FileName,
- PULONG Protocol)
-/*
- * FUNCTION: Returns the protocol number from a file name
- * ARGUMENTS:
- * FileName = Pointer to string with file name
- * Protocol = Pointer to buffer to put protocol number in
- * RETURNS:
- * Status of operation
- */
-{
- UNICODE_STRING us;
- NTSTATUS Status;
- ULONG Value;
- PWSTR Name;
-
- TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName));
-
- Name = FileName->Buffer;
-
- if (*Name++ != (WCHAR)L'\\')
- return STATUS_UNSUCCESSFUL;
-
- if (*Name == (WCHAR)NULL)
- return STATUS_UNSUCCESSFUL;
-
- RtlInitUnicodeString(&us, Name);
-
- Status = RtlUnicodeStringToInteger(&us, 10, &Value);
- if (!NT_SUCCESS(Status) || ((Value > 255)))
- return STATUS_UNSUCCESSFUL;
-
- *Protocol = Value;
-
- return STATUS_SUCCESS;
-}
-
-
/*
* FUNCTION: Creates a file object
* ARGUMENTS:
* RETURNS:
* Status of the operation
*/
+
NTSTATUS TiCreateFileObject(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
return STATUS_INSUFFICIENT_RESOURCES;
}
CP
- Context->RefCount = 1;
Context->CancelIrps = FALSE;
KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
CP
Request.RequestContext = Irp;
CP
/* Branch to the right handler */
- if (EaInfo &&
- (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
+ if (EaInfo &&
+ (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
(RtlCompareMemory
(&EaInfo->EaName, TdiTransportAddress,
TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) {
/* XXX This should probably be done in IoCreateFile() */
/* Parameter checks */
+
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + EaInfo->EaNameLength + 1); //0-term
+
if ((EaInfo->EaValueLength < sizeof(TA_IP_ADDRESS)) ||
(Address->TAAddressCount != 1) ||
(Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
if( Address->TAAddressCount == 1 ) {
- TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
+ TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
Address->Address[0].AddressLength));
- TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
+ TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
Address->Address[0].AddressType));
}
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
CP
Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
} else {
TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
CP
Context->Handle.AddressHandle = Request.Handle.AddressHandle;
}
CP
- } else if (EaInfo &&
- (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
+ } else if (EaInfo &&
+ (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
(RtlCompareMemory
(&EaInfo->EaName, TdiConnectionContext,
- TDI_CONNECTION_CONTEXT_LENGTH) ==
+ TDI_CONNECTION_CONTEXT_LENGTH) ==
TDI_CONNECTION_CONTEXT_LENGTH)) {
/* This is a request to open a connection endpoint */
CP
if (EaInfo->EaValueLength < sizeof(PVOID)) {
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
if (DeviceObject != TCPDeviceObject) {
TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
}
if (!NT_SUCCESS(Status))
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+ Irp->IoStatus.Status = Status;
return Status;
}
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
Irp->IoStatus.Status = Status;
-
- IoAcquireCancelSpinLock(&OldIrql);
-
- /* Remove the initial reference provided at object creation time */
- TranContext->RefCount--;
-#ifdef DBG
- if (TranContext->RefCount != 0)
- TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount is %i, should be 0.\n", TranContext->RefCount));
-#endif
+ IoAcquireCancelSpinLock(&OldIrql);
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
KIRQL OldIrql;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- Context = IrpSp->FileObject->FsContext;
+ Context = IrpSp->FileObject->FsContext;
if (!Context) {
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
return STATUS_INVALID_PARAMETER;
if (Status != STATUS_PENDING)
TiCleanupFileObjectComplete(Irp, Status);
-
+
KeWaitForSingleObject(&Context->CleanupEvent,
UserRequest, KernelMode, FALSE, NULL);
-
+
return Irp->IoStatus.Status;
}
NTSTATUS Status;
PTRANSPORT_CONTEXT Context;
+ RIRP(Irp);
+
TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
IoMarkIrpPending(Irp);
case IRP_MJ_CLOSE:
Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
if (Context)
- ExFreePool(Context);
+ PoolFreeBuffer(Context);
Status = STATUS_SUCCESS;
break;
- /* Release resources bound to an address file, connection endpoint,
+ /* Release resources bound to an address file, connection endpoint,
or control connection */
case IRP_MJ_CLEANUP:
Status = TiCleanupFileObject(DeviceObject, Irp);
BOOL Complete = TRUE;
PIO_STACK_LOCATION IrpSp;
+ RIRP(Irp);
+
IrpSp = IoGetCurrentIrpStackLocation(Irp);
TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
switch (IrpSp->MinorFunction) {
case TDI_RECEIVE:
Status = DispTdiReceive(Irp);
+ Complete = FALSE;
break;
case TDI_RECEIVE_DATAGRAM:
Status = DispTdiReceiveDatagram(Irp);
+ Complete = FALSE;
break;
case TDI_SEND:
case TDI_SEND_DATAGRAM:
Status = DispTdiSendDatagram(Irp);
+ Complete = FALSE;
break;
case TDI_ACCEPT:
case TDI_LISTEN:
Status = DispTdiListen(Irp);
+ Complete = FALSE;
break;
case TDI_CONNECT:
Status = DispTdiConnect(Irp);
+ Complete = FALSE; /* Completed by the TCP event handler */
break;
case TDI_DISCONNECT:
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
- if( Complete )
+ if( Complete )
IRPFinish( Irp, Status );
return Status;
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
+ RIRP(Irp);
+
IrpSp = IoGetCurrentIrpStackLocation(Irp);
TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
/* See if this request is TCP/IP specific */
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_TCP_QUERY_INFORMATION_EX:
- TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
+ TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
Status = DispTdiQueryInformationEx(Irp, IrpSp);
break;
case IOCTL_TCP_SET_INFORMATION_EX:
- TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
+ TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
Status = DispTdiSetInformationEx(Irp, IrpSp);
break;
+ case IOCTL_SET_IP_ADDRESS:
+ TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
+ Status = DispTdiSetIPAddress(Irp, IrpSp);
+ break;
+
+ case IOCTL_DELETE_IP_ADDRESS:
+ TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
+ Status = DispTdiDeleteIPAddress(Irp, IrpSp);
+ break;
+
default:
TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
IrpSp->Parameters.DeviceIoControl.IoControlCode));
#ifdef DBG
KIRQL OldIrql;
- KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
+ TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
if (!IsListEmpty(&AddressFileListHead)) {
TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
}
- KeReleaseSpinLock(&AddressFileListLock, OldIrql);
+ TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
+ ChewShutdown();
+
+ /* Cancel timer */
+ KeCancelTimer(&IPTimer);
/* Unregister loopback adapter */
LoopUnregisterAdapter(NULL);
TCPShutdown();
UDPShutdown();
RawIPShutdown();
- DGShutdown();
/* Shutdown network level protocol subsystem */
IPShutdown();
+ /* Shutdown the lan worker */
+ LANShutdown();
+
/* Free NDIS buffer descriptors */
if (GlobalBufferPool)
NdisFreeBufferPool(GlobalBufferPool);
IoDeleteDevice(IPDeviceObject);
if (EntityList)
- ExFreePool(EntityList);
+ PoolFreeBuffer(EntityList);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
+VOID STDCALL IPTimeoutDpcFn(
+ PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2)
+/*
+ * FUNCTION: Timeout DPC
+ * ARGUMENTS:
+ * Dpc = Pointer to our DPC object
+ * DeferredContext = Pointer to context information (unused)
+ * SystemArgument1 = Unused
+ * SystemArgument2 = Unused
+ * NOTES:
+ * This routine is dispatched once in a while to do maintainance jobs
+ */
+{
+ if( !IpWorkItemQueued ) {
+ ExQueueWorkItem( &IpWorkItem, CriticalWorkQueue );
+ IpWorkItemQueued = TRUE;
+ }
+}
NTSTATUS
#ifndef _MSC_VER
*/
{
NTSTATUS Status;
- UNICODE_STRING strDeviceName;
- UNICODE_STRING strNdisDeviceName;
+ UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
+ UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
+ UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
+ UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
+ UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
NDIS_STATUS NdisStatus;
- NDIS_STRING DeviceName;
+ LARGE_INTEGER DueTime;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
+
TrackingInit();
TrackTag(NDIS_BUFFER_TAG);
TrackTag(NDIS_PACKET_TAG);
TrackTag(FBSD_MALLOC);
TrackTag(EXALLOC_TAG);
- InitOskitTCP();
-
/* TdiInitialize() ? */
/* FIXME: Create symbolic links in Win32 namespace */
/* Create IP device object */
- RtlRosInitUnicodeStringFromLiteral(&strDeviceName, DD_IP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
return Status;
}
+ ChewInit( IPDeviceObject );
+
/* Create RawIP device object */
- RtlRosInitUnicodeStringFromLiteral(&strDeviceName, DD_RAWIP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
}
/* Create UDP device object */
- RtlRosInitUnicodeStringFromLiteral(&strDeviceName, DD_UDP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
}
/* Create TCP device object */
- RtlRosInitUnicodeStringFromLiteral(&strDeviceName, DD_TCP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
KeInitializeSpinLock(&InterfaceListLock);
/* Initialize network level protocol subsystem */
- IPStartup(DriverObject, RegistryPath);
+ IPStartup(RegistryPath);
/* Initialize transport level protocol subsystems */
- DGStartup();
RawIPStartup();
UDPStartup();
TCPStartup();
+ /* Initialize the lan worker */
+ LANStartup();
+
/* Register protocol with NDIS */
/* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
- RtlInitUnicodeString(&strNdisDeviceName, TCPIP_PROTOCOL_NAME);
Status = LANRegisterProtocol(&strNdisDeviceName);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
DriverObject->DriverUnload = TiUnload;
- PREPARE_TESTS
+ /* Initialize our periodic timer and its associated DPC object. When the
+ timer expires, the IPTimeout deferred procedure call (DPC) is queued */
+ ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL );
+ KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
+ KeInitializeTimer(&IPTimer);
+
+ /* Start the periodic timer with an initial and periodic
+ relative expiration time of IP_TIMEOUT milliseconds */
+ DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
+ KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);
return STATUS_SUCCESS;
}