diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/isn/fwd | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/tdi/isn/fwd')
35 files changed, 12445 insertions, 0 deletions
diff --git a/private/ntos/tdi/isn/fwd/ddreqs.c b/private/ntos/tdi/isn/fwd/ddreqs.c new file mode 100644 index 000000000..76ab93ea4 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/ddreqs.c @@ -0,0 +1,220 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\ddreqs.c + +Abstract: + Management of demand dial request queues + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + +LIST_ENTRY ConnectionIrpQueue; +LIST_ENTRY ConnectionRequestQueue; + +/*++ + Q u e u e C o n n e c t i o n R e q u e s t + +Routine Description: + Adds request to connected the interface to the queue + +Arguments: + ifCB - control block of the interface that needs to be + connected + packet - packet that prompted the connection request + data - pointer to actual data in the packet + oldIRQL - IRQL at which interface lock was acquired + +Return Value: + None + + Note that interface lock must be acquired before calling this + routine which will release it + +--*/ +VOID +QueueConnectionRequest ( + PINTERFACE_CB ifCB, + PNDIS_PACKET packet, + PUCHAR data, + KIRQL oldIRQL + ) { + KIRQL cancelIRQL; + + IoAcquireCancelSpinLock (&cancelIRQL); + SET_IF_CONNECTING (ifCB); + if (!IsListEmpty (&ConnectionIrpQueue)) { + PIRP irp = CONTAINING_RECORD ( + ConnectionIrpQueue.Flink, + IRP, + Tail.Overlay.ListEntry); + PIO_STACK_LOCATION irpStack=IoGetCurrentIrpStackLocation(irp); + RemoveEntryList (&irp->Tail.Overlay.ListEntry); + ASSERT (irpStack->Parameters.DeviceIoControl.IoControlCode + ==IOCTL_FWD_GET_DIAL_REQUEST); + ASSERT ((irpStack->Parameters.DeviceIoControl.IoControlCode&3) + ==METHOD_BUFFERED); + IoSetCancelRoutine (irp, NULL); + IoReleaseCancelSpinLock (cancelIRQL); + + FillConnectionRequest ( + ifCB->ICB_Index, + packet, + data, + (PFWD_DIAL_REQUEST)irp->AssociatedIrp.SystemBuffer, + irpStack->Parameters.DeviceIoControl.OutputBufferLength, + &irp->IoStatus.Information); + irp->IoStatus.Status = STATUS_SUCCESS; + + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_DIALREQS, DBG_WARNING, + ("IpxFwd: Passing dial request for if %ld (icb:%08lx) with %d bytes of data.\n", + ifCB->ICB_Index, ifCB, irp->IoStatus.Information)); + IoCompleteRequest (irp, IO_NO_INCREMENT); + } + else { + InsertTailList (&ConnectionRequestQueue, &ifCB->ICB_ConnectionLink); + IoReleaseCancelSpinLock (cancelIRQL); + ifCB->ICB_ConnectionPacket = packet; + ifCB->ICB_ConnectionData = data; + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + } +} + +/*++ + D e q u e u e C o n n e c t i o n R e q u e s t + +Routine Description: + Removes conection requset for the interface from the queue + +Arguments: + ifCB - control block of the interface that needs to be + removed + +Return Value: + None + +--*/ +VOID +DequeueConnectionRequest ( + PINTERFACE_CB ifCB + ) { + KIRQL cancelIRQL; + IoAcquireCancelSpinLock (&cancelIRQL); + if (IsListEntry (&ifCB->ICB_ConnectionLink)) { + RemoveEntryList (&ifCB->ICB_ConnectionLink); + InitializeListEntry (&ifCB->ICB_ConnectionLink); + } + IoReleaseCancelSpinLock (cancelIRQL); +} + +/*++ + F i l l C o n n e c t i o n R e q u e s t + +Routine Description: + Fills the provided buffer with index of interface that needs + to be connected and packet that prompted the request + +Arguments: + index - if index + packet - packet that prompted the request + data - pointer to IPX data (IPX header) inside of the packet + request - request buffer to fill + reqSize - size of request buffer + bytesCopied - bytesCopied into the request buffer + +Return Value: + STATUS_SUCCESS - array was filled successfully + This routine assumes that there it is called only when there + are outstanding requests in the request queue + +--*/ +VOID +FillConnectionRequest ( + IN ULONG index, + IN PNDIS_PACKET packet, + IN PUCHAR data, + IN OUT PFWD_DIAL_REQUEST request, + IN ULONG reqSize, + OUT PULONG bytesCopied + ) { + PNDIS_BUFFER buf; + + *bytesCopied = 0; + request->IfIndex = index; + NdisQueryPacket (packet, NULL, NULL, &buf, NULL); + do { + PVOID va; + UINT length; + + NdisQueryBuffer (buf, &va, &length); + if (((PUCHAR)va<=data) + && ((PUCHAR)va+length>data)) { + TdiCopyMdlToBuffer (buf, + data-(PUCHAR)va, + request, + FIELD_OFFSET (FWD_DIAL_REQUEST, Packet), + reqSize, + bytesCopied); + *bytesCopied += FIELD_OFFSET (FWD_DIAL_REQUEST, Packet); + break; + } + NdisGetNextBuffer (buf, &buf); + } + while (buf!=NULL); +} + +/*++ + F a i l C o n n e c t i o n R e q u e s t s + +Routine Description: + Cleans up on connection request failure + +Arguments: + InterfaceIndex - index of interface that could not be connected + +Return Value: + STATUS_SUCCESS - clean up was successfull + STATUS_UNSUCCESSFUL - interface with this index does not exist + +--*/ +NTSTATUS +FailConnectionRequest ( + IN ULONG InterfaceIndex + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + + ASSERT (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX); + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + IpxFwdDbgPrint (DBG_DIALREQS, DBG_WARNING, + ("IpxFwd: Dial request failed for if %ld (icb:%08lx).\n", + ifCB->ICB_Index, ifCB)); + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (IS_IF_CONNECTING (ifCB)) { + SET_IF_NOT_CONNECTING (ifCB); + DequeueConnectionRequest (ifCB); + } + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + diff --git a/private/ntos/tdi/isn/fwd/ddreqs.h b/private/ntos/tdi/isn/fwd/ddreqs.h new file mode 100644 index 000000000..416091c92 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/ddreqs.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\ddreqs.h + +Abstract: + Management of demand dial request queues + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ +#ifndef _IPXFWD_DDREQS_ +#define _IPXFWD_DDREQS_ + +// Connection requests to DIM +// Queue of request that need to be satisfied by DIM +extern LIST_ENTRY ConnectionRequestQueue; +// Queue of request IRPs posted by the router manager +extern LIST_ENTRY ConnectionIrpQueue; + +/*++ + I n i t i a l i z e C o n n e c t i o n Q u e u e s + +Routine Description: + Initializes connection request and irp queues + +Arguments: + None + +Return Value: + None + +--*/ +//VOID +//InitializeConnectionQueues ( +// void +// ); +#define InitializeConnectionQueues() { \ + InitializeListHead (&ConnectionIrpQueue); \ + InitializeListHead (&ConnectionRequestQueue); \ +} + +/*++ + F i l l C o n n e c t i o n R e q u e s t + +Routine Description: + Fills the provided buffer with index of interface that needs + to be connected and packet that prompted the request + +Arguments: + index - if index + packet - packet that prompted the request + data - pointer to IPX data (IPX header) inside of the packet + request - request buffer to fill + reqSize - size of request buffer + bytesCopied - bytesCopied into the request buffer + +Return Value: + STATUS_SUCCESS - array was filled successfully + This routine assumes that there it is called only when there + are outstanding requests in the request queue + +--*/ +VOID +FillConnectionRequest ( + IN ULONG index, + IN PNDIS_PACKET packet, + IN PUCHAR data, + IN OUT PFWD_DIAL_REQUEST request, + IN ULONG reqSize, + OUT PULONG bytesCopied + ); + +/*++ + F a i l C o n n e c t i o n R e q u e s t s + +Routine Description: + Cleans up on connection request failure + +Arguments: + InterfaceIndex - index of interface that could not be connected + +Return Value: + STATUS_SUCCESS - clean up was successfull + STATUS_UNSUCCESSFUL - interface with this index does not exist + +--*/ +NTSTATUS +FailConnectionRequest ( + IN ULONG InterfaceIndex + ); + +/*++ + Q u e u e C o n n e c t i o n R e q u e s t + +Routine Description: + Adds request to connected the interface to the queue + +Arguments: + ifCB - control block of the interface that needs to be + connected + packet - packet that prompted the connection request + data - pointer to actual data in the packet + oldIRQL - IRQL at which interface lock was acquired + +Return Value: + None + + Note that interface lock must be acquired before calling this + routine which will release it + +--*/ +VOID +QueueConnectionRequest ( + PINTERFACE_CB ifCB, + PNDIS_PACKET packet, + PUCHAR data, + KIRQL oldIRQL + ); + +/*++ + D e q u e u e C o n n e c t i o n R e q u e s t + +Routine Description: + Removes conection requset for the interface from the queue + +Arguments: + ifCB - control block of the interface that needs to be + removed + +Return Value: + None + +--*/ +VOID +DequeueConnectionRequest ( + PINTERFACE_CB ifCB + ); + +#endif + diff --git a/private/ntos/tdi/isn/fwd/debug.c b/private/ntos/tdi/isn/fwd/debug.c new file mode 100644 index 000000000..9fa2f3f1c --- /dev/null +++ b/private/ntos/tdi/isn/fwd/debug.c @@ -0,0 +1,7 @@ +#include "precomp.h" + +#if DBG +ULONG DbgLevel = DEF_DBG_LEVEL; +LONGLONG ActivityTreshhold = _I64_MAX; +LARGE_INTEGER CounterFrequency; +#endif diff --git a/private/ntos/tdi/isn/fwd/debug.h b/private/ntos/tdi/isn/fwd/debug.h new file mode 100644 index 000000000..251d23895 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/debug.h @@ -0,0 +1,69 @@ +/*******************************************************************/ +/* Copyright(c) 1993 Microsoft Corporation */ +/*******************************************************************/ + +//*** +// +// Filename: debug.h +// +// Description: Debug macros definitions +// +// Author: Stefan Solomon (stefans) October 4, 1993. +// +// Revision History: +// +//*** + +#ifndef _IPXFWD_DEBUG_ +#define _IPXFWD_DEBUG_ + +#if DBG +#define DBG_PACKET_ALLOC ((ULONG)0x00000001) +#define DBG_INTF_TABLE ((ULONG)0x00000002) +#define DBG_ROUTE_TABLE ((ULONG)0x00000004) +#define DBG_NBROUTE_TABLE ((ULONG)0x00000008) +#define DBG_IOCTLS ((ULONG)0x00000010) +#define DBG_LINEIND ((ULONG)0x00000020) +#define DBG_IPXBIND ((ULONG)0x00000040) +#define DBG_REGISTRY ((ULONG)0x00000080) +#define DBG_INT_RECV ((ULONG)0x00000100) +#define DBG_RECV ((ULONG)0x00000200) +#define DBG_SEND ((ULONG)0x00000400) +#define DBG_INT_SEND ((ULONG)0x00000800) +#define DBG_NETBIOS ((ULONG)0x00001000) +#define DBG_IPXROUTE ((ULONG)0x00002000) +#define DBG_DIALREQS ((ULONG)0x00004000) +#define DBG_SPOOFING ((ULONG)0x00008000) + +#define DBG_INFORMATION ((ULONG)0x10000000) +#define DBG_WARNING ((ULONG)0x20000000) +#define DBG_ERROR ((ULONG)0x40000000) + +#define DEF_DBG_LEVEL ( \ + DBG_ERROR|DBG_WARNING \ + | DBG_INTF_TABLE \ + | DBG_LINEIND \ + | DBG_IPXBIND \ + | DBG_REGISTRY \ + | DBG_IPXROUTE \ + | DBG_IOCTLS \ + | DBG_DIALREQS \ + | DBG_SPOOFING \ + ) + +extern ULONG DbgLevel; +extern LONGLONG ActivityTreshhold; +extern LARGE_INTEGER CounterFrequency; + +#define IpxFwdDbgPrint(COMPONENT,LEVEL,ARGS) \ + do { \ + if ((DbgLevel & ((COMPONENT)|(LEVEL)))==((COMPONENT)|(LEVEL))){ \ + DbgPrint ARGS; \ + } \ + } while (0) + +#else +#define IpxFwdDbgPrint(COMPONENT,LEVEL,ARGS) do {NOTHING;} while (0) +#endif + +#endif diff --git a/private/ntos/tdi/isn/fwd/dirs b/private/ntos/tdi/isn/fwd/dirs new file mode 100644 index 000000000..0dab2f056 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/dirs @@ -0,0 +1,22 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + +NOTE: Commented description of this file is in \nt\bak\bin\dirs.tpl + +!ENDIF + +DIRS=up mp diff --git a/private/ntos/tdi/isn/fwd/driver.c b/private/ntos/tdi/isn/fwd/driver.c new file mode 100644 index 000000000..ac03cb31e --- /dev/null +++ b/private/ntos/tdi/isn/fwd/driver.c @@ -0,0 +1,1157 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\driver.c + +Abstract: + IPX Forwarder driver dispatch routines + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + +const UCHAR BROADCAST_NODE[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +const LONGLONG WaitTimeout = -50000000i64; +volatile BOOLEAN IpxFwdInitialized = FALSE; + +BOOLEAN MeasuringPerformance = FALSE; +KSPIN_LOCK PerfCounterLock; +FWD_PERFORMANCE PerfBlock; + +LONG ClientCount = 0; +KEVENT ClientsGoneEvent; + +PFILE_OBJECT RouterFile, FilterFile; + +NTSTATUS +IpxFwdDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID +IpxFwdUnload( + IN PDRIVER_OBJECT DriverObject + ); + +NTSTATUS +DoStart ( + IN ULONG RouteHashTableSize, + IN BOOLEAN thisMachineOnly + ); + +NTSTATUS +DoStop ( + void + ); + +NTSTATUS +DoSetInterface ( + IN ULONG InterfaceIndex, + IN BOOLEAN NetbiosAccept, + IN UCHAR NetbiosDeliver + ); + +NTSTATUS +DoGetInterface ( + IN ULONG InterfaceIndex, + OUT PFWD_IF_STATS stats, + OUT BOOLEAN *NetbiosAccept, + OUT UCHAR *NetbiosDeliver + ); + +NTSTATUS +DoSetNbNames ( + IN ULONG InterfaceIndex, + IN ULONG Count, + IN PFWD_NB_NAME Names + ); + +NTSTATUS +DoGetNbNames ( + IN ULONG InterfaceIndex, + IN OUT ULONG *BufferSize, + OUT ULONG *Count, + OUT PFWD_NB_NAME Names + ); + +NTSTATUS +DoBindInterface ( + IN ULONG InterfaceIndex, + IN PFWD_ADAPTER_BINDING_INFO info + ); + +NTSTATUS +DoUnbindInterface ( + IN ULONG InterfaceIndex + ); + +NTSTATUS +DoDisableInterface ( + IN ULONG InterfaceIndex + ); + +NTSTATUS +DoEnableInterface ( + IN ULONG InterfaceIndex + ); + +NTSTATUS +DoSetRoutes ( + IN PFWD_ROUTE_SET_PARAMS routeArray, + IN ULONG nRoutes, + OUT PULONG nProcessed + ); + +VOID +IpxFwdCancel ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP irp + ); + +NTSTATUS +DoGetPerfCounters ( + PFWD_PERFORMANCE_PARAMS perfParams + ); + +/*++ + D r i v e r E n t r y + +Routine Description: + + Installable driver initialization entry point. + This entry point is called directly by the I/O system. + +Arguments: + + DriverObject - pointer to the driver object + + RegistryPath - pointer to a unicode string representing the path + to driver-specific key in the registry + +Return Value: + + STATUS_SUCCESS if successful, + STATUS_UNSUCCESSFUL otherwise + +--*/ +NTSTATUS +DriverEntry ( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) { + + PDEVICE_OBJECT deviceObject = NULL; + NTSTATUS status; + WCHAR deviceNameBuffer[] = IPXFWD_NAME; + UNICODE_STRING deviceNameUnicodeString; + + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, + ("IpxFwd: Entering DriverEntry\n")); + + // + // Create an non-EXCLUSIVE device object + // + + RtlInitUnicodeString (&deviceNameUnicodeString, + deviceNameBuffer); + + status = IoCreateDevice (DriverObject, + 0, + &deviceNameUnicodeString, + FILE_DEVICE_IPXFWD, + 0, + FALSE, // Non-Exclusive + &deviceObject + ); + + if (NT_SUCCESS(status)) { + // + // Create dispatch points for device control, create, close. + // + GetForwarderParameters (RegistryPath); + DriverObject->MajorFunction[IRP_MJ_CREATE] + = DriverObject->MajorFunction[IRP_MJ_CLEANUP] + = DriverObject->MajorFunction[IRP_MJ_CLOSE] + = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] + = IpxFwdDispatch; + DriverObject->DriverUnload = IpxFwdUnload; + status = BindToIpxDriver (KernelMode); + if (NT_SUCCESS (status)) { + +#if DBG + KeQueryPerformanceCounter (&CounterFrequency); +#endif + FilterFile = RouterFile = NULL; + ClientCount = 0; + return STATUS_SUCCESS; + } + IoDeleteDevice (DriverObject->DeviceObject); + } + else + IpxFwdDbgPrint (DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: IoCreateDevice failed\n")); + + return status; +} + + + +/*++ + +Routine Description: + + Process the IRPs sent to this device. + +Arguments: + + DeviceObject - pointer to a device object + + Irp - pointer to an I/O Request Packet + +Return Value: + + +--*/ +NTSTATUS +IpxFwdDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) { + PIO_STACK_LOCATION IrpStack; + PVOID inBuffer, outBuffer; + ULONG inpBufLength; + ULONG outBufLength; + NTSTATUS status; + KIRQL cancelIRQL; + + + Irp->IoStatus.Information = 0; + status = STATUS_SUCCESS; + + // + // Get a pointer to the current location in the Irp. This is where + // the function codes and parameters are located. + // + + IrpStack = IoGetCurrentIrpStackLocation(Irp); + + + switch (IrpStack->MajorFunction) { + case IRP_MJ_CREATE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, ("IpxFwd: IRP_MJ_CREATE\n")); + break; + + case IRP_MJ_CLOSE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, ("IpxFwd: IRP_MJ_CLOSE\n")); + if (EnterForwarder ()) { + if (IrpStack->FileObject==RouterFile) { + LeaveForwarder (); + IpxFwdInitialized = FALSE; + while (InterlockedDecrement (&ClientCount)>=0) { + KeWaitForSingleObject (&ClientsGoneEvent, + Executive, + KernelMode, + FALSE, + (PLARGE_INTEGER)&WaitTimeout); + InterlockedIncrement (&ClientCount); + IpxFwdDbgPrint(DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: Waiting for all clients (%ld) to exit.\n", + ClientCount)); + } + status = DoStop (); + ClientCount = 0; + RouterFile = NULL; + } + else if (IrpStack->FileObject==FilterFile) { + UnbindFilterDriver (); + FilterFile = NULL; + LeaveForwarder (); + } + else + LeaveForwarder (); + } + break; + + case IRP_MJ_CLEANUP: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, ("IpxFwd: IRP_MJ_CLEANUP\n")); + if (EnterForwarder ()) { + if (IrpStack->FileObject==RouterFile) { + IoAcquireCancelSpinLock (&cancelIRQL); + while (!IsListEmpty (&ConnectionIrpQueue)) { + PIRP irp = CONTAINING_RECORD (ConnectionIrpQueue.Blink, + IRP, Tail.Overlay.ListEntry); + irp->Cancel = TRUE; + irp->CancelIrql = cancelIRQL; + irp->CancelRoutine = NULL; + IpxFwdCancel(DeviceObject, irp); + IoAcquireCancelSpinLock (&cancelIRQL); + } + IoReleaseCancelSpinLock(cancelIRQL); + } + LeaveForwarder (); + } + break; + + case IRP_MJ_DEVICE_CONTROL: + // + // Get the pointer to the input/output buffer and it's length + // + + status = STATUS_INVALID_PARAMETER; + inpBufLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; + outBufLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; + switch (IrpStack->Parameters.DeviceIoControl.IoControlCode&3) { + case METHOD_BUFFERED: + inBuffer = outBuffer = Irp->AssociatedIrp.SystemBuffer; + break; + + case METHOD_IN_DIRECT: + case METHOD_OUT_DIRECT: + inBuffer = Irp->AssociatedIrp.SystemBuffer; + if (outBufLength>0) { + outBuffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + } + else { + outBuffer = NULL; + IpxFwdDbgPrint(DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: IOCTL...METHOD_DIRECT with 0 output buffer ???\n")); + } + break; + default: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: IOCTL...METHOD_NEITHER ???\n")); + goto DispatchExit; + } + + + if (EnterForwarder ()) { + if (IrpStack->FileObject==RouterFile) { + switch (IrpStack->Parameters.DeviceIoControl.IoControlCode) { + case IOCTL_FWD_SET_ROUTES: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_SET_ROUTES\n")); + if (inpBufLength>=sizeof (FWD_ROUTE_SET_PARAMS)) + status = DoSetRoutes ( + (PFWD_ROUTE_SET_PARAMS)inBuffer, + inpBufLength/sizeof(FWD_ROUTE_SET_PARAMS), + &Irp->IoStatus.Information); + + break; + + case IOCTL_FWD_SET_NB_NAMES: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_SET_NB_NAMES\n")); + if (inpBufLength==sizeof (ULONG)) + status = DoSetNbNames ( + *((PULONG)inBuffer), + outBufLength/sizeof (FWD_NB_NAME), + (PFWD_NB_NAME)outBuffer); + break; + + case IOCTL_FWD_RESET_NB_NAMES: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_RESET_NB_NAMES\n")); + if (inpBufLength==sizeof (ULONG)) + status = DoSetNbNames (*((PULONG)inBuffer), 0, NULL); + + break; + case IOCTL_FWD_GET_NB_NAMES: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_GET_NB_NAMES\n")); + if ((inpBufLength==sizeof (ULONG)) + && (outBufLength>=sizeof(ULONG))) { + Irp->IoStatus.Information = outBufLength + -FIELD_OFFSET (FWD_NB_NAMES_PARAMS, Names); + status = DoGetNbNames ( + *((PULONG)inBuffer), + &Irp->IoStatus.Information, + &((PFWD_NB_NAMES_PARAMS)outBuffer)->TotalCount, + ((PFWD_NB_NAMES_PARAMS)outBuffer)->Names); + if (NT_SUCCESS (status)) { + Irp->IoStatus.Information += FIELD_OFFSET ( + FWD_NB_NAMES_PARAMS, Names); + } + } + break; + + case IOCTL_FWD_CREATE_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_CREATE_INTERFACE\n")); + if (inpBufLength==sizeof(FWD_IF_CREATE_PARAMS)) + status = AddInterface ( + ((PFWD_IF_CREATE_PARAMS)inBuffer)->Index, + ((PFWD_IF_CREATE_PARAMS)inBuffer)->InterfaceType, + ((PFWD_IF_CREATE_PARAMS)inBuffer)->NetbiosAccept, + ((PFWD_IF_CREATE_PARAMS)inBuffer)->NetbiosDeliver); + break; + + case IOCTL_FWD_DELETE_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_DELETE_INTERFACE\n")); + if (inpBufLength==sizeof(ULONG)) + status = DeleteInterface ( + *((PULONG)inBuffer)); + + break; + + case IOCTL_FWD_SET_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_SET_INTERFACE\n")); + if (inpBufLength==sizeof(FWD_IF_SET_PARAMS)) + status = DoSetInterface ( + ((PFWD_IF_SET_PARAMS)inBuffer)->Index, + ((PFWD_IF_SET_PARAMS)inBuffer)->NetbiosAccept, + ((PFWD_IF_SET_PARAMS)inBuffer)->NetbiosDeliver); + break; + + case IOCTL_FWD_GET_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_GET_INTERFACE\n")); + if ((inpBufLength==sizeof(ULONG)) + && (outBufLength==sizeof(FWD_IF_GET_PARAMS))) { + status = DoGetInterface ( + *((PULONG)inBuffer), + &((PFWD_IF_GET_PARAMS)outBuffer)->Stats, + &((PFWD_IF_GET_PARAMS)outBuffer)->NetbiosAccept, + &((PFWD_IF_GET_PARAMS)outBuffer)->NetbiosDeliver); + if (NT_SUCCESS (status)) + Irp->IoStatus.Information = sizeof(FWD_IF_GET_PARAMS); + } + break; + + case IOCTL_FWD_BIND_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_BIND_INTERFACE\n")); + if (inpBufLength==sizeof(FWD_IF_BIND_PARAMS)) + status = DoBindInterface ( + ((PFWD_IF_BIND_PARAMS)inBuffer)->Index, + &((PFWD_IF_BIND_PARAMS)inBuffer)->Info); + break; + + case IOCTL_FWD_UNBIND_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_UNBIND_INTERFACE\n")); + if (inpBufLength==sizeof(ULONG)) + status = DoUnbindInterface (*((PULONG)inBuffer)); + break; + + case IOCTL_FWD_GET_DIAL_REQUEST: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_GET_DIAL_REQUEST\n")); + if (outBufLength>=sizeof (ULONG)) { + IoAcquireCancelSpinLock (&cancelIRQL); + if (!IsListEmpty (&ConnectionRequestQueue)) { + PINTERFACE_CB ifCB = CONTAINING_RECORD ( + ConnectionRequestQueue.Flink, + INTERFACE_CB, + ICB_ConnectionLink); + RemoveEntryList (&ifCB->ICB_ConnectionLink); + InitializeListEntry (&ifCB->ICB_ConnectionLink); + IoReleaseCancelSpinLock (cancelIRQL); + KeAcquireSpinLock (&ifCB->ICB_Lock, &cancelIRQL); + FillConnectionRequest ( + ifCB->ICB_Index, + ifCB->ICB_ConnectionPacket, + ifCB->ICB_ConnectionData, + (PFWD_DIAL_REQUEST)outBuffer, + outBufLength, + &Irp->IoStatus.Information); + status = STATUS_SUCCESS; + KeReleaseSpinLock (&ifCB->ICB_Lock, cancelIRQL); + } + else { + InsertTailList (&ConnectionIrpQueue, + &Irp->Tail.Overlay.ListEntry); + IoSetCancelRoutine (Irp, IpxFwdCancel); + IoReleaseCancelSpinLock (cancelIRQL); + IoMarkIrpPending (Irp); + Irp->IoStatus.Status = status = STATUS_PENDING; + } + } + break; + case IOCTL_FWD_DIAL_REQUEST_FAILED: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_DIAL_REQUEST_FAILED\n")); + if (inpBufLength==sizeof (ULONG)) + status = FailConnectionRequest ( + *((PULONG)inBuffer)); + break; + case IOCTL_FWD_DISABLE_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_DISABLE_INTERFACE\n")); + if (inpBufLength==sizeof (ULONG)) + status = DoDisableInterface ( + *((PULONG)inBuffer)); + break; + case IOCTL_FWD_ENABLE_INTERFACE: + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_ENABLE_INTERFACE\n")); + if (inpBufLength==sizeof (ULONG)) + status = DoEnableInterface ( + *((PULONG)inBuffer)); + break; + default: + IpxFwdDbgPrint (DBG_IOCTLS, DBG_WARNING, ("IpxFwd: unknown IRP_MJ_DEVICE_CONTROL\n")); + break; + + } + } + else if (IrpStack->Parameters.DeviceIoControl.IoControlCode + ==IOCTL_FWD_INTERNAL_BIND_FILTER) { + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_INTERNAL_BIND_FILTER\n")); + if ((inpBufLength==sizeof (IPX_FLT_BIND_INPUT)) + && (outBufLength>=sizeof (ULONG))) { + if (outBufLength>=sizeof (IPX_FLT_BIND_OUTPUT)) { + BindFilterDriver ( + (PIPX_FLT_BIND_INPUT)inBuffer, + (PIPX_FLT_BIND_OUTPUT)outBuffer); + Irp->IoStatus.Information = sizeof (IPX_FLT_BIND_OUTPUT); + FilterFile = IrpStack->FileObject; + status = STATUS_SUCCESS; + } + else { + IPX_FLT_BIND_OUTPUT bindOutput; + BindFilterDriver ( + (PIPX_FLT_BIND_INPUT)inBuffer, + &bindOutput); + memcpy (outBuffer, &bindOutput, outBufLength); + Irp->IoStatus.Information = outBufLength; + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else if (IrpStack->Parameters.DeviceIoControl.IoControlCode + ==IOCTL_FWD_GET_PERF_COUNTERS) { + IpxFwdDbgPrint(DBG_IOCTLS, DBG_INFORMATION, ("IpxFwd: IOCTL_FWD_GET_PERF_COUNTERS\n")); + if (outBufLength==sizeof (FWD_PERFORMANCE_PARAMS)) + status = DoGetPerfCounters ( + ((PFWD_PERFORMANCE_PARAMS)outBuffer)); + } + else { + status = STATUS_ACCESS_DENIED; + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, + ("IpxFwd: IOCTL: %08lx on non-router file object!\n", + IrpStack->Parameters.DeviceIoControl.IoControlCode)); + } + LeaveForwarder (); + } else { + if (IrpStack->Parameters.DeviceIoControl.IoControlCode==IOCTL_FWD_START) { + IpxFwdDbgPrint (DBG_IOCTLS, DBG_WARNING, + ("IpxFwd: IOCTL_FWD_START\n")); + if (inpBufLength==sizeof (FWD_START_PARAMS)) { + KeInitializeEvent (&ClientsGoneEvent, + SynchronizationEvent, + FALSE); + status = DoStart ( + ((PFWD_START_PARAMS)inBuffer)->RouteHashTableSize, + ((PFWD_START_PARAMS)inBuffer)->ThisMachineOnly); + if (NT_SUCCESS (status)) { + RouterFile = IrpStack->FileObject; + IpxFwdInitialized = TRUE; + } + } + } + else { + IpxFwdDbgPrint (DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: IOCTL: %08lx but fwd not started.\n", + IrpStack->Parameters.DeviceIoControl.IoControlCode)); + } + } + break; + default: + IpxFwdDbgPrint (DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: unknown MajorFunction.\n")); + break; + } + +DispatchExit: + if (status!=STATUS_PENDING) { + IpxFwdDbgPrint(DBG_IOCTLS, + NT_ERROR(status) ? DBG_WARNING : DBG_INFORMATION, + ("IpxFwd: completing IOCTL %08lx with status %08lx.\n", + IrpStack->Parameters.DeviceIoControl.IoControlCode, + status)); + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + return status; +} + + + +/*++ + +Routine Description: + Cleans up on driver unload + +Arguments: + + DriverObject - pointer to a driver object + +Return Value: + + +--*/ +VOID +IpxFwdUnload( + IN PDRIVER_OBJECT DriverObject + ) { + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, ("IpxFwd: unloading\n")); + if (EnterForwarder ()) { + LeaveForwarder (); + IpxFwdInitialized = FALSE; + while (InterlockedDecrement (&ClientCount)>=0) { + KeWaitForSingleObject (&ClientsGoneEvent, + Executive, + KernelMode, + FALSE, + (PLARGE_INTEGER)&WaitTimeout); + InterlockedIncrement (&ClientCount); + IpxFwdDbgPrint(DBG_IOCTLS, DBG_ERROR, + ("IpxFwd: Waiting for all clients (%ld) to exit.\n", + ClientCount)); + } + DoStop (); + } + + UnbindFromIpxDriver (KernelMode); + IoDeleteDevice (DriverObject->DeviceObject); +} + + + +/*++ + D o S t a r t + +Routine Description: + Initializes all driver components and binds to IPX + stack driver at strat up + +Arguments: + RouteHashTableSize - size of route hash table + thisMachineOnly - whether to forward dialin client packets + to other dests on the net + +Return Value: + STATUS_SUCCESS - initialization succeded + STATUS_UNSUCCESSFULL - failure + +--*/ +NTSTATUS +DoStart ( + IN ULONG RouteHashTableSize, + IN BOOLEAN thisMachineOnly + ) { + NTSTATUS status; + + InitializeConnectionQueues (); + RouteHashSize = RouteHashTableSize; + status = CreateTables (); + if (NT_SUCCESS (status)) { + InitializePacketAllocator (); + InitializeNetbiosQueue (); + InitializeRecvQueue (); + InitializeSendQueue (); + MeasuringPerformance = FALSE; + KeInitializeSpinLock (&PerfCounterLock); + ThisMachineOnly = thisMachineOnly; + + return STATUS_SUCCESS; + } + return status; +} + +/*++ + D o S t o p + +Routine Description: + Cleans up allocated resources and unbinds from IPX stack + driver when forwarder is stopped + +Arguments: + None + +Return Value: + STATUS_SUCCESS - cleanup succeded + +--*/ +NTSTATUS +DoStop ( + void + ) { + if (FilterFile!=NULL) { + UnbindFilterDriver (); + FilterFile = NULL; + } + DeleteSendQueue (); + DeleteRecvQueue (); + DeleteNetbiosQueue (); + DeleteTables (); // Unbinds all bound interfaces + if (WanPacketListId!=-1) { + DeregisterPacketConsumer (WanPacketListId); + WanPacketListId = -1; + } + DeletePacketAllocator (); + return STATUS_SUCCESS; +} + +/*++ + D o S e t R o u t e s + +Routine Description: + Updates route table with supplied routes + +Arguments: + routeArray - array of routes to add/de;ete/update + nRoutes - number of routes in the array + nProcessed - number of routes that were processed successfully + +Return Value: + STATUS_SUCCESS - all routes were processed ok + error status - reason of failure for the first unprocessed route + +--*/ +NTSTATUS +DoSetRoutes ( + IN PFWD_ROUTE_SET_PARAMS routeArray, + IN ULONG nRoutes, + OUT PULONG nProcessed + ) { + NTSTATUS status=STATUS_SUCCESS; + UINT i; + + for (i=0; i<nRoutes; i++, routeArray++) { + switch (routeArray->Action) { + case FWD_ADD_ROUTE: + status = AddRoute (routeArray->Network, + routeArray->NextHopAddress, + routeArray->TickCount, + routeArray->HopCount, + routeArray->InterfaceIndex); + break; + case FWD_DELETE_ROUTE: + status = DeleteRoute (routeArray->Network); + break; + case FWD_UPDATE_ROUTE: + status = UpdateRoute (routeArray->Network, + routeArray->NextHopAddress, + routeArray->TickCount, + routeArray->HopCount, + routeArray->InterfaceIndex); + break; + default: + status = STATUS_INVALID_PARAMETER; + break; + } + if (!NT_SUCCESS (status)) + break; + } + *nProcessed = i; + return status; +} + + +/*++ + D o S e t N b N a m e s + +Routine Description: + Sets static Netbios Names on the interface + +Arguments: + InterfaceIndex - index oc interface on which to set names + Count - number of names to set + Names - array of netbios names + +Return Value: + STATUS_SUCCESS - names were set OK + STATUS_UNSUCCESSFULL - interface does not exist + STATUS_INSUFFICIENT_RESOURCES - not enough resources to complete + the operation + +--*/ +NTSTATUS +DoSetNbNames ( + IN ULONG InterfaceIndex, + IN ULONG Count, + IN PFWD_NB_NAME Names + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + PNB_ROUTE nbRoutes; + NTSTATUS status=STATUS_SUCCESS; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + if (ifCB->ICB_NBRoutes!=NULL) { + DeleteNBRoutes (ifCB->ICB_NBRoutes, ifCB->ICB_NBRouteCount); + ifCB->ICB_NBRoutes = NULL; + ifCB->ICB_NBRouteCount = 0; + } + if (Count>0) { + status = AddNBRoutes (ifCB, Names, Count, &nbRoutes); + if (NT_SUCCESS (status)) { + ifCB->ICB_NBRoutes = nbRoutes; + ifCB->ICB_NBRouteCount = Count; + } + } + ReleaseInterfaceReference (ifCB); + } + else + status = STATUS_UNSUCCESSFUL; + + return status; +} + + +/*++ + D o G e t N b N a m e s + +Routine Description: + Gets all static Netbios Names on the interface + +Arguments: + InterfaceIndex - index of interface from which to get names + ArraySize - on input: size of the buffer to put names into + on output: size of data put into the array + Names - buffer to put names into names, if buffer + is to small to hold all names, this orutine stuffs + total number of names into the first ULONG in the + array (this is the only way to return in to the + caller through the IOCTL interface) + +Return Value: + STATUS_SUCCESS - names were copied into the array + STATUS_UNSUCCESSFULL - interface does not exist + STATUS_BUFFER_OVERFLOW - buffer is too small to copy all the + names, number of names are in the first ULONG of + the buffer + +--*/ +NTSTATUS +DoGetNbNames ( + IN ULONG InterfaceIndex, + IN OUT ULONG *ArraySize, + OUT ULONG *TotalCount, + OUT PFWD_NB_NAME Names + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + NTSTATUS status=STATUS_SUCCESS; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + if (ifCB->ICB_NBRoutes!=NULL) { + ULONG i; + PFWD_NB_NAME nameLM = Names+(*ArraySize/sizeof(FWD_NB_NAME)); + for (i=0; (i<ifCB->ICB_NBRouteCount)&&(Names<nameLM); i++, Names++) + NB_NAME_CPY (Names, &ifCB->ICB_NBRoutes[i].NBR_Name); + *ArraySize = sizeof (FWD_NB_NAME)*i; + *TotalCount = ifCB->ICB_NBRouteCount; + } + else { + *ArraySize = 0; + *TotalCount = 0; + } + ReleaseInterfaceReference (ifCB); + } + else + status = STATUS_UNSUCCESSFUL; + + return status; +} + + +/*++ + D o S e t I n t e r f a c e + +Routine Description: + Sets interface configurable parameters + +Arguments: + InterfaceIndex - index of interface to set + NetbiosAccept - whether to accept nb packets on the interface + NetbiosDeliver - whether to deliver nb packets on the interface + +Return Value: + STATUS_SUCCESS - interface was set OK + STATUS_UNSUCCESSFULL - interface does not exist + +--*/ +NTSTATUS +DoSetInterface ( + IN ULONG InterfaceIndex, + IN BOOLEAN NetbiosAccept, + IN UCHAR NetbiosDeliver + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + ifCB->ICB_NetbiosAccept = NetbiosAccept; + ifCB->ICB_NetbiosDeliver = NetbiosDeliver; + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + + +/*++ + D o G e t I n t e r f a c e + +Routine Description: + Gets interface configurable parameters and statistics + +Arguments: + InterfaceIndex - index of interface to query + stats - interface statistics + NetbiosAccept - whether nb packets accepter on the interface + NetbiosDeliver - whether nb packets delivered on the interface + +Return Value: + STATUS_SUCCESS - interface data was queried OK + STATUS_UNSUCCESSFULL - interface does not exist + +--*/ +NTSTATUS +DoGetInterface ( + IN ULONG InterfaceIndex, + OUT PFWD_IF_STATS stats, + OUT BOOLEAN *NetbiosAccept, + OUT UCHAR *NetbiosDeliver + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + *NetbiosAccept = ifCB->ICB_NetbiosAccept; + *NetbiosDeliver = ifCB->ICB_NetbiosDeliver; + IF_STATS_CPY (stats, &ifCB->ICB_Stats); + if (!IS_IF_ENABLED(ifCB)) + stats->OperationalState = FWD_OPER_STATE_DOWN; + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + +/*++ + D o B i n d I n t e r f a c e + +Routine Description: + Binds interface to the specified adapter and sets binding + parameters + +Arguments: + InterfaceIndex - index of interface to bind + info - binding info + +Return Value: + STATUS_SUCCESS - interface was bound OK + STATUS_UNSUCCESSFULL - interface does not exist or could not be + bound +--*/ +NTSTATUS +DoBindInterface ( + IN ULONG InterfaceIndex, + IN PFWD_ADAPTER_BINDING_INFO info + ) { + PINTERFACE_CB ifCB; + NTSTATUS status; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + if (ifCB->ICB_InterfaceType==FWD_IF_PERMANENT) + status = BindInterface (ifCB, + (USHORT)info->AdapterIndex, + info->MaxPacketSize, + info->Network, + info->LocalNode, + info->RemoteNode); + else + status = STATUS_SUCCESS; + ReleaseInterfaceReference (ifCB); + return status; + } + else + return STATUS_UNSUCCESSFUL; +} + + +/*++ + D o U n b i n d I n t e r f a c e + +Routine Description: + Unbinds interface from the adapter and invalidates binding + parameters + +Arguments: + InterfaceIndex - index of interface to unbind + +Return Value: + STATUS_SUCCESS - interface was unbound OK + STATUS_UNSUCCESSFULL - interface does not exist +--*/ +NTSTATUS +DoUnbindInterface ( + IN ULONG InterfaceIndex + ) { + PINTERFACE_CB ifCB; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + if (ifCB->ICB_InterfaceType==FWD_IF_PERMANENT) + UnbindInterface (ifCB); + + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + +/*++ + D o D i s a b l e I n t e r f a c e + +Routine Description: + Disables all packet traffic through the interface + +Arguments: + InterfaceIndex - index of interface to disable + +Return Value: + STATUS_SUCCESS - interface was disabled OK + STATUS_UNSUCCESSFULL - interface does not exist +--*/ +NTSTATUS +DoDisableInterface ( + IN ULONG InterfaceIndex + ) { + PINTERFACE_CB ifCB; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + KIRQL oldIRQL; + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (IS_IF_ENABLED (ifCB)) { + SET_IF_DISABLED (ifCB); + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) { + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + } + else + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + + +/*++ + D o E n a b l e I n t e r f a c e + +Routine Description: + Enables all packet traffic through the interface + +Arguments: + InterfaceIndex - index of interface to enable + +Return Value: + STATUS_SUCCESS - interface was disabled OK + STATUS_UNSUCCESSFULL - interface does not exist +--*/ +NTSTATUS +DoEnableInterface ( + IN ULONG InterfaceIndex + ) { + PINTERFACE_CB ifCB; + + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + SET_IF_ENABLED (ifCB); + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; + } + else + return STATUS_UNSUCCESSFUL; +} + + + +/*++ + I p x F w d C a n c e l + +Routine Description: + Cancels specified IRP + +Arguments: + DeviceObject - forwarder device object + irp - irp to cancel + +Return Value: + None +--*/ +VOID +IpxFwdCancel ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP irp + ) { + RemoveEntryList (&irp->Tail.Overlay.ListEntry); + IoReleaseCancelSpinLock (irp->CancelIrql); + + irp->IoStatus.Information = 0; + irp->IoStatus.Status = STATUS_CANCELLED; + IpxFwdDbgPrint(DBG_IOCTLS, DBG_WARNING, ("IpxFwd: completing cancelled irp.\n")); + IoCompleteRequest(irp, IO_NO_INCREMENT); +} + +/*++ + D o G e t P e r f C o u n t e r s + +Routine Description: + Gets performance counters + +Arguments: + perfParams - buffer ot pu counters into + +Return Value: + STATUS_SUCCESS - counter were copied ok + STATUS_UNSUCCESSFULL - performance measurement were not enabled +--*/ +NTSTATUS +DoGetPerfCounters ( + OUT PFWD_PERFORMANCE_PARAMS perfParams + ) { + LONGLONG lTotalPacketProcessingTime; + LONGLONG lMaxPacketProcessingTime; + LONG lPacketCounter; + LONGLONG lTotalNbPacketProcessingTime; + LONGLONG lMaxNbPacketProcessingTime; + LONG lNbPacketCounter; + KIRQL oldIRQL; + + if (!MeasuringPerformance) + return STATUS_UNSUCCESSFUL; + + KeAcquireSpinLock (&PerfCounterLock, &oldIRQL); + *perfParams = PerfBlock; + memset (&PerfBlock, 0, sizeof (PerfBlock)); + KeReleaseSpinLock (&PerfCounterLock, oldIRQL); + return STATUS_SUCCESS; +} + + +BOOLEAN +DoLeaveForwarder ( + VOID + ) { + return LeaveForwarder (); +} diff --git a/private/ntos/tdi/isn/fwd/driver.h b/private/ntos/tdi/isn/fwd/driver.h new file mode 100644 index 000000000..ecc298345 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/driver.h @@ -0,0 +1,102 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\driver.h + +Abstract: + IPX Forwarder driver dispatch routines + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + + +#ifndef _IPXFWD_DRIVER_ +#define _IPXFWD_DRIVER_ + +// Pseudo constant 0xFFFFFFFFFFFFF +extern const UCHAR BROADCAST_NODE[6]; + +// Performance measurement: +// Enabling flag +extern BOOLEAN MeasuringPerformance; +// Access control +extern KSPIN_LOCK PerfCounterLock; +// Statistic accumulators (counters) +extern FWD_PERFORMANCE PerfBlock; + +// Access control for external callers (ipx stack, filter driver) +// Flag set upon completion of initialization of all components +extern volatile BOOLEAN IpxFwdInitialized; +// Number of clients executing forwarder code (if -1, the forwarder +// is being stopped) +extern LONG ClientCount; +// Event to be signalled by the last client inside forwarder +extern KEVENT ClientsGoneEvent; + + +/*++ + E n t e r F o r w a r d e r + +Routine Description: + Checks if forwarder is initialized and grants access + to it (records the entrance as well + +Arguments: + None + +Return Value: + TRUE - access granted + FALSE - forwarder is not yet initialized or is being stopped + +--*/ +//BOOLEAN +//EnterForwarder ( +// void +// ); +#define EnterForwarder() ( \ + (InterlockedIncrement(&ClientCount), IpxFwdInitialized) \ + ? TRUE \ + : (DoLeaveForwarder(), FALSE) \ + ) + +/*++ + L e a v e F o r w a r d e r + +Routine Description: + Records the fact that external client stopped using forwarder + +Arguments: + None + +Return Value: + None + +--*/ +//BOOLEAN +//EnterForwarder ( +// void +// ); +#define LeaveForwarder() \ + ((InterlockedDecrement(&ClientCount)<0) \ + ? KeSetEvent (&ClientsGoneEvent,0,FALSE) \ + : 0 \ + ) + +// Same as above but implemented as a routine to be used in +// the EnterForwarder macro above (this reduces code size +// and aids in debugging by improving readability of disassembly +BOOLEAN +DoLeaveForwarder ( + VOID + ); + +#endif diff --git a/private/ntos/tdi/isn/fwd/filterif.c b/private/ntos/tdi/isn/fwd/filterif.c new file mode 100644 index 000000000..f1fa584a3 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/filterif.c @@ -0,0 +1,211 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\filterif.c + +Abstract: + IPX Forwarder driver interface with filter driver + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + + // Filter driver entry points +IPX_FLT_BIND_INPUT FltBindInput = {NULL, NULL}; + // Protects access to filter driver contexts +RW_LOCK FltLock; + + +/*++ + D o F i l t e r + +Routine Description: + + Calls filter driver entry point while holding reader access + to interface contexts + +Arguments: + ipxHdr - pointer to packet header + ipxHdrLength - size of the header buffer (must be at least 30) + ifInContext - context associated with interface on which packet + was received + ifOutContext - context associated with interface on which packet + will be sent +Return Value: + FILTER_PERMIT - packet should be passed on by the forwarder + FILTER_DENY - packet should be dropped + +--*/ +FILTER_ACTION +DoFilter ( + IN PUCHAR ipxHdr, + IN ULONG ipxHdrLength, + IN PVOID ifInContext, + IN PVOID ifOutContex + ) { + RWCOOKIE cookie; + FILTER_ACTION result; + AcquireReaderAccess (&FltLock, cookie); + result = FltBindInput.FilterHandler (ipxHdr, + ipxHdrLength, + ifInContext, + ifOutContex); + ReleaseReaderAccess (&FltLock, cookie); + return result; +} + +/*++ + D o I n t e r f a c e D e l e t e d + +Routine Description: + Resets interface contexts and calls filter dirver entry point + making sure that all no one holds reader access to filter driver + interface contexts +Arguments: + ifCB - interface to be deleted +Return Value: + None + +--*/ +VOID +DoInterfaceDeleted ( + PINTERFACE_CB ifCB + ) { + PVOID inContext = ifCB->ICB_FilterInContext, + outContext = ifCB->ICB_FilterOutContext; + ifCB->ICB_FilterInContext = NO_FILTER_CONTEXT; + ifCB->ICB_FilterOutContext = NO_FILTER_CONTEXT; + WaitForAllReaders (&FltLock); + FltBindInput.InterfaceDeletedHandler(inContext, + outContext); +} + +/*++ + S e t I f I n C o n t e x t + +Routine Description: + Associates filter driver context with + the packets received on the interface +Arguments: + InterfaceIndex - index of the interface + ifInContext - filter driver context +Return Value: + STATUS_SUCCESS - context associated ok + STATUS_UNSUCCESSFUL - interface does not exist +--*/ +NTSTATUS +SetIfInContext ( + IN ULONG InterfaceIndex, + IN PVOID ifInContext + ) { + PINTERFACE_CB ifCB; + NTSTATUS status = STATUS_SUCCESS; + + if (EnterForwarder ()) { + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + ifCB->ICB_FilterInContext = ifInContext; + WaitForAllReaders (&FltLock); + } + else + status = STATUS_UNSUCCESSFUL; + LeaveForwarder (); + } + return status; +} + +/*++ + S e t I f O u t C o n t e x t + +Routine Description: + Associates filter driver context with + the packets sent on the interface +Arguments: + InterfaceIndex - index of the interface + ifOutContext - filter driver context +Return Value: + STATUS_SUCCESS - context associated ok + STATUS_UNSUCCESSFUL - interface does not exist +--*/ +NTSTATUS +SetIfOutContext ( + IN ULONG InterfaceIndex, + IN PVOID ifOutContext + ) { + PINTERFACE_CB ifCB; + NTSTATUS status = STATUS_SUCCESS; + + if (EnterForwarder ()) { + ifCB = GetInterfaceReference (InterfaceIndex); + if (ifCB!=NULL) { + ifCB->ICB_FilterOutContext = ifOutContext; + WaitForAllReaders (&FltLock); + } + else + status = STATUS_UNSUCCESSFUL; + LeaveForwarder (); + } + return status; +} + +/*++ + B i n d F i l t e r D r i v e r + +Routine Description: + Exchanges entry points with filter driver +Arguments: + bindInput - filter driver entry points + bindOutput - forwarder driver entry points +Return Value: + None +--*/ +VOID +BindFilterDriver ( + IN PIPX_FLT_BIND_INPUT bindInput, + OUT PIPX_FLT_BIND_OUTPUT bindOutput + ) { + memcpy (&FltBindInput, bindInput, sizeof (IPX_FLT_BIND_INPUT)); + bindOutput->Size = sizeof (IPX_FLT_BIND_OUTPUT); + bindOutput->SetIfInContextHandler = SetIfInContext; + bindOutput->SetIfOutContextHandler = SetIfOutContext; + InitializeRWLock (&FltLock); +} + +/*++ + U n b i n d F i l t e r D r i v e r + +Routine Description: + Resets locally stored filter driver entry points + and resets filter driver contexts on all interfaces +Arguments: + None +Return Value: + None +--*/ +VOID +UnbindFilterDriver ( + VOID + ) { + PINTERFACE_CB ifCB = NULL; + FltBindInput.FilterHandler = NULL; + FltBindInput.InterfaceDeletedHandler = NULL; + + while ((ifCB=GetNextInterfaceReference (ifCB))!=NULL) { + ifCB->ICB_FilterInContext = NO_FILTER_CONTEXT; + ifCB->ICB_FilterOutContext = NO_FILTER_CONTEXT; + } + InternalInterface->ICB_FilterInContext = NO_FILTER_CONTEXT; + InternalInterface->ICB_FilterOutContext = NO_FILTER_CONTEXT; + WaitForAllReaders (&FltLock); +} + diff --git a/private/ntos/tdi/isn/fwd/filterif.h b/private/ntos/tdi/isn/fwd/filterif.h new file mode 100644 index 000000000..0e09df1de --- /dev/null +++ b/private/ntos/tdi/isn/fwd/filterif.h @@ -0,0 +1,126 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\filterif.h + +Abstract: + IPX Forwarder interface with filter driver + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + + +#ifndef _IPXFWD_FILTERIF_ +#define _IPXFWD_FILTERIF_ + // Filter driver entry points +extern IPX_FLT_BIND_INPUT FltBindInput; + + // Macros to improve performance when filter driver + // is not bound or has not associated its contexts + // with interfaces of interest +#define FltFilter(hdr,hdrSize,inContext,outContext) ( \ + ((FltBindInput.FilterHandler==NULL) \ + || ((inContext==NO_FILTER_CONTEXT) \ + &&(outContext==NO_FILTER_CONTEXT))) \ + ? FILTER_PERMIT \ + : DoFilter (hdr,hdrSize,inContext,outContext) \ +) + +#define FltInterfaceDeleted(ifCB) { \ + if ((FltBindInput.InterfaceDeletedHandler!=NULL) \ + && ((ifCB->ICB_FilterInContext!=NO_FILTER_CONTEXT) \ + ||(ifCB->ICB_FilterOutContext!=NO_FILTER_CONTEXT))) \ + DoInterfaceDeleted (ifCB); \ +} + +/*++ + B i n d F i l t e r D r i v e r + +Routine Description: + Exchanges entry points with filter driver +Arguments: + bindInput - filter driver entry points + bindOutput - forwarder driver entry points +Return Value: + None +--*/ +VOID +BindFilterDriver ( + IN PIPX_FLT_BIND_INPUT bindInput, + OUT PIPX_FLT_BIND_OUTPUT bindOutput + ); + +/*++ + U n b i n d F i l t e r D r i v e r + +Routine Description: + Resets locally stored filter driver entry points + and resets filter driver contexts on all interfaces +Arguments: + None +Return Value: + None +--*/ +VOID +UnbindFilterDriver ( + VOID + ); + + +/*++ + D o F i l t e r + +Routine Description: + + Calls filter driver entry point while holding reader access + to interface contexts + +Arguments: + ipxHdr - pointer to packet header + ipxHdrLength - size of the header buffer (must be at least 30) + ifInContext - context associated with interface on which packet + was received + ifOutContext - context associated with interface on which packet + will be sent +Return Value: + FILTER_PERMIT - packet should be passed on by the forwarder + FILTER_DENY - packet should be dropped + +--*/ +FILTER_ACTION +DoFilter ( + IN PUCHAR ipxHdr, + IN ULONG ipxHdrLength, + IN PVOID ifInContext, + IN PVOID ifOutContex + ); + +/*++ + D o I n t e r f a c e D e l e t e d + +Routine Description: + Resets interface contexts and calls filter dirver entry point + making sure that all no one holds reader access to filter driver + interface contexts +Arguments: + ifCB - interface to be deleted +Return Value: + None + +--*/ +VOID +DoInterfaceDeleted ( + PINTERFACE_CB ifCB + ); + +#endif + diff --git a/private/ntos/tdi/isn/fwd/fwd.mak b/private/ntos/tdi/isn/fwd/fwd.mak new file mode 100644 index 000000000..e47660250 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/fwd.mak @@ -0,0 +1,2427 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.10 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (PPC) Dynamic-Link Library" 0x0702 +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +!IF "$(CFG)" == "" +CFG=fwd - Win32 Release +!MESSAGE No configuration specified. Defaulting to fwd - Win32 Release. +!ENDIF + +!IF "$(CFG)" != "fwd - Win32 Release" && "$(CFG)" !=\ + "fwd - Win32 (PPC) Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fwd.mak" CFG="fwd - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fwd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "fwd - Win32 (PPC) Release" (based on\ + "Win32 (PPC) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "fwd - Win32 Release" + +!IF "$(CFG)" == "fwd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\fwd.dll" + +CLEAN : + -@erase "$(INTDIR)\ddreqs.obj" + -@erase "$(INTDIR)\debug.obj" + -@erase "$(INTDIR)\driver.obj" + -@erase "$(INTDIR)\filterif.obj" + -@erase "$(INTDIR)\ipxbind.obj" + -@erase "$(INTDIR)\lineind.obj" + -@erase "$(INTDIR)\netbios.obj" + -@erase "$(INTDIR)\nwlnkfwd.res" + -@erase "$(INTDIR)\packets.obj" + -@erase "$(INTDIR)\rcvind.obj" + -@erase "$(INTDIR)\registry.obj" + -@erase "$(INTDIR)\send.obj" + -@erase "$(INTDIR)\tables.obj" + -@erase "$(OUTDIR)\fwd.dll" + -@erase "$(OUTDIR)\fwd.exp" + -@erase "$(OUTDIR)\fwd.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\inc" /I "..\..\inc" /I "..\..\..\inc" /I "..\..\..\..\net\routing\inc" /I "..\..\..\..\inc" /D _X86_=1 /D i386=1 /D "STD_CALL" /D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D WIN32=100 /D _NT1X_=100 /D WINNT=1 /D WIN32_LEAN_AND_MEAN=1 /D DBG=1 /D DEVL=1 /D FPO=0 /D "_NTDRIVER_" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "..\inc" /I "..\..\inc" /I "..\..\..\inc"\ + /I "..\..\..\..\net\routing\inc" /I "..\..\..\..\inc" /D _X86_=1 /D i386=1 /D\ + "STD_CALL" /D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D WIN32=100 /D\ + _NT1X_=100 /D WINNT=1 /D WIN32_LEAN_AND_MEAN=1 /D DBG=1 /D DEVL=1 /D FPO=0 /D\ + "_NTDRIVER_" /Fp"$(INTDIR)/fwd.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/nwlnkfwd.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/fwd.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\ + /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)/fwd.pdb" /machine:I386\ + /out:"$(OUTDIR)/fwd.dll" /implib:"$(OUTDIR)/fwd.lib" +LINK32_OBJS= \ + "$(INTDIR)\ddreqs.obj" \ + "$(INTDIR)\debug.obj" \ + "$(INTDIR)\driver.obj" \ + "$(INTDIR)\filterif.obj" \ + "$(INTDIR)\ipxbind.obj" \ + "$(INTDIR)\lineind.obj" \ + "$(INTDIR)\netbios.obj" \ + "$(INTDIR)\nwlnkfwd.res" \ + "$(INTDIR)\packets.obj" \ + "$(INTDIR)\rcvind.obj" \ + "$(INTDIR)\registry.obj" \ + "$(INTDIR)\send.obj" \ + "$(INTDIR)\tables.obj" + +"$(OUTDIR)\fwd.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "fwd___Wi" +# PROP BASE Intermediate_Dir "fwd___Wi" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "fwd___Wi" +# PROP Intermediate_Dir "fwd___Wi" +# PROP Target_Dir "" +OUTDIR=.\fwd___Wi +INTDIR=.\fwd___Wi + +ALL : "$(OUTDIR)\fwd.dll" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CLEAN : + -@erase ".\fwd___Wi\fwd.dll" + -@erase ".\fwd___Wi\Tables.obj" + -@erase ".\fwd___Wi\rcvind.obj" + -@erase ".\fwd___Wi\packets.obj" + -@erase ".\fwd___Wi\ipxbind.obj" + -@erase ".\fwd___Wi\driver.obj" + -@erase ".\fwd___Wi\send.obj" + -@erase ".\fwd___Wi\registry.obj" + -@erase ".\fwd___Wi\netbios.obj" + -@erase ".\fwd___Wi\lineind.obj" + -@erase ".\fwd___Wi\nwlnkfwd.res" + -@erase ".\fwd___Wi\fwd.lib" + -@erase ".\fwd___Wi\fwd.exp" + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /PPC32 +# ADD MTL /nologo /D "NDEBUG" /PPC32 +MTL_PROJ=/nologo /D "NDEBUG" /PPC32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /Z7 /Oi /Gy /I "..\inc" /I "..\..\..\inc" /I "..\..\..\..\inc" /I "e:\NT\public\oak\inc" /I "e:\NT\public\sdk\inc" /I "e:\NT\public\sdk\inc\crt" /FI"e:\NT\public\sdk\inc\warning.h" /D PPC=1 /D _PPC_=1 /D "NO_EXT_KEYS" /D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D WIN32=100 /D _NT1X_=100 /D WINNT=1 /D WIN32_LEAN_AND_MEAN=1 /D _M_PPC=1 /D DBG=1 /D DEVL=1 /D "_NTDRIVER_" /D __stdcall= /D __cdecl= /D _cdecl= /D cdecl= /D FPO=1 /D "LANGUAGE_C" -Zel -ZB64 /c +CPP_PROJ=/nologo /ML /W3 /Z7 /Oi /Gy /I "..\inc" /I "..\..\..\inc" /I\ + "..\..\..\..\inc" /I "e:\NT\public\oak\inc" /I "e:\NT\public\sdk\inc" /I\ + "e:\NT\public\sdk\inc\crt" /FI"e:\NT\public\sdk\inc\warning.h" /D PPC=1 /D\ + _PPC_=1 /D "NO_EXT_KEYS" /D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D\ + WIN32=100 /D _NT1X_=100 /D WINNT=1 /D WIN32_LEAN_AND_MEAN=1 /D _M_PPC=1 /D\ + DBG=1 /D DEVL=1 /D "_NTDRIVER_" /D __stdcall= /D __cdecl= /D _cdecl= /D cdecl=\ + /D FPO=1 /D "LANGUAGE_C" /Fo"$(INTDIR)/" -Zel -ZB64 /c +CPP_OBJS=.\fwd___Wi/ +CPP_SBRS= + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/nwlnkfwd.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/fwd.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:PPC +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:PPC +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\ + /subsystem:windows /dll /pdb:"$(OUTDIR)/fwd.pdb" /machine:PPC\ + /out:"$(OUTDIR)/fwd.dll" /implib:"$(OUTDIR)/fwd.lib" +LINK32_OBJS= \ + "$(INTDIR)/Tables.obj" \ + "$(INTDIR)/rcvind.obj" \ + "$(INTDIR)/packets.obj" \ + "$(INTDIR)/ipxbind.obj" \ + "$(INTDIR)/driver.obj" \ + "$(INTDIR)/send.obj" \ + "$(INTDIR)/registry.obj" \ + "$(INTDIR)/netbios.obj" \ + "$(INTDIR)/lineind.obj" \ + "$(INTDIR)/nwlnkfwd.res" + +"$(OUTDIR)\fwd.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Target + +# Name "fwd - Win32 Release" +# Name "fwd - Win32 (PPC) Release" + +!IF "$(CFG)" == "fwd - Win32 Release" + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\sources.inc + +!IF "$(CFG)" == "fwd - Win32 Release" + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\send.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_SEND_=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\send.obj" : $(SOURCE) $(DEP_CPP_SEND_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_SEND_=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\send.obj" : $(SOURCE) $(DEP_CPP_SEND_) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\rcvind.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_RCVIN=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\rcvind.obj" : $(SOURCE) $(DEP_CPP_RCVIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_RCVIN=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\rcvind.obj" : $(SOURCE) $(DEP_CPP_RCVIN) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\netbios.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_NETBI=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\netbios.obj" : $(SOURCE) $(DEP_CPP_NETBI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_NETBI=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\netbios.obj" : $(SOURCE) $(DEP_CPP_NETBI) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\lineind.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_LINEI=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\lineind.obj" : $(SOURCE) $(DEP_CPP_LINEI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_LINEI=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\lineind.obj" : $(SOURCE) $(DEP_CPP_LINEI) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ipxbind.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_IPXBI=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\ipxbind.obj" : $(SOURCE) $(DEP_CPP_IPXBI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_IPXBI=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\ipxbind.obj" : $(SOURCE) $(DEP_CPP_IPXBI) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\driver.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_DRIVE=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\driver.obj" : $(SOURCE) $(DEP_CPP_DRIVE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_DRIVE=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\driver.obj" : $(SOURCE) $(DEP_CPP_DRIVE) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mp\sources + +!IF "$(CFG)" == "fwd - Win32 Release" + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\up\sources + +!IF "$(CFG)" == "fwd - Win32 Release" + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\registry.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_REGIS=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\registry.obj" : $(SOURCE) $(DEP_CPP_REGIS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_REGIS=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\registry.obj" : $(SOURCE) $(DEP_CPP_REGIS) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\packets.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_PACKE=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\packets.obj" : $(SOURCE) $(DEP_CPP_PACKE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_CPP_PACKE=\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntmp.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\..\inc\ipxfwd.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\send.h"\ + ".\tables.h"\ + "e:\NT\public\oak\inc\zwapi.h"\ + "e:\NT\public\sdk\inc\cfg.h"\ + "e:\NT\public\sdk\inc\devioctl.h"\ + "E:\NT\public\sdk\inc\mipsinst.h"\ + "e:\NT\public\sdk\inc\netevent.h"\ + "e:\NT\public\sdk\inc\nt.h"\ + "E:\nt\public\sdk\inc\ntalpha.h"\ + "e:\NT\public\sdk\inc\ntconfig.h"\ + "e:\NT\public\sdk\inc\ntddndis.h"\ + "e:\NT\public\sdk\inc\ntddtdi.h"\ + "e:\NT\public\sdk\inc\ntdef.h"\ + "e:\NT\public\sdk\inc\ntelfapi.h"\ + "e:\NT\public\sdk\inc\ntexapi.h"\ + "E:\nt\public\sdk\inc\nti386.h"\ + "e:\NT\public\sdk\inc\ntimage.h"\ + "e:\NT\public\sdk\inc\ntioapi.h"\ + "e:\NT\public\sdk\inc\ntiolog.h"\ + "e:\NT\public\sdk\inc\ntkeapi.h"\ + "e:\NT\public\sdk\inc\ntkxapi.h"\ + "e:\NT\public\sdk\inc\ntldr.h"\ + "e:\NT\public\sdk\inc\ntlpcapi.h"\ + "E:\nt\public\sdk\inc\ntmips.h"\ + "e:\NT\public\sdk\inc\ntmmapi.h"\ + "e:\NT\public\sdk\inc\ntnls.h"\ + "e:\NT\public\sdk\inc\ntobapi.h"\ + "e:\NT\public\sdk\inc\ntpnpapi.h"\ + "e:\NT\public\sdk\inc\ntpoapi.h"\ + "E:\nt\public\sdk\inc\ntppc.h"\ + "e:\NT\public\sdk\inc\ntpsapi.h"\ + "e:\NT\public\sdk\inc\ntregapi.h"\ + "e:\NT\public\sdk\inc\ntrtl.h"\ + "e:\NT\public\sdk\inc\ntseapi.h"\ + "e:\NT\public\sdk\inc\ntstatus.h"\ + "e:\NT\public\sdk\inc\ntxcapi.h"\ + "E:\NT\public\sdk\inc\ppcinst.h"\ + + +"$(INTDIR)\packets.obj" : $(SOURCE) $(DEP_CPP_PACKE) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\nwlnkfwd.rc + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_RSC_NWLNK=\ + {$(INCLUDE)}"\common.ver"\ + {$(INCLUDE)}"\ntverp.h"\ + + +"$(INTDIR)\nwlnkfwd.res" : $(SOURCE) $(DEP_RSC_NWLNK) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +DEP_RSC_NWLNK=\ + ".\common.ver"\ + ".\ntverp.h"\ + + +"$(INTDIR)\nwlnkfwd.res" : $(SOURCE) $(DEP_RSC_NWLNK) "$(INTDIR)" + $(RSC) /l 0x409 /fo"$(INTDIR)/nwlnkfwd.res" /d "NDEBUG" $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\tables.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_TABLE=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\tables.obj" : $(SOURCE) $(DEP_CPP_TABLE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ddreqs.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_DDREQ=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\ddreqs.obj" : $(SOURCE) $(DEP_CPP_DDREQ) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\debug.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_DEBUG=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\debug.obj" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\filterif.c + +!IF "$(CFG)" == "fwd - Win32 Release" + +DEP_CPP_FILTE=\ + "..\..\..\..\inc\ipxfwd.h"\ + "..\..\..\..\inc\nettypes.h"\ + "..\..\..\..\inc\packoff.h"\ + "..\..\..\..\inc\packon.h"\ + "..\..\..\..\inc\tdi.h"\ + "..\..\..\..\inc\tdikrnl.h"\ + "..\..\..\inc\afilter.h"\ + "..\..\..\inc\bugcodes.h"\ + "..\..\..\inc\efilter.h"\ + "..\..\..\inc\exlevels.h"\ + "..\..\..\inc\ffilter.h"\ + "..\..\..\inc\ndis.h"\ + "..\..\..\inc\ntddk.h"\ + "..\..\..\inc\ntiologc.h"\ + "..\..\..\inc\ntos.h"\ + "..\..\..\inc\tfilter.h"\ + "..\inc\bind.h"\ + "..\inc\ipxfltif.h"\ + "..\inc\isnkrnl.h"\ + ".\..\..\..\inc\alpha.h"\ + ".\..\..\..\inc\alpharef.h"\ + ".\..\..\..\inc\arc.h"\ + ".\..\..\..\inc\cache.h"\ + ".\..\..\..\inc\cm.h"\ + ".\..\..\..\inc\dbgk.h"\ + ".\..\..\..\inc\ex.h"\ + ".\..\..\..\inc\exboosts.h"\ + ".\..\..\..\inc\hal.h"\ + ".\..\..\..\inc\i386.h"\ + ".\..\..\..\inc\init.h"\ + ".\..\..\..\inc\kd.h"\ + ".\..\..\..\inc\ke.h"\ + ".\..\..\..\inc\lfs.h"\ + ".\..\..\..\inc\lpc.h"\ + ".\..\..\..\inc\mips.h"\ + ".\..\..\..\inc\mm.h"\ + ".\..\..\..\inc\ntosdef.h"\ + ".\..\..\..\inc\ob.h"\ + ".\..\..\..\inc\pnp.h"\ + ".\..\..\..\inc\po.h"\ + ".\..\..\..\inc\ppc.h"\ + ".\..\..\..\inc\ps.h"\ + ".\..\..\..\inc\se.h"\ + ".\..\..\..\inc\v86emul.h"\ + ".\ddreqs.h"\ + ".\debug.h"\ + ".\driver.h"\ + ".\filterif.h"\ + ".\fwddefs.h"\ + ".\ipxbind.h"\ + ".\lineind.h"\ + ".\netbios.h"\ + ".\packets.h"\ + ".\precomp.h"\ + ".\rcvind.h"\ + ".\registry.h"\ + ".\rwlock.h"\ + ".\send.h"\ + ".\tables.h"\ + "c:\nt\public\sdk\inc\mipsinst.h"\ + "c:\nt\public\sdk\inc\ntalpha.h"\ + "c:\nt\public\sdk\inc\nti386.h"\ + "c:\nt\public\sdk\inc\ntmips.h"\ + "c:\nt\public\sdk\inc\ntppc.h"\ + "c:\nt\public\sdk\inc\ppcinst.h"\ + {$(INCLUDE)}"\cfg.h"\ + {$(INCLUDE)}"\devioctl.h"\ + {$(INCLUDE)}"\netevent.h"\ + {$(INCLUDE)}"\nt.h"\ + {$(INCLUDE)}"\ntconfig.h"\ + {$(INCLUDE)}"\ntddndis.h"\ + {$(INCLUDE)}"\ntddtdi.h"\ + {$(INCLUDE)}"\ntdef.h"\ + {$(INCLUDE)}"\ntelfapi.h"\ + {$(INCLUDE)}"\ntexapi.h"\ + {$(INCLUDE)}"\ntimage.h"\ + {$(INCLUDE)}"\ntioapi.h"\ + {$(INCLUDE)}"\ntiolog.h"\ + {$(INCLUDE)}"\ntkeapi.h"\ + {$(INCLUDE)}"\ntkxapi.h"\ + {$(INCLUDE)}"\ntldr.h"\ + {$(INCLUDE)}"\ntlpcapi.h"\ + {$(INCLUDE)}"\ntmmapi.h"\ + {$(INCLUDE)}"\ntnls.h"\ + {$(INCLUDE)}"\ntobapi.h"\ + {$(INCLUDE)}"\ntpnpapi.h"\ + {$(INCLUDE)}"\ntpoapi.h"\ + {$(INCLUDE)}"\ntpsapi.h"\ + {$(INCLUDE)}"\ntregapi.h"\ + {$(INCLUDE)}"\ntrtl.h"\ + {$(INCLUDE)}"\ntseapi.h"\ + {$(INCLUDE)}"\ntstatus.h"\ + {$(INCLUDE)}"\ntxcapi.h"\ + {$(INCLUDE)}"\zwapi.h"\ + + +"$(INTDIR)\filterif.obj" : $(SOURCE) $(DEP_CPP_FILTE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "fwd - Win32 (PPC) Release" + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/private/ntos/tdi/isn/fwd/fwddefs.h b/private/ntos/tdi/isn/fwd/fwddefs.h new file mode 100644 index 000000000..af862b3b5 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/fwddefs.h @@ -0,0 +1,125 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\fwddefs.h + +Abstract: + IPX Forwarder driver constants and general macro definitions + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_FWDDEFS_ +#define _IPXFWD_FWDDEFS_ + + +// Forwarder tag used in memory allocations +#define FWD_POOL_TAG 'wFwN' + +//*** Offsets into the IPX header +#define IPXH_HDRSIZE 30 // Size of the IPX header +#define IPXH_CHECKSUM 0 // Checksum +#define IPXH_LENGTH 2 // Length +#define IPXH_XPORTCTL 4 // Transport Control +#define IPXH_PKTTYPE 5 // Packet Type +#define IPXH_DESTADDR 6 // Dest. Address (Total) +#define IPXH_DESTNET 6 // Dest. Network Address +#define IPXH_DESTNODE 10 // Dest. Node Address +#define IPXH_DESTSOCK 16 // Dest. Socket Number +#define IPXH_SRCADDR 18 // Source Address (Total) +#define IPXH_SRCNET 18 // Source Network Address +#define IPXH_SRCNODE 22 // Source Node Address +#define IPXH_SRCSOCK 28 // Source Socket Number + +//*** Packet Types we care about +#define IPX_NETBIOS_TYPE 20 // Netbios propagated packet + +//*** Socket Numbers we care about +#define IPX_NETBIOS_SOCKET ((USHORT)0x0455) +#define IPX_SAP_SOCKET ((USHORT)0x0452) +#define IPX_SMB_NAME_SOCKET ((USHORT)0x0551) + +//*** maximum nr of hops for a normal packet *** +#define IPX_MAX_HOPS 16 + +//*** offsets into the netbios name frames *** +#define NB_NAME_TYPE_FLAG 62 +#define NB_DATA_STREAM_TYPE2 63 +#define NB_NAME 64 +#define NB_TOTAL_DATA_LENGTH 80 +// *** offsets into smb name claim/query frames +#define SMB_OPERATION 62 +#define SMB_NAME_TYPE 63 +#define SMB_MESSAGE_IF 64 +#define SMB_NAME 66 + + +// Some commonly used macros +#define IPX_NODE_CPY(dst,src) memcpy(dst,src,6) +#define IPX_NODE_CMP(node1,node2) memcmp(node1,node2,6) + +#define IPX_NET_CPY(dst,src) memcpy(dst,src,4) +#define IPX_NET_CMP(net1,net2) memcmp(net1,net2,4) + +#define NB_NAME_CPY(dst,src) strncpy((char *)dst,(char *)src,16) +#define NB_NAME_CMP(name1,name2) strncmp((char *)name1,(char *)name2,16) + +// Make sure the structure is copied with DWORD granularity +#define IF_STATS_CPY(dst,src) \ + (dst)->OperationalState = (src)->OperationalState; \ + (dst)->MaxPacketSize = (src)->MaxPacketSize; \ + (dst)->InHdrErrors = (src)->InHdrErrors; \ + (dst)->InFiltered = (src)->InFiltered; \ + (dst)->InNoRoutes = (src)->InNoRoutes; \ + (dst)->InDiscards = (src)->InDiscards; \ + (dst)->InDelivers = (src)->InDelivers; \ + (dst)->OutFiltered = (src)->OutFiltered; \ + (dst)->OutDiscards = (src)->OutDiscards; \ + (dst)->OutDelivers = (src)->OutDelivers; \ + (dst)->NetbiosReceived = (src)->NetbiosReceived; \ + (dst)->NetbiosSent = (src)->NetbiosSent; + +// Extensions to list macros +#define InitializeListEntry(entry) InitializeListHead(entry) +#define IsListEntry(entry) IsListEmpty(entry) +#define IsSingleEntry(head) ((head)->Flink==(head)->Blink) + +// Conversions from/to on-the-wire format +#define GETUSHORT(src) ( \ + (USHORT)( \ + (((UCHAR *)src)[0]<<8) \ + + (((UCHAR *)src)[1]) \ + ) \ +) + +#define GETULONG(src) ( \ + (ULONG)( \ + (((UCHAR *)src)[0]<<24) \ + + (((UCHAR *)src)[1]<<16) \ + + (((UCHAR *)src)[2]<<8) \ + + (((UCHAR *)src)[3]) \ + ) \ +) + +#define PUTUSHORT(src,dst) { \ + ((UCHAR *)dst)[0] = ((UCHAR)(src>>8)); \ + ((UCHAR *)dst)[1] = ((UCHAR)src); \ +} + +#define PUTULONG(src,dst) { \ + ((UCHAR *)dst)[0] = ((UCHAR)(src>>24)); \ + ((UCHAR *)dst)[1] = ((UCHAR)(src>>16)); \ + ((UCHAR *)dst)[2] = ((UCHAR)(src>>8)); \ + ((UCHAR *)dst)[3] = ((UCHAR)src); \ +} + + +#endif diff --git a/private/ntos/tdi/isn/fwd/ipxbind.c b/private/ntos/tdi/isn/fwd/ipxbind.c new file mode 100644 index 000000000..71c7a37b3 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/ipxbind.c @@ -0,0 +1,462 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\ipxbind.c + +Abstract: + IPX Forwarder Driver interface with IPX stack driver + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + + +// global handle of the IPX driver +HANDLE HdlIpxFile; + + +// Buffer for IPX binding output structure +PIPX_INTERNAL_BIND_RIP_OUTPUT IPXBindOutput=NULL; + +NTSTATUS +IpxFwdFindRoute ( + IN PUCHAR Network, + IN PUCHAR Node, + OUT PIPX_FIND_ROUTE_REQUEST RouteEntry + ); + +/*++ +******************************************************************* + B i n d T o I p x D r i v e r + +Routine Description: + Exchanges binding information with IPX stack driver +Arguments: + None +Return Value: + STATUS_SUCCESS - exchange was done OK + STATUS_INSUFFICIENT_RESOURCES - could not allocate buffers for + info exchange + error status returned by IPX stack driver + +******************************************************************* +--*/ +NTSTATUS +BindToIpxDriver ( + KPROCESSOR_MODE requestorMode + ) { + NTSTATUS status; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + PIPX_INTERNAL_BIND_INPUT bip; + UNICODE_STRING UstrIpxFileName; + PWSTR WstrIpxFileName; + + ASSERT (IPXBindOutput==NULL); + + // Read Ipx exported device name from the registry + status = ReadIpxDeviceName (&WstrIpxFileName); + if (!NT_SUCCESS (status)) + return status; + + RtlInitUnicodeString (&UstrIpxFileName, WstrIpxFileName); + InitializeObjectAttributes( + &ObjectAttributes, + &UstrIpxFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + if (requestorMode==UserMode) + status = ZwCreateFile(&HdlIpxFile, + SYNCHRONIZE | GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0L); + else + status = NtCreateFile(&HdlIpxFile, + SYNCHRONIZE | GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0L); + + if (!NT_SUCCESS(status)) { + IpxFwdDbgPrint (DBG_IPXBIND, DBG_ERROR, + ("IpxFwd: Open of the IPX driver failed with %lx\n", status)); + return status; + } + + IpxFwdDbgPrint (DBG_IPXBIND, DBG_INFORMATION, + ("IpxFwd: Open of the IPX driver was successful.\n")); + + // First, send a IOCTL to find out how much data we need to allocate + if ((bip = ExAllocatePoolWithTag ( + PagedPool, + sizeof(IPX_INTERNAL_BIND_INPUT), + FWD_POOL_TAG)) == NULL) { + + if (KeGetPreviousMode()!=KernelMode) + ZwClose (HdlIpxFile); + else + NtClose (HdlIpxFile); + IpxFwdDbgPrint (DBG_IPXBIND, DBG_ERROR, + ("IpxFwd: Could not allocate input binding buffer!\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // fill in our bind data + // bip->Version = 1; + bip->Version = ISN_VERSION; + bip->Identifier = IDENTIFIER_RIP; + bip->BroadcastEnable = TRUE; + bip->LookaheadRequired = IPXH_HDRSIZE; + bip->ProtocolOptions = 0; + bip->ReceiveHandler = IpxFwdReceive; + bip->ReceiveCompleteHandler = IpxFwdReceiveComplete; + bip->SendCompleteHandler = IpxFwdSendComplete; + bip->TransferDataCompleteHandler = IpxFwdTransferDataComplete; + bip->FindRouteCompleteHandler = NULL; + bip->LineUpHandler = IpxFwdLineUp; + bip->LineDownHandler = IpxFwdLineDown; + bip->InternalSendHandler = IpxFwdInternalSend; + bip->FindRouteHandler = IpxFwdFindRoute; + bip->InternalReceiveHandler = IpxFwdInternalReceive; +// bip->RipParameters = GlobalWanNetwork ? IPX_RIP_PARAM_GLOBAL_NETWORK : 0; + + + if (requestorMode==UserMode) + status = ZwDeviceIoControlFile( + HdlIpxFile, // HANDLE to File + NULL, // HANDLE to Event + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, // IO_STATUS_BLOCK + IOCTL_IPX_INTERNAL_BIND, // IoControlCode + bip, // Input Buffer + sizeof(IPX_INTERNAL_BIND_INPUT),// Input Buffer Length + NULL, // Output Buffer + 0); // Output Buffer Length + else + status = NtDeviceIoControlFile( + HdlIpxFile, // HANDLE to File + NULL, // HANDLE to Event + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, // IO_STATUS_BLOCK + IOCTL_IPX_INTERNAL_BIND, // IoControlCode + bip, // Input Buffer + sizeof(IPX_INTERNAL_BIND_INPUT),// Input Buffer Length + NULL, // Output Buffer + 0); // Output Buffer Length + + + if (status == STATUS_PENDING) { + if (requestorMode==UserMode) + status = ZwWaitForSingleObject( + HdlIpxFile, + FALSE, + NULL); + else + status = NtWaitForSingleObject( + HdlIpxFile, + FALSE, + NULL); + if (NT_SUCCESS(status)) + status = IoStatusBlock.Status; + } + + if (status != STATUS_BUFFER_TOO_SMALL) { + IpxFwdDbgPrint (DBG_IPXBIND, DBG_ERROR, + ("IpxFwd: Ioctl to the IPX driver failed with %lx\n", status)); + + ExFreePool(bip); + if (requestorMode==UserMode) + ZwClose (HdlIpxFile); + else + NtClose (HdlIpxFile); + return STATUS_INVALID_PARAMETER; + } + + if ((IPXBindOutput = (PIPX_INTERNAL_BIND_RIP_OUTPUT) + ExAllocatePoolWithTag(NonPagedPool, + IoStatusBlock.Information, + FWD_POOL_TAG)) == NULL) { + + ExFreePool(bip); + if (requestorMode==UserMode) + ZwClose (HdlIpxFile); + else + NtClose (HdlIpxFile); + IpxFwdDbgPrint (DBG_IPXBIND, DBG_ERROR, + ("IpxFwd: Could not allocate output binding buffer!\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + + + if (requestorMode==UserMode) + status = ZwDeviceIoControlFile( + HdlIpxFile, // HANDLE to File + NULL, // HANDLE to Event + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, // IO_STATUS_BLOCK + IOCTL_IPX_INTERNAL_BIND, // IoControlCode + bip, // Input Buffer + sizeof(IPX_INTERNAL_BIND_INPUT),// Input Buffer Length + IPXBindOutput, // Output Buffer + IoStatusBlock.Information); // Output Buffer Length + else + status = NtDeviceIoControlFile( + HdlIpxFile, // HANDLE to File + NULL, // HANDLE to Event + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, // IO_STATUS_BLOCK + IOCTL_IPX_INTERNAL_BIND, // IoControlCode + bip, // Input Buffer + sizeof(IPX_INTERNAL_BIND_INPUT),// Input Buffer Length + IPXBindOutput, // Output Buffer + IoStatusBlock.Information); // Output Buffer Length + + + if (status == STATUS_PENDING) { + if (requestorMode==UserMode) + status = ZwWaitForSingleObject( + HdlIpxFile, + (BOOLEAN)FALSE, + NULL); + else + status = NtWaitForSingleObject( + HdlIpxFile, + (BOOLEAN)FALSE, + NULL); + if (NT_SUCCESS(status)) + status = IoStatusBlock.Status; + } + + if (!NT_SUCCESS (status)) { + IpxFwdDbgPrint (DBG_IPXBIND, DBG_ERROR, + ("IpxFwd: Ioctl to the IPX driver failed with %lx\n", IoStatusBlock.Status)); + + ExFreePool(bip); + ExFreePool(IPXBindOutput); + IPXBindOutput = NULL; + if (requestorMode==UserMode) + ZwClose (HdlIpxFile); + else + NtClose (HdlIpxFile); + return status; + } + + IpxFwdDbgPrint (DBG_IPXBIND, DBG_INFORMATION, + ("IpxFwd: Succesfuly bound to the IPX driver\n")); + + ExFreePool (bip); + ExFreePool (WstrIpxFileName); + + return status; +} + + +/*++ +******************************************************************* + U n b i n d F r o m I p x D r i v e r + +Routine Description: + Closes connection to IPX stack driver +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +UnbindFromIpxDriver ( + KPROCESSOR_MODE requestorMode + ) { + // Free binding output buffer and close driver handle + ASSERT (IPXBindOutput!=NULL); + ExFreePool (IPXBindOutput); + IPXBindOutput = NULL; + IpxFwdDbgPrint (DBG_IPXBIND, DBG_WARNING, + ("IpxFwd: Closing IPX driver handle\n")); + if (requestorMode==UserMode) + ZwClose (HdlIpxFile); + else + NtClose (HdlIpxFile); +} + + +/*++ +******************************************************************* + F w F i n d R o u t e + +Routine Description: + This routine is provided by the Kernel Forwarder to find the route + to a given node and network +Arguments: + Network - the destination network + Node - destination node + RouteEntry - filled in by the Forwarder if a route exists +Return Value: + STATUS_SUCCESS + STATUS_NETWORK_UNREACHABLE - if the findroute failed +******************************************************************* +--*/ +NTSTATUS +IpxFwdFindRoute ( + IN PUCHAR Network, + IN PUCHAR Node, + OUT PIPX_FIND_ROUTE_REQUEST RouteEntry + ) { + PINTERFACE_CB ifCB; + ULONG net; + KIRQL oldIRQL; + NTSTATUS status; + PFWD_ROUTE fwRoute; + + if (!EnterForwarder ()) + return STATUS_UNSUCCESSFUL; + + net = GETULONG (Network); + + ifCB = FindDestination (net, Node, &fwRoute); + if (ifCB!=NULL) { + if (IS_IF_ENABLED(ifCB)) { + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + switch (ifCB->ICB_Stats.OperationalState) { + case FWD_OPER_STATE_UP: + IPX_NET_CPY (&RouteEntry->Network, Network); + if (fwRoute->FR_Network==ifCB->ICB_Network) { + if (Node!=NULL) { + IPX_NODE_CPY (RouteEntry->LocalTarget.MacAddress, Node); + } + else { + IPX_NODE_CPY (RouteEntry->LocalTarget.MacAddress, + BROADCAST_NODE); + } + } + else { + IPX_NODE_CPY (RouteEntry->LocalTarget.MacAddress, + fwRoute->FR_NextHopAddress); + } + if (ifCB!=InternalInterface) { + ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + ifCB->ICB_AdapterContext, + &RouteEntry->LocalTarget); + } + else { + CONSTANT_ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + VIRTUAL_NET_ADAPTER_CONTEXT, + &RouteEntry->LocalTarget); + } + status = STATUS_SUCCESS; + break; + case FWD_OPER_STATE_SLEEPING: + IPX_NODE_CPY (&RouteEntry->LocalTarget.MacAddress, + fwRoute->FR_NextHopAddress); + CONSTANT_ADAPTER_CONTEXT_TO_LOCAL_TARGET (DEMAND_DIAL_ADAPTER_CONTEXT, + &RouteEntry->LocalTarget); + status = STATUS_SUCCESS; + break; + case FWD_OPER_STATE_DOWN: + status = STATUS_NETWORK_UNREACHABLE; + break; + default: + ASSERTMSG ("Inavalid operational state", FALSE); + } + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + #if DBG + if (Node!=NULL) { + if (NT_SUCCESS (status)) { + IpxFwdDbgPrint (DBG_IPXBIND, DBG_INFORMATION, + ("IpxFwd: Found route for IPX driver:" + " %08lX:%02X%02X%02X%02X%02X%02X" + " -> %ld(%ld):%02X%02X%02X%02X%02X%02X\n", + net, Node[0],Node[1],Node[2],Node[3],Node[4],Node[5], + ifCB->ICB_Index, RouteEntry->LocalTarget.NicId, + RouteEntry->LocalTarget.MacAddress[0], + RouteEntry->LocalTarget.MacAddress[1], + RouteEntry->LocalTarget.MacAddress[2], + RouteEntry->LocalTarget.MacAddress[3], + RouteEntry->LocalTarget.MacAddress[4], + RouteEntry->LocalTarget.MacAddress[5])); + } + else { + IpxFwdDbgPrint (DBG_IPXROUTE, DBG_WARNING, + ("IpxFwd: Network unreachable for:" + " %08lX:%02X%02X%02X%02X%02X%02X -> %ld.\n", + net, Node[0],Node[1],Node[2],Node[3],Node[4],Node[5], + ifCB->ICB_Index)); + } + } + else { + if (NT_SUCCESS (status)) { + IpxFwdDbgPrint (DBG_IPXBIND, DBG_INFORMATION, + ("IpxFwd: Found route for IPX driver:" + " %08lX" + " -> %ld(%ld):%02X%02X%02X%02X%02X%02X\n", + net, ifCB->ICB_Index, RouteEntry->LocalTarget.NicId, + RouteEntry->LocalTarget.MacAddress[0], + RouteEntry->LocalTarget.MacAddress[1], + RouteEntry->LocalTarget.MacAddress[2], + RouteEntry->LocalTarget.MacAddress[3], + RouteEntry->LocalTarget.MacAddress[4], + RouteEntry->LocalTarget.MacAddress[5])); + } + else { + IpxFwdDbgPrint (DBG_IPXROUTE, DBG_WARNING, + ("IpxFwd: Network unreachable for:" + " %08lX -> %ld.\n", net)); + } + } + #endif + ReleaseInterfaceReference (ifCB); + ReleaseRouteReference (fwRoute); + + } + } + else { +#if DBG + if (Node!=NULL) { + IpxFwdDbgPrint (DBG_IPXROUTE, DBG_WARNING, + ("IpxFwd: No route for:" + " %08lX:%02X%02X%02X%02X%02X%02X.\n", + net, Node[0],Node[1],Node[2],Node[3],Node[4],Node[5])); + } + else { + IpxFwdDbgPrint (DBG_IPXROUTE, DBG_WARNING, + ("IpxFwd: No route for: %08lX.\n", net)); + } +#endif + status = STATUS_NETWORK_UNREACHABLE; + } + LeaveForwarder (); + return status; +} + + diff --git a/private/ntos/tdi/isn/fwd/ipxbind.h b/private/ntos/tdi/isn/fwd/ipxbind.h new file mode 100644 index 000000000..7cf367a2b --- /dev/null +++ b/private/ntos/tdi/isn/fwd/ipxbind.h @@ -0,0 +1,75 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\ipxbind.h + +Abstract: + IPX Forwarder Driver interface with IPX stack driver + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + + +#ifndef _IPXFWD_IPXBIND_ +#define _IPXFWD_IPXBIND_ + +extern PIPX_INTERNAL_BIND_RIP_OUTPUT IPXBindOutput; +#define IPXMacHeaderSize (IPXBindOutput->MacHeaderNeeded) +#define IPXOpenAdapterProc (IPXBindOutput->OpenAdapterHandler) +#define IPXCloseAdapterProc (IPXBindOutput->CloseAdapterHandler) +#define IPXInternalSendCompletProc (IPXBindOutput->InternalSendCompleteHandler) +#define IPXSendProc (IPXBindOutput->SendHandler) +#define IPXTransferData (IPXBindOutput->TransferDataHandler) + + +/*++ +******************************************************************* + B i n d T o I p x D r i v e r + +Routine Description: + Exchanges binding information with IPX stack driver +Arguments: +Return Value: + STATUS_SUCCESS - exchange was done OK + STATUS_INSUFFICIENT_RESOURCES - could not allocate buffers for + info exchange + error status returned by IPX stack driver + +******************************************************************* +--*/ +NTSTATUS +BindToIpxDriver ( + KPROCESSOR_MODE requestorMode + ); + + +/*++ +******************************************************************* + U n b i n d T o I p x D r i v e r + +Routine Description: + Closes connection to IPX stack driver +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +UnbindFromIpxDriver ( + KPROCESSOR_MODE requestorMode + ); + + +#endif + diff --git a/private/ntos/tdi/isn/fwd/lineind.c b/private/ntos/tdi/isn/fwd/lineind.c new file mode 100644 index 000000000..e00518d6a --- /dev/null +++ b/private/ntos/tdi/isn/fwd/lineind.c @@ -0,0 +1,323 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\lineind.c + +Abstract: + Processing line indication (bind/unbind) + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + + +/*++ +******************************************************************* + B i n d I n t e r f a c e + +Routine Description: + Binds interface to physical adapter and exchanges contexts + with IPX stack +Arguments: + ifCB - interface to bind + NicId - id of an adapter + MaxPacketSize - max size of packet allowed + Network - adapter network address + LocalNode - adapter local node address + RemoteNode - peer node address (for clients on global + net) +Return Value: + STATUS_SUCCESS - interface was bound OK + error status returned by IPX stack driver + +******************************************************************* +--*/ +NTSTATUS +BindInterface ( + IN PINTERFACE_CB ifCB, + IN USHORT NicId, + IN ULONG MaxPacketSize, + IN ULONG Network, + IN PUCHAR LocalNode, + IN PUCHAR RemoteNode + ) { + KIRQL oldIRQL; + NTSTATUS status; + NIC_HANDLE NicHandle={0}; + + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (ifCB->ICB_Stats.OperationalState!=FWD_OPER_STATE_UP) { + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) + status = RegisterPacketConsumer (MaxPacketSize, + &ifCB->ICB_PacketListId); + else + status = STATUS_SUCCESS; + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + if (IS_IF_CONNECTING (ifCB)) { + SET_IF_NOT_CONNECTING (ifCB); + DequeueConnectionRequest (ifCB); + } + status = STATUS_SUCCESS; + break; + default: + ASSERTMSG ("Invalid interface type ", FALSE); + break; + } + if (NT_SUCCESS (status)) { + if (Network==GlobalNetwork) { + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode); + status = AddGlobalNetClient (ifCB); + ASSERT (status==STATUS_SUCCESS); + } + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + NIC_HANDLE_FROM_NIC(NicHandle, NicId); + status = IPXOpenAdapterProc (NicHandle, (ULONG)ifCB, + &ifCB->ICB_AdapterContext); + } + + if (NT_SUCCESS (status)) { + ifCB->ICB_Network = Network; + IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode); + IPX_NODE_CPY (ifCB->ICB_LocalNode, LocalNode); + if (ifCB->ICB_InterfaceType==FWD_IF_PERMANENT) + ifCB->ICB_Stats.MaxPacketSize = MaxPacketSize; + else + ifCB->ICB_Stats.MaxPacketSize = WAN_PACKET_SIZE; + ifCB->ICB_NicId = NicId; + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_UP; + + AcquireInterfaceReference (ifCB); + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, + ("IpxFwd: Bound interface %ld (icb: %08lx):" + " Nic-%d, Net-%08lx," + " LocalNode-%02x%02x%02x%02x%02x%02x," + " RemoteNode-%02x%02x%02x%02x%02x%02x.\n", + ifCB->ICB_Index, ifCB, NicId, Network, + LocalNode[0], LocalNode[1], LocalNode[2], + LocalNode[3], LocalNode[4], LocalNode[5], + RemoteNode[0], RemoteNode[1], RemoteNode[2], + RemoteNode[3], RemoteNode[4], RemoteNode[5])); + + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + return STATUS_SUCCESS; + } + + IpxFwdDbgPrint (DBG_LINEIND, DBG_ERROR, + ("IpxFwd: Could not open adapter %d to bind" + " interface %ld (icb: %08lx)!\n", + NicId, ifCB->ICB_Index, ifCB)); + + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (Network==GlobalNetwork) { + DeleteGlobalNetClient (ifCB); + } + + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + DeregisterPacketConsumer (ifCB->ICB_PacketListId); + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + break; + } + } + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + else { + ASSERT (Network==ifCB->ICB_Network); + ASSERT (NicId==(USHORT)ifCB->ICB_AdapterContext.NicId); + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + status = STATUS_SUCCESS; // Report success if already + // connected + IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING, + ("IpxFwd: Interface %ld (icb: %08lx) is already bound to Nic %d.\n", + ifCB->ICB_Index, ifCB, NicId)); + } + return status; +} + + +/*++ +******************************************************************* + U n b i n d I n t e r f a c e + +Routine Description: + Unbinds interface from physical adapter and breaks connection + with IPX stack +Arguments: + ifCB - interface to unbind +Return Value: + None +******************************************************************* +--*/ +VOID +UnbindInterface ( + PINTERFACE_CB ifCB + ) { + KIRQL oldIRQL; + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (ifCB->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) { + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) + DeregisterPacketConsumer (ifCB->ICB_PacketListId); + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_SLEEPING; + KeQuerySystemTime ((PLARGE_INTEGER)&ifCB->ICB_DisconnectTime); + break; + default: + ASSERTMSG ("Invalid interface type ", FALSE); + break; + } + if (ifCB->ICB_CashedInterface!=NULL) + ReleaseInterfaceReference (ifCB->ICB_CashedInterface); + ifCB->ICB_CashedInterface = NULL; + if (ifCB->ICB_CashedRoute!=NULL) + ReleaseRouteReference (ifCB->ICB_CashedRoute); + ifCB->ICB_CashedRoute = NULL; + if (ifCB->ICB_Network==GlobalNetwork) + DeleteGlobalNetClient (ifCB); + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, + ("IpxFwd: Unbinding interface %ld (icb: %08lx) from Nic %ld.\n", + ifCB->ICB_Index, ifCB, ifCB->ICB_AdapterContext)); + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + IPXCloseAdapterProc (ifCB->ICB_AdapterContext); + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + ReleaseInterfaceReference (ifCB); + } + else { + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING, + ("IpxFwd: Interface %ld (icb: %08lx) is already unbound.\n", + ifCB->ICB_Index, ifCB)); + } +} + + + +/*++ +******************************************************************* + F w L i n e U p + +Routine Description: + Process line up indication delivered by IPX stack +Arguments: + NicId - adapter ID on which connection was established + LineInfo - NDIS/IPX line information + DeviceType - medium specs + ConfigurationData - IPX CP configuration data +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineUp ( + IN USHORT NicId, + IN PIPX_LINE_INFO LineInfo, + IN NDIS_MEDIUM DeviceType, + IN PVOID ConfigurationData + ) { + PINTERFACE_CB ifCB; + if (ConfigurationData==NULL) // This is just an update for multilink + // connections + return; + + if (!EnterForwarder()) { + return; + } + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineUp.\n")); + + ifCB = GetInterfaceReference ( + ((PIPXCP_CONFIGURATION)ConfigurationData)->InterfaceIndex); + if (ifCB!=NULL) { + LONG Net = GETULONG (((PIPXCP_CONFIGURATION)ConfigurationData)->Network); + + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT); + + BindInterface (ifCB, + NicId, + LineInfo->MaximumPacketSize, + Net, + ((PIPXCP_CONFIGURATION)ConfigurationData)->LocalNode, + ((PIPXCP_CONFIGURATION)ConfigurationData)->RemoteNode + ); + ReleaseInterfaceReference (ifCB); + } + LeaveForwarder (); +} + + + + +/*++ +******************************************************************* + F w L i n e D o w n + +Routine Description: + Process line down indication delivered by IPX stack +Arguments: + NicId - disconnected adapter ID +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineDown ( + IN USHORT NicId, + IN ULONG Context + ) { + PINTERFACE_CB ifCB; + + if (!EnterForwarder()) { + return; + } + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineDown.\n")); + + + ifCB = InterfaceContextToReference ((PVOID)Context, NicId); + if (ifCB!=NULL) { + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT); + UnbindInterface (ifCB); + ReleaseInterfaceReference (ifCB); + } + LeaveForwarder (); +} + diff --git a/private/ntos/tdi/isn/fwd/lineind.h b/private/ntos/tdi/isn/fwd/lineind.h new file mode 100644 index 000000000..bbc8df7ac --- /dev/null +++ b/private/ntos/tdi/isn/fwd/lineind.h @@ -0,0 +1,116 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\lineind.h + +Abstract: + Processing line indication (bind/unbind) + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_LINEIND_ +#define _IPXFWD_LINEIND_ + +/*++ +******************************************************************* + B i n d I n t e r f a c e + +Routine Description: + Binds interface to physical adapter and exchanges contexts + with IPX stack +Arguments: + ifCB - interface to bind + NicId - id of an adapter + MaxPacketSize - max size of packet allowed + Network - adapter network address + LocalNode - adapter local node address + RemoteNode - peer node address (for clients on global + net) +Return Value: + STATUS_SUCCESS - interface was bound OK + error status returned by IPX stack driver + +******************************************************************* +--*/ +NTSTATUS +BindInterface ( + IN PINTERFACE_CB ifCB, + IN USHORT NicId, + IN ULONG MaxPacketSize, + IN ULONG Network, + IN PUCHAR LocalNode, + IN PUCHAR RemoteNode + ); + +/*++ +******************************************************************* + U n b i n d I n t e r f a c e + +Routine Description: + Unbinds interface from physical adapter and breaks connection + with IPX stack +Arguments: + ifCB - interface to unbind +Return Value: + None +******************************************************************* +--*/ +VOID +UnbindInterface ( + PINTERFACE_CB ifCB + ); + +/*++ +******************************************************************* + F w L i n e U p + +Routine Description: + Process line up indication delivered by IPX stack +Arguments: + NicId - adapter ID on which connection was established + LineInfo - NDIS/IPX line information + DeviceType - medium specs + ConfigurationData - IPX CP configuration data +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineUp ( + IN USHORT NicId, + IN PIPX_LINE_INFO LineInfo, + IN NDIS_MEDIUM DeviceType, + IN PVOID ConfigurationData + ); + +/*++ +******************************************************************* + F w L i n e D o w n + +Routine Description: + Process line down indication delivered by IPX stack +Arguments: + NicId - disconnected adapter ID +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineDown ( + IN USHORT NicId, + IN ULONG Context + ); + +#endif diff --git a/private/ntos/tdi/isn/fwd/mp/makefile b/private/ntos/tdi/isn/fwd/mp/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/ntos/tdi/isn/fwd/mp/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ntos/tdi/isn/fwd/mp/sources b/private/ntos/tdi/isn/fwd/mp/sources new file mode 100644 index 000000000..dc48d81bb --- /dev/null +++ b/private/ntos/tdi/isn/fwd/mp/sources @@ -0,0 +1,29 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +NT_UP=0 + +TARGETPATH=\nt\public\sdk\lib + +!include ..\sources.inc diff --git a/private/ntos/tdi/isn/fwd/netbios.c b/private/ntos/tdi/isn/fwd/netbios.c new file mode 100644 index 000000000..4a1f9b84b --- /dev/null +++ b/private/ntos/tdi/isn/fwd/netbios.c @@ -0,0 +1,311 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\netbios.c + +Abstract: + Netbios packet processing + +Author: + + Vadim Eydelman + +Revision History: + +--*/ +#include "precomp.h" + +LIST_ENTRY NetbiosQueue; +KSPIN_LOCK NetbiosQueueLock; +WORK_QUEUE_ITEM NetbiosWorker; +BOOLEAN NetbiosWorkerScheduled=FALSE; +ULONG NetbiosPacketsQuota; +ULONG MaxNetbiosPacketsQueued = DEF_MAX_NETBIOS_PACKETS_QUEUED; + + +/*++ +******************************************************************* + P r o c e s s N e t b i o s Q u e u e + +Routine Description: + Process packets in the netbios broadcast queue (sends them on + all interfaces in sequence) +Arguments: + Context - unused +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessNetbiosQueue ( + PVOID Context + ) { + KIRQL oldIRQL; + LIST_ENTRY tempQueue; + + KeAcquireSpinLock (&NetbiosQueueLock, &oldIRQL); + // Check if there is something in the queue + if (!IsListEmpty (&NetbiosQueue)) { + // Move the queue to local variable + InsertHeadList (&NetbiosQueue, &tempQueue); + RemoveEntryList (&NetbiosQueue); + InitializeListHead (&NetbiosQueue); + + KeReleaseSpinLock (&NetbiosQueueLock, oldIRQL); + do { + PLIST_ENTRY cur; + PPACKET_TAG pktTag; + + cur = RemoveHeadList (&tempQueue); + pktTag = CONTAINING_RECORD (cur, PACKET_TAG, PT_QueueLink); + // Check if this packet has to be sent on other + // interfaces + if (!(pktTag->PT_Flags&PT_NB_DESTROY)) { + PINTERFACE_CB dstIf = pktTag->PT_InterfaceReference; + PUCHAR dataPtr = pktTag->PT_Data; + UINT rtCount = *(dataPtr+IPXH_XPORTCTL); + PUCHAR netListPtr; + UINT i; + + if (dstIf==NULL) { + // This is a brand new packet: not sent on any + // interface yet + USHORT dstSock = GETUSHORT (dataPtr+IPXH_DESTSOCK); + // Check if we have a static route for this name + // (offset to name depends on packet dest socket) + if (dstSock==IPX_NETBIOS_SOCKET) + dstIf = FindNBDestination (dataPtr+NB_NAME); + else if (dstSock==IPX_SMB_NAME_SOCKET) + dstIf = FindNBDestination (dataPtr+SMB_NAME); + else + dstIf = NULL; + + if (dstIf!=NULL) { + // Static route found, make sure this packet + // won't be sent on any other interface + pktTag->PT_Flags |= PT_NB_DESTROY; + InterlockedIncrement (&NetbiosPacketsQuota); + // Make sure the packet has not traversed + // this network already + for (i=0, netListPtr=dataPtr+IPXH_HDRSIZE; i<rtCount; i++,netListPtr+=4) { + if (GETULONG (netListPtr)==dstIf->ICB_Network) + break; + } + // Make sure we are allowed to send on this + // interface + if ((dstIf!=InternalInterface) + && (i==rtCount) // Has not already traversed + // this network + && IS_IF_ENABLED (dstIf) + && ((dstIf->ICB_NetbiosDeliver==FWD_NB_DELIVER_ALL) + || (dstIf->ICB_NetbiosDeliver + ==FWD_NB_DELIVER_STATIC) + || ((dstIf->ICB_NetbiosDeliver + ==FWD_NB_DELIVER_IF_UP) + && (dstIf->ICB_Stats.OperationalState + ==FWD_OPER_STATE_UP)))) { + NOTHING; + } + else { + // We have static route, but can't send it, + // no point to propagate in on other interfaces + // as well + ReleaseInterfaceReference (dstIf); + dstIf = NULL; + goto FreePacket; + } + } + else { // no static route + goto FindNextInterface; + } + } + else { // not a brand new packet (already sent on some + // interfaces) + + FindNextInterface: + + // Loop through the interface list till we find + // the one on which we can send + while ((dstIf=GetNextInterfaceReference (dstIf))!=NULL) { + // Check if we allowed to send on this interface + if (IS_IF_ENABLED (dstIf) + && ((dstIf->ICB_NetbiosDeliver==FWD_NB_DELIVER_ALL) + || ((dstIf->ICB_NetbiosDeliver + ==FWD_NB_DELIVER_IF_UP) + && (dstIf->ICB_Stats.OperationalState + ==FWD_OPER_STATE_UP)))) { + // Make sure the packet has not traversed + // this network already + for (i=0, netListPtr=dataPtr+IPXH_HDRSIZE; i<rtCount; i++,netListPtr+=4) { + if (GETULONG (netListPtr)==dstIf->ICB_Network) + break; + } + // Network was not in the list + if (i==rtCount) + break; + } + } + } + // Save the destination interface in the packet + pktTag->PT_InterfaceReference = dstIf; + // Go ahead and send if we have a valid destination + if (dstIf!=NULL) { + SendPacket (dstIf, pktTag); + // The rest does not apply: if the packet was sent or + // failed, it will be queued back to NetbiosQueue; + // if it was queued to interface to be connected, + // a copy of it will be queued to NetbiosQueue + continue; + } + // else no more destinations to send this packet on + } + else { // Packet has to be destroyed + if (pktTag->PT_InterfaceReference!=NULL) + ReleaseInterfaceReference (pktTag->PT_InterfaceReference); + } + + FreePacket: + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: No more interfaces for nb packet %08lx.\n", + pktTag)); + if (MeasuringPerformance + && (pktTag->PT_PerfCounter!=0)) { + LARGE_INTEGER PerfCounter = KeQueryPerformanceCounter (NULL); + PerfCounter.QuadPart -= pktTag->PT_PerfCounter; + KeAcquireSpinLock (&PerfCounterLock, &oldIRQL); + PerfBlock.TotalNbPacketProcessingTime += PerfCounter.QuadPart; + PerfBlock.NbPacketCounter += 1; + if (PerfBlock.MaxNbPacketProcessingTime < PerfCounter.QuadPart) + PerfBlock.MaxNbPacketProcessingTime = PerfCounter.QuadPart; + KeReleaseSpinLock (&PerfCounterLock, oldIRQL); + } + if (!(pktTag->PT_Flags&PT_NB_DESTROY)) + InterlockedIncrement (&NetbiosPacketsQuota); + FreePacket (pktTag); + } while (!IsListEmpty (&tempQueue)); + + KeAcquireSpinLock (&NetbiosQueueLock, &oldIRQL); + if (IsListEmpty (&NetbiosQueue) + || !EnterForwarder ()) { + NetbiosWorkerScheduled = FALSE; + } + else { + ExQueueWorkItem (&NetbiosWorker, DelayedWorkQueue); + } + } + KeReleaseSpinLock (&NetbiosQueueLock, oldIRQL); + LeaveForwarder (); +} + +/*++ +******************************************************************* + P r o c e s s N e t b i o s P a c k e t + +Routine Description: + Processes received netbios broadcast packet (checks network list + and source filter, updates input statistics) +Arguments: + srcIf - interfae on which packet was received + pktTag - netbios packet +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessNetbiosPacket ( + PINTERFACE_CB srcIf, + PPACKET_TAG pktTag + ) { + PUCHAR dataPtr; + UINT rtCount; + UINT i; + KIRQL oldIRQL; + + + dataPtr = pktTag->PT_Data; + rtCount = *(dataPtr+IPXH_XPORTCTL); + + // Check if source network is already in the packet network list + for (i=0, dataPtr+=IPXH_HDRSIZE; i<rtCount; i++, dataPtr+=4) { + if (srcIf->ICB_Network==GETULONG (dataPtr)) + break; + } + // We scaned the whole list and we haven't found it + if (i==rtCount) { + FILTER_ACTION action; + action = FltFilter (pktTag->PT_Data, + GETUSHORT (pktTag->PT_Data+IPXH_LENGTH), + srcIf->ICB_FilterInContext, NULL); + // Apply the input filter + if (action==FILTER_PERMIT) { + InterlockedIncrement (&srcIf->ICB_Stats.NetbiosReceived); + InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); + PUTULONG (srcIf->ICB_Network, dataPtr); + *(pktTag->PT_Data+IPXH_XPORTCTL) += 1; + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, BROADCAST_NODE); + // Initialize the packet + pktTag->PT_InterfaceReference = NULL; // not yet sent on any + // interfaces + pktTag->PT_Flags = 0; // No flags + QueueNetbiosPacket (pktTag); + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Queued nb packet %08lx from if %ld.\n", + pktTag, srcIf->ICB_Index)); + } + else { + ASSERT (action==FILTER_DENY_IN); + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: Filtered out nb packet %08lx" + " from if %ld.\n", pktTag, srcIf->ICB_Index)); + InterlockedIncrement (&NetbiosPacketsQuota); + InterlockedIncrement (&srcIf->ICB_Stats.InFiltered); + FreePacket (pktTag); + } + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: Source net is already in nb packet %08lx" + " from if %ld.\n", pktTag, srcIf->ICB_Index)); + InterlockedIncrement (&NetbiosPacketsQuota); + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + FreePacket (pktTag); + } + ReleaseInterfaceReference (srcIf); + +} + + +/*++ +******************************************************************* + D e l e t e N e t b i o s Q u e u e + +Routine Description: + Deletes the netbios bradcast queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteNetbiosQueue ( + void + ) { + while (!IsListEmpty (&NetbiosQueue)) { + PPACKET_TAG pktTag = CONTAINING_RECORD (NetbiosQueue.Flink, + PACKET_TAG, + PT_QueueLink); + RemoveEntryList (&pktTag->PT_QueueLink); + if (pktTag->PT_InterfaceReference!=NULL) { + ReleaseInterfaceReference (pktTag->PT_InterfaceReference); + } + FreePacket (pktTag); + } +} + diff --git a/private/ntos/tdi/isn/fwd/netbios.h b/private/ntos/tdi/isn/fwd/netbios.h new file mode 100644 index 000000000..ffa6da1c4 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/netbios.h @@ -0,0 +1,134 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\netbios.h + +Abstract: + Netbios packet processing + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef IPXFWD_NETBIOS +#define IPXFWD_NETBIOS + +extern LIST_ENTRY NetbiosQueue; +extern KSPIN_LOCK NetbiosQueueLock; +extern WORK_QUEUE_ITEM NetbiosWorker; +extern BOOLEAN NetbiosWorkerScheduled; +extern ULONG NetbiosPacketsQuota; +extern ULONG MaxNetbiosPacketsQueued; +#define DEF_MAX_NETBIOS_PACKETS_QUEUED 256 + + +/*++ +******************************************************************* + I n i t i a l i z e N e t b i o s Q u e u e + +Routine Description: + Initializes the netbios bradcast queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +//VOID +//InitializeNetbiosQueue ( +// void +// ) +#define InitializeNetbiosQueue() { \ + InitializeListHead (&NetbiosQueue); \ + KeInitializeSpinLock (&NetbiosQueueLock); \ + ExInitializeWorkItem (&NetbiosWorker, &ProcessNetbiosQueue, NULL);\ + NetbiosWorkerScheduled = FALSE; \ + NetbiosPacketsQuota = MaxNetbiosPacketsQueued; \ +} + +/*++ +******************************************************************* + D e l e t e N e t b i o s Q u e u e + +Routine Description: + Deletes the netbios bradcast queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteNetbiosQueue ( + void + ); + + +/*++ +******************************************************************* + P r o c e s s N e t b i o s Q u e u e + +Routine Description: + Process packets in the netbios bradcast queue +Arguments: + Context - unused +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessNetbiosQueue ( + PVOID Context + ); + +/*++ +******************************************************************* + P r o c e s s N e t b i o s P a c k e t + +Routine Description: + Processes received netbios broadcast packet +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessNetbiosPacket ( + PINTERFACE_CB srcIf, + PPACKET_TAG pktTag + ); + + +#define QueueNetbiosPacket(pktTag) { \ + KIRQL oldIRQL; \ + KeAcquireSpinLock (&NetbiosQueueLock, &oldIRQL); \ + InsertTailList (&NetbiosQueue, &pktTag->PT_QueueLink); \ + KeReleaseSpinLock (&NetbiosQueueLock, oldIRQL); \ +} + +#define ScheduleNetbiosWorker() { \ + KIRQL oldIRQL; \ + KeAcquireSpinLock (&NetbiosQueueLock, &oldIRQL); \ + if (!NetbiosWorkerScheduled \ + && !IsListEmpty (&NetbiosQueue) \ + && EnterForwarder ()) { \ + NetbiosWorkerScheduled = TRUE; \ + ExQueueWorkItem (&NetbiosWorker, DelayedWorkQueue); \ + } \ + KeReleaseSpinLock (&NetbiosQueueLock, oldIRQL); \ +} + +#endif + diff --git a/private/ntos/tdi/isn/fwd/nwlnkfwd.rc b/private/ntos/tdi/isn/fwd/nwlnkfwd.rc new file mode 100644 index 000000000..477fd6e01 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/nwlnkfwd.rc @@ -0,0 +1,12 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_NETWORK +#define VER_FILEDESCRIPTION_STR "NWLINK2 Forwarder Driver" +#define VER_INTERNALNAME_STR "nwlnkfwd.sys" +#define VER_ORIGINALFILENAME_STR "nwlnkfwd.sys" + +#include "common.ver" + diff --git a/private/ntos/tdi/isn/fwd/packets.c b/private/ntos/tdi/isn/fwd/packets.c new file mode 100644 index 000000000..9577a6d2c --- /dev/null +++ b/private/ntos/tdi/isn/fwd/packets.c @@ -0,0 +1,528 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\packets.c + +Abstract: + IPX Forwarder Driver packet allocator + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + +ULONG RcvPktsPerSegment = DEF_RCV_PKTS_PER_SEGMENT; +ULONG MaxRcvPktsPoolSize =0; +ULONG RcvPktsPoolSize = 0; +KSPIN_LOCK AllocatorLock; +const LONGLONG SegmentTimeout = -10i64*10000000i64; + +SEGMENT_LIST ListEther={1500}; +SEGMENT_LIST ListTR4={4500}; +SEGMENT_LIST ListTR16={17986}; + +PSEGMENT_LIST SegmentMap[FRAME_SIZE_VARIATIONS][FRAME_SIZE_VARIATIONS] = { + {&ListEther, &ListEther, &ListEther}, + {&ListEther, &ListTR4, &ListTR4}, + {&ListEther, &ListTR4, &ListTR16} +}; + +VOID +AllocationWorker ( + PVOID Context + ); + +VOID +SegmentTimeoutDpc ( + PKDPC dpc, + PVOID Context, + PVOID SystemArgument1, + PVOID SystemArgument2 + ); + +/*++ +******************************************************************* + C r e a t e S e g m e n t + +Routine Description: + Allocates and initializes packet segment +Arguments: + list - segment list to which new segment will be added +Return Value: + Pointer to allocated segment, NULL if fails + +******************************************************************* +--*/ +PPACKET_SEGMENT +CreateSegment ( + PSEGMENT_LIST list + ) { + KIRQL oldIRQL; + NDIS_STATUS status; + PPACKET_SEGMENT segment; + ULONG segmentsize = list->SL_BlockCount*list->SL_BlockSize + +FIELD_OFFSET(PACKET_SEGMENT,PS_Buffers); + if (MaxRcvPktsPoolSize!=0) { + // Check if this allocation would exceed the limit + KeAcquireSpinLock (&AllocatorLock, &oldIRQL); + if (RcvPktsPoolSize+segmentsize<MaxRcvPktsPoolSize) { + RcvPktsPoolSize += segmentsize; + KeReleaseSpinLock (&AllocatorLock, oldIRQL); + } + else { + KeReleaseSpinLock (&AllocatorLock, oldIRQL); + return NULL; + } + } + + // Allocate chunk of memory to hold segment header and buffers + segment = ExAllocatePoolWithTag ( + NonPagedPool, + segmentsize, + FWD_POOL_TAG); + if (segment!=NULL) { + segment->PS_SegmentList = list; + segment->PS_FreeHead = NULL; + segment->PS_BusyCount = 0; + KeQuerySystemTime ((PLARGE_INTEGER)&segment->PS_FreeStamp); + NdisAllocatePacketPool ( + &status, + &segment->PS_PacketPool, + list->SL_BlockCount, + IPXMacHeaderSize + +FIELD_OFFSET (PACKET_TAG, PT_MacHeader)); + if (status==NDIS_STATUS_SUCCESS) { + NdisAllocateBufferPool ( + &status, + &segment->PS_BufferPool, + list->SL_BlockCount*2); + if (status==NDIS_STATUS_SUCCESS) { + PUCHAR bufferptr = segment->PS_Buffers; + PNDIS_PACKET packetDscr; + PNDIS_BUFFER bufferDscr; + PPACKET_TAG packetTag; + ULONG i; + + for (i=0; i<list->SL_BlockCount; i++, + bufferptr+=list->SL_BlockSize) { + NdisAllocatePacket ( + &status, + &packetDscr, + segment->PS_PacketPool); + ASSERT (status==NDIS_STATUS_SUCCESS); + + packetTag = (PPACKET_TAG)packetDscr->ProtocolReserved; + packetTag->PT_Segment = segment; + packetTag->PT_Data = bufferptr; + packetTag->PT_InterfaceReference = NULL; + + NdisAllocateBuffer ( + &status, + &packetTag->PT_MacHdrBufDscr, + segment->PS_BufferPool, + packetTag->PT_MacHeader, + IPXMacHeaderSize); + ASSERT (status==NDIS_STATUS_SUCCESS); + + NdisAllocateBuffer ( + &status, + &bufferDscr, + segment->PS_BufferPool, + bufferptr, + list->SL_BlockSize); + ASSERT (status==NDIS_STATUS_SUCCESS); + NdisChainBufferAtFront (packetDscr, bufferDscr); + + packetTag->PT_Next = segment->PS_FreeHead; + segment->PS_FreeHead = packetTag; + } + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_WARNING, + ("IpxFwd: Allocated packet segment %08lx for list %ld.\n", + segment, list->SL_BlockSize)); + return segment; + } + else { + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_ERROR, + ("IpxFwd: Failed to allocate buffer pool" + " for new segment in list %ld.\n", + list->SL_BlockSize)); + } + NdisFreePacketPool (segment->PS_PacketPool); + } + else { + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_ERROR, + ("IpxFwd: Failed to allocate packet pool" + " for new segment in list %ld.\n", + list->SL_BlockSize)); + } + ExFreePool (segment); + } + else { + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_ERROR, + ("IpxFwd: Failed to allocate new segment for list %ld.\n", + list->SL_BlockSize)); + } + + return NULL; +} + + +/*++ +******************************************************************* + D e l e t e S e g m e n t + +Routine Description: + Frees packet segment +Arguments: + segment - segment to free +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteSegment ( + PPACKET_SEGMENT segment + ) { + PSEGMENT_LIST list = segment->PS_SegmentList; + + ASSERT (segment->PS_BusyCount == 0); + // Free all NDIS packet and buffer descriptors first + while (segment->PS_FreeHead!=NULL) { + PNDIS_BUFFER bufferDscr; + PPACKET_TAG packetTag = segment->PS_FreeHead; + PNDIS_PACKET packetDscr = CONTAINING_RECORD (packetTag, + NDIS_PACKET, ProtocolReserved); + + segment->PS_FreeHead = packetTag->PT_Next; + + ASSERT (packetTag->PT_MacHdrBufDscr!=NULL); + NdisFreeBuffer (packetTag->PT_MacHdrBufDscr); + + NdisUnchainBufferAtFront (packetDscr, &bufferDscr); + ASSERT (bufferDscr!=NULL); + NdisFreeBuffer (bufferDscr); + + NdisFreePacket (packetDscr); + } + NdisFreeBufferPool (segment->PS_BufferPool); + NdisFreePacketPool (segment->PS_PacketPool); + + // Decrement memory used if we have a quota + if (MaxRcvPktsPoolSize!=0) { + KIRQL oldIRQL; + ULONG segmentsize = list->SL_BlockCount*list->SL_BlockSize + +FIELD_OFFSET(PACKET_SEGMENT,PS_Buffers); + KeAcquireSpinLock (&AllocatorLock, &oldIRQL); + RcvPktsPoolSize -= segmentsize; + KeReleaseSpinLock (&AllocatorLock, oldIRQL); + } + ExFreePool (segment); + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_WARNING, + ("IpxFwd: Deleting segment %08lx in list %ld.\n", + segment, list->SL_BlockSize)); +} + + +/*++ +******************************************************************* + R e g i s t e r P a c k e t C o n s u m e r + +Routine Description: + Registers a consumer (bound interface) of packets of the + given size +Arguments: + pktsize - maximum size of packets needed + listId - buffer to return packet list id where packets + of required size are located +Return Value: + STATUS_SUCCESS - registration succeded + STATUS_INSUFFICIENT_RESOURCES - not enogh resources to register + +******************************************************************* +--*/ +NTSTATUS +RegisterPacketConsumer ( + IN ULONG pktsize, + OUT INT *listID + ) { + NTSTATUS status=STATUS_SUCCESS; + KIRQL oldIRQL; + PSEGMENT_LIST list; + INT i; + LONG addRefCount = 1; + + KeAcquireSpinLock (&AllocatorLock, &oldIRQL); + ASSERT (pktsize<=SegmentMap[FRAME_SIZE_VARIATIONS-1] + [FRAME_SIZE_VARIATIONS-1]->SL_BlockSize); + + for (i=0; i<FRAME_SIZE_VARIATIONS; i++) { + list = SegmentMap[i][i]; + if (pktsize<=list->SL_BlockSize) { + list->SL_RefCount += 1; + *listID = i; + break; + } + } + KeReleaseSpinLock (&AllocatorLock, oldIRQL); + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_WARNING, + ("IpxFwd: Registered packet consumer, pktsz: %ld, list: %ld.\n", + pktsize, list->SL_BlockSize)); + return status; +} + +/*++ +******************************************************************* + D e r e g i s t e r P a c k e t C o n s u m e r + +Routine Description: + Deregisters a consumer (bound interface) of packets of the + given size +Arguments: + listId - packet list id used by the consumer +Return Value: + None + +******************************************************************* +--*/ +VOID +DeregisterPacketConsumer ( + IN INT listID + ) { + KIRQL oldIRQL; + PSEGMENT_LIST list; + + ASSERT ((listID>=0) && (listID<FRAME_SIZE_VARIATIONS)); + + KeAcquireSpinLock (&AllocatorLock, &oldIRQL); + list = SegmentMap[listID][listID]; + + ASSERT (list->SL_RefCount>0); + + list->SL_RefCount -= 1; + + KeReleaseSpinLock (&AllocatorLock, oldIRQL); + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_WARNING, + ("IpxFwd: Deregistered packet consumer, list: %ld.\n", + list->SL_BlockSize)); + + } + +/*++ +******************************************************************* + I n i t i a l i z e S e g m e n t L i s t + +Routine Description: + Initializes list of packet segments +Arguments: + list - list to initalize +Return Value: + None + +******************************************************************* +--*/ +VOID +InitializeSegmentList( + PSEGMENT_LIST list + ) { + InitializeListHead (&list->SL_Head); + list->SL_FreeCount = 0; + // Make sure we don't have any leftover larger than + // the buffer size (kernel memory allocator + // allocates full pages) + list->SL_BlockCount = + (ROUND_TO_PAGES ( + list->SL_BlockSize*RcvPktsPerSegment + +FIELD_OFFSET(PACKET_SEGMENT,PS_Buffers)) + -FIELD_OFFSET(PACKET_SEGMENT,PS_Buffers)) + /list->SL_BlockSize; + list->SL_LowCount = list->SL_BlockCount/2; + list->SL_RefCount = 0; + list->SL_AllocatorPending = FALSE; + list->SL_TimerDpcPending = FALSE; + KeInitializeSpinLock (&list->SL_Lock); + KeInitializeTimer (&list->SL_Timer); + KeInitializeDpc (&list->SL_TimerDpc, SegmentTimeoutDpc, list); + ExInitializeWorkItem (&list->SL_Allocator, AllocationWorker, list); +} + +/*++ +******************************************************************* + D e l e t e S e g m e n t L i s t + +Routine Description: + Deletes list of packet segments +Arguments: + list - list to delete +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteSegmentList ( + PSEGMENT_LIST list + ) { + KeCancelTimer (&list->SL_Timer); + while (!IsListEmpty (&list->SL_Head)) { + PPACKET_SEGMENT segment; + segment = CONTAINING_RECORD (list->SL_Head.Blink, + PACKET_SEGMENT, PS_Link); + + RemoveEntryList (&segment->PS_Link); + DeleteSegment (segment); + } +} + + +/*++ +******************************************************************* + S e g m e n t T i m e o u t D p c + +Routine Description: + Timer DPC that launches allocator worker to get rid of unused + segments +Arguments: + Context - segment list to check for unused segments +Return Value: + None + +******************************************************************* +--*/ +VOID +SegmentTimeoutDpc ( + PKDPC dpc, + PVOID Context, + PVOID SystemArgument1, + PVOID SystemArgument2 + ) { +#define list ((PSEGMENT_LIST)Context) + KIRQL oldIRQL; + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_INFORMATION, + ("IpxFwd: Segment timed out in list: %ld.\n", + list->SL_BlockSize)); + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); + list->SL_TimerDpcPending = FALSE; + if (!list->SL_AllocatorPending + && (list->SL_FreeCount>=list->SL_BlockCount) + && EnterForwarder ()) { + list->SL_AllocatorPending = TRUE; + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + ExQueueWorkItem (&list->SL_Allocator, DelayedWorkQueue); + } + else { + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + } + LeaveForwarder (); +#undef list +} + + +/*++ +******************************************************************* + A l l o c a t i o n W o r k e r + +Routine Description: + Adds new segment or releases unused segments from the list + depending on the free packet count and time that segments + are not used +Arguments: + Context - packet list to process +Return Value: + None + +******************************************************************* +--*/ +VOID +AllocationWorker ( + PVOID Context + ) { +#define list ((PSEGMENT_LIST)Context) + KIRQL oldIRQL; + PPACKET_SEGMENT segment = NULL; + LONGLONG curTime; + + IpxFwdDbgPrint (DBG_PACKET_ALLOC, DBG_INFORMATION, + ("IpxFwd: Allocating/scavenging segment(s) in list: %ld.\n", + list->SL_BlockSize)); + KeQuerySystemTime ((PLARGE_INTEGER)&curTime); + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); + list->SL_AllocatorPending = FALSE; + if (list->SL_FreeCount<list->SL_BlockCount) { + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + // First allocate a segment + segment = CreateSegment (list); + if (segment!=NULL) { + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); + InsertTailList (&list->SL_Head, &segment->PS_Link); + list->SL_FreeCount += list->SL_BlockCount; + if (!list->SL_TimerDpcPending + && EnterForwarder ()) { + list->SL_TimerDpcPending = TRUE; + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + KeSetTimer (&list->SL_Timer, *((PLARGE_INTEGER)&SegmentTimeout), &list->SL_TimerDpc); + } + else { + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + } + } + } + else { + // Make sure that there is either more than segment in the list + // or there is one and no registered users + if (!IsListEmpty (&list->SL_Head)) { + segment = CONTAINING_RECORD (list->SL_Head.Blink, + PACKET_SEGMENT, PS_Link); + // Check for all segments with no used blocks + // except for the last one (delete event the last + // one if there are no clients) + while ((segment->PS_BusyCount==0) + && ((list->SL_Head.Flink!=&segment->PS_Link) + || (list->SL_RefCount<=0))) { + LONGLONG timeDiff; + // Check if it has not been used for long enough + timeDiff = SegmentTimeout - (segment->PS_FreeStamp-curTime); + if (timeDiff>=0) { + // Delete the segment + RemoveEntryList (&segment->PS_Link); + list->SL_FreeCount -= list->SL_BlockCount; + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + DeleteSegment (segment); + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); + if (!IsListEmpty (&list->SL_Head)) { + segment = CONTAINING_RECORD (list->SL_Head.Blink, + PACKET_SEGMENT, PS_Link); + continue; + } + } + else { // Reschedule the timer otherwise + if (!list->SL_TimerDpcPending + && EnterForwarder ()) { + list->SL_TimerDpcPending = TRUE; + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + KeSetTimer (&list->SL_Timer, + *((PLARGE_INTEGER)&timeDiff), + &list->SL_TimerDpc); + goto ExitAllocator; // Spinlock is already released + } + } + break; + } // while + } // if (IsListEmpty) + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); + } +ExitAllocator: + LeaveForwarder (); +#undef list +} + + diff --git a/private/ntos/tdi/isn/fwd/packets.h b/private/ntos/tdi/isn/fwd/packets.h new file mode 100644 index 000000000..98de68377 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/packets.h @@ -0,0 +1,464 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\packets.h + +Abstract: + IPX Forwarder Driver packet allocator + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_PACKETS_ +#define _IPXFWD_PACKETS_ + +// Forward structure prototypes +struct _SEGMENT_LIST; +typedef struct _SEGMENT_LIST SEGMENT_LIST, *PSEGMENT_LIST; +struct _PACKET_SEGMENT; +typedef struct _PACKET_SEGMENT PACKET_SEGMENT, *PPACKET_SEGMENT; +struct _PACKET_TAG; +typedef struct _PACKET_TAG PACKET_TAG, *PPACKET_TAG; + +// Forwarder data associated with each packet it allocates +struct _PACKET_TAG { + union { + UCHAR PT_Identifier; // this should be IDENTIFIER_RIP + PPACKET_TAG PT_Next; // link in packet segment + }; + union { + PVOID SEND_RESERVED[SEND_RESERVED_COMMON_SIZE]; // needed by ipx + // for padding on ethernet + PINTERFACE_CB PT_SourceIf; // Source interface reference needed + // for spoofing keep-alives and + // queuing connection requests + }; + PPACKET_SEGMENT PT_Segment; // segment where it belongs + LONGLONG PT_PerfCounter; + ULONG PT_Flags; +#define PT_NB_DESTROY 0x1 // NB packet to be not requeued +#define PT_SOURCE_IF 0x2 // Spoofing packet with src if reference + PUCHAR PT_Data; // Data buffer + PNDIS_BUFFER PT_MacHdrBufDscr; // buffer descriptor for + // mac header buffer required + // by IPX + PINTERFACE_CB PT_InterfaceReference; // points to the interface CB where + // it is queued + LIST_ENTRY PT_QueueLink; // links this packet in send queue + IPX_LOCAL_TARGET PT_Target; // destination target for ipx + // stack + UCHAR PT_MacHeader[1];// Mac header buffer reserved for IPX +}; + +// Segment of preallocated packets complete with buffers +struct _PACKET_SEGMENT { + LIST_ENTRY PS_Link; // Link in segment list + PSEGMENT_LIST PS_SegmentList; // Segment list we belong to + PPACKET_TAG PS_FreeHead; // List of free packets in + // this segment + ULONG PS_BusyCount; // Count of packets allocated + // from this segment + NDIS_HANDLE PS_PacketPool; // Pool of NDIS packet + // descriptors used by the + // packets in this segment + NDIS_HANDLE PS_BufferPool; // Pool of NDIS buffer + // descriptors used by the + // packets in this segment + LONGLONG PS_FreeStamp; // Time when last packet was freed + union { + UCHAR PS_Buffers[1]; // Memory used by buffers + LONGLONG PS_BuffersAlign; + }; +}; + + +// List of segment with preallocated packets +struct _SEGMENT_LIST { + const ULONG SL_BlockSize; // Size of packet's buffer + LIST_ENTRY SL_Head; // Head of the segment list + ULONG SL_FreeCount; // Total number of free packets + // in all segment in the list + ULONG SL_BlockCount; // Number of packets per segment + ULONG SL_LowCount; // Free count at which we + // will preallocate new segment + LONG SL_RefCount; // Number of consumers that are + // using packets in this list + BOOLEAN SL_TimerDpcPending; + BOOLEAN SL_AllocatorPending; + WORK_QUEUE_ITEM SL_Allocator; // Allocation work item + KTIMER SL_Timer; // Timer to free unused segments + KDPC SL_TimerDpc; // DPC of the timer of unused segments + KSPIN_LOCK SL_Lock; // Access control +}; + + +// The number of rcv packets per segment (config parameter) +#define MIN_RCV_PKTS_PER_SEGMENT 8 +#define DEF_RCV_PKTS_PER_SEGMENT 64 +#define MAX_RCV_PKTS_PER_SEGMENT 256 +extern ULONG RcvPktsPerSegment; + +// Maximum size of memory that can be used to allocate packets (config +// param). 0 means no limit +extern ULONG MaxRcvPktsPoolSize; + +// There are currently three known frame sizes: ethernet-1500, +// token ring 4k - 4500, token ring 16k - 17986 +#define FRAME_SIZE_VARIATIONS 3 + +// List of packet segments for Ethernet packets +extern SEGMENT_LIST ListEther; +// List of packet segments for Token Ring 4K packets +extern SEGMENT_LIST ListTR4; +// List of packet segments for Token Ring 16K packets +extern SEGMENT_LIST ListTR16; +// Mapping from src and destination packet size requirments +// to the appropriate segment list +extern PSEGMENT_LIST SegmentMap[FRAME_SIZE_VARIATIONS][FRAME_SIZE_VARIATIONS]; +// Timeout for unused segment +extern const LONGLONG SegmentTimeout; +extern KSPIN_LOCK AllocatorLock; + +/*++ +******************************************************************* + I n i t i a l i z e P a c k e t A l l o c a t o r + +Routine Description: + Initializes packet allocator +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +// VOID +// InitializePacketAllocator ( +// void +// ); +#define InitializePacketAllocator() { \ + KeInitializeSpinLock(&AllocatorLock); \ + InitializeSegmentList(&ListEther); \ + InitializeSegmentList(&ListTR4); \ + InitializeSegmentList(&ListTR16); \ +} + +/*++ +******************************************************************* + D e l e t e P a c k e t A l l o c a t o r + +Routine Description: + Disposes of all resources in packet allocator +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +// VOID +// DeletePacketAllocator ( +// void +// ); +#define DeletePacketAllocator() { \ + DeleteSegmentList(&ListEther); \ + DeleteSegmentList(&ListTR4); \ + DeleteSegmentList(&ListTR16); \ +} + + +/*++ +******************************************************************* + A l l o c a t e P a c k e t + +Routine Description: + Allocate packet for source - destination combination +Arguments: + srcListId - identifies max frame size for source interface + dstListId - identifies max frame size for destination + packet - receives pointer to allocated packet or NULL if allocation + fails +Return Value: + None + +******************************************************************* +--*/ +// VOID +// AllocatePacket ( +// IN INT srcListId, +// IN INT dstListId, +// OUT PPACKET_TAG packet +// ); +#define AllocatePacket(srcListId,dstListId,packet) { \ + PSEGMENT_LIST list; \ + ASSERT ((srcListId>=0) && (srcListId<FRAME_SIZE_VARIATIONS)); \ + ASSERT ((dstListId>=0) && (dstListId<FRAME_SIZE_VARIATIONS)); \ + list = SegmentMap[srcListId][dstListId]; \ + AllocatePacketFromList(list,packet); \ +} + +/*++ +******************************************************************* + D u p l i c a t e P a c k e t + +Routine Description: + Duplicates packet +Arguments: + src - source packet + dst - receives pointer to duplicated packet or NUUL if operation + failed +Return Value: + None + +******************************************************************* +--*/ +// VOID +// DuplicatePacket ( +// IN PPACKET_TAG src +// OUT PPACKET_TAG dst +// ); +#define DuplicatePacket(src,dst) { \ + PSEGMENT_LIST list; \ + list = src->PT_Segment->PS_SegmentList; \ + AllocatePacketFromList(list,dst); \ +} + + +/*++ +******************************************************************* + A l l o c a t e P a c k e t F r o m L i s t + +Routine Description: + Allocate packet from specified packet segment list +Arguments: + list - list from which to allocate + packet - receives pointer to allocated packet or NULL if allocation + fails +Return Value: + None + +******************************************************************* +--*/ +// VOID +// AllocatePacketFromList ( +// IN PSEGMENT_LIST list +// OUT PPACKET_TAG packet +// ); +#define AllocatePacketFromList(list,packet) { \ + PPACKET_SEGMENT segment; \ + KIRQL oldIRQL; \ + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); \ + do { \ + if (list->SL_FreeCount>0) { \ + segment = CONTAINING_RECORD (list->SL_Head.Flink, \ + PACKET_SEGMENT, PS_Link); \ + while (segment->PS_FreeHead==NULL) { \ + segment = CONTAINING_RECORD (segment->PS_Link.Flink, \ + PACKET_SEGMENT, PS_Link); \ + ASSERT (&segment->PS_Link!=&list->SL_Head); \ + } \ + list->SL_FreeCount -= 1; \ + if ((list->SL_FreeCount<list->SL_LowCount) \ + && !list->SL_AllocatorPending \ + && EnterForwarder ()) { \ + list->SL_AllocatorPending = TRUE; \ + ExQueueWorkItem (&list->SL_Allocator, DelayedWorkQueue);\ + } \ + } \ + else { \ + segment = CreateSegment (list); \ + if (segment!=NULL) { \ + InsertTailList (&list->SL_Head, &segment->PS_Link); \ + segment->PS_SegmentList = list; \ + list->SL_FreeCount = list->SL_BlockCount-1; \ + } \ + else { \ + packet = NULL; \ + break; \ + } \ + } \ + packet = segment->PS_FreeHead; \ + segment->PS_FreeHead = packet->PT_Next; \ + segment->PS_BusyCount += 1; \ + packet->PT_Identifier = IDENTIFIER_RIP; \ + packet->PT_Flags = 0; \ + } \ + while (FALSE); \ + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); \ +} + +/*++ +******************************************************************* + F r e e P a c k e t + +Routine Description: + Free allocated packet +Arguments: + packet - packet to free +Return Value: + None + +******************************************************************* +--*/ +// VOID +// FreePacket ( +// IN PPACKET_TAG packet +// ); +#define FreePacket(packet) { \ + PPACKET_SEGMENT segment=packet->PT_Segment; \ + PSEGMENT_LIST list; \ + KIRQL oldIRQL; \ + list = segment->PS_SegmentList; \ + KeAcquireSpinLock (&list->SL_Lock, &oldIRQL); \ + packet->PT_Next = segment->PS_FreeHead; \ + segment->PS_FreeHead = packet; \ + list->SL_FreeCount += 1; \ + segment->PS_BusyCount -= 1; \ + if (segment->PS_BusyCount==0) { \ + if (list->SL_TimerDpcPending) { \ + KeQuerySystemTime ((PLARGE_INTEGER)&segment->PS_FreeStamp); \ + KeReleaseSpinLock (&list->SL_Lock, oldIRQL);\ + } \ + else if (EnterForwarder ()) { \ + list->SL_TimerDpcPending = TRUE; \ + KeReleaseSpinLock (&list->SL_Lock, oldIRQL);\ + KeSetTimer (&list->SL_Timer, \ + *((PLARGE_INTEGER)&SegmentTimeout), \ + &list->SL_TimerDpc); \ + } \ + else { \ + KeReleaseSpinLock (&list->SL_Lock, oldIRQL);\ + } \ + } \ + else { \ + KeReleaseSpinLock (&list->SL_Lock, oldIRQL); \ + } \ +} + + +/*++ +******************************************************************* + C r e a t e S e g m e n t + +Routine Description: + Allocates and initializes packet segment +Arguments: + list - segment list to which new segment will be added +Return Value: + Pointer to allocated segment, NULL if fails + +******************************************************************* +--*/ +PPACKET_SEGMENT +CreateSegment ( + PSEGMENT_LIST list + ); + +/*++ +******************************************************************* + D e l e t e S e g m e n t + +Routine Description: + Frees packet segment +Arguments: + segment - segment to free +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteSegment ( + PPACKET_SEGMENT segment + ); + +/*++ +******************************************************************* + R e g i s t e r P a c k e t C o n s u m e r + +Routine Description: + Registers a consumer (bound interface) of packets of the + given size +Arguments: + pktsize - maximum size of packets needed + listId - buffer to return packet list id where packets + of required size are located +Return Value: + STATUS_SUCCESS - registration succeded + STATUS_INSUFFICIENT_RESOURCES - not enogh resources to register + +******************************************************************* +--*/ +NTSTATUS +RegisterPacketConsumer ( + IN ULONG pktsize, + OUT INT *listID + ); + +/*++ +******************************************************************* + D e r e g i s t e r P a c k e t C o n s u m e r + +Routine Description: + Deregisters a consumer (bound interface) of packets of the + given size +Arguments: + listId - packet list id used by the consumer +Return Value: + None + +******************************************************************* +--*/ +VOID +DeregisterPacketConsumer ( + IN INT listID + ); + +/*++ +******************************************************************* + I n i t i a l i z e S e g m e n t L i s t + +Routine Description: + Initializes list of packet segments +Arguments: + list - list to initalize +Return Value: + None + +******************************************************************* +--*/ +VOID +InitializeSegmentList( + PSEGMENT_LIST list + ); + + +/*++ +******************************************************************* + D e l e t e S e g m e n t L i s t + +Routine Description: + Deletes list of packet segments +Arguments: + list - list to delete +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteSegmentList ( + PSEGMENT_LIST list + ); + +#endif + diff --git a/private/ntos/tdi/isn/fwd/precomp.h b/private/ntos/tdi/isn/fwd/precomp.h new file mode 100644 index 000000000..bc471bd40 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/precomp.h @@ -0,0 +1,61 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\precomp.h + +Abstract: + IPX Forwarder driver precompiled header file + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#define ISN_NT 1 +#define NT 1 + +#if DBG +#define DEBUG 1 +#endif + +// System includes +#include <ntos.h> +#include <tdikrnl.h> +#include <ndis.h> +#include <zwapi.h> +#include <limits.h> + +// IPX shared includes +#include "bind.h" +#include "ipxfwd.h" +#include "ipxfltif.h" + +// Constants and macros +#include "fwddefs.h" +#include "rwlock.h" + +// Internal module prototypes +#include "tables.h" +#include "registry.h" +#include "packets.h" +#include "ipxbind.h" +#include "rcvind.h" +#include "send.h" +#include "netbios.h" +#include "lineind.h" +#include "ddreqs.h" +#include "driver.h" +#include "filterif.h" +#include "debug.h" + +#pragma hdrstop + + + diff --git a/private/ntos/tdi/isn/fwd/rcvind.c b/private/ntos/tdi/isn/fwd/rcvind.c new file mode 100644 index 000000000..7c4bc2d39 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/rcvind.c @@ -0,0 +1,825 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\rcvind.c + +Abstract: + Receive indication processing + +Author: + + Vadim Eydelman + +Revision History: + +--*/ +#include "precomp.h" + +#if DBG +VOID +DbgFilterReceivedPacket(PUCHAR hdrp); +#endif + +// Doesn't allow accepting packets (for routing) from dial-in clients +BOOLEAN ThisMachineOnly = FALSE; + +/*++ +******************************************************************* + F w R e c e i v e + +Routine Description: + Called by the IPX stack to indicate that the IPX packet was + received by the NIC dirver. Only external destined packets are + indicated by this routine (with the exception of Netbios boradcasts + that indicated both for internal and external handlers) +Arguments: + MacBindingHandle - handle of NIC driver + MaxReceiveContext - NIC driver context + RemoteAddress - sender's address + MacOptions - + LookaheadBuffer - packet lookahead buffer that contains complete + IPX header + LookaheadBufferSize - its size (at least 30 bytes) + LookaheadBufferOffset - offset of lookahead buffer in the physical + packet +Return Value: + TRUE if we take the MDL chain to return later with NdisReturnPacket + +******************************************************************* +--*/ +BOOLEAN +IpxFwdReceive ( + NDIS_HANDLE MacBindingHandle, + NDIS_HANDLE MacReceiveContext, + ULONG Context, + PIPX_LOCAL_TARGET RemoteAddress, + ULONG MacOptions, + PUCHAR LookaheadBuffer, + UINT LookaheadBufferSize, + UINT LookaheadBufferOffset, + UINT PacketSize, + PMDL pMdl + ) { + PINTERFACE_CB srcIf, dstIf; + PPACKET_TAG pktTag; + PNDIS_PACKET pktDscr; + NDIS_STATUS status; + UINT BytesTransferred; + LARGE_INTEGER PerfCounter; + + // check that our configuration process has terminated OK + if (!EnterForwarder ()) { + return FALSE; + } + + if (!MeasuringPerformance) { + PerfCounter.QuadPart = 0; + } + else { +#if DBG + static LONGLONG LastCall = 0; + KIRQL oldIRQL; +#endif + PerfCounter = KeQueryPerformanceCounter (NULL); +#if DBG + KeAcquireSpinLock (&PerfCounterLock, &oldIRQL); + ASSERT (PerfCounter.QuadPart-LastCall<ActivityTreshhold); + LastCall = PerfCounter.QuadPart; + KeReleaseSpinLock (&PerfCounterLock, oldIRQL); +#endif + } + + IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, + ("IpxFwd: FwdReceive on %0lx," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + Context, GETULONG (LookaheadBuffer+IPXH_DESTNET), + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + +#if DBG + DbgFilterReceivedPacket (LookaheadBuffer); +#endif + srcIf = InterfaceContextToReference ((PVOID)Context, RemoteAddress->NicId); + // Check if interface is valid + if (srcIf!=NULL) { + USHORT pktlen; + ULONG dstNet; + KIRQL oldIRQL; + + dstNet = GETULONG (LookaheadBuffer + IPXH_DESTNET); + pktlen = GETUSHORT(LookaheadBuffer + IPXH_LENGTH); + + // check if we got the whole IPX header in the lookahead buffer + if ((LookaheadBufferSize >= IPXH_HDRSIZE) + && (*(LookaheadBuffer + IPXH_XPORTCTL) < 16) + && (pktlen<=PacketSize)) { + // Lock interface CB to ensure coherency of information in it + KeAcquireSpinLock(&srcIf->ICB_Lock, &oldIRQL); + // Check if shoud accept packets on this interface + if (IS_IF_ENABLED(srcIf) + && (srcIf->ICB_Stats.OperationalState!=FWD_OPER_STATE_DOWN) + && (!ThisMachineOnly + || (srcIf->ICB_InterfaceType + !=FWD_IF_REMOTE_WORKSTATION))) { + // Check for looped back packets + if (IPX_NODE_CMP (RemoteAddress->MacAddress, + srcIf->ICB_LocalNode)!=0) { + + // Separate processing of netbios broadcast packets (20) + if (*(LookaheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { + PFWD_ROUTE dstRoute; + INT srcListId, dstListId; + // Temp IPX bug fix, they shou;d ensure that + // we only get packets that can be routed + if ((dstNet==srcIf->ICB_Network) + || (dstNet==InternalInterface->ICB_Network)) { + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + ReleaseInterfaceReference (srcIf); + LeaveForwarder (); + return FALSE; + } +// ASSERT (dstNet!=srcIf->ICB_Network); +// ASSERT ((InternalInterface==NULL) +// || (InternalInterface->ICB_Network==0) +// || (dstNet!=InternalInterface->ICB_Network)); + // Check if needed route is in cash + if ((srcIf->ICB_CashedRoute!=NULL) + && (dstNet==srcIf->ICB_CashedRoute->FR_Network) + // If route was changed or deleted, this will fail + && (srcIf->ICB_CashedRoute->FR_InterfaceReference + ==srcIf->ICB_CashedInterface)) { + dstIf = srcIf->ICB_CashedInterface; + dstRoute = srcIf->ICB_CashedRoute; + AcquireInterfaceReference (dstIf); + AcquireRouteReference (dstRoute); + IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, + ("IpxFwd: Destination in cash.\n")); + } + else { // Find and cash the route + dstIf = FindDestination (dstNet, + LookaheadBuffer+IPXH_DESTNODE, + &dstRoute + ); + + if (dstIf!=NULL) { // If route is found + IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, + ("IpxFwd: Found destination %0lx.\n", dstIf)); + // Don't cash global wan clients and + // routes to the same net + if ((dstNet!=GlobalNetwork) + && (dstIf!=srcIf)) { + if (srcIf->ICB_CashedInterface!=NULL) + ReleaseInterfaceReference (srcIf->ICB_CashedInterface); + if (srcIf->ICB_CashedRoute!=NULL) + ReleaseRouteReference (srcIf->ICB_CashedRoute); + srcIf->ICB_CashedInterface = dstIf; + srcIf->ICB_CashedRoute = dstRoute; + AcquireInterfaceReference (dstIf); + AcquireRouteReference (dstRoute); + } + } + else { // No route + InterlockedIncrement (&srcIf->ICB_Stats.InNoRoutes); + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, + ("IpxFwd: No route for packet on interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + ReleaseInterfaceReference (srcIf); + LeaveForwarder (); + return FALSE; + } + } + srcListId = srcIf->ICB_PacketListId; + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + + // Check if destination if can take the packet + if (IS_IF_ENABLED (dstIf) + // If interface is UP check packet againts actual size limit + && (((dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) + && (PacketSize<=dstIf->ICB_Stats.MaxPacketSize)) + // if sleeping (WAN), check we can allocate it from WAN list + || ((dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_SLEEPING) + && (PacketSize<=WAN_PACKET_SIZE)) + // otherwise, interface is down and we can't take the packet + ) ){ + FILTER_ACTION action; + action = FltFilter (LookaheadBuffer, LookaheadBufferSize, + srcIf->ICB_FilterInContext, + dstIf->ICB_FilterOutContext); + if (action==FILTER_PERMIT) { + InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); + dstListId = dstIf->ICB_PacketListId; + // try to get a packet from the rcv pkt pool + AllocatePacket (srcListId, dstListId, pktTag); + if (pktTag!=NULL) { + // Set destination mac in local target if + // possible + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + if (dstIf->ICB_InterfaceType==FWD_IF_PERMANENT) { + // Permanent interface: send to the next + // hop router if net is not directly connected + // or to the dest node otherwise + if (dstNet!=dstIf->ICB_Network) { + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, + dstRoute->FR_NextHopAddress); + } + else { + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, + LookaheadBuffer+IPXH_DESTNODE); + } + } + else { // Demand dial interface: assumed to be + // point to point connection -> send to + // the other party if connection has already + // been made, otherwise wait till connected + if (dstIf->ICB_Stats.OperationalState + == FWD_OPER_STATE_UP) { + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, + dstIf->ICB_RemoteNode); + } // Copy source mac address and nic id in case + // we need to spoof this packet + else if ((*(LookaheadBuffer+IPXH_PKTTYPE)==0) + && (pktlen==IPXH_HDRSIZE+2) + && ((LookaheadBufferSize<IPXH_HDRSIZE+2) + ||(*(LookaheadBuffer+IPXH_HDRSIZE+1)=='?'))) { + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, + RemoteAddress->MacAddress); + pktTag->PT_SourceIf = srcIf; + AcquireInterfaceReference (srcIf); + pktTag->PT_Flags |= PT_SOURCE_IF; + } + + } + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + ReleaseRouteReference (dstRoute); + goto GetPacket; + } + else { // Allocation failure + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + } + } + else {// Filtered out + if (action==FILTER_DENY_OUT) + InterlockedIncrement (&dstIf->ICB_Stats.OutFiltered); + else { + ASSERT (action==FILTER_DENY_IN); + InterlockedIncrement (&srcIf->ICB_Stats.InFiltered); + } + IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, + ("IpxFwd: Filtered out" + " packet on interface %ld (icb:%0lx)," + " dst-%ld (icb %08lx) %08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstIf->ICB_Index, dstIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + } + } + else { // Destination interface is down + InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, + ("IpxFwd: Dest interface %ld (icb %08lx) down" + " for packet on interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + dstIf->ICB_Index, dstIf, srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + } + ReleaseInterfaceReference (dstIf); + ReleaseRouteReference (dstRoute); + } + else { // if netbios + // check that this is a netbios bcast packet and + // didnt exceed the limit of routers to traverse + // and we can accept it on this interface + if (srcIf->ICB_NetbiosAccept + && (*(LookaheadBuffer + IPXH_XPORTCTL) < 8)) { + INT srcListId; + srcListId = srcIf->ICB_PacketListId; + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + // Check if packet is valid + if (IPX_NODE_CMP (LookaheadBuffer + IPXH_DESTNODE, + BROADCAST_NODE)==0) { + // Check if we haven't exceeded the quota + if (InterlockedDecrement (&NetbiosPacketsQuota)>=0) { + // try to get a packet from the rcv pkt pool + AllocatePacket (srcListId, srcListId, pktTag); + if (pktTag!=NULL) { + dstIf = srcIf; + AcquireInterfaceReference (dstIf); + goto GetPacket; + } + } + else {// Netbios quota exceded + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: Netbios quota exceded" + " for packet on interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + } + InterlockedIncrement (&NetbiosPacketsQuota); + } + else { // Bad netbios packet + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: Bad nb packet on interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + InterlockedIncrement (&srcIf->ICB_Stats.InHdrErrors); + } + } + else { // Netbios accept disabled or to many routers crossed + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: NB packet dropped on disabled interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + } + } // End netbios specific processing (else if netbios) + } + else { // Looped back packets discarded without counting + // (We shouldn't get them in IPX stack does the right job) + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + } + } + else { // Interface is down or disabled + KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, + ("IpxFwd: Packet dropped on disabled interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + } + } + else { // Obvious header errors (shouldn't IPX do this for us ? + InterlockedIncrement (&srcIf->ICB_Stats.InHdrErrors); + IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, + ("IpxFwd: Header errors in packet on interface %ld (icb:%0lx)," + " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", + srcIf->ICB_Index, srcIf, dstNet, + LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], + LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], + LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], + LookaheadBuffer[IPXH_PKTTYPE])); + } + ReleaseInterfaceReference (srcIf); + } // We could not locate the interface from IPX supplied context: there + // is just a little time window when interface is deleted + // but IPX had already pushed the context on the stack + else { + IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, + ("IpxFwd: Receive, type-%02x" + " - src interface context is invalid.\n", + LookaheadBuffer[IPXH_PKTTYPE])); + } + LeaveForwarder (); + return FALSE ; + +GetPacket: + + InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); + ReleaseInterfaceReference (srcIf); + + pktDscr = CONTAINING_RECORD (pktTag, NDIS_PACKET, ProtocolReserved); + pktTag->PT_InterfaceReference = dstIf; + pktTag->PT_PerfCounter = PerfCounter.QuadPart; + + // try to get the packet data + IPXTransferData(&status, + MacBindingHandle, + MacReceiveContext, + LookaheadBufferOffset, // start of IPX header + PacketSize, // packet size starting at IPX header + pktDscr, + &BytesTransferred); + + if (status != NDIS_STATUS_PENDING) { + // complete the frame processing (LeaveForwarder will be called there) + IpxFwdTransferDataComplete(pktDscr, status, BytesTransferred); + } + return FALSE; +} + + +/*++ +******************************************************************* + F w T r a n s f e r D a t a C o m p l e t e + +Routine Description: + Called by the IPX stack when NIC driver completes data transger. +Arguments: + pktDscr - handle of NIC driver + status - result of the transfer + bytesTransferred - number of bytest trasferred +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdTransferDataComplete ( + PNDIS_PACKET pktDscr, + NDIS_STATUS status, + UINT bytesTransferred + ) { + PPACKET_TAG pktTag; + + pktTag = (PPACKET_TAG)(&pktDscr->ProtocolReserved); + + // If transfer failed, release the packet and interface + if (status==NDIS_STATUS_SUCCESS) { + if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + SendPacket (pktTag->PT_InterfaceReference, pktTag); + else + ProcessNetbiosPacket (pktTag->PT_InterfaceReference, pktTag); + + } + else { + IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, + ("IpxFwd: Transfer data failed for packet %08lx on interface %08lx!\n", + pktTag, pktTag->PT_InterfaceReference)); + if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { + InterlockedIncrement ( + &pktTag->PT_InterfaceReference->ICB_Stats.OutDiscards); + } + else { // For netbios packets interface reference is + // actually a source interface + InterlockedIncrement (&NetbiosPacketsQuota); + InterlockedIncrement ( + &pktTag->PT_InterfaceReference->ICB_Stats.InDiscards); + } + ReleaseInterfaceReference (pktTag->PT_InterfaceReference); + FreePacket (pktTag); + } + + LeaveForwarder (); + return; +} + + +/*++ +******************************************************************* + F w R e c e i v e C o m p l e t e + +Routine Description: + + This routine receives control from the IPX driver after one or + more receive operations have completed and no receive is in progress. + It is called under less severe time constraints than IpxFwdReceive. + It is used to process netbios queue + +Arguments: + None +Return Value: + None +******************************************************************* +--*/ +VOID +IpxFwdReceiveComplete ( + USHORT NicId + ) { + + // check that our configuration process has terminated OK + if(!EnterForwarder ()) { + return; + } + IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, ("IpxFwd: FwdReceiveComplete.\n")); + ScheduleNetbiosWorker (); + LeaveForwarder (); +} + +/*++ +******************************************************************* + I p x F w d I n t e r n a l R e c e i v e + +Routine Description: + Called by the IPX stack to indicate that the IPX packet destined + to local client was received by the NIC dirver. +Arguments: + Context - forwarder context associated with + the NIC (interface block pointer) + RemoteAddress - sender's address + LookaheadBuffer - packet lookahead buffer that contains complete + IPX header + LookaheadBufferSize - its size (at least 30 bytes) +Return Value: + STATUS_SUCCESS - the packet will be delivered to local destination + STATUS_UNSUCCESSFUL - the packet will be dropped + +******************************************************************* +--*/ +NTSTATUS +IpxFwdInternalReceive ( + IN ULONG Context, + IN PIPX_LOCAL_TARGET RemoteAddress, + IN PUCHAR LookAheadBuffer, + IN UINT LookAheadBufferSize + ) { + NTSTATUS status = STATUS_SUCCESS; + PINTERFACE_CB srcIf; + + if (!EnterForwarder ()) { + return STATUS_UNSUCCESSFUL; + } + if (Context!=VIRTUAL_NET_FORWARDER_CONTEXT) { + // Check if interface context supplied by IPX driver is valid + srcIf = InterfaceContextToReference ((PVOID)Context, RemoteAddress->NicId); + } + else { + srcIf = InternalInterface; + AcquireInterfaceReference (srcIf); + } + + if (srcIf!=NULL) { + // Check if we can accept on this interface + if (IS_IF_ENABLED (srcIf) + && (srcIf->ICB_Stats.OperationalState!=FWD_OPER_STATE_DOWN) + && ((*(LookAheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + || srcIf->ICB_NetbiosAccept)) { + // Check if we can accept on internal interface + if (IS_IF_ENABLED(InternalInterface)) { + FILTER_ACTION action; + action = FltFilter (LookAheadBuffer, LookAheadBufferSize, + srcIf->ICB_FilterInContext, + InternalInterface->ICB_FilterOutContext); + // Check the filter + if (action==FILTER_PERMIT) { + // Update source interface statistics + InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); + // Handle NB packets separatedly + if (*(LookAheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { + InterlockedIncrement ( + &InternalInterface->ICB_Stats.OutDelivers); + IpxFwdDbgPrint (DBG_INT_RECV, DBG_INFORMATION, + ("IpxFwd: FwdInternalReceive," + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," + " type-%02x.\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], + LookAheadBuffer[IPXH_PKTTYPE])); + } + else { + // Check if destination netbios name is staticly assigned to + // an external interface or netbios delivery options do not + // allow us to deliver this packet + PINTERFACE_CB dstIf; + USHORT dstSock = GETUSHORT (LookAheadBuffer+IPXH_DESTSOCK); + + InterlockedIncrement (&srcIf->ICB_Stats.NetbiosReceived); + // First try to find a static name if we have enough data + // in the lookahead buffer + if ((dstSock==IPX_NETBIOS_SOCKET) + && (LookAheadBufferSize>(NB_NAME+16))) + dstIf = FindNBDestination (LookAheadBuffer+(NB_NAME-IPXH_HDRSIZE)); + else if ((dstSock==IPX_SMB_NAME_SOCKET) + && (LookAheadBufferSize>(SMB_NAME+16))) + dstIf = FindNBDestination (LookAheadBuffer+(SMB_NAME-IPXH_HDRSIZE)); + else + dstIf = NULL; + // Now see, if we can deliver the packet + if ((((dstIf==NULL) || (dstIf==InternalInterface)) + && (InternalInterface->ICB_NetbiosDeliver==FWD_NB_DELIVER_ALL)) + || ((dstIf==InternalInterface) + && (InternalInterface->ICB_NetbiosDeliver==FWD_NB_DELIVER_STATIC))) { + InterlockedIncrement ( + &InternalInterface->ICB_Stats.NetbiosSent); + InterlockedIncrement ( + &InternalInterface->ICB_Stats.OutDelivers); + IpxFwdDbgPrint (DBG_INT_RECV, DBG_INFORMATION, + ("IpxFwd: FwdInternalReceive, NB" + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5])); + } + else { + InterlockedIncrement ( + &InternalInterface->ICB_Stats.OutDiscards); + IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, + ("IpxFwd: FwdInternalReceive, NB dropped because delivery disabled" + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5])); + status = STATUS_UNSUCCESSFUL; + } + if (dstIf!=NULL) + ReleaseInterfaceReference (dstIf); + } + } + else {// Filtered Out + if (action==FILTER_DENY_OUT) + InterlockedIncrement ( + &InternalInterface->ICB_Stats.OutFiltered); + else { + ASSERT (action==FILTER_DENY_IN); + InterlockedIncrement (&srcIf->ICB_Stats.InFiltered); + } + IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, + ("IpxFwd: FwdInternalReceive, filtered out" + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," + " type-%02x.\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], + LookAheadBuffer[IPXH_PKTTYPE])); + } + } + else {// Internal interface is disabled + InterlockedIncrement ( + &InternalInterface->ICB_Stats.OutDiscards); + status = STATUS_UNSUCCESSFUL; + IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, + ("IpxFwd: FwdInternalReceive, internal if disabled" + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," + " type-%02x.\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], + LookAheadBuffer[IPXH_PKTTYPE])); + } + } + else { // Disabled source interface + InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); + IpxFwdDbgPrint (DBG_INT_RECV, DBG_ERROR, + ("IpxFwd: FwdInternalReceive, source if disabled" + " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," + " type-%02x.\n", + srcIf->ICB_Index, srcIf, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], + LookAheadBuffer[IPXH_PKTTYPE])); + status = STATUS_UNSUCCESSFUL; + } + ReleaseInterfaceReference (srcIf); + } + else { // Invalid source interface context + IpxFwdDbgPrint (DBG_INT_RECV, DBG_ERROR, + ("IpxFwd: FwdInternalReceive, source if context is invalid" + " from (%lx:%d)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," + " type-%02x.\n", + Context, RemoteAddress->NicId, + LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], + LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], + LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], + LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], + LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], + LookAheadBuffer[IPXH_PKTTYPE])); + status = STATUS_UNSUCCESSFUL; + } + LeaveForwarder (); + return status; +} + +/*++ +******************************************************************* + D e l e t e R e c v Q u e u e + +Routine Description: + Initializes the netbios bradcast queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteRecvQueue ( + void + ) { +// while (!IsListEmpty (&RecvQueue)) { +// PPACKET_TAG pktTag = CONTAINING_RECORD (RecvQueue.Flink, +// PACKET_TAG, +// PT_QueueLink); +// RemoveEntryList (&pktTag->PT_QueueLink); +// if (pktTag->PT_InterfaceReference!=NULL) { +// ReleaseInterfaceReference (pktTag->PT_InterfaceReference); +// } +// FreePacket (pktTag); +// } +} +#if DBG + +ULONG DbgFilterTrap = 0; // 1 - on dst and src (net + node), + // 2 - on dst (net + node), + // 3 - on src (net + node), + // 4 - on dst (net + node + socket) + +UCHAR DbgFilterDstNet[4]; +UCHAR DbgFilterDstNode[6]; +UCHAR DbgFilterDstSocket[2]; +UCHAR DbgFilterSrcNet[4]; +UCHAR DbgFilterSrcNode[6]; +UCHAR DbgFilterSrcSocket[2]; +PUCHAR DbgFilterFrame; + +VOID +DbgFilterReceivedPacket(PUCHAR hdrp) +{ + switch(DbgFilterTrap) { + + case 1: + + if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && + !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6) && + !memcmp(hdrp + IPXH_SRCNET, DbgFilterSrcNet, 4) && + !memcmp(hdrp + IPXH_SRCNODE, DbgFilterSrcNode, 6)) { + + DbgBreakPoint(); + } + + break; + + case 2: + + if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && + !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6)) { + + DbgBreakPoint(); + } + + break; + + case 3: + + if(!memcmp(hdrp + IPXH_SRCNET, DbgFilterSrcNet, 4) && + !memcmp(hdrp + IPXH_SRCNODE, DbgFilterSrcNode, 6)) { + + DbgBreakPoint(); + } + + break; + + case 4: + + if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && + !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6) && + !memcmp(hdrp + IPXH_DESTSOCK, DbgFilterDstSocket, 2)) { + + DbgBreakPoint(); + } + + break; + + default: + + break; + } + + DbgFilterFrame = hdrp; +} + +#endif + diff --git a/private/ntos/tdi/isn/fwd/rcvind.h b/private/ntos/tdi/isn/fwd/rcvind.h new file mode 100644 index 000000000..50f240bdd --- /dev/null +++ b/private/ntos/tdi/isn/fwd/rcvind.h @@ -0,0 +1,180 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\rcvind.h + +Abstract: + Receive indication processing + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_RCVIND +#define _IPXFWD_RCVIND + +// Doesn't allow accepting packets (for routing) from dial-in clients +extern BOOLEAN ThisMachineOnly; + +/*++ +******************************************************************* + I n i t i a l i z e R e c v Q u e u e + +Routine Description: + Initializes recv queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +//VOID +//DeleteRecvQueue ( +// void +// ) +#define InitializeRecvQueue() { \ +} + +/*++ +******************************************************************* + D e l e t e R e c v Q u e u e + +Routine Description: + Deletes recv queue +Arguments: + None +Return Value: + None + +******************************************************************* +--*/ +VOID +DeleteRecvQueue ( + void + ); + +/*++ +******************************************************************* + F w R e c e i v e + +Routine Description: + Called by the IPX stack to indicate that the IPX packet was + received by the NIC dirver. Only external destined packets are + indicated by this routine (with the exception of Netbios boradcasts + that indicated both for internal and external handlers) +Arguments: + MacBindingHandle - handle of NIC driver + MaxReceiveContext - NIC driver context + Context - forwarder context associated with + the NIC (interface block pointer) + RemoteAddress - sender's address + MacOptions - + LookaheadBuffer - packet lookahead buffer that contains complete + IPX header + LookaheadBufferSize - its size (at least 30 bytes) + LookaheadBufferOffset - offset of lookahead buffer in the physical + packet +Return Value: + None + +******************************************************************* +--*/ +BOOLEAN +IpxFwdReceive ( + NDIS_HANDLE MacBindingHandle, + NDIS_HANDLE MacReceiveContext, + ULONG Context, + PIPX_LOCAL_TARGET RemoteAddress, + ULONG MacOptions, + PUCHAR LookaheadBuffer, + UINT LookaheadBufferSize, + UINT LookaheadBufferOffset, + UINT PacketSize, + PMDL pMdl + + ); + + +/*++ +******************************************************************* + F w T r a n s f e r D a t a C o m p l e t e + +Routine Description: + Called by the IPX stack when NIC driver completes data transger. +Arguments: + pktDscr - handle of NIC driver + status - result of the transfer + bytesTransferred - number of bytest trasferred +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdTransferDataComplete ( + PNDIS_PACKET pktDscr, + NDIS_STATUS status, + UINT bytesTransferred + ); + + +/*++ +******************************************************************* + F w T r a n s f e r D a t a C o m p l e t e + +Routine Description: + + This routine receives control from the IPX driver after one or + more receive operations have completed and no receive is in progress. + It is called under less severe time constraints than IpxFwdReceive. + It is used to process netbios queue + +Arguments: + None +Return Value: + None +******************************************************************* +--*/ +VOID +IpxFwdReceiveComplete ( + USHORT NicId + ); + +/*++ +******************************************************************* + F w R e c e i v e + +Routine Description: + Called by the IPX stack to indicate that the IPX packet destined + to local client was received by the NIC dirver. +Arguments: + Context - forwarder context associated with + the NIC (interface block pointer) + RemoteAddress - sender's address + LookaheadBuffer - packet lookahead buffer that contains complete + IPX header + LookaheadBufferSize - its size (at least 30 bytes) +Return Value: + STATUS_SUCCESS - the packet will be delivered to local destination + STATUS_UNSUCCESSFUL - the packet will be dropped + +******************************************************************* +--*/ +NTSTATUS +IpxFwdInternalReceive ( + IN ULONG FwdAdapterContext, + IN PIPX_LOCAL_TARGET RemoteAddress, + IN PUCHAR LookAheadBuffer, + IN UINT LookAheadBufferSize + ); + +#endif + diff --git a/private/ntos/tdi/isn/fwd/registry.c b/private/ntos/tdi/isn/fwd/registry.c new file mode 100644 index 000000000..b38a3b4e1 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/registry.c @@ -0,0 +1,273 @@ +/*******************************************************************/ +/* Copyright(c) 1993 Microsoft Corporation */ +/*******************************************************************/ + +//*** +// +// Filename: registry.c +// +// Description: routines for reading the registry configuration +// +// Author: Stefan Solomon (stefans) November 9, 1993. +// +// Revision History: +// Updated to read parameters of new forwarder driver (11/95) +// +//*** + +#include "precomp.h" + +NTSTATUS +SetIpxDeviceName( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ); + +/*++ +******************************************************************* + R e a d I p x D e v i c e N a m e + +Routine Description: + Allocates buffer and reads device name exported by the IPX stack + into it +Arguments: + FileName - pointer to buffer to hold the name +Return Value: + STATUS_SUCCESS - tables were created ok + STATUS_INSUFFICIENT_RESOURCES - resource allocation failed + STATUS_OBJECT_NAME_NOT_FOUND - if name value is not found +******************************************************************* +--*/ +NTSTATUS +ReadIpxDeviceName ( + PWSTR *FileName + ) { + NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + PWSTR Export = L"Export"; + PWSTR IpxRegistryPath = L"NwLnkIpx\\Linkage"; + + // + // Set up QueryTable to do the following: + // + + // + // 1) Call SetIpxDeviceName for the string in "Export" + // + + QueryTable[0].QueryRoutine = SetIpxDeviceName; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].Name = Export; + QueryTable[0].EntryContext = FileName; + QueryTable[0].DefaultType = 0; + + // + // 2) Stop + // + + QueryTable[1].QueryRoutine = NULL; + QueryTable[1].Flags = 0; + QueryTable[1].Name = NULL; + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_SERVICES, + IpxRegistryPath, + QueryTable, + NULL, + NULL); + + return Status; +} + + +/*++ +******************************************************************* + S e t I p x D e v i c e N a m e + +Routine Description: + This routine is a callback routine for RtlQueryRegistryValues + It is called for each piece of the "Export" multi-string and + saves the information in a ConfigurationInfo structure. +Arguments: + ValueName - The name of the value ("Export" -- ignored). + ValueType - The type of the value (REG_SZ -- ignored). + ValueData - The null-terminated data for the value. + ValueLength - The length of ValueData. + Context - NULL. + EntryContext - file name pointer. +Return Value: + STATUS_SUCCESS - name was allocated and copied OK + STATUS_INSUFFICIENT_RESOURCES - name allocation failed +******************************************************************* +--*/ +NTSTATUS +SetIpxDeviceName( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ) { + PWSTR *FileName = (PWSTR *)EntryContext; + + ASSERT (ValueType==REG_SZ); + *FileName = (PWSTR)ExAllocatePoolWithTag(NonPagedPool, + ValueLength, FWD_POOL_TAG); + if (*FileName != NULL) { + RtlCopyMemory (*FileName, ValueData, ValueLength); + return STATUS_SUCCESS; + } + else + return STATUS_INSUFFICIENT_RESOURCES; + +} + +/*++ +******************************************************************* + G e t R o u t e r P a r a m e t e r s + +Routine Description: + Reads the parameters from the registry or sets the defaults +Arguments: + RegistryPath - where to read from. +Return Value: + STATUS_SUCCESS +******************************************************************* +--*/ +NTSTATUS +GetForwarderParameters ( + IN PUNICODE_STRING RegistryPath + ) { + NTSTATUS Status; + PWSTR RegistryPathBuffer; + PWSTR Parameters = L"Parameters"; + RTL_QUERY_REGISTRY_TABLE paramTable[11]; // table size = nr of params + 1 + + RegistryPathBuffer = (PWSTR)ExAllocatePool(NonPagedPool, RegistryPath->Length + sizeof(WCHAR)); + + if (RegistryPathBuffer == NULL) { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length); + *(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0'; + + RtlZeroMemory(¶mTable[0], sizeof(paramTable)); + + paramTable[0].QueryRoutine = NULL; + paramTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; + paramTable[0].Name = Parameters; + + paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[1].Name = L"MaxRcvPktPoolSize"; + paramTable[1].EntryContext = &MaxRcvPktsPoolSize; + paramTable[1].DefaultType = REG_DWORD; + paramTable[1].DefaultData = &MaxRcvPktsPoolSize; + paramTable[1].DefaultLength = sizeof(ULONG); + + paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[2].Name = L"RcvPktsPerSegment"; + paramTable[2].EntryContext = &RcvPktsPerSegment; + paramTable[2].DefaultType = REG_DWORD; + paramTable[2].DefaultData = &RcvPktsPerSegment; + paramTable[2].DefaultLength = sizeof(ULONG); + + paramTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[3].Name = L"RouteTableSegmentSize"; + paramTable[3].EntryContext = &RouteSegmentSize; + paramTable[3].DefaultType = REG_DWORD; + paramTable[3].DefaultData = &RouteSegmentSize; + paramTable[3].DefaultLength = sizeof(ULONG); + + paramTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[4].Name = L"MaxSendPktsQueued"; + paramTable[4].EntryContext = &MaxSendPktsQueued; + paramTable[4].DefaultType = REG_DWORD; + paramTable[4].DefaultData = &MaxSendPktsQueued; + paramTable[4].DefaultLength = sizeof(ULONG); + + paramTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[5].Name = L"ClientHashSize"; + paramTable[5].EntryContext = &ClientHashSize; + paramTable[5].DefaultType = REG_DWORD; + paramTable[5].DefaultData = &ClientHashSize; + paramTable[5].DefaultLength = sizeof(ULONG); + + paramTable[6].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[6].Name = L"InterfaceHashSize"; + paramTable[6].EntryContext = &InterfaceHashSize; + paramTable[6].DefaultType = REG_DWORD; + paramTable[6].DefaultData = &InterfaceHashSize; + paramTable[6].DefaultLength = sizeof(ULONG); + + paramTable[7].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[7].Name = L"MaxNetbiosPacketsQueued"; + paramTable[7].EntryContext = &MaxNetbiosPacketsQueued; + paramTable[7].DefaultType = REG_DWORD; + paramTable[7].DefaultData = &MaxNetbiosPacketsQueued; + paramTable[7].DefaultLength = sizeof(ULONG); + + paramTable[8].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[8].Name = L"SpoofingTimeout"; + paramTable[8].EntryContext = &SpoofingTimeout; + paramTable[8].DefaultType = REG_DWORD; + paramTable[8].DefaultData = &SpoofingTimeout; + paramTable[8].DefaultLength = sizeof(ULONG); + + paramTable[9].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[9].Name = L"DontSuppressNonAgentSapAdvertisements"; + paramTable[9].EntryContext = &DontSuppressNonAgentSapAdvertisements; + paramTable[9].DefaultType = REG_DWORD; + paramTable[9].DefaultData = &DontSuppressNonAgentSapAdvertisements; + paramTable[9].DefaultLength = sizeof(ULONG); + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + RegistryPathBuffer, + paramTable, + NULL, + NULL); + + if(!NT_SUCCESS(Status)) { + + IpxFwdDbgPrint (DBG_REGISTRY, DBG_WARNING, + ("IpxFwd: Missing Parameters key in the registry\n")); + } + + ExFreePool(RegistryPathBuffer); + + if ((RcvPktsPerSegment > MAX_RCV_PKTS_PER_SEGMENT) || + (RcvPktsPerSegment < MIN_RCV_PKTS_PER_SEGMENT)) { + + RcvPktsPerSegment = DEF_RCV_PKTS_PER_SEGMENT; + } + + if ((RouteSegmentSize > MAX_ROUTE_SEGMENT_SIZE) || + (RouteSegmentSize < MIN_ROUTE_SEGMENT_SIZE)) { + + RouteSegmentSize = DEF_ROUTE_SEGMENT_SIZE; + } + else + RouteSegmentSize = ROUND_TO_PAGES(RouteSegmentSize); + + if ((InterfaceHashSize > MAX_INTERFACE_HASH_SIZE) || + (InterfaceHashSize < MIN_INTERFACE_HASH_SIZE)) { + + InterfaceHashSize = DEF_INTERFACE_HASH_SIZE; + } + + if ((ClientHashSize > MAX_CLIENT_HASH_SIZE) || + (ClientHashSize < MIN_CLIENT_HASH_SIZE)) { + + ClientHashSize = DEF_CLIENT_HASH_SIZE; + } + // even if the RtlQueryRegistryValues has failed, we return success and will + // use the defaults. + return STATUS_SUCCESS; +} + diff --git a/private/ntos/tdi/isn/fwd/registry.h b/private/ntos/tdi/isn/fwd/registry.h new file mode 100644 index 000000000..6cff0eef2 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/registry.h @@ -0,0 +1,61 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\registry.h + +Abstract: + IPX Forwarder Driver registry interface + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ +#ifndef _IPXFWD_REGISTRY_ +#define _IPXFWD_REGISTRY_ + +/*++ +******************************************************************* + R e a d I p x D e v i c e N a m e + +Routine Description: + Allocates buffer and reads device name exported by the IPX stack + into it +Arguments: + FileName - pointer to variable to hold the name buffer +Return Value: + STATUS_SUCCESS - tables were created ok + STATUS_INSUFFICIENT_RESOURCES - resource allocation failed + STATUS_OBJECT_NAME_NOT_FOUND - if name value is not found +******************************************************************* +--*/ +NTSTATUS +ReadIpxDeviceName ( + PWSTR *FileName + ); + +/*++ +******************************************************************* + G e t R o u t e r P a r a m e t e r s + +Routine Description: + Reads the parameters from the registry or sets the defaults +Arguments: + RegistryPath - where to read from. +Return Value: + STATUS_SUCCESS +******************************************************************* +--*/ +NTSTATUS +GetForwarderParameters ( + IN PUNICODE_STRING RegistryPath + ); + +#endif + diff --git a/private/ntos/tdi/isn/fwd/rwlock.h b/private/ntos/tdi/isn/fwd/rwlock.h new file mode 100644 index 000000000..d1a390651 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/rwlock.h @@ -0,0 +1,179 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\rwlock.h + +Abstract: + Reader-Writer lock macros + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_RWLOCK_ +#define _IPXFWD_RWLOCK_ + +typedef volatile LONG VOLCTR, *PVOLCTR; +typedef PVOLCTR RWCOOKIE, *PRWCOOKIE; + +// Reader- writer lock. +// Allows no-lock access to the tables for readers - they merely +// increment the counter to record their presence upon entrance +// and decrement the same counter as they leave. +// Writers are supposed to be serialized (externally) and their +// actions are limited to ATOMIC insertions of new elements and +// ATOMIC removals/replacements. The removals/replacements MUST +// be followed by a wait for all potential readers who might still +// be using the element that was removed/replaced + +typedef struct _RW_LOCK { + KEVENT Event; // Event to release waiting writer + VOLCTR Ctr1; // Two alternating + VOLCTR Ctr2; // reader counters + volatile PVOLCTR CurCtr; // Counter currently in use +} RW_LOCK, *PRW_LOCK; + + +/*++ +******************************************************************* + I n i t i a l i z e R W L o c k + +Routine Description: + Initializes RW lock +Arguments: + lock - pointer to lock to initialize +Return Value: + None +******************************************************************* +--*/ +//VOID +//InitializeRWLock ( +// PRW_LOCK lock +// ); +#define InitializeRWLock(lock) { \ + KeInitializeEvent (&(lock)->Event, \ + SynchronizationEvent, \ + FALSE); \ + (lock)->Ctr1 = (lock)->Ctr2 = 0; \ + (lock)->CurCtr = &(lock)->Ctr1; \ +} + +/*++ +******************************************************************* + A c q u i r e R e a d e r A c c e s s + +Routine Description: + Acquires reader access to resource protected by the lock +Arguments: + lock - pointer to lock + cookie - pointer to buffer to store lock state for subsequent + release operation +Return Value: + None +******************************************************************* +--*/ +//VOID +//AcquireReaderAccess ( +// IN PRW_LOCK lock, +// OUT RWCOOKIE cookie +// ); +#define AcquireReaderAccess(lock,cookie) \ + do { \ + register LONG local,local1; \ + cookie = (lock)->CurCtr; /*Get current counter pointer*/ \ + local = *(cookie); /*Copy counter value*/ \ + local1 = local + 1; \ + if ((local>=0) /*If counter is valid*/ \ + /*and it hasn't changed while*/ \ + /*we were checking and trying*/ \ + /*to increment it,*/ \ + && (InterlockedCompareExchange ( \ + (PVOID *)(cookie), \ + (PVOID)(local1), \ + (PVOID)local) \ + ==(PVOID)local)) \ + break; /*then we obtained the access*/ \ + } while (1) /*otherwise, we have to do it again (possibly with*/\ + /*the other counter if writer switched it on us)*/ + + +/*++ +******************************************************************* + R e l e a s e R e a d e r A c c e s s + +Routine Description: + Releases reader access to resource protected by the lock +Arguments: + lock - pointer to lock + cookie - lock state for subsequent stored during acquire operation +Return Value: + None +******************************************************************* +--*/ +//VOID +//ReleaseReaderAccess ( +// IN PRW_LOCK lock, +// IN RWCOOKIE cookie +// ); +#define ReleaseReaderAccess(lock,cookie) { \ + /*If counter drops below 0, we have to signal the writer*/ \ + if (InterlockedDecrement((PLONG)cookie)<0) { \ + LONG res; \ + ASSERT (*(cookie)==-1); \ + res = KeSetEvent (&(lock)->Event, 0, FALSE); \ + ASSERT (res==0); \ + } \ +} + +/*++ +******************************************************************* + W a i t F o r A l l R e a d e r s + +Routine Description: + Waits for all readers that were accessing the resource prior + to the call to exit (New readers are not included) +Arguments: + lock - pointer to lock +Return Value: + None +******************************************************************* +--*/ +//VOID +//WaitForAllReaders ( +// PRW_LOCK lock +// ); +#define WaitForAllReaders(lock) { \ + RWCOOKIE prevCtr = (lock)->CurCtr; \ + /*Switch the counter first*/ \ + if (prevCtr==&(lock)->Ctr1) { \ + (lock)->Ctr2 = 0; \ + (lock)->CurCtr = &(lock)->Ctr2; \ + } \ + else { \ + ASSERT (prevCtr==&(lock)->Ctr2); \ + (lock)->Ctr1 = 0; \ + (lock)->CurCtr = &(lock)->Ctr1; \ + } \ + /* If not all readers are gone, we'll have to wait for them*/ \ + if (InterlockedDecrement((PLONG)prevCtr)>=0) { \ + NTSTATUS status \ + = KeWaitForSingleObject ( \ + &(lock)->Event, \ + Executive, \ + KeGetPreviousMode(),\ + FALSE, \ + 0); \ + ASSERT (NT_SUCCESS(status)); \ + ASSERT (*prevCtr==-1); \ + } \ +} + +#endif diff --git a/private/ntos/tdi/isn/fwd/send.c b/private/ntos/tdi/isn/fwd/send.c new file mode 100644 index 000000000..35c3ea2d6 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/send.c @@ -0,0 +1,1253 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\send.c + +Abstract: + Send routines + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + + +ULONG SpoofingTimeout=DEF_SPOOFING_TIMEOUT; +LIST_ENTRY SpoofingQueue; +KSPIN_LOCK SpoofingQueueLock; +WORK_QUEUE_ITEM SpoofingWorker; +BOOLEAN SpoofingWorkerActive = FALSE; +ULONG DontSuppressNonAgentSapAdvertisements = 0; + +#define IsLocalSapNonAgentAdvertisement(hdr,data,ln,ifCB) ( \ + (DontSuppressNonAgentSapAdvertisements==0) \ + && (GETUSHORT(hdr+IPXH_DESTSOCK)==IPX_SAP_SOCKET) \ + && (GETUSHORT(hdr+IPXH_SRCSOCK)!=IPX_SAP_SOCKET) \ + && (ln>=IPXH_HDRSIZE+2) \ + && (GETUSHORT(data)==2) \ + && ((IPX_NODE_CMP(hdr+IPXH_DESTNODE,BROADCAST_NODE)==0) \ + || (IPX_NODE_CMP(hdr+IPXH_DESTNODE,ifCB->ICB_RemoteNode)==0)) \ +) + +/*++ +******************************************************************* + D o S e n d + +Routine Description: + Prepares and sends packet. Interface lock must be help while + callin this routine +Arguments: + dstIf - over which interface to send + pktTag - packet to send +Return Value: + result returned by IPX + +******************************************************************* +--*/ +NDIS_STATUS +DoSend ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag, + KIRQL oldIRQL + ) { + NDIS_STATUS status; + PNDIS_PACKET pktDscr; + PNDIS_BUFFER bufDscr, aDscr; + UINT dataLen; + ULONG dstNet = GETULONG (pktTag->PT_Data+IPXH_DESTNET); + + if (dstIf!=InternalInterface) { + ADAPTER_CONTEXT_TO_LOCAL_TARGET (dstIf->ICB_AdapterContext, + &pktTag->PT_Target); + } + else { + CONSTANT_ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + VIRTUAL_NET_ADAPTER_CONTEXT, + &pktTag->PT_Target); + } + +#if DBG + // Keep track of packets being processed by IPX stack + InsertTailList (&dstIf->ICB_InSendQueue, &pktTag->PT_QueueLink); +#endif + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + + if (pktTag->PT_Flags&PT_SOURCE_IF) + ReleaseInterfaceReference (pktTag->PT_SourceIf); + pktTag->SEND_RESERVED[0] = pktTag->SEND_RESERVED[1] = 0; + pktDscr = CONTAINING_RECORD(pktTag, NDIS_PACKET, ProtocolReserved); + NdisQueryPacket(pktDscr, NULL, NULL, &bufDscr, NULL); +#if DBG + { // Verify packet integrity + PUCHAR dataPtr; + UINT bufLen; + ASSERT (NDIS_BUFFER_LINKAGE (bufDscr)==NULL); + NdisQueryBuffer (bufDscr, &dataPtr, &bufLen); + ASSERT (dataPtr==pktTag->PT_Data); + ASSERT (bufLen==pktTag->PT_Segment->PS_SegmentList->SL_BlockSize); + } +#endif + // Prepare packet for IPX stack (mac header buffer goes in + // front and packet length adjusted to reflect the size of the data + dataLen = GETUSHORT(pktTag->PT_Data+IPXH_LENGTH); + NdisAdjustBufferLength(bufDscr, dataLen); + NdisChainBufferAtFront(pktDscr, pktTag->PT_MacHdrBufDscr); + + + if (EnterForwarder ()) {// To make sure that we won't unload + // until IPX driver has a chance to call us back + status = IPXSendProc (&pktTag->PT_Target, pktDscr, dataLen, 0); + + if (status!=NDIS_STATUS_PENDING) { + LeaveForwarder (); // No callback + + // Restore original packet structure + NdisUnchainBufferAtFront (pktDscr, &aDscr); +#if DBG + // Make sure IPX stack did not mess our packet + ASSERT (aDscr==pktTag->PT_MacHdrBufDscr); + NdisQueryPacket(pktDscr, NULL, NULL, &aDscr, NULL); + ASSERT (aDscr==bufDscr); + ASSERT (NDIS_BUFFER_LINKAGE (aDscr)==NULL); +#endif + // Restore original packet size + NdisAdjustBufferLength(bufDscr, + pktTag->PT_Segment->PS_SegmentList->SL_BlockSize); +#if DBG + // Remove packet from temp queue + KeAcquireSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, &oldIRQL); + RemoveEntryList (&pktTag->PT_QueueLink); + KeReleaseSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, oldIRQL); +#endif + } + } + else { + // We are going down, restore the packet + NdisUnchainBufferAtFront (pktDscr, &aDscr); + NdisAdjustBufferLength(bufDscr, + pktTag->PT_Segment->PS_SegmentList->SL_BlockSize); + NdisRecalculatePacketCounts (pktDscr); + status = STATUS_UNSUCCESSFUL; +#if DBG + KeAcquireSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, &oldIRQL); + RemoveEntryList (&pktTag->PT_QueueLink); + KeReleaseSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, oldIRQL); +#endif + } + return status; +} + + +/*++ +******************************************************************* + P r o c e s s S e n t P a c k e t + +Routine Description: + Process completed sent packets +Arguments: + dstIf - interface over which packet was sent + pktTag - completed packet + status - result of send operation +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessSentPacket ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag, + NDIS_STATUS status + ) { + KIRQL oldIRQL; + + // Packet processing is completed -> can take more packets + InterlockedIncrement (&dstIf->ICB_PendingQuota); + + if (*(pktTag->PT_Data+IPXH_PKTTYPE) == IPX_NETBIOS_TYPE) { + // Continue processing netbios packets + if (status==NDIS_STATUS_SUCCESS) { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: NB Packet %08lx sent.", pktTag)); + InterlockedIncrement (&dstIf->ICB_Stats.OutDelivers); + InterlockedIncrement (&dstIf->ICB_Stats.NetbiosSent); + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_ERROR, + ("IpxFwd: NB Packet %08lx send failed with error: %08lx.\n", + pktTag, status)); + } + // Queue nb packet for further processing (broadcast on all interfaces) + QueueNetbiosPacket (pktTag); + } + else { + // Destroy completed packet + if (status==NDIS_STATUS_SUCCESS) { + InterlockedIncrement (&dstIf->ICB_Stats.OutDelivers); + IpxFwdDbgPrint (DBG_SEND, DBG_INFORMATION, + ("IpxFwd: Packet %08lx sent.", pktTag)); + } + else { + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + IpxFwdDbgPrint (DBG_SEND, DBG_ERROR, + ("IpxFwd: Packet %08lx send failed with error: %08lx.\n", + pktTag, status)); + } + ReleaseInterfaceReference (dstIf); + if (MeasuringPerformance + && (pktTag->PT_PerfCounter!=0)) { + LARGE_INTEGER PerfCounter = KeQueryPerformanceCounter (NULL); + PerfCounter.QuadPart -= pktTag->PT_PerfCounter; + KeAcquireSpinLock (&PerfCounterLock, &oldIRQL); + ASSERT (PerfCounter.QuadPart<ActivityTreshhold); + PerfBlock.TotalPacketProcessingTime += PerfCounter.QuadPart; + PerfBlock.PacketCounter += 1; + if (PerfBlock.MaxPacketProcessingTime < PerfCounter.QuadPart) + PerfBlock.MaxPacketProcessingTime = PerfCounter.QuadPart; + KeReleaseSpinLock (&PerfCounterLock, oldIRQL); + } + FreePacket (pktTag); + } +} + +/*++ +******************************************************************* + S e n d P a c k e t + +Routine Description: + Enqueues packets to be sent by IPX stack +Arguments: + dstIf - over which interface to send + pktTag - packet to send +Return Value: + None + +******************************************************************* +--*/ +VOID +SendPacket ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag + ) { + NDIS_STATUS status; + KIRQL oldIRQL; + + + ASSERT (dstIf->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + // Make sure we have not exceded the quota of pending packets on the interface + if (InterlockedDecrement (&dstIf->ICB_PendingQuota)>=0) { + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + // Decide what to do with the packet based on the interface state + switch (dstIf->ICB_Stats.OperationalState) { + case FWD_OPER_STATE_UP: + if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + NOTHING; + else { + PUTULONG (dstIf->ICB_Network, pktTag->PT_Data+IPXH_DESTNET); + } + status = DoSend (dstIf, pktTag, oldIRQL); + IpxFwdDbgPrint (DBG_SEND, DBG_INFORMATION, + ("IpxFwd: Sent external packet %08lx on if %ld.\n", + pktTag, dstIf->ICB_Index)); + break; + case FWD_OPER_STATE_SLEEPING: + if ((*(pktTag->PT_Data+IPXH_PKTTYPE)!=0) + || (GETUSHORT(pktTag->PT_Data+IPXH_LENGTH)!=IPXH_HDRSIZE+2) + || (*(pktTag->PT_Data+IPXH_HDRSIZE+1)!='?')) { + // Queue this packet on the interface until it is connected + // by Router Manager (DIM) if this is not a NCP keepalive + // (watchdog) + InsertTailList (&dstIf->ICB_ExternalQueue, &pktTag->PT_QueueLink); + if (!IS_IF_CONNECTING (dstIf)) { + // Ask for connection if interface is not in the connection + // queue yet + QueueConnectionRequest (dstIf, + CONTAINING_RECORD (pktTag, + NDIS_PACKET, + ProtocolReserved), + pktTag->PT_Data, + oldIRQL); + IpxFwdDbgPrint (DBG_DIALREQS, DBG_WARNING, + ("IpxFwd: Queued dd request on if %ld (ifCB:%08lx)" + " for packet to %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%02x%02x" + " from %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%02x%02x\n", + dstIf->ICB_Index, dstIf, + *(pktTag->PT_Data+6),*(pktTag->PT_Data+7), + *(pktTag->PT_Data+8),*(pktTag->PT_Data+9), + *(pktTag->PT_Data+10),*(pktTag->PT_Data+11), + *(pktTag->PT_Data+12),*(pktTag->PT_Data+13), + *(pktTag->PT_Data+14),*(pktTag->PT_Data+15), + *(pktTag->PT_Data+16),*(pktTag->PT_Data+17), + *(pktTag->PT_Data+18),*(pktTag->PT_Data+19), + *(pktTag->PT_Data+20),*(pktTag->PT_Data+21), + *(pktTag->PT_Data+22),*(pktTag->PT_Data+23), + *(pktTag->PT_Data+24),*(pktTag->PT_Data+25), + *(pktTag->PT_Data+26),*(pktTag->PT_Data+27), + *(pktTag->PT_Data+28),*(pktTag->PT_Data+29))); + } + else + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_SEND, DBG_INFORMATION, + ("IpxFwd: Queued external packet %08lx on if %ld.\n", + pktTag, dstIf->ICB_Index)); + if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + NOTHING; + else if (!(pktTag->PT_Flags&PT_NB_DESTROY)) { + // If this nb packet is not to be destroyed after this + // send, we have to make a copy of it to send on + // other interfaces while the original is waiting + // for connection + PPACKET_TAG newPktTag; + DuplicatePacket (pktTag, newPktTag); + if (newPktTag!=NULL) { + UINT bytesCopied; + PNDIS_PACKET packet = CONTAINING_RECORD (pktTag, + NDIS_PACKET, + ProtocolReserved); + PNDIS_PACKET newPacket = CONTAINING_RECORD (newPktTag, + NDIS_PACKET, + ProtocolReserved); + NdisCopyFromPacketToPacket (newPacket, 0, + GETUSHORT(pktTag->PT_Data+IPXH_LENGTH), + packet, 0, &bytesCopied); + + ASSERT (bytesCopied==GETUSHORT(pktTag->PT_Data+IPXH_LENGTH)); + IpxFwdDbgPrint (DBG_NETBIOS, + DBG_INFORMATION, + ("IpxFwd: Duplicated queued nb packet" + " %08lx -> %08lx on if %ld.\n", + pktTag, newPktTag, dstIf->ICB_Index)); + AcquireInterfaceReference (dstIf); + newPktTag->PT_InterfaceReference = dstIf; + newPktTag->PT_PerfCounter = pktTag->PT_PerfCounter; + QueueNetbiosPacket (newPktTag); + // The original copy will have to be + // destroyed after it is sent on the + // connected interface + pktTag->PT_Flags |= PT_NB_DESTROY; + } + } + status = NDIS_STATUS_PENDING; + break; + } + else { // Process keepalives + LONGLONG curTime; + KeQuerySystemTime ((PLARGE_INTEGER)&curTime); + if (((curTime-dstIf->ICB_DisconnectTime)/10000000) < SpoofingTimeout) { + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_SPOOFING, DBG_INFORMATION, + ("IpxFwd: Queueing reply to keepalive from server" + " on if %ld (ifCB %lx)" + " at %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%02x%02x.\n", + dstIf->ICB_Index, dstIf, + *(pktTag->PT_Data+IPXH_SRCNET),*(pktTag->PT_Data+IPXH_SRCNET+1), + *(pktTag->PT_Data+IPXH_SRCNET+2),*(pktTag->PT_Data+IPXH_SRCNET+3), + *(pktTag->PT_Data+IPXH_SRCNODE),*(pktTag->PT_Data+IPXH_SRCNODE+1), + *(pktTag->PT_Data+IPXH_SRCNODE+2),*(pktTag->PT_Data+IPXH_SRCNODE+3), + *(pktTag->PT_Data+IPXH_SRCNODE+4),*(pktTag->PT_Data+IPXH_SRCNODE+5), + *(pktTag->PT_Data+IPXH_SRCSOCK),*(pktTag->PT_Data+IPXH_SRCNODE+1))); + // Spoof the packet if timeout has not been exceeded + KeAcquireSpinLock (&SpoofingQueueLock, &oldIRQL); + InsertTailList (&SpoofingQueue, &pktTag->PT_QueueLink); + if (!SpoofingWorkerActive + && EnterForwarder()) { + SpoofingWorkerActive = TRUE; + ExQueueWorkItem (&SpoofingWorker, DelayedWorkQueue); + } + KeReleaseSpinLock (&SpoofingQueueLock, oldIRQL); + // We will actually send this packet though + // in other direction, so mark it as pending + // to prevent ProcessSentPacket to be called + status = NDIS_STATUS_PENDING; + break; + } + // else don't spoof (fall through and fail the packet) + } + case FWD_OPER_STATE_DOWN: + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + status = NDIS_STATUS_ADAPTER_NOT_READY; + IpxFwdDbgPrint (DBG_SEND, DBG_WARNING, + ("IpxFwd: Failed external packet %08lx on if %ld(down?).\n", + pktTag, dstIf->ICB_Index)); + break; + default: + ASSERTMSG ("Invalid operational state ", FALSE); + } + } + else { + IpxFwdDbgPrint (DBG_SEND, DBG_WARNING, + ("IpxFwd: Could not send packet %08lx on if %ld (quota exceeded).\n", + pktTag, dstIf->ICB_Index)); + status = NDIS_STATUS_RESOURCES; + } + + if (status!=NDIS_STATUS_PENDING) + ProcessSentPacket (dstIf, pktTag, status); +} + +/*++ +******************************************************************* + F w S e n d C o m p l e t e + +Routine Description: + Called by IPX stack when send completes asynchronously +Arguments: + pktDscr - descriptor of the completed packet + status - result of send operation +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdSendComplete ( + PNDIS_PACKET pktDscr, + NDIS_STATUS status + ) { + PPACKET_TAG pktTag; + PNDIS_BUFFER bufDscr; + + pktTag = (PPACKET_TAG)pktDscr->ProtocolReserved; + + NdisUnchainBufferAtFront (pktDscr, &bufDscr); + ASSERT (bufDscr==pktTag->PT_MacHdrBufDscr); + + NdisQueryPacket(pktDscr, + NULL, + NULL, + &bufDscr, + NULL); + NdisAdjustBufferLength(bufDscr, + pktTag->PT_Segment->PS_SegmentList->SL_BlockSize); + NdisRecalculatePacketCounts (pktDscr); +#if DBG + { + KIRQL oldIRQL; + KeAcquireSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, &oldIRQL); + RemoveEntryList (&pktTag->PT_QueueLink); + KeReleaseSpinLock (&pktTag->PT_InterfaceReference->ICB_Lock, oldIRQL); + } +#endif + ProcessSentPacket (pktTag->PT_InterfaceReference, pktTag, status); + LeaveForwarder (); // Entered before calling IpxSendPacket +} + + +/*++ +******************************************************************* + + F w I n t e r n a l S e n d + +Routine Description: + Filter and routes packets sent by IPX stack +Arguments: + LocalTarget - the NicId and next hop router MAC address + Context - preferred interface on which to send + Packet - packet to be sent + ipxHdr - pointer to ipx header inside the packet + PacketLength - length of the packet + fIterate - a flag to indicate if this is a packet for the + iteration of which the Fwd takes responsibility + - typically type 20 NetBIOS frames +Return Value: + + STATUS_SUCCESS - if the preferred NIC was OK and packet passed filtering + STATUS_NETWORK_UNREACHABLE - if the preferred was not OK or packet failed filtering + STATUS_PENDING - packet was queued until connection is established +******************************************************************* +--*/ +NTSTATUS +IpxFwdInternalSend ( + IN OUT PIPX_LOCAL_TARGET LocalTarget, + IN ULONG Context, + IN PNDIS_PACKET pktDscr, + IN PUCHAR ipxHdr, + IN PUCHAR data, + IN ULONG PacketLength, + IN BOOLEAN fIterate + ) { + PINTERFACE_CB dstIf = NULL, // Initialized to indicate + // first path through the iteration + // as well as the fact the we do not + // know it initially + stDstIf; // Static destination for + // NetBIOS names + PFWD_ROUTE fwRoute = NULL; + ULONG dstNet; + USHORT dstSock; + NTSTATUS status; + + if (!EnterForwarder()) + return STATUS_NETWORK_UNREACHABLE; + + if (IS_IF_ENABLED(InternalInterface) + && ((*(ipxHdr+IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + || InternalInterface->ICB_NetbiosAccept)) { + + do { // Big loop used to iterate over interfaces + status = STATUS_SUCCESS; // Assume success + if (!fIterate) { + dstNet = GETULONG (ipxHdr+IPXH_DESTNET); + + if (Context!=INVALID_CONTEXT_VALUE) { + if (Context!=VIRTUAL_NET_FORWARDER_CONTEXT) { + // IPX driver supplied interface context, just verify that it + // exists and can be used to reach the destination network + dstIf = InterfaceContextToReference ((PVOID)Context, + LocalTarget->NicId); + } + else { + dstIf = InternalInterface; + AcquireInterfaceReference (dstIf); + } + if (dstIf!=NULL) { + // It does exist + // First process direct connections + if ((dstNet==0) + || (dstNet==dstIf->ICB_Network)) { + NOTHING; + } + else { // Network is not connected directly + PINTERFACE_CB dstIf2; + // Verify the route + dstIf2 = FindDestination (dstNet, + ipxHdr+IPXH_DESTNODE, + &fwRoute); + if (dstIf==dstIf2) { + // Route OK, release the extra interface reference + ReleaseInterfaceReference (dstIf2); + } + else { + // Route not OK, release interface/route references + InterlockedIncrement (&InternalInterface->ICB_Stats.InNoRoutes); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Failed direct internal send on" + " if %ld to %08lx:%02x%02x%02x%02x%02x%02x" + " (no route).\n", + dstIf->ICB_Index, dstNet, + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + if (dstIf2!=NULL) { + ReleaseInterfaceReference (dstIf2); + } + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + } + else { + InterlockedIncrement (&InternalInterface->ICB_Stats.InDiscards); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Invalid interface context (%08lx)" + " from IPX driver on internal send to" + " %08lx:%02x%02x%02x%02x%02x%02x.\n", + Context, dstNet, + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + status = STATUS_NO_SUCH_DEVICE; + break; + } + } + else {// No interface context supplied by IPX driver, have to find the route + dstIf = FindDestination (dstNet, ipxHdr+IPXH_DESTNODE, + &fwRoute); + if (dstIf!=NULL) + NOTHING; + else { + InterlockedIncrement (&InternalInterface->ICB_Stats.InNoRoutes); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Failed internal send because no route to" + " %08lx:%02x%02x%02x%02x%02x%02x exists.\n", + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + InterlockedIncrement (&InternalInterface->ICB_Stats.InDelivers); + } + else { // Iterative sends + dstNet = 0; // Don't care, it must be a local send + if (*(ipxHdr+IPXH_PKTTYPE) == IPX_NETBIOS_TYPE) { + if (dstIf==NULL) { // First time through internal loop + dstSock = GETUSHORT (ipxHdr+IPXH_DESTSOCK); + + // See if we can get a static route for this packet + if (dstSock==IPX_NETBIOS_SOCKET) + stDstIf = FindNBDestination (data+(NB_NAME-IPXH_HDRSIZE)); + else if (dstSock==IPX_SMB_NAME_SOCKET) + stDstIf = FindNBDestination (data+(SMB_NAME-IPXH_HDRSIZE)); + else + stDstIf = NULL; + } + + if ((Context==INVALID_CONTEXT_VALUE) && (dstIf==NULL)) { + // First time through the loop, increment counters + InterlockedIncrement (&InternalInterface->ICB_Stats.InDelivers); + InterlockedIncrement (&InternalInterface->ICB_Stats.NetbiosSent); + + if (stDstIf!=NULL) { + dstIf = stDstIf; + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Allowed internal NB broadcast (1st iteration) on if %d (%lx)" + " to static name %.16s.\n", + dstIf->ICB_Index, dstIf, + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + } + else { // No static route + dstIf = GetNextInterfaceReference (NULL); + if (dstIf!=NULL) + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Allowed internal nb broadcast (1st iteration) on if %d (%lx)," + " to name %.16s.\n", + dstIf->ICB_Index, dstIf, + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Nb broadcast no destinations" + " to name %.16s.\n", + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + } + else { + // N-th iteration + if (stDstIf==NULL) { + if (dstIf==NULL) + dstIf = InterfaceContextToReference ((PVOID)Context, + LocalTarget->NicId); + dstIf = GetNextInterfaceReference (dstIf); + if (dstIf!=NULL) { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Allowed internal NB broadcast (1+ iteration)" + " on if %d (%lx, ctx: %08lx, nic: %d)" + " to name %.16s.\n", + dstIf->ICB_Index, dstIf, + Context, LocalTarget->NicId, + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: NB broadcast no more iterations" + " for ctx: %08lx, nic: %d" + " to name %.16s.\n", + Context, LocalTarget->NicId, + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Static NB broadcast (1+ iteration)" + " on if %d (%lx, ctx: %08lx, nic: %d)" + " to name %.16s.\n", + stDstIf->ICB_Index, stDstIf, + Context, LocalTarget->NicId, + (dstSock==IPX_NETBIOS_SOCKET) + ? data+(NB_NAME-IPXH_HDRSIZE) + : ((dstSock==IPX_SMB_NAME_SOCKET) + ? data+(SMB_NAME-IPXH_HDRSIZE) + : "Not a name frame") + )); + ReleaseInterfaceReference (stDstIf); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + } + else { + if ((dstIf==NULL) + && (Context!=INVALID_CONTEXT_VALUE)) + dstIf = InterfaceContextToReference ((PVOID)Context, + LocalTarget->NicId); + dstIf = GetNextInterfaceReference (dstIf); + if (dstIf!=NULL) { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: Allowed internal iterative send" + " on if %d (%lx, ctx: %08lx, nic: %d)" + " to %02x%02x%02x%02x%02x%02x.\n", + dstIf->ICB_Index, dstIf, + Context, LocalTarget->NicId, + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_INFORMATION, + ("IpxFwd: No destinations to internal iterative send" + " for ctx: %08lx, nic: %d" + " to %02x%02x%02x%02x%02x%02x.\n", + Context, LocalTarget->NicId, + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + } + + } // End iterative send processing + + // We were able to find a destination interface + if (IS_IF_ENABLED (dstIf) + && ((*(ipxHdr+IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) + || (dstIf->ICB_NetbiosDeliver==FWD_NB_DELIVER_ALL) + || ((dstIf->ICB_NetbiosDeliver==FWD_NB_DELIVER_IF_UP) + && (dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP)) + || ((stDstIf!=NULL) + && (dstIf->ICB_NetbiosDeliver==FWD_NB_DELIVER_STATIC)))) { + KIRQL oldIRQL; + FILTER_ACTION action; + + // In/Out filter check and statistics update + + action = FltFilter (ipxHdr, IPXH_HDRSIZE, + InternalInterface->ICB_FilterInContext, + dstIf->ICB_FilterOutContext); + if (action==FILTER_PERMIT) { + NOTHING; + } + else { + InterlockedIncrement (&dstIf->ICB_Stats.OutFiltered); + status = STATUS_NETWORK_UNREACHABLE; + break; + } + + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + // All set, try to send now + switch (dstIf->ICB_Stats.OperationalState) { + case FWD_OPER_STATE_UP: + // Interface is up, let it go right away + // Set NIC ID + if (dstIf!=InternalInterface) { + ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + dstIf->ICB_AdapterContext, + LocalTarget); + } + else { + CONSTANT_ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + VIRTUAL_NET_ADAPTER_CONTEXT, + LocalTarget); + } + // Set destination node + if (IsLocalSapNonAgentAdvertisement (ipxHdr,data,PacketLength,dstIf)) { + // Loop back sap ads from non-sap socket + IPX_NODE_CPY (&LocalTarget->MacAddress, + dstIf->ICB_LocalNode); + } + else if ((dstNet==0) || (dstNet==dstIf->ICB_Network)) { + // Direct connection: send to destination specified + // in the header + IPX_NODE_CPY (LocalTarget->MacAddress, + ipxHdr+IPXH_DESTNODE); + } + else { // Indirect connection: send to next hop router + if (dstIf->ICB_InterfaceType==FWD_IF_PERMANENT) { + ASSERT (fwRoute!=NULL); + IPX_NODE_CPY (LocalTarget->MacAddress, + fwRoute->FR_NextHopAddress); + } + else { + // Only one peer on the other side + IPX_NODE_CPY (LocalTarget->MacAddress, + dstIf->ICB_RemoteNode); + } + } + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + // Update statistics + InterlockedIncrement ( + &dstIf->ICB_Stats.OutDelivers); + if (*(ipxHdr+IPXH_PKTTYPE)==IPX_NETBIOS_TYPE) + InterlockedIncrement ( + &dstIf->ICB_Stats.NetbiosSent); + + IpxFwdDbgPrint (DBG_INT_SEND, DBG_INFORMATION, + ("IpxFwd: Allowed internal send:" + " %ld-%08lx:%02x%02x%02x%02x%02x%02x.\n", + dstIf->ICB_Index, dstNet, + LocalTarget->MacAddress[0], + LocalTarget->MacAddress[1], + LocalTarget->MacAddress[2], + LocalTarget->MacAddress[3], + LocalTarget->MacAddress[4], + LocalTarget->MacAddress[5])); + // status = STATUS_SUCCESS; // Let it go + break; + case FWD_OPER_STATE_SLEEPING: + // Interface is disconnected, queue the packet and try to connecte + if ((*(ipxHdr+IPXH_PKTTYPE)!=0) + || (*(ipxHdr+IPXH_LENGTH)!=IPXH_HDRSIZE+2) + || (*(data+1)!='?')) { + // Not a keep-alive packet, + if (((*(ipxHdr+IPXH_PKTTYPE)!=IPX_NETBIOS_TYPE)) + || (dstIf->ICB_NetbiosDeliver!=FWD_NB_DELIVER_IF_UP)) { + // Not a netbios broadcast or we are allowed to connect + // the interface to deliver netbios broadcasts + if (InterlockedDecrement (&dstIf->ICB_PendingQuota)>=0) { + PINTERNAL_PACKET_TAG pktTag; + // Create a queue element to enqueue the packet + pktTag = (PINTERNAL_PACKET_TAG)ExAllocatePoolWithTag ( + NonPagedPool, + sizeof (INTERNAL_PACKET_TAG), + FWD_POOL_TAG); + if (pktTag!=NULL) { + pktTag->IPT_Packet = pktDscr; + pktTag->IPT_Length = PacketLength; + pktTag->IPT_DataPtr = ipxHdr; + // Save next hop address if after connection is + // established we determine that destination net + // is not connected directly + if (fwRoute!=NULL) + IPX_NODE_CPY (pktTag->IPT_Target.MacAddress, + fwRoute->FR_NextHopAddress); + AcquireInterfaceReference (dstIf); // To make sure interface + // block won't go away until we are done with + // the packet + pktTag->IPT_InterfaceReference = dstIf; + InsertTailList (&dstIf->ICB_InternalQueue, + &pktTag->IPT_QueueLink); + if (!IS_IF_CONNECTING (dstIf)) { + QueueConnectionRequest (dstIf, pktDscr, ipxHdr, oldIRQL); + IpxFwdDbgPrint (DBG_DIALREQS, DBG_WARNING, + ("IpxFwd: Queued dd request on if %ld (ifCB:%08lx)" + " for internal packet" + " to %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%02x%02x" + " from socket:%02x%02x\n", + dstIf->ICB_Index, dstIf, + *(ipxHdr+6),*(ipxHdr+7), + *(ipxHdr+8),*(ipxHdr+9), + *(ipxHdr+10),*(ipxHdr+11), + *(ipxHdr+12),*(ipxHdr+13), + *(ipxHdr+14),*(ipxHdr+15), + *(ipxHdr+16),*(ipxHdr+17), + *(ipxHdr+28),*(ipxHdr+29))); + } + else + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_INFORMATION, + ("IpxFwd: Queueing internal send packet %08lx on if %ld.\n", + pktTag, dstIf->ICB_Index)); + status = STATUS_PENDING; + break; + } + else { + IpxFwdDbgPrint (DBG_INT_SEND, DBG_ERROR, + ("IpxFwd: Could not allocate" + " internal packet tag.\n")); + } + } + InterlockedIncrement (&dstIf->ICB_PendingQuota); + } + else { + IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, + ("IpxFwd: Droped internal NB packet" + " because FWD_NB_DELIVER_IF_UP.\n")); + } + } + else { // Process keep-alives + LONGLONG curTime; + KeQuerySystemTime ((PLARGE_INTEGER)&curTime); + if (((curTime-dstIf->ICB_DisconnectTime)/10000000) < SpoofingTimeout) { + PPACKET_TAG pktTag; + // Spoofing timeout has not been exceeded, + // Create a reply packet + AllocatePacket (WanPacketListId, + WanPacketListId, + pktTag); + if (pktTag!=NULL) { + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + PUTUSHORT (0xFFFF, pktTag->PT_Data+IPXH_CHECKSUM); + PUTUSHORT (IPXH_HDRSIZE+2, pktTag->PT_Data+IPXH_LENGTH); + *(pktTag->PT_Data+IPXH_XPORTCTL) = 0; + *(pktTag->PT_Data+IPXH_PKTTYPE) = 0; + memcpy (pktTag->PT_Data+IPXH_DESTADDR, + ipxHdr+IPXH_SRCADDR, + 12); + memcpy (pktTag->PT_Data+IPXH_SRCADDR, + ipxHdr+IPXH_DESTADDR, + 12); + *(pktTag->PT_Data+IPXH_HDRSIZE) = *data; + *(pktTag->PT_Data+IPXH_HDRSIZE+1) = 'Y'; + // Destination for this packet will have to + // be the first active LAN adapter in the system + // SHOULD BE REMOVED WHEN LOOPBACK SUPPORT US ADDED BY IPX + + pktTag->PT_InterfaceReference = NULL; + IpxFwdDbgPrint (DBG_SPOOFING, DBG_INFORMATION, + ("IpxFwd: Queueing reply to keepalive from internal server" + " at %02x%02x.\n",*(ipxHdr+IPXH_DESTSOCK),*(ipxHdr+IPXH_DESTSOCK+1))); + // Enqueue to spoofing queue to be sent back + // to the server + KeAcquireSpinLock (&SpoofingQueueLock, &oldIRQL); + InsertTailList (&SpoofingQueue, &pktTag->PT_QueueLink); + // Start worker if not running already + if (!SpoofingWorkerActive + && EnterForwarder()) { + SpoofingWorkerActive = TRUE; + ExQueueWorkItem (&SpoofingWorker, DelayedWorkQueue); + } + KeReleaseSpinLock (&SpoofingQueueLock, oldIRQL); + status = STATUS_DROP_SILENTLY; + break; + } + else { + IpxFwdDbgPrint (DBG_SPOOFING, DBG_ERROR, + ("IpxFwd: Could not allocate" + " packet tag for spoofing.\n")); + } + } + else { + IpxFwdDbgPrint (DBG_SPOOFING, DBG_WARNING, + ("IpxFwd: Internal spoofing" + " timeout exceded.\n")); + } + } + case FWD_OPER_STATE_DOWN: + // Interface down or send failed + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + if (*(ipxHdr+IPXH_PKTTYPE)!=IPX_NETBIOS_TYPE) + InterlockedIncrement ( + &dstIf->ICB_Stats.OutDiscards); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Internal send not allowed" + " on if %ld (down?).\n", dstIf->ICB_Index)); + status = STATUS_NETWORK_UNREACHABLE; + break; + default: + ASSERTMSG ("Invalid operational state ", FALSE); + } + } + else {// Interface is disabled + if (*(ipxHdr+IPXH_PKTTYPE)!=IPX_NETBIOS_TYPE) + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Internal send not allowed" + " on because dst if (or Netbios deliver on it) %ld (ifCB: %08lx) is disabled.\n", + dstIf->ICB_Index, dstIf)); + status = STATUS_NETWORK_UNREACHABLE; + } + + + } + while (fIterate && (status!=STATUS_SUCCESS) && (status!=STATUS_PENDING)); + + if (dstIf!=NULL) + ReleaseInterfaceReference (dstIf); + if (fwRoute!=NULL) + ReleaseRouteReference (fwRoute); + } + else { // Internal interface is disabled + IpxFwdDbgPrint (DBG_INT_SEND, DBG_WARNING, + ("IpxFwd: Internal send not allowed" + " because internal if (or Netbios accept on it) is disabled.\n")); + InterlockedIncrement ( + &InternalInterface->ICB_Stats.InDiscards); + status = STATUS_NETWORK_UNREACHABLE; + } + + LeaveForwarder (); + return status; +} + + +/*++ +******************************************************************* + + P r o c e s s I n t e r n a l Q u e u e + +Routine Description: + Processes packets in the interface internal queue. + Called when connection request completes +Arguments: + dstIf - interface to process +Return Value: + None +******************************************************************* +--*/ +VOID +ProcessInternalQueue ( + PINTERFACE_CB dstIf + ) { + KIRQL oldIRQL; + LIST_ENTRY tempQueue; + + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + InsertHeadList (&dstIf->ICB_InternalQueue, &tempQueue); + RemoveEntryList (&dstIf->ICB_InternalQueue); + InitializeListHead (&dstIf->ICB_InternalQueue); + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + + while (!IsListEmpty (&tempQueue)) { + PINTERNAL_PACKET_TAG pktTag; + PLIST_ENTRY cur; + NTSTATUS status; + + cur = RemoveHeadList (&tempQueue); + pktTag = CONTAINING_RECORD (cur, INTERNAL_PACKET_TAG, IPT_QueueLink); + InterlockedIncrement (&dstIf->ICB_PendingQuota); + + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + if (IS_IF_ENABLED(dstIf) + && (dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP)) { + IPX_NODE_CPY (pktTag->IPT_Target.MacAddress, + dstIf->ICB_RemoteNode); + ADAPTER_CONTEXT_TO_LOCAL_TARGET ( + dstIf->ICB_AdapterContext, + &pktTag->IPT_Target); + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + InterlockedIncrement (&dstIf->ICB_Stats.OutDelivers); + if (*(pktTag->IPT_DataPtr + IPXH_PKTTYPE) == IPX_NETBIOS_TYPE) { + InterlockedIncrement (&dstIf->ICB_Stats.NetbiosSent); + } + status = STATUS_SUCCESS; + } + else { + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + status = STATUS_NETWORK_UNREACHABLE; + } + + IPXInternalSendCompletProc (&pktTag->IPT_Target, + pktTag->IPT_Packet, + pktTag->IPT_Length, + status); + IpxFwdDbgPrint (DBG_INT_SEND, + NT_SUCCESS (status) ? DBG_INFORMATION : DBG_WARNING, + ("IpxFwd: Returned internal packet %08lx" + " for send on if %ld with status %08lx.\n", + pktTag, dstIf->ICB_Index, status)); + ReleaseInterfaceReference (pktTag->IPT_InterfaceReference); + ExFreePool (pktTag); + } +} + + + +/*++ +******************************************************************* + + P r o c e s s E x t e r n a l Q u e u e + +Routine Description: + Processes packets in the interface external queue. + Called when connection request completes +Arguments: + dstIf - interface to process +Return Value: + None +******************************************************************* +--*/ +VOID +ProcessExternalQueue ( + PINTERFACE_CB dstIf + ) { + KIRQL oldIRQL; + LIST_ENTRY tempQueue; + + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + InsertHeadList (&dstIf->ICB_ExternalQueue, &tempQueue); + RemoveEntryList (&dstIf->ICB_ExternalQueue); + InitializeListHead (&dstIf->ICB_ExternalQueue); + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + + while (!IsListEmpty (&tempQueue)) { + PPACKET_TAG pktTag; + PLIST_ENTRY cur; + NDIS_STATUS status; + + cur = RemoveHeadList (&tempQueue); + pktTag = CONTAINING_RECORD (cur, PACKET_TAG, PT_QueueLink); + + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + if (IS_IF_ENABLED(dstIf) + && (dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP)) { + IPX_NODE_CPY (pktTag->PT_Target.MacAddress, + dstIf->ICB_RemoteNode); + if (*(pktTag->PT_Data + IPXH_PKTTYPE) == IPX_NETBIOS_TYPE) { + PUTULONG (dstIf->ICB_Network, pktTag->PT_Data+IPXH_DESTNET); + } + status = DoSend (dstIf, pktTag, oldIRQL); + IpxFwdDbgPrint (DBG_SEND, DBG_INFORMATION, + ("IpxFwd: Sent queued external packet %08lx if %ld.\n", + pktTag, dstIf->ICB_Index)); + } + else { + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_SEND, DBG_WARNING, + ("IpxFwd: Dropped queued external packet %08lx on dead if %ld.\n", + pktTag, dstIf->ICB_Index)); + status = STATUS_UNSUCCESSFUL; + } + + if (status!=STATUS_PENDING) + ProcessSentPacket (dstIf, pktTag, status); + } +} + + +/*++ +******************************************************************* + + S p o o f e r + +Routine Description: + Processes packets in spoofing queue +Arguments: + None +Return Value: + None +******************************************************************* +--*/ +VOID +Spoofer ( + PVOID Context + ) { + KIRQL oldIRQL; + NTSTATUS status; + UNREFERENCED_PARAMETER (Context); + + KeAcquireSpinLock (&SpoofingQueueLock, &oldIRQL); + // Keep going till queue is empty + while (!IsListEmpty (&SpoofingQueue)) { + PINTERFACE_CB dstIf; + PPACKET_TAG pktTag = CONTAINING_RECORD (SpoofingQueue.Flink, + PACKET_TAG, + PT_QueueLink); + RemoveEntryList (&pktTag->PT_QueueLink); + KeReleaseSpinLock (&SpoofingQueueLock, oldIRQL); + dstIf = pktTag->PT_InterfaceReference; + if (dstIf==NULL) { + // Replies for internal server require first active LAN adapter + // SHOULD BE REMOVED WHEN LOOPBACK SUPPORT US ADDED BY IPX + while ((dstIf=GetNextInterfaceReference (dstIf))!=NULL) { + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + if (IS_IF_ENABLED (dstIf) + && (dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) + && (dstIf->ICB_InterfaceType==FWD_IF_PERMANENT)) { + pktTag->PT_InterfaceReference = dstIf; + IPX_NODE_CPY (&pktTag->PT_Target.MacAddress, dstIf->ICB_LocalNode); + status = DoSend (dstIf, pktTag, oldIRQL); // releases spin lock + if (status!=STATUS_PENDING) + ProcessSentPacket (dstIf, pktTag, status); + break; + } + else + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + } + if (dstIf==NULL) { + FreePacket (pktTag); + } + + } + else { // Reply for external server, interface is already known + UCHAR addr[12]; + FILTER_ACTION action; + pktTag->PT_Flags &= (~PT_SOURCE_IF); + + // Switch source and destination + memcpy (addr, pktTag->PT_Data+IPXH_DESTADDR, 12); + memcpy (pktTag->PT_Data+IPXH_DESTADDR, + pktTag->PT_Data+IPXH_SRCADDR, 12); + memcpy (pktTag->PT_Data+IPXH_SRCADDR, addr, 12); + // Say yes in reply + *(pktTag->PT_Data+IPXH_HDRSIZE+1) = 'Y'; + + action = FltFilter (pktTag->PT_Data, + GETUSHORT (pktTag->PT_Data+IPXH_LENGTH), + dstIf->ICB_FilterInContext, + pktTag->PT_SourceIf->ICB_FilterOutContext); + if (action==FILTER_PERMIT) { + + // Release destination if and use source as destination + ReleaseInterfaceReference (dstIf); + dstIf = pktTag->PT_InterfaceReference = pktTag->PT_SourceIf; + // Send the packet if we can + KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); + if (IS_IF_ENABLED (dstIf) + && (dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP)) { + status = DoSend (dstIf, pktTag, oldIRQL); + if (status!=STATUS_PENDING) + ProcessSentPacket (dstIf, pktTag, status); + } + else { + KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); + InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); + ReleaseInterfaceReference (dstIf); + FreePacket (pktTag); + } + } + else { + if (action==FILTER_DENY_OUT) + InterlockedIncrement (&pktTag->PT_SourceIf->ICB_Stats.OutFiltered); + else { + ASSERT (action==FILTER_DENY_IN); + InterlockedIncrement (&dstIf->ICB_Stats.InFiltered); + } + ReleaseInterfaceReference (dstIf); + ReleaseInterfaceReference (pktTag->PT_SourceIf); + FreePacket (pktTag); + } + } + KeAcquireSpinLock (&SpoofingQueueLock, &oldIRQL); + } // end while + SpoofingWorkerActive = FALSE; + KeReleaseSpinLock (&SpoofingQueueLock, oldIRQL); + LeaveForwarder (); +} + + diff --git a/private/ntos/tdi/isn/fwd/send.h b/private/ntos/tdi/isn/fwd/send.h new file mode 100644 index 000000000..e46651e13 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/send.h @@ -0,0 +1,220 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\send.c + +Abstract: + Send routines + +Author: + + Vadim Eydelman + +Revision History: + +--*/ +#ifndef IPXFWD_SEND +#define IPXFWD_SEND + +typedef struct _INTERNAL_PACKET_TAG { + LIST_ENTRY IPT_QueueLink; + PNDIS_PACKET IPT_Packet; + PUCHAR IPT_DataPtr; + ULONG IPT_Length; + PINTERFACE_CB IPT_InterfaceReference; + IPX_LOCAL_TARGET IPT_Target; +} INTERNAL_PACKET_TAG, *PINTERNAL_PACKET_TAG; + + +#define DEF_SPOOFING_TIMEOUT (120*60) // Seconds +extern ULONG SpoofingTimeout; +extern LIST_ENTRY SpoofingQueue; +extern KSPIN_LOCK SpoofingQueueLock; +extern WORK_QUEUE_ITEM SpoofingWorker; +extern BOOLEAN SpoofingWorkerActive; +extern ULONG DontSuppressNonAgentSapAdvertisements; +VOID +Spoofer ( + PVOID Context + ); + +#define InitializeSendQueue() { \ + InitializeListHead (&SpoofingQueue); \ + KeInitializeSpinLock (&SpoofingQueueLock); \ + ExInitializeWorkItem (&SpoofingWorker, Spoofer, NULL); \ + SpoofingWorkerActive = FALSE; \ +} + +#define DeleteSendQueue() { \ + while (!IsListEmpty (&SpoofingQueue)) { \ + PPACKET_TAG pktTag = CONTAINING_RECORD (SpoofingQueue.Flink, \ + PACKET_TAG, \ + PT_QueueLink); \ + RemoveEntryList (&pktTag->PT_QueueLink); \ + if (pktTag->PT_InterfaceReference!=NULL) \ + ReleaseInterfaceReference (pktTag->PT_InterfaceReference); \ + FreePacket (pktTag); \ + } \ +} + + +/*++ +******************************************************************* + S e n d P a c k e t + +Routine Description: + Enqueues packets to be sent by IPX stack +Arguments: + dstIf - over which interface to send + pktTag - packet to send +Return Value: + None + +******************************************************************* +--*/ +VOID +SendPacket ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag + ); + +/*++ +******************************************************************* + F w S e n d C o m p l e t e + +Routine Description: + Called by IPX stack when send completes asynchronously +Arguments: + pktDscr - descriptor of the completed packet + status - result of send operation +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdSendComplete ( + PNDIS_PACKET pktDscr, + NDIS_STATUS NdisStatus + ); + +/*++ +******************************************************************* + + F w I n t e r n a l S e n d + +Routine Description: + Filter and routes packets sent by IPX stack +Arguments: + LocalTarget - the NicId and next hop router MAC address + Context - preferred interface on which to send + Packet - packet to be sent + ipxHdr - pointer to ipx header inside the packet + PacketLength - length of the packet + fIterate - a flag to indicate if this is a packet for the + iteration of which the Fwd takes responsibility + - typically type 20 NetBIOS frames + +Return Value: + + STATUS_SUCCESS - if the preferred NIC was OK and packet passed filtering + STATUS_NETWORK_UNREACHABLE - if the preferred was not OK or packet failed filtering + STATUS_PENDING - packet was queued until connection is established +******************************************************************* +--*/ +NTSTATUS +IpxFwdInternalSend ( + IN OUT PIPX_LOCAL_TARGET LocalTarget, + IN ULONG Context, + IN PNDIS_PACKET pktDscr, + IN PUCHAR ipxHdr, + IN PUCHAR data, + IN ULONG PacketLength, + IN BOOLEAN fIterate + ); + +/*++ +******************************************************************* + + P r o c e s s I n t e r n a l Q u e u e + +Routine Description: + Processes packets in the interface internal queue. + Called when connection request completes +Arguments: + dstIf - interface to process +Return Value: + None +******************************************************************* +--*/ +VOID +ProcessInternalQueue ( + PINTERFACE_CB dstIf + ); + + +/*++ +******************************************************************* + + P r o c e s s E x t e r n a l Q u e u e + +Routine Description: + Processes packets in the interface external queue. + Called when connection request completes +Arguments: + dstIf - interface to process +Return Value: + None +******************************************************************* +--*/ +VOID +ProcessExternalQueue ( + PINTERFACE_CB dstIf + ); +/*++ +******************************************************************* + D o S e n d + +Routine Description: + Prepares and sends packet. Interface lock must be help while + callin this routine +Arguments: + dstIf - over which interface to send + pktTag - packet to send +Return Value: + result returned by IPX + +******************************************************************* +--*/ +NDIS_STATUS +DoSend ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag, + KIRQL oldIRQL + ); + +/*++ +******************************************************************* + P r o c e s s S e n t P a c k e t + +Routine Description: + Process completed sent packets +Arguments: + dstIf - interface over which packet was sent + pktTag - completed packet + status - result of send operation +Return Value: + None + +******************************************************************* +--*/ +VOID +ProcessSentPacket ( + PINTERFACE_CB dstIf, + PPACKET_TAG pktTag, + NDIS_STATUS status + ); +#endif diff --git a/private/ntos/tdi/isn/fwd/sources.inc b/private/ntos/tdi/isn/fwd/sources.inc new file mode 100644 index 000000000..3a7cd7ab5 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/sources.inc @@ -0,0 +1,61 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: Vadim Eydelman + +!ENDIF + +MAJORCOMP=ntos +MINORCOMP=ndis + +TARGETNAME=nwlnkfwd +TARGETTYPE=DRIVER + +TARGETLIBS=\ + $(BASEDIR)\public\sdk\lib\*\tdi.lib \ + $(BASEDIR)\public\sdk\lib\*\ndis.lib + +INCLUDES=..\;..\..\inc;..\..\..\..\inc;..\..\..\..\..\inc + +C_DEFINES=$(C_DEFINES) -D_NTDRIVER_ -D_PNP_POWER + +!IFDEF BUILD_FOR_3_51 +C_DEFINES= $(C_DEFINES) -D_NTIFS_ +!ENDIF + +PRECOMPILED_INCLUDE=..\precomp.h +PRECOMPILED_PCH=precomp.pch +PRECOMPILED_OBJ=precomp.obj +MSC_WARNING_LEVEL=/W3 /WX + +SOURCES=..\driver.c \ + ..\ipxbind.c \ + ..\rcvind.c \ + ..\send.c \ + ..\registry.c \ + ..\lineind.c \ + ..\ddreqs.c \ + ..\netbios.c \ + ..\packets.c \ + ..\tables.c \ + ..\debug.c \ + ..\filterif.c \ + ..\nwlnkfwd.rc + +RELATIVE_DEPTH=..\.. +ALT_PROJECT_TARGET=Routing + +
\ No newline at end of file diff --git a/private/ntos/tdi/isn/fwd/tables.c b/private/ntos/tdi/isn/fwd/tables.c new file mode 100644 index 000000000..baec3cced --- /dev/null +++ b/private/ntos/tdi/isn/fwd/tables.c @@ -0,0 +1,1512 @@ + +#include "precomp.h" + +// Memory zone for interfaces +ZONE_HEADER InterfaceZone; +// Segment size in interface sone +ULONG InterfaceSegmentSize= + sizeof(INTERFACE_CB)*NUM_INTERFACES_PER_SEGMENT + +sizeof (ZONE_SEGMENT_HEADER); +KSPIN_LOCK InterfaceZoneLock; + +// Interface tables +LIST_ENTRY *InterfaceIndexHash; // Hash by interface index +PINTERFACE_CB *ClientNodeHash; // Hash by node on qlobal net +INTERFACE_CB TheInternalInterface; // The internal interface +PINTERFACE_CB InternalInterface=&TheInternalInterface; +KSPIN_LOCK InterfaceTableLock; // Protection for interface hash tables + +// Memory Zone for routes +ZONE_HEADER RouteZone; +// Segment size in route sone +ULONG RouteSegmentSize=DEF_ROUTE_SEGMENT_SIZE; +KSPIN_LOCK RouteZoneLock; + +// Route tables +PFWD_ROUTE *RouteHash; +PFWD_ROUTE GlobalRoute; +ULONG GlobalNetwork; + + +// NB Route table +PNB_ROUTE *NBRouteHash; + + +// Reader-writer lock to wait for all readers to drain when +// updating the route tables +RW_LOCK RWLock; +// Mutex to serialize writers to route tables +FAST_MUTEX WriterMutex; + + +// Sizes of the tables +ULONG RouteHashSize; // Must be specified +ULONG InterfaceHashSize=DEF_INTERFACE_HASH_SIZE; +ULONG ClientHashSize=DEF_CLIENT_HASH_SIZE; +ULONG NBRouteHashSize=DEF_NB_ROUTE_HASH_SIZE; + +//*** max send pkts queued limit: over this limit the send pkts get discarded +ULONG MaxSendPktsQueued = MAX_SEND_PKTS_QUEUED; +INT WanPacketListId = -1; + +// Initial memory block allocated for the tables +CHAR *TableBlock = NULL; + +// Hash functions +#define InterfaceIndexHashFunc(Interface) (Interface%InterfaceHashSize) +#define ClientNodeHashFunc(Node64) ((UINT)(Node64%ClientHashSize)) +#define NetworkNumberHashFunc(Network) (Network%RouteHashSize) +#define NetbiosNameHashFunc(Name128) ((UINT)(Name128[0]+Name128[1])%NBRouteHashSize) + +/*++ +******************************************************************* + A l l o c a t e R o u t e + +Routine Description: + Allocates memory for route from memory zone reserved + for route storage. Extends zone if there are no + free blocks in currently allocated segements. +Arguments: + None +Return Value: + Pointer to allocated route + +******************************************************************* +--*/ +PFWD_ROUTE +AllocateRoute ( + void + ) { + PFWD_ROUTE fwRoute; + KIRQL oldIRQL; + + KeAcquireSpinLock (&RouteZoneLock, &oldIRQL); + // Check if there are free blocks in the zone + if (ExIsFullZone (&RouteZone)) { + // Try to allocate new segment if not + NTSTATUS status; + PVOID segment = ExAllocatePoolWithTag + (NonPagedPool, RouteSegmentSize, FWD_POOL_TAG); + if (segment==NULL) { + KeReleaseSpinLock (&RouteZoneLock, oldIRQL); + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Can't allocate route zone segment.\n")); + return NULL; + } + status = ExExtendZone (&RouteZone, segment, RouteSegmentSize); + ASSERTMSG ("Could not extend RouteZone ", NT_SUCCESS (status)); + } + fwRoute = (PFWD_ROUTE)ExAllocateFromZone (&RouteZone); + KeReleaseSpinLock (&RouteZoneLock, oldIRQL); + return fwRoute; +} + +/*++ +******************************************************************* + F r e e R o u t e + +Routine Description: + Releases memory allocated for route to route memory + zone. +Arguments: + fwRoute - route block to release +Return Value: + None +******************************************************************* +--*/ +VOID +FreeRoute ( + PFWD_ROUTE fwRoute + ) { + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_INFORMATION, + ("IpxFwd: Freeing route block %08lx.\n", fwRoute)); + ASSERT (fwRoute->FR_InterfaceReference==NULL); + ExInterlockedFreeToZone(&RouteZone,fwRoute,&RouteZoneLock); +} + + +/*++ +******************************************************************* + A l l o c a t e I n t e r f a c e + +Routine Description: + Allocates memory for interface from memory zone reserved + for interface storage. Extends zone if there are no + free blocks in currently allocated segements. +Arguments: + None +Return Value: + Pointer to allocated route + +******************************************************************* +--*/ +PINTERFACE_CB +AllocateInterface ( + void + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + + KeAcquireSpinLock (&RouteZoneLock, &oldIRQL); + // Check if there are free blocks in the zone + if (ExIsFullZone (&InterfaceZone)) { + // Try to allocate new segment if not + NTSTATUS status; + PVOID segment = ExAllocatePoolWithTag + (NonPagedPool, InterfaceSegmentSize, FWD_POOL_TAG); + if (segment==NULL) { + KeReleaseSpinLock (&RouteZoneLock, oldIRQL); + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Can't allocate interface zone segment.\n")); + return NULL; + } + status = ExExtendZone (&InterfaceZone, segment, InterfaceSegmentSize); + ASSERTMSG ("Could not extend InterfaceZone ", NT_SUCCESS (status)); + } + ifCB = (PINTERFACE_CB)ExAllocateFromZone (&InterfaceZone); + KeReleaseSpinLock (&RouteZoneLock, oldIRQL); + return ifCB; +} + +/*++ +******************************************************************* + F r e e I n t e r f a c e + +Routine Description: + Releases memory allocated for interface to interface memory + zone. +Arguments: + fwRoute - route block to release +Return Value: + None +******************************************************************* +--*/ +VOID +FreeInterface ( + PINTERFACE_CB ifCB + ) { + KIRQL oldIRQL; + + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_WARNING, + ("IpxFwd: Freeing icb %08lx.\n", ifCB)); + + ASSERT(ifCB->ICB_Stats.OperationalState==FWD_OPER_STATE_DOWN); + KeAcquireSpinLock (&InterfaceZoneLock, &oldIRQL); + ExFreeToZone(&InterfaceZone, ifCB); + KeReleaseSpinLock (&InterfaceZoneLock, oldIRQL); +} + +/*++ +******************************************************************* + C r e a t e T a b l e s + +Routine Description: + Allocates and intializes all hash tables and related structures +Arguments: + None +Return Value: + STATUS_SUCCESS - tables were created ok + STATUS_INSUFFICIENT_RESOURCES - resource allocation failed +******************************************************************* +--*/ +NTSTATUS +CreateTables ( + void + ) { + UINT i; + CHAR *segment; + NTSTATUS status; + ULONG blockSize; + + ASSERT (TableBlock==NULL); + + blockSize = ROUND_TO_PAGES ( + InterfaceHashSize*sizeof(*InterfaceIndexHash) + +ClientHashSize*sizeof(*ClientNodeHash) + +RouteHashSize*sizeof(*RouteHash) + +NBRouteHashSize*sizeof(*NBRouteHash) + +InterfaceSegmentSize + +RouteSegmentSize + ); + + // Allocate first segment for route zone + TableBlock = segment = (CHAR *)ExAllocatePoolWithTag ( + NonPagedPool, blockSize, FWD_POOL_TAG); + if (segment!=NULL) { + InterfaceIndexHash = (LIST_ENTRY *)segment; + segment = (CHAR *)ALIGN_UP((ULONG)(InterfaceIndexHash+InterfaceHashSize),ULONGLONG); + + ClientNodeHash = (PINTERFACE_CB *)segment; + segment = (CHAR *)ALIGN_UP((ULONG)(ClientNodeHash+ClientHashSize),ULONGLONG); + + RouteHash = (PFWD_ROUTE *)segment; + segment = (CHAR *)ALIGN_UP((ULONG)(RouteHash + RouteHashSize),ULONGLONG); + + NBRouteHash = (PNB_ROUTE *)segment; + segment = (CHAR *)ALIGN_UP((ULONG)(NBRouteHash + NBRouteHashSize),ULONGLONG); + + status = ExInitializeZone (&InterfaceZone, + ALIGN_UP(sizeof (INTERFACE_CB),ULONGLONG), + segment, + InterfaceSegmentSize); + ASSERTMSG ("Could not initalize InterfaceZone ", + NT_SUCCESS (status)); + segment = (CHAR *)ALIGN_UP((ULONG)(segment+InterfaceSegmentSize),ULONGLONG); + + status = ExInitializeZone (&RouteZone, + ALIGN_UP(sizeof (FWD_ROUTE), ULONGLONG), + segment, + blockSize - (segment - TableBlock)); + + ASSERTMSG ("Could not initalize RouteZone ", NT_SUCCESS (status)); + + + // No global route yet + GlobalRoute = NULL; + GlobalNetwork = 0xFFFFFFFF; + + InternalInterface = &TheInternalInterface; + InitICB (InternalInterface, + FWD_INTERNAL_INTERFACE_INDEX, + FWD_IF_PERMANENT, + TRUE, + FWD_NB_DELIVER_ALL); +#if DBG + InitializeListHead (&InternalInterface->ICB_InSendQueue); +#endif + + KeInitializeSpinLock (&InterfaceTableLock); + KeInitializeSpinLock (&InterfaceZoneLock); + KeInitializeSpinLock (&RouteZoneLock); + InitializeRWLock (&RWLock); + ExInitializeFastMutex (&WriterMutex); + + // Initialize hash tables buckets + for (i=0; i<InterfaceHashSize; i++) + InitializeListHead (&InterfaceIndexHash[i]); + + for (i=0; i<ClientHashSize; i++) { + ClientNodeHash[i] = NULL; + } + + for (i=0; i<RouteHashSize; i++) { + RouteHash[i] = NULL; + } + + for (i=0; i<NBRouteHashSize; i++) { + NBRouteHash[i] = NULL; + } + return STATUS_SUCCESS; + } + else { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Could not allocate table block!\n")); + } + + return STATUS_INSUFFICIENT_RESOURCES; +} + +/*++ +******************************************************************* + D e l e t e T a b l e s + +Routine Description: + Releases resources allocated for all hash tables +Arguments: + None +Return Value: + STATUS_SUCCESS - tables were freed ok +******************************************************************* +--*/ +NTSTATUS +DeleteTables ( + void + ) { + UINT i; + PVOID segment; + + + if (TableBlock==NULL) { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, ("Tables already deleted.\n")); + return STATUS_SUCCESS; + } + // First get rid of all routes + // (that should release all references to interface + // control blocks + for (i=0; i<RouteHashSize; i++) { + while (RouteHash[i]!=NULL) { + PFWD_ROUTE fwRoute = RouteHash[i]; + RouteHash[i] = fwRoute->FR_Next; + if (fwRoute->FR_InterfaceReference!=GLOBAL_INTERFACE_REFERENCE) { + ReleaseInterfaceReference (fwRoute->FR_InterfaceReference); + } + fwRoute->FR_InterfaceReference = NULL; + ReleaseRouteReference (fwRoute); + } + } + // Don't forget about global route + if (GlobalRoute!=NULL) { + GlobalRoute->FR_InterfaceReference = NULL; + ReleaseRouteReference (GlobalRoute); + GlobalRoute = NULL; + GlobalNetwork = 0xFFFFFFFF; + } + + // Now we should be able to release all interfaces + for (i=0; i<InterfaceHashSize; i++) { + while (!IsListEmpty (&InterfaceIndexHash[i])) { + PINTERFACE_CB ifCB = CONTAINING_RECORD (InterfaceIndexHash[i].Flink, + INTERFACE_CB, + ICB_IndexHashLink); + RemoveEntryList (&ifCB->ICB_IndexHashLink); + if (ifCB->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) { + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + DeregisterPacketConsumer (ifCB->ICB_PacketListId); + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + break; + default: + ASSERTMSG ("Invalid interface type ", FALSE); + break; + } + if (ifCB->ICB_CashedInterface!=NULL) + ReleaseInterfaceReference (ifCB->ICB_CashedInterface); + ifCB->ICB_CashedInterface = NULL; + if (ifCB->ICB_CashedRoute!=NULL) + ReleaseRouteReference (ifCB->ICB_CashedRoute); + ifCB->ICB_CashedRoute = NULL; + if (ifCB->ICB_Network==GlobalNetwork) + DeleteGlobalNetClient (ifCB); + IPXCloseAdapterProc (ifCB->ICB_AdapterContext); + ReleaseInterfaceReference (ifCB); // Binding reference + } + + if (IS_IF_CONNECTING (ifCB)) { + SET_IF_NOT_CONNECTING (ifCB); + DequeueConnectionRequest (ifCB); + } + + while (!IsListEmpty (&ifCB->ICB_ExternalQueue)) { + PPACKET_TAG pktTag; + + pktTag = CONTAINING_RECORD (ifCB->ICB_ExternalQueue.Flink, + PACKET_TAG, PT_QueueLink); + RemoveEntryList (&pktTag->PT_QueueLink); + ReleaseInterfaceReference (pktTag->PT_InterfaceReference); + FreePacket (pktTag); + } + + while (!IsListEmpty (&ifCB->ICB_InternalQueue)) { + PINTERNAL_PACKET_TAG pktTag; + + pktTag = CONTAINING_RECORD (ifCB->ICB_InternalQueue.Flink, + INTERNAL_PACKET_TAG, IPT_QueueLink); + RemoveEntryList (&pktTag->IPT_QueueLink); + IPXInternalSendCompletProc (&pktTag->IPT_Target, + pktTag->IPT_Packet, + pktTag->IPT_Length, + STATUS_NETWORK_UNREACHABLE); + ReleaseInterfaceReference (pktTag->IPT_InterfaceReference); + ExFreePool (pktTag); + } + + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + if (ifCB->ICB_NBRoutes!=NULL) { + DeleteNBRoutes (ifCB->ICB_NBRoutes, ifCB->ICB_NBRouteCount); + ifCB->ICB_NBRoutes = NULL; + } + ReleaseInterfaceReference (ifCB); + } + } + + if (InternalInterface->ICB_NBRoutes!=NULL) { + DeleteNBRoutes (InternalInterface->ICB_NBRoutes, + InternalInterface->ICB_NBRouteCount); + InternalInterface->ICB_NBRoutes = NULL; + } + if (InternalInterface->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) { + InternalInterface->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + ReleaseInterfaceReference (InternalInterface); // Binding reference + } + ReleaseInterfaceReference (InternalInterface); + + + + // Release extra memory segments used for route table entries + segment = PopEntryList (&RouteZone.SegmentList); + while (RouteZone.SegmentList.Next!=NULL) { + ExFreePool (segment); + segment = PopEntryList (&RouteZone.SegmentList); + } + + // Release extra memory segments used for interface table entries + segment = PopEntryList (&InterfaceZone.SegmentList); + while (InterfaceZone.SegmentList.Next!=NULL) { + ExFreePool (segment); + segment = PopEntryList (&InterfaceZone.SegmentList); + } + + ExFreePool (TableBlock); + TableBlock = NULL; + return STATUS_SUCCESS; +} + +/*++ +******************************************************************* + L o c a t e I n t e r f a c e + +Routine Description: + Finds interface control block in interface + index hash table. Optionally returns the + insertion point pointer if interface block + with given index is not in the table. +Arguments: + InterfaceIndex - unique id of the interface + insertBefore - buffer to place the pointer to + hash table element where interface + block should be inserted if it is not + already in the table +Return Value: + Pointer to interface control block if found + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +LocateInterface ( + ULONG InterfaceIndex, + PLIST_ENTRY *insertBefore OPTIONAL + ) { + PLIST_ENTRY cur; + PINTERFACE_CB ifCB; + PLIST_ENTRY HashList; + + ASSERT (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX); + + // Find hash bucket + HashList = &InterfaceIndexHash[InterfaceIndexHashFunc(InterfaceIndex)]; + cur = HashList->Flink; + // Walk the list + while (cur!=HashList) { + ifCB = CONTAINING_RECORD(cur, INTERFACE_CB, ICB_IndexHashLink); + + if (ifCB->ICB_Index==InterfaceIndex) + // Found, return it (insertion point is irrelevant) + return ifCB; + else if (ifCB->ICB_Index>InterfaceIndex) + // No chance to find it + break; + cur = cur->Flink; + } + // Return insertion point if asked + if (ARGUMENT_PRESENT(insertBefore)) + *insertBefore = cur; + return NULL; +} + +/*++ +******************************************************************* + L o c a t e C l i e n t I n t e r f a c e + +Routine Description: + Finds interface control block in client + node hash bucket. Optionally returns the + insertion point pointer if interface block + with given node is not in the table +Arguments: + ClientNode - node address of the client on global network + insertBefore - buffer to place the pointer to + hash table element where interface + block should be inserted if it is not + already in the table +Return Value: + Pointer to interface control block if found + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +LocateClientInterface ( + ULONGLONG *NodeAddress64, + PINTERFACE_CB **prevLink OPTIONAL + ) { + PINTERFACE_CB cur, *prev; + + prev = &ClientNodeHash[ClientNodeHashFunc (*NodeAddress64)]; + cur = *prev; + while (cur!=NULL) { + if (*NodeAddress64==cur->ICB_ClientNode64[0]) + break; + else if (*NodeAddress64>cur->ICB_ClientNode64[0]) { + // No chance to find it + cur = NULL; + break; + } + prev = &cur->ICB_NodeHashLink; + cur = cur->ICB_NodeHashLink; + } + if (ARGUMENT_PRESENT(prevLink)) + *prevLink = prev; + return cur; +} + +/*++ +******************************************************************* + L o c a t e R o u t e + +Routine Description: + Finds route block in network number + hash table. Optionally returns the + insertion point pointer if route + for given destination netowrk is not in the table +Arguments: + Network - destination netowork number + insertBefore - buffer to place the pointer to + hash table element where route + block should be inserted if it is not + already in the table +Return Value: + Pointer to route block if found + NULL otherwise +******************************************************************* +--*/ +PFWD_ROUTE +LocateRoute ( + ULONG Network, + PFWD_ROUTE **prevLink OPTIONAL + ) { + PFWD_ROUTE cur, *prev; + + prev = &RouteHash[NetworkNumberHashFunc(Network)]; + cur = *prev; + + while (cur!=NULL) { + if (cur->FR_Network==Network) + break; + else if (cur->FR_Network>Network) { + cur = NULL; + // No chance to find it + break; + } + prev = &cur->FR_Next; + cur = *prev; + } + if (ARGUMENT_PRESENT(prevLink)) + *prevLink = prev; + + return cur; +} + +/*++ +******************************************************************* + L o c a t e N B R o u t e + +Routine Description: + Finds nb route block in nb name + hash table. Optionally returns the + insertion point pointer if nb route + for given name is not in the table +Arguments: + Name - netbios name + insertBefore - buffer to place the pointer to + hash table element where route + block should be inserted if it is not + already in the table +Return Value: + Pointer to nb route block if found + NULL otherwise +******************************************************************* +--*/ +PNB_ROUTE +LocateNBRoute ( + ULONGLONG *Name128, + PNB_ROUTE **prevLink OPTIONAL + ) { + PNB_ROUTE cur, *prev; + + prev = &NBRouteHash[NetbiosNameHashFunc(Name128)]; + cur = *prev; + + while (cur!=NULL) { + if ((cur->NBR_Name128[0]==Name128[0]) + && (cur->NBR_Name128[1]==Name128[1])) + break; + else if ((cur->NBR_Name128[0]>Name128[0]) + || ((cur->NBR_Name128[0]==Name128[0]) + && (cur->NBR_Name128[1]>Name128[1]))) { + cur = NULL; + // No chance to find it + break; + } + prev = &cur->NBR_Next; + cur = *prev; + } + if (ARGUMENT_PRESENT(prevLink)) + *prevLink = prev; + + return cur; +} + +/*++ +******************************************************************* + G e t I n t e r f a c e R e f e r e n c e + +Routine Description: + Returns reference interface based on its index +Arguments: + InterfaceIndex - unique id of the interface +Return Value: + Pointer to interface control block if there is one in the table + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +GetInterfaceReference ( + ULONG InterfaceIndex + ) { + KIRQL oldIRQL; + PINTERFACE_CB ifCB; + + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) + ifCB = LocateInterface (InterfaceIndex, NULL); + else + ifCB = InternalInterface; + + if (ifCB!=NULL) + AcquireInterfaceReference (ifCB); + else { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Could not get interface reference %ld.\n", InterfaceIndex)); + } + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + return ifCB; +} + +/*++ +******************************************************************* + G e t N e x t I n t e r f a c e R e f e r e n c e + +Routine Description: + Returns reference to the next interface in the table + Reference to the provided interface is released +Arguments: + ifCB - interface to start with or NULL to start from the + beginning of the interface table +Return Value: + Pointer to interface control block if thare are any more interfaces + in the table + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +GetNextInterfaceReference ( + PINTERFACE_CB ifCB + ) { + PLIST_ENTRY cur; + PLIST_ENTRY HashList; + KIRQL oldIRQL; + + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (ifCB!=NULL) { + // Find hash bucket + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + HashList = &InterfaceIndexHash[InterfaceIndexHashFunc(ifCB->ICB_Index)]; + if (LocateInterface (ifCB->ICB_Index, &cur)!=NULL) + cur = ifCB->ICB_IndexHashLink.Flink; + ReleaseInterfaceReference (ifCB); + ifCB = NULL; + } + else + cur = HashList = InterfaceIndexHash-1; + + if (cur==HashList) { + do { + HashList += 1; + if (HashList==&InterfaceIndexHash[InterfaceHashSize]) { + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + return NULL; + } + } while (IsListEmpty (HashList)); + cur = HashList->Flink; + } + ifCB = CONTAINING_RECORD (cur, INTERFACE_CB, ICB_IndexHashLink); + AcquireInterfaceReference (ifCB); + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + + return ifCB; +} + + +/*++ +******************************************************************* + A d d I n t e r f a c e + +Routine Description: + Adds interface control block to the table. +Arguments: + InterfaceIndex - unique if of the interface + Info - interface paramters +Return Value: + STATUS_SUCCESS - interface added ok + STATUS_UNSUCCESSFUL - interface is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + interface CB +******************************************************************* +--*/ +NTSTATUS +AddInterface ( + ULONG InterfaceIndex, + UCHAR InterfaceType, + BOOLEAN NetbiosAccept, + UCHAR NetbiosDeliver + ) { + PINTERFACE_CB ifCB; + PLIST_ENTRY cur; + KIRQL oldIRQL; + NTSTATUS status = STATUS_SUCCESS; + + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) { + ifCB = LocateInterface (InterfaceIndex, &cur); + if (ifCB==NULL) { + ifCB = AllocateInterface (); + if (ifCB!=NULL) + NOTHING; + else { + status = STATUS_INSUFFICIENT_RESOURCES; + goto AddEnd; + } + } + else { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Interface %ld is already in the table!\n", InterfaceIndex)); + status = STATUS_UNSUCCESSFUL; + goto AddEnd; + } + } + else + ifCB = InternalInterface; + + InitICB (ifCB, InterfaceIndex,InterfaceType,NetbiosAccept,NetbiosDeliver); +#if DBG + InitializeListHead (&ifCB->ICB_InSendQueue); +#endif + + switch (InterfaceType) { + case FWD_IF_PERMANENT: + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + ASSERT (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX); + if (WanPacketListId==-1) { + status = RegisterPacketConsumer ( + WAN_PACKET_SIZE, + &WanPacketListId); + if (!NT_SUCCESS (status)) { + WanPacketListId = -1; + break; + } + } + ifCB->ICB_PacketListId = WanPacketListId; + break; + } + + if (NT_SUCCESS (status)) { + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) { + InsertTailList (cur, &ifCB->ICB_IndexHashLink); + } + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_WARNING, + ("IpxFwd: Adding interface %d (icb: %08lx, plid: %d)\n", + InterfaceIndex, ifCB, ifCB->ICB_PacketListId)); + } + else + FreeInterface (ifCB); + +AddEnd: + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + return status; +} + + +/*++ +******************************************************************* + A d d G l o b a l N e t C l i e n t + +Routine Description: + Adds interface control block to the table of + clients on the global network (should be done when + client connects) +Arguments: + ifCB - interface control block to add to the table +Return Value: + STATUS_SUCCESS - interface was added ok + STATUS_UNSUCCESSFUL - another interface with the same + node address is already in the table +******************************************************************* +--*/ +NTSTATUS +AddGlobalNetClient ( + PINTERFACE_CB ifCB + ) { + KIRQL oldIRQL; + RWCOOKIE cookie; + PINTERFACE_CB *prev; + NTSTATUS status = STATUS_SUCCESS; + + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + + AcquireReaderAccess (&RWLock, cookie); + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (LocateClientInterface (ifCB->ICB_ClientNode64, &prev)==NULL) { + ifCB->ICB_NodeHashLink = *prev; + *prev = ifCB; + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + ReleaseReaderAccess (&RWLock, cookie); + AcquireInterfaceReference (ifCB); // To make sure that + // interface block does not + // get deleted until it is + // removed from the node table + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_WARNING, + ("IpxFwd: Adding interface %ld (icb: %08lx)" + " to global client table.\n", ifCB->ICB_Index, ifCB)); + } + else { + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + ReleaseReaderAccess (&RWLock, cookie); + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Interface %ld (icb: %08lx)" + " is already in the global client table.\n", + ifCB->ICB_Index, ifCB)); + status = STATUS_UNSUCCESSFUL; + } + + return status; +} + +/*++ +******************************************************************* + D e l e t e G l o b a l N e t C l i e n t + +Routine Description: + Removes interface control block from the table of + clients on the global network (should be done when + client disconnects) +Arguments: + ifCB - interface control block to remove from the table +Return Value: + STATUS_SUCCESS - interface was removed ok +******************************************************************* +--*/ +NTSTATUS +DeleteGlobalNetClient ( + PINTERFACE_CB ifCB + ) { + KIRQL oldIRQL; + RWCOOKIE cookie; + PINTERFACE_CB cur, *prev; + + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_WARNING, + ("IpxFwd: Deleting interface %ld (icb: %08lx)" + " from global client table.\n", ifCB->ICB_Index, ifCB)); + + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + + AcquireReaderAccess (&RWLock, cookie); + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + cur = LocateClientInterface (ifCB->ICB_ClientNode64, &prev); + ASSERT (cur==ifCB); + *prev = ifCB->ICB_NodeHashLink; + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + ReleaseReaderAccess (&RWLock, cookie); + + ReleaseInterfaceReference (ifCB); + return STATUS_SUCCESS; +} + + +/*++ +******************************************************************* + D e l e t e I n t e r f a c e + +Routine Description: + Deletes interface control block (the block is not actually + disposed of until all references to it are released). +Arguments: + InterfaceIndex - unique if of the interface +Return Value: + STATUS_SUCCESS - interface info retreived ok + STATUS_UNSUCCESSFUL - interface is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteInterface ( + ULONG InterfaceIndex + ) { + PINTERFACE_CB ifCB; + KIRQL oldIRQL; + NTSTATUS status = STATUS_SUCCESS; + + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) + ifCB = LocateInterface (InterfaceIndex, NULL); + else + ifCB = InternalInterface; + if (ifCB!=NULL) { + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) { + RemoveEntryList (&ifCB->ICB_IndexHashLink); + } + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + if (ifCB->ICB_Stats.OperationalState == FWD_OPER_STATE_UP) { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Interface %ld (icb: %08lx) was still bound" + " when asked to delete it.\n", + ifCB->ICB_Index, ifCB)); + UnbindInterface (ifCB); + } + else if (IS_IF_CONNECTING (ifCB)) { + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Interface %ld (icb: %08lx) was still being connected" + " when asked to delete it.\n", + ifCB->ICB_Index, ifCB)); + SET_IF_NOT_CONNECTING (ifCB); + DequeueConnectionRequest (ifCB); + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_WARNING, + ("IpxFwd: Deleting interface %ld (icb: %08lx).\n", + ifCB->ICB_Index, ifCB)); + + if (ifCB->ICB_NBRoutes!=NULL) { + DeleteNBRoutes (ifCB->ICB_NBRoutes, ifCB->ICB_NBRouteCount); + ifCB->ICB_NBRoutes = NULL; + } + + FltInterfaceDeleted (ifCB); + ReleaseInterfaceReference (ifCB); + } + else { + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + IpxFwdDbgPrint (DBG_INTF_TABLE, DBG_ERROR, + ("IpxFwd: Could not delete interface %ld because it is not found.\n", + InterfaceIndex)); + status = STATUS_UNSUCCESSFUL; + } + return status; + +} + +/*++ +******************************************************************* + A d d R o u t e + +Routine Description: + Adds route to the hash table and finds and stores the reference + to the associated interface control block in the route. +Arguments: + Network - route's destination network + NextHopAddress - mac address of next hop router if network is not + directly connected + TickCount - ticks to reach the destination net + HopCount - hopss to reach the destination net + InterfaceIndex - index of the associated interface (through which + packets destined to the network are to be sent) +Return Value: + STATUS_SUCCESS - route was added ok + STATUS_UNSUCCESSFUL - route is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + route block +******************************************************************* +--*/ +NTSTATUS +AddRoute ( + ULONG Network, + UCHAR *NextHopAddress, + USHORT TickCount, + USHORT HopCount, + ULONG InterfaceIndex + ) { + PFWD_ROUTE fwRoute; + PFWD_ROUTE *prev; + NTSTATUS status = STATUS_SUCCESS; + KIRQL oldIRQL; + + // Assume success, allocate route and intialize it + // (the goal is to spend as little time as possible + // inside exclusive usage zone) + fwRoute = AllocateRoute (); + if (fwRoute!=NULL) { + fwRoute->FR_Network = Network; + IPX_NODE_CPY (fwRoute->FR_NextHopAddress, NextHopAddress); + fwRoute->FR_TickCount = TickCount; + fwRoute->FR_HopCount = HopCount; + fwRoute->FR_ReferenceCount = 0; + + if (InterfaceIndex!=0xFFFFFFFF) { + // See if interface is there + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) + fwRoute->FR_InterfaceReference + = LocateInterface (InterfaceIndex, NULL); + else + fwRoute->FR_InterfaceReference = InternalInterface; + if (fwRoute->FR_InterfaceReference!=NULL) { + AcquireInterfaceReference (fwRoute->FR_InterfaceReference); + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + + ExAcquireFastMutex (&WriterMutex); + // Check if route is already there + if (LocateRoute (Network, &prev)==NULL) { + fwRoute->FR_Next = *prev; + *prev = fwRoute; + } + else { + ReleaseInterfaceReference (fwRoute->FR_InterfaceReference); + fwRoute->FR_InterfaceReference = NULL; + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Route for net %08lx" + " is already in the table!\n", Network)); + status = STATUS_UNSUCCESSFUL; + } + + ExReleaseFastMutex (&WriterMutex); + } + else { + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Interface %ld for route for net %08lx" + " is not in the table!\n", InterfaceIndex, Network)); + status = STATUS_UNSUCCESSFUL; + } + } + else { + ExAcquireFastMutex (&WriterMutex); + // Just check if we do not have it already + if (GlobalRoute==NULL) { + fwRoute->FR_InterfaceReference = GLOBAL_INTERFACE_REFERENCE; + GlobalNetwork = Network; + GlobalRoute = fwRoute; + } + else { + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Route for global net %08lx" + " is already in the table!\n", Network)); + status = STATUS_UNSUCCESSFUL; + } + ExReleaseFastMutex (&WriterMutex); + } + + if (NT_SUCCESS (status)) { + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_WARNING, + ("IpxFwd: Adding route for net %08lx" + " (rb: %08lx, NHA: %02x%02x%02x%02x%02x%02x," + " if: %ld, icb: %08lx).\n", + Network, fwRoute, + NextHopAddress[0], NextHopAddress[1], + NextHopAddress[2], NextHopAddress[3], + NextHopAddress[4], NextHopAddress[5], + InterfaceIndex, fwRoute->FR_InterfaceReference)); + } + else { + FreeRoute (fwRoute); + } + } + else + status = STATUS_INSUFFICIENT_RESOURCES; + + return status; +} + +/*++ +******************************************************************* + D e l e t e R o u t e + +Routine Description: + Deletes route from the hash table and releases the reference + to the interface control block associated with the route. +Arguments: + Network - route's destination network +Return Value: + STATUS_SUCCESS - route was deleted ok + STATUS_UNSUCCESSFUL - route is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteRoute ( + ULONG Network + ) { + PFWD_ROUTE fwRoute, *prev; + NTSTATUS status = STATUS_SUCCESS; + + ExAcquireFastMutex (&WriterMutex); + + if ((GlobalRoute!=NULL) + && (GlobalNetwork==Network)) { + fwRoute = GlobalRoute; + GlobalNetwork = 0xFFFFFFFF; + GlobalRoute = NULL; + } + else if ((fwRoute=LocateRoute (Network, &prev))!=NULL) { + *prev = fwRoute->FR_Next; + } + + if (fwRoute!=NULL) { + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_WARNING, + ("IpxFwd: Deleting route for net %08lx (rb: %08lx).\n", + Network, fwRoute)); + WaitForAllReaders (&RWLock); + if (fwRoute->FR_InterfaceReference!=GLOBAL_INTERFACE_REFERENCE) { + ReleaseInterfaceReference (fwRoute->FR_InterfaceReference); + } + fwRoute->FR_InterfaceReference = NULL; + ReleaseRouteReference (fwRoute); + } + else { + IpxFwdDbgPrint (DBG_ROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Could not delete route for net %08lx because it is not in the table.\n", + Network)); + status = STATUS_UNSUCCESSFUL; + } + + ExReleaseFastMutex (&WriterMutex); + return status; +} + + +/*++ +******************************************************************* + U p d a t e R o u t e + +Routine Description: + Updates route in the hash table +Arguments: + Network - route's destination network + NextHopAddress - mac address of next hop router if network is not + directly connected + TickCount - ticks to reach the destination net + HopCount - hopss to reach the destination net + InterfaceIndex - index of the associated interface (through which + packets destined to the network are to be sent) +Return Value: + STATUS_SUCCESS - interface info retreived ok + STATUS_UNSUCCESSFUL - interface is not in the table +******************************************************************* +--*/ +NTSTATUS +UpdateRoute ( + ULONG Network, + UCHAR *NextHopAddress, + USHORT TickCount, + USHORT HopCount, + ULONG InterfaceIndex + ) { + PFWD_ROUTE fwRoute = NULL, newRoute, *prev; + PINTERFACE_CB ifCB = NULL; + KIRQL oldIRQL; + NTSTATUS status = STATUS_SUCCESS; + + + ExAcquireFastMutex (&WriterMutex); + + if ((GlobalRoute!=NULL) + && (GlobalNetwork==Network)) { + ASSERT (InterfaceIndex==0xFFFFFFFF); + fwRoute = GlobalRoute; + } + else { + ASSERT (InterfaceIndex!=0xFFFFFFFF); + fwRoute = LocateRoute (Network, &prev); + } + + if (fwRoute!=NULL) { + if (InterfaceIndex!=0xFFFFFFFF) { + if (fwRoute->FR_InterfaceReference->ICB_Index!=InterfaceIndex) { + // Get a reference to new interface + KeAcquireSpinLock (&InterfaceTableLock, &oldIRQL); + if (InterfaceIndex!=FWD_INTERNAL_INTERFACE_INDEX) + ifCB = LocateInterface (InterfaceIndex, NULL); + else + ifCB = InternalInterface; + if (ifCB!=NULL) { + AcquireInterfaceReference (ifCB); + } + else { + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + status = STATUS_UNSUCCESSFUL; + goto ExitUpdate; + } + KeReleaseSpinLock (&InterfaceTableLock, oldIRQL); + } + else { + ifCB = fwRoute->FR_InterfaceReference; + AcquireInterfaceReference (ifCB); + } + } + else + ifCB = GLOBAL_INTERFACE_REFERENCE; + newRoute = AllocateRoute (); + if (newRoute!=NULL) { + newRoute->FR_Network = Network; + IPX_NODE_CPY (newRoute->FR_NextHopAddress, NextHopAddress); + newRoute->FR_TickCount = TickCount; + newRoute->FR_HopCount = HopCount; + newRoute->FR_ReferenceCount = 0; + newRoute->FR_InterfaceReference = ifCB; + // Lock the table only when updating it + if (InterfaceIndex!=0xFFFFFFFF) { + newRoute->FR_Next = fwRoute->FR_Next; + *prev = newRoute; + } + else + GlobalRoute = newRoute; + + WaitForAllReaders (&RWLock) + if (fwRoute->FR_InterfaceReference!=GLOBAL_INTERFACE_REFERENCE) { + ReleaseInterfaceReference (fwRoute->FR_InterfaceReference); + } + fwRoute->FR_InterfaceReference = NULL; + ReleaseRouteReference (fwRoute); + + } + else + status = STATUS_INSUFFICIENT_RESOURCES; + } + else + status = STATUS_UNSUCCESSFUL; + +ExitUpdate: + ExReleaseFastMutex (&WriterMutex); + return status; +} + + +/*++ +******************************************************************* + F i n d D e s t i n a t i o n + +Routine Description: + Finds destination interface for IPX address and + returns reference to its control block. +Arguments: + Network - destination network + Node - destination node (needed in case of global client) + Route - buffer to hold reference to route block +Return Value: + Reference to destination interface CB + NULL if route it not found +******************************************************************* +--*/ +PINTERFACE_CB +FindDestination ( + IN ULONG Network, + IN PUCHAR Node, + OUT PFWD_ROUTE *Route + ) { + PFWD_ROUTE fwRoute; + PINTERFACE_CB ifCB; + RWCOOKIE cookie; + + AcquireReaderAccess (&RWLock, cookie); + if ((GlobalRoute!=NULL) + && (GlobalNetwork==Network)) { + if (Node!=NULL) { // If caller did not specify node, + // we can't find the route + union { + ULONGLONG Node64[1]; + UCHAR Node[6]; + } u; + u.Node64[0] = 0; + IPX_NODE_CPY (u.Node, Node); + + ifCB = LocateClientInterface (u.Node64, NULL); + if (ifCB!=NULL) { + AcquireRouteReference (GlobalRoute); + *Route = GlobalRoute; + AcquireInterfaceReference (ifCB); + } + else + *Route = NULL; + } + else { + ifCB = NULL; + *Route = NULL; + } + } + else { + *Route = fwRoute = LocateRoute (Network, NULL); + if (fwRoute!=NULL) { + AcquireRouteReference (fwRoute); + ifCB = fwRoute->FR_InterfaceReference; + AcquireInterfaceReference (ifCB); + } + else + ifCB = NULL; + } + ReleaseReaderAccess (&RWLock, cookie); + return ifCB; +} + +/*++ +******************************************************************* + A d d N B R o u t e s + +Routine Description: + Adds netbios names associated with interface to netbios + route hash table +Arguments: + ifCB - interface with which names are associated + Names - array of names + Count - number of names in the array + routeArray - buffer to place allocated array of routes +Return Value: + STATUS_SUCCESS - names were added ok + STATUS_UNSUCCESSFUL - one of the names is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + route array +******************************************************************* +--*/ +NTSTATUS +AddNBRoutes ( + PINTERFACE_CB ifCB, + FWD_NB_NAME Names[], + ULONG Count, + PNB_ROUTE *routeArray + ) { + PNB_ROUTE nbRoutes, *prev; + NTSTATUS status = STATUS_SUCCESS; + + nbRoutes = (PNB_ROUTE)ExAllocatePoolWithTag ( + NonPagedPool, sizeof (NB_ROUTE)*Count, FWD_POOL_TAG); + if (nbRoutes!=NULL) { + ULONG i; + + ExAcquireFastMutex (&WriterMutex); + + for (i=0; i<Count; i++) { + nbRoutes[i].NBR_Name128[0] = nbRoutes[i].NBR_Name128[1] = 0; + NB_NAME_CPY (nbRoutes[i].NBR_Name, &Names[i]); + // Check if route is already there + if (LocateNBRoute (nbRoutes[i].NBR_Name128, &prev)==NULL) { + nbRoutes[i].NBR_Destination = ifCB; + nbRoutes[i].NBR_Next = *prev; + *prev = &nbRoutes[i]; + IpxFwdDbgPrint (DBG_NBROUTE_TABLE, DBG_WARNING, + ("IpxFwd: Adding nb route for name %16s.\n",Names[i])); + } + else { + IpxFwdDbgPrint (DBG_NBROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Route for nb name %16s" + " is already in the table!\n", Names[i])); + break; + } + } + ExReleaseFastMutex (&WriterMutex); + if (i==Count) { + *routeArray = nbRoutes; + status = STATUS_SUCCESS; + + } + else { + status = STATUS_UNSUCCESSFUL; + DeleteNBRoutes (nbRoutes, i); + } + } + else { + IpxFwdDbgPrint (DBG_NBROUTE_TABLE, DBG_ERROR, + ("IpxFwd: Could allocate nb route array for if: %ld" + " (icb: %08lx).\n", ifCB->ICB_Index, ifCB)); + status = STATUS_INSUFFICIENT_RESOURCES; + } + return status; +} + +/*++ +******************************************************************* + D e l e t e N B R o u t e s + +Routine Description: + Deletes nb routes in the array from the route table and frees + the array +Arguments: + nbRoutes - array of routes + Count - number of routes in the array +Return Value: + STATUS_SUCCESS - route was deleted ok + STATUS_UNSUCCESSFUL - route is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteNBRoutes ( + PNB_ROUTE nbRoutes, + ULONG Count + ) { + PNB_ROUTE *prev; + NTSTATUS status = STATUS_SUCCESS; + ULONG i; + + ExAcquireFastMutex (&WriterMutex); + for (i=0; i<Count; i++) { + PNB_ROUTE cur = LocateNBRoute (nbRoutes[i].NBR_Name128, &prev); + ASSERT (cur==&nbRoutes[i]); + *prev = nbRoutes[i].NBR_Next; + IpxFwdDbgPrint (DBG_NBROUTE_TABLE, DBG_WARNING, + ("IpxFwd: Deleting nb route for name %16s.\n", + nbRoutes[i].NBR_Name)); + } + + WaitForAllReaders (&RWLock); + ExReleaseFastMutex (&WriterMutex); + + ExFreePool (nbRoutes); + + return STATUS_SUCCESS; +} + + +/*++ +******************************************************************* + F i n d N B D e s t i n a t i o n + +Routine Description: + Finds destination interface for nb name and + returns reference to its control block. +Arguments: + Name - name to look for +Return Value: + Reference to destination interface CB + NULL if route it not found +******************************************************************* +--*/ +PINTERFACE_CB +FindNBDestination ( + IN PUCHAR Name + ) { + PNB_ROUTE nbRoute; + PINTERFACE_CB ifCB; + RWCOOKIE cookie; + union { + ULONGLONG Name128[2]; + UCHAR Name[16]; + } u; + u.Name128[0] = u.Name128[1] = 0; + NB_NAME_CPY (u.Name, Name); + + AcquireReaderAccess (&RWLock, cookie); + nbRoute = LocateNBRoute (u.Name128, NULL); + if (nbRoute!=NULL) { + ifCB = nbRoute->NBR_Destination; + AcquireInterfaceReference (ifCB); + } + else + ifCB = NULL; + ReleaseReaderAccess (&RWLock, cookie); + return ifCB; +} + diff --git a/private/ntos/tdi/isn/fwd/tables.h b/private/ntos/tdi/isn/fwd/tables.h new file mode 100644 index 000000000..6f86e52a8 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/tables.h @@ -0,0 +1,708 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\tables.h + +Abstract: + IPX Forwarder Driver Tables + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#ifndef _IPXFWD_TABLES_ +#define _IPXFWD_TABLES_ + +// Ranges and defaults for registry configurable parameters +#define MIN_ROUTE_SEGMENT_SIZE PAGE_SIZE +#define MAX_ROUTE_SEGMENT_SIZE (PAGE_SIZE*8) +#define DEF_ROUTE_SEGMENT_SIZE MIN_ROUTE_SEGMENT_SIZE + +#define MIN_INTERFACE_HASH_SIZE 31 +#define MAX_INTERFACE_HASH_SIZE 257 +#define DEF_INTERFACE_HASH_SIZE MAX_INTERFACE_HASH_SIZE + +#define MIN_CLIENT_HASH_SIZE 31 +#define MAX_CLIENT_HASH_SIZE 257 +#define DEF_CLIENT_HASH_SIZE MAX_CLIENT_HASH_SIZE + +#define MIN_NB_ROUTE_HASH_SIZE 31 +#define MAX_NB_ROUTE_HASH_SIZE 1023 +#define DEF_NB_ROUTE_HASH_SIZE 257 + +#define MAX_SEND_PKTS_QUEUED 256 // No defined range + +#define NUM_INTERFACES_PER_SEGMENT 16 // Not configurable currently +#define NUM_NB_ROUTES_PER_SEGMENT 16 // Not configurable currently + + +// Special number reserved for routes that point to +// client on global net +#define GLOBAL_INTERFACE_REFERENCE ((PINTERFACE_CB)-1) + +// All types of WAN are emulated as ETHERNET by NDIS +#define WAN_PACKET_SIZE 1500 + + +#define INVALID_NETWORK_NUMBER 0xFFFFFFFF +#define INVALID_NIC_ID 0xFFFF + + +// Interface control block +struct _INTERFACE_CB; +typedef struct _INTERFACE_CB INTERFACE_CB, *PINTERFACE_CB; +struct _FWD_ROUTE; +typedef struct _FWD_ROUTE FWD_ROUTE, *PFWD_ROUTE; +struct _NB_ROUTE; +typedef struct _NB_ROUTE NB_ROUTE, *PNB_ROUTE; + +struct _FWD_ROUTE { + ULONG FR_Network; // Dest network + USHORT FR_TickCount; // Route params + USHORT FR_HopCount; // + UCHAR FR_NextHopAddress[6]; // Next hop router + PINTERFACE_CB FR_InterfaceReference; // Associated if CB + // or NULL if global + // network for clients + LONG FR_ReferenceCount; // Number of external + // references for this + // block (must keep the + // it till all of them + // are released + PFWD_ROUTE FR_Next; // Next route in the + // table +}; + +struct _INTERFACE_CB { + ULONG ICB_Index; // Unique ID + ULONG ICB_Network; // Network we boud to + union { + ULONGLONG ICB_ClientNode64[1];// For clients on + // global net (faster + // comparisons and + // hashing using 64 + // bit support) + UCHAR ICB_RemoteNode[6]; // Peer node for demand + // dial connections + }; + UCHAR ICB_LocalNode[6]; // Node we bound to + USHORT ICB_Flags; +#define FWD_IF_ENABLED 0x0001 +#define SET_IF_ENABLED(ifCB) ifCB->ICB_Flags |= FWD_IF_ENABLED; +#define SET_IF_DISABLED(ifCB) ifCB->ICB_Flags &= ~FWD_IF_ENABLED; +#define IS_IF_ENABLED(ifCB) (ifCB->ICB_Flags&FWD_IF_ENABLED) + +#define FWD_IF_CONNECTING 0x0002 +#define SET_IF_CONNECTING(ifCB) ifCB->ICB_Flags |= FWD_IF_CONNECTING; +#define SET_IF_NOT_CONNECTING(ifCB) ifCB->ICB_Flags &= ~FWD_IF_CONNECTING; +#define IS_IF_CONNECTING(ifCB) (ifCB->ICB_Flags&FWD_IF_CONNECTING) + USHORT ICB_NicId; // Nic id we bound to + UCHAR ICB_InterfaceType; + UCHAR ICB_NetbiosDeliver; + BOOLEAN ICB_NetbiosAccept; + + PNB_ROUTE ICB_NBRoutes; // Array of associated + // NB routes + ULONG ICB_NBRouteCount; // Number of nb routes + + LONGLONG ICB_DisconnectTime; // Time when if was disconnected + FWD_IF_STATS ICB_Stats; // Accumulated + PFWD_ROUTE ICB_CashedRoute; // MRU dest route + PINTERFACE_CB ICB_CashedInterface;// MRU dest if + NIC_HANDLE ICB_AdapterContext; // IPX stack supplied + PVOID ICB_FilterInContext; + PVOID ICB_FilterOutContext; + LONG ICB_PendingQuota; // Remaining quota of + // packets that can be + // pending on + // the interface + LIST_ENTRY ICB_ExternalQueue; // Queue of external (received) + // packets + LIST_ENTRY ICB_InternalQueue; // Queue of internal (send) + // requests +#if DBG + LIST_ENTRY ICB_InSendQueue; // packets being + // sent by ipx +#endif + INT ICB_PacketListId; // ID of the packet list + // (for the max frame size + // on this interface) + LIST_ENTRY ICB_IndexHashLink; // Link in interface idx hash + LIST_ENTRY ICB_ConnectionLink; // Link in connection queue + PNDIS_PACKET ICB_ConnectionPacket; // Packet that caused connection + // request + PUCHAR ICB_ConnectionData; // Pointer into packet to + // place where actual data + // (header) starts + PINTERFACE_CB ICB_NodeHashLink; // Link in client node hash + ULONG ICB_ReferenceCount; // Number of routes that + // point to this CB + KSPIN_LOCK ICB_Lock; // Protects state, + // queues +}; + +#define InitICB(ifCB,IfIndex,IfType,NbAccept,NbDeliver) { \ + (ifCB)->ICB_Index = IfIndex; \ + (ifCB)->ICB_Network = INVALID_NETWORK_NUMBER; \ + (ifCB)->ICB_Flags = 0; \ + (ifCB)->ICB_NicId = INVALID_NIC_ID; \ + (ifCB)->ICB_InterfaceType = IfType; \ + (ifCB)->ICB_NetbiosAccept = NbAccept; \ + (ifCB)->ICB_NetbiosDeliver = NbDeliver; \ + memset (&(ifCB)->ICB_Stats, 0, sizeof (FWD_IF_STATS));\ + KeInitializeSpinLock (&(ifCB)->ICB_Lock); \ + (ifCB)->ICB_CashedInterface = NULL; \ + (ifCB)->ICB_CashedRoute = NULL; \ + (ifCB)->ICB_ReferenceCount = 0; \ + (ifCB)->ICB_FilterInContext = NULL; \ + (ifCB)->ICB_FilterOutContext = NULL; \ + (ifCB)->ICB_ClientNode64[0] = 0; \ + (ifCB)->ICB_NBRoutes = NULL; \ + (ifCB)->ICB_PacketListId = -1; \ + InitializeListHead (&(ifCB)->ICB_InternalQueue); \ + InitializeListHead (&(ifCB)->ICB_ExternalQueue); \ + (ifCB)->ICB_PendingQuota = MaxSendPktsQueued; \ + switch ((ifCB)->ICB_InterfaceType) { \ + case FWD_IF_PERMANENT: \ + (ifCB)->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN;\ + break; \ + case FWD_IF_DEMAND_DIAL: \ + case FWD_IF_LOCAL_WORKSTATION: \ + case FWD_IF_REMOTE_WORKSTATION: \ + (ifCB)->ICB_Stats.OperationalState = FWD_OPER_STATE_SLEEPING;\ + KeQuerySystemTime ((PLARGE_INTEGER)&(ifCB)->ICB_DisconnectTime);\ + (ifCB)->ICB_DisconnectTime -= (LONGLONG)SpoofingTimeout*10000000;\ + break; \ + } \ +} + + +// Routes for netbios names (staticly seeded to reduce +// internet broadcast traffic) +struct _NB_ROUTE { + union { + ULONGLONG NBR_Name128[2]; + UCHAR NBR_Name[16]; // Netbios name of destination + }; + PINTERFACE_CB NBR_Destination; // Interface to send to + PNB_ROUTE NBR_Next; // Next route in the name list +}; + + +// List used to allocate packets destined to WAN interfaces +extern INT WanPacketListId; +// Max number of outstanding sends +extern ULONG MaxSendPktsQueued; + +// Segment sizes +extern ULONG RouteSegmentSize; +extern ULONG InterfaceSegmentSize; +extern ULONG NBNameSegementSize; + +// Sizes of hash tables +extern ULONG RouteHashSize; +extern ULONG InterfaceHashSize; +extern ULONG ClientHashSize; +extern ULONG NBRouteHashSize; + +// Number of global client network +extern ULONG GlobalNetwork; +// Interface reserved for internal network +extern PINTERFACE_CB InternalInterface; + +/*++ +******************************************************************* + C r e a t e T a b l e s + +Routine Description: + Allocates and intializes all hash tables and related structures +Arguments: + None +Return Value: + STATUS_SUCCESS - tables were created ok + STATUS_INSUFFICIENT_RESOURCES - resource allocation failed +******************************************************************* +--*/ +NTSTATUS +CreateTables ( + void + ); + +/*++ +******************************************************************* + D e l e t e T a b l e s + +Routine Description: + Releases resources allocated for all hash tables +Arguments: + None +Return Value: + STATUS_SUCCESS - tables were freed ok +******************************************************************* +--*/ +NTSTATUS +DeleteTables ( + void + ); + +/*++ +******************************************************************* + F r e e I n t e r f a c e + +Routine Description: + Releases memory allocated for interface to interface memory + zone. +Arguments: + fwRoute - route block to release +Return Value: + None +******************************************************************* +--*/ +VOID +FreeInterface ( + PINTERFACE_CB ifCB + ); + +/*++ +******************************************************************* + F r e e R o u t e + +Routine Description: + Releases memory allocated for route to route memory + zone. +Arguments: + fwRoute - route block to release +Return Value: + None +******************************************************************* +--*/ +VOID +FreeRoute ( + PFWD_ROUTE fwRoute + ); +/*++ +******************************************************************* + A c q u i r e I n t e r f a c e R e f e r e n c e + +Routine Description: + Increments refernce count of interface control block + ICB can't be freed until all references to it are released. + The caller of this routine should have already had a reference + to the interface or must hold an InterfaceLock +Arguments: + ifCB - interface control block to reference +Return Value: + None +******************************************************************* +--*/ +//VOID +//AcquireInterfaceReference ( +// PINTERFACE_CB ifCB +// ); +#if DBG +#define AcquireInterfaceReference(ifCB) \ + do { \ + ASSERTMSG ("Referenced ifCB is dead ", \ + InterlockedIncrement(&ifCB->ICB_ReferenceCount)>0); \ + } while (0) +#else +#define AcquireInterfaceReference(ifCB) \ + InterlockedIncrement(&ifCB->ICB_ReferenceCount) +#endif +/*++ +******************************************************************* + R e l e a s e I n t e r f a c e R e f e r e n c e + +Routine Description: + Decrements refernce count of interface control block +Arguments: + ifCB - interface control block to release +Return Value: + None +******************************************************************* +--*/ +//PINTERFACE_CB +//ReleaseInterfaceReference ( +// PINTERFACE_CB ifCB +// ); +// if it drops below 0, it has alredy been removed from the table +#define ReleaseInterfaceReference(ifCB) ( \ + (InterlockedDecrement (&ifCB->ICB_ReferenceCount)>=0) \ + ? ifCB \ + : (FreeInterface (ifCB), (ifCB = NULL)) \ +) + +/*++ +******************************************************************* + I n t e r f a c e C o n t e x t T o R e f e r e n c e + +Routine Description: + Verifies that context supplied by the IPX stack is a valid + interface block and is still bound to the adapter with which + it is associated in the IPX stack +Arguments: + ifCB - interface control block to reference + NicId - id of the adapter to which interface is bound +Return Value: + None +******************************************************************* +--*/ +//PINTERFACE_CB +//InterfaceContextToReference ( +// PVOID Context +// ); +#define InterfaceContextToReference(Context,NicId) ( \ + (InterlockedIncrement(&((PINTERFACE_CB)Context)->ICB_ReferenceCount)>0) \ + ? ((NicId==((PINTERFACE_CB)Context)->ICB_NicId) \ + ? (PINTERFACE_CB)Context \ + : (ReleaseInterfaceReference(((PINTERFACE_CB)Context)), NULL)) \ + : NULL \ + ) + +/*++ +******************************************************************* + G e t I n t e r f a c e R e f e r e n c e + +Routine Description: + Returns reference interface based on its index +Arguments: + InterfaceIndex - unique id of the interface +Return Value: + Pointer to interface control block if there is one in the table + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +GetInterfaceReference ( + ULONG InterfaceIndex + ); + + +/*++ +******************************************************************* + G e t N e x t I n t e r f a c e R e f e r e n c e + +Routine Description: + Returns reference to the next interface in the table + Reference to the provided interface is released +Arguments: + ifCB - interface to start with or NULL to start from the + beginning of the interface table +Return Value: + Pointer to interface control block if thare are any more interfaces + in the table + NULL otherwise +******************************************************************* +--*/ +PINTERFACE_CB +GetNextInterfaceReference ( + PINTERFACE_CB ifCB + ); + +/*++ +******************************************************************* + A d d I n t e r f a c e + +Routine Description: + Adds interface control block to the table. +Arguments: + InterfaceIndex - unique if of the interface + Info - interface paramters +Return Value: + STATUS_SUCCESS - interface added ok + STATUS_UNSUCCESSFULL - interface is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + interface CB +******************************************************************* +--*/ +NTSTATUS +AddInterface ( + ULONG InterfaceIndex, + UCHAR InterfaceType, + BOOLEAN NetbiosAccept, + UCHAR NetbiosDeliver + ); + +/*++ +******************************************************************* + A d d G l o b a l N e t C l i e n t + +Routine Description: + Adds interface control block to the table of + clients on the global network (should be done when + client connects) +Arguments: + ifCB - interface control block to add to the table +Return Value: + STATUS_SUCCESS - interface was added ok + STATUS_UNSUCCESSFULL - another interface with the same + node address is already in the table +******************************************************************* +--*/ +NTSTATUS +AddGlobalNetClient ( + PINTERFACE_CB ifCB + ); + +/*++ +******************************************************************* + D e l e t e G l o b a l N e t C l i e n t + +Routine Description: + Removes interface control block from the table of + clients on the global network (should be done when + client disconnects) +Arguments: + ifCB - interface control block to remove from the table +Return Value: + STATUS_SUCCESS - interface was removed ok +******************************************************************* +--*/ +NTSTATUS +DeleteGlobalNetClient ( + PINTERFACE_CB ifCB + ); + +/*++ +******************************************************************* + D e l e t e I n t e r f a c e + +Routine Description: + Deletes interface control block (the block is not actually + disposed of until all references to it are released). +Arguments: + InterfaceIndex - unique if of the interface +Return Value: + STATUS_SUCCESS - interface info retreived ok + STATUS_UNSUCCESSFULL - interface is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteInterface ( + ULONG InterfaceIndex + ); + +/*++ +******************************************************************* + A d d R o u t e + +Routine Description: + Adds route to the hash table and finds and stores the reference + to the associated interface control block in the route. +Arguments: + Network - route's destination network + NextHopAddress - mac address of next hop router if network is not + directly connected + TickCount - ticks to reach the destination net + HopCount - hopss to reach the destination net + InterfaceIndex - index of the associated interface (through which + packets destined to the network are to be sent) +Return Value: + STATUS_SUCCESS - route was added ok + STATUS_UNSUCCESSFUL - route is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + route block +******************************************************************* +--*/ +NTSTATUS +AddRoute ( + ULONG Network, + UCHAR *NextHopAddress, + USHORT TickCount, + USHORT HopCount, + ULONG InterfaceIndex + ); + +/*++ +******************************************************************* + D e l e t e R o u t e + +Routine Description: + Deletes route from the hash table and releases the reference + to the interface control block associated with the route. +Arguments: + Network - route's destination network +Return Value: + STATUS_SUCCESS - route was deleted ok + STATUS_UNSUCCESSFUL - route is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteRoute ( + ULONG Network + ); + +/*++ +******************************************************************* + U p d a t e R o u t e + +Routine Description: + Updates route in the hash table +Arguments: + Network - route's destination network + NextHopAddress - mac address of next hop router if network is not + directly connected + TickCount - ticks to reach the destination net + HopCount - hopss to reach the destination net + InterfaceIndex - index of the associated interface (through which + packets destined to the network are to be sent) +Return Value: + STATUS_SUCCESS - interface info retreived ok + STATUS_UNSUCCESSFUL - interface is not in the table +******************************************************************* +--*/ +NTSTATUS +UpdateRoute ( + ULONG Network, + UCHAR *NextHopAddress, + USHORT TickCount, + USHORT HopCount, + ULONG InterfaceIndex + ); + +/*++ +******************************************************************* + F i n d D e s t i n a t i o n + +Routine Description: + Finds destination interface for IPX address and + returns reference to its control block. +Arguments: + Network - destination network + Node - destination node (needed in case of global client) + Route - buffer to place route reference +Return Value: + Reference to destination interface CB + NULL if route it not found +******************************************************************* +--*/ +PINTERFACE_CB +FindDestination ( + IN ULONG Network, + IN PUCHAR Node, + OUT PFWD_ROUTE *Route + ); +/*++ +******************************************************************* + A c q u i r e R o u t e R e f e r e n c e + +Routine Description: + Increments refernce count of the route block + Route block can't be freed until all references to it are released. + The caller of this routine should have already had a reference + to the route or must hold an TableWriteLock +Arguments: + fwRoute - route block to reference +Return Value: + None +******************************************************************* +--*/ +//VOID +//AcquireRouteReference ( +// PFW+ROUTE fwRoute +// ); +#define AcquireRouteReference(fwRoute) \ + InterlockedIncrement(&fwRoute->FR_ReferenceCount) + + + +/*++ +******************************************************************* + R e l e a s e R o u t e R e f e r e n c e + +Routine Description: + Decrements refernce count of route block +Arguments: + fwRoute - route block to release +Return Value: + None +******************************************************************* +--*/ +//VOID +//ReleaseRouteReference ( +// PFW_ROUTE fwRoute +// ); +// if it drops below 0, it has alredy been removed from the table +#define ReleaseRouteReference(fwRoute) { \ + if (InterlockedDecrement (&fwRoute->FR_ReferenceCount)<0) { \ + FreeRoute (fwRoute); \ + fwRoute = NULL; \ + } \ +} + + +/*++ +******************************************************************* + A d d N B R o u t e s + +Routine Description: + Adds netbios names associated with interface to netbios + route hash table +Arguments: + ifCB - interface with which names are associated + Names - array of names + Count - number of names in the array + routeArray - buffer to place pointer to allocated array of routes +Return Value: + STATUS_SUCCESS - names were added ok + STATUS_UNSUCCESSFUL - one of the names is already in the table + STATUS_INSUFFICIENT_RESOURCES - can't allocate memory for + route array +******************************************************************* +--*/ +NTSTATUS +AddNBRoutes ( + PINTERFACE_CB ifCB, + FWD_NB_NAME Names[], + ULONG Count, + PNB_ROUTE *routeArray + ); + +/*++ +******************************************************************* + D e l e t e N B R o u t e s + +Routine Description: + Deletes nb routes in the array from the route table and frees + the array +Arguments: + nbRoutes - array of routes + Count - number of routes in the array +Return Value: + STATUS_SUCCESS - route was deleted ok + STATUS_UNSUCCESSFUL - route is not in the table +******************************************************************* +--*/ +NTSTATUS +DeleteNBRoutes ( + PNB_ROUTE nbRoutes, + ULONG Count + ); + +/*++ +******************************************************************* + F i n d N B D e s t i n a t i o n + +Routine Description: + Finds destination interface for nb name and + returns reference to its control block. +Arguments: + Name - name to look for +Return Value: + Reference to destination interface CB + NULL if route it not found +******************************************************************* +--*/ +PINTERFACE_CB +FindNBDestination ( + IN PUCHAR Name + ); +#endif diff --git a/private/ntos/tdi/isn/fwd/up/makefile b/private/ntos/tdi/isn/fwd/up/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/ntos/tdi/isn/fwd/up/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ntos/tdi/isn/fwd/up/sources b/private/ntos/tdi/isn/fwd/up/sources new file mode 100644 index 000000000..229bd8e34 --- /dev/null +++ b/private/ntos/tdi/isn/fwd/up/sources @@ -0,0 +1,31 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +UP_DRIVER=yes + +BINPLACE_FLAGS=$(BINPLACE_FLAGS) -d dump\up + +TARGETPATH=obj + +!include ..\sources.inc |