From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/tdi/isn/rip/driver.c | 1023 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1023 insertions(+) create mode 100644 private/ntos/tdi/isn/rip/driver.c (limited to 'private/ntos/tdi/isn/rip/driver.c') diff --git a/private/ntos/tdi/isn/rip/driver.c b/private/ntos/tdi/isn/rip/driver.c new file mode 100644 index 000000000..ece07e568 --- /dev/null +++ b/private/ntos/tdi/isn/rip/driver.c @@ -0,0 +1,1023 @@ +/*******************************************************************/ +/* Copyright(c) 1993 Microsoft Corporation */ +/*******************************************************************/ + +//*** +// +// Filename: driver.c +// +// Description: router driver entry point +// +// Author: Stefan Solomon (stefans) October 13, 1993. +// +// Revision History: +// +//*** + +#include +#include "rtdefs.h" +#include "driver.h" + +#if DBG +ULONG RouterDebugLevel = DEF_DBG_LEVEL; +#else +ULONG RouterDebugLevel; +#endif + +NTSTATUS +GetRouterParameters(PUNICODE_STRING); + +NTSTATUS +RouterDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID +RouterUnload( + IN PDRIVER_OBJECT DriverObject + ); + +NTSTATUS +RouterIoctl( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PVOID ioBuffer, + IN ULONG inputBufferLength, + IN ULONG outputBufferLength + ); + +USHORT dbgpktnr; + +NTSTATUS +IoctlSnapRoutes(VOID); + +NTSTATUS +IoctlGetNextRoute(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG sizep); + +NTSTATUS +IoctlCheckNetNumber(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlShowNicInfo(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlZeroNicStatistics(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlShowMemStatistics(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlGetWanInactivity(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlSetWanGlobalNet(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +NTSTATUS +IoctlDeleteWanGlobalAddress(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp); + +VOID +DeleteGlobalWanNet(VOID); + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +/*++ + +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 + +--*/ +{ + + PDEVICE_OBJECT deviceObject = NULL; + NTSTATUS ntStatus; + WCHAR deviceNameBuffer[] = L"\\Device\\Ipxroute"; + UNICODE_STRING deviceNameUnicodeString; + PIPX_INTERNAL_BIND_RIP_OUTPUT IpxBindBuffp = NULL; + + RtPrint(DBG_INIT, ("IPXROUTER: Entering DriverEntry\n")); + + // + // Create a non - EXCLUSIVE device object (more than 1 thread at a time + // can make requests to this device) + // + + RtlInitUnicodeString (&deviceNameUnicodeString, + deviceNameBuffer); + + ntStatus = IoCreateDevice (DriverObject, + 0, + &deviceNameUnicodeString, + FILE_DEVICE_IPXROUTER, + 0, + FALSE, + &deviceObject + ); + + if (NT_SUCCESS(ntStatus)) + { + // + // Create dispatch points for device control, create, close. + // + + DriverObject->MajorFunction[IRP_MJ_CREATE] = + DriverObject->MajorFunction[IRP_MJ_CLOSE] = + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RouterDispatch; + DriverObject->DriverUnload = RouterUnload; + + } + else + { + RtPrint (DBG_INIT, ("IPXROUTER: IoCreateDevice failed\n")); + goto failure_exit; + } + + // get registry configuration + ntStatus = GetRouterParameters(RegistryPath); + + if(!NT_SUCCESS(ntStatus)) { + + RtPrint (DBG_INIT, ("IPXROUTER: Error reading registry parameters\n")); + goto failure_exit; + } + + // Bind to the ipx driver. + // If succesful, it will point the argument to a paged pool buffered with + // the Ipx driver output data. This buffer has to be freed after usage. + // The buffer is freed in the RouterInit routine. + ntStatus = BindToIpxDriver(&IpxBindBuffp); + + if(!NT_SUCCESS(ntStatus)) { + + RtPrint (DBG_INIT, ("IPXROUTER: Bind to Ipx driver failed\n")); + goto failure_exit; + } + + // initialize the router + ntStatus = RouterInit(IpxBindBuffp); + + if(!NT_SUCCESS(ntStatus)) { + + RtPrint (DBG_INIT, ("IPXROUTER: Error initializing the router\n")); + goto failure_exit; + } + + // Start the global timer + StartRtTimer(); + + // all initialization done + RouterInitialized = TRUE; + + // Start the routing functionality + ntStatus = RouterStart(); + + if(!NT_SUCCESS(ntStatus)) { + + RtPrint (DBG_INIT, ("IPXROUTER: Error starting the router\n")); + goto failure_exit; + } + + // started OK + return STATUS_SUCCESS; + +failure_exit: + + IoDeleteDevice (DriverObject->DeviceObject); + return ntStatus; +} + + + +NTSTATUS +RouterDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +/*++ + +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: + + +--*/ +{ + PIO_STACK_LOCATION irpStack; + PVOID ioBuffer; + ULONG inputBufferLength; + ULONG outputBufferLength; + ULONG ioControlCode; + NTSTATUS ntStatus; + + + // + // Init to default settings- we only expect 1 type of + // IOCTL to roll through here, all others an error. + // + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + // + // Get a pointer to the current location in the Irp. This is where + // the function codes and parameters are located. + // + + irpStack = IoGetCurrentIrpStackLocation(Irp); + + + // + // Get the pointer to the input/output buffer and it's length + // + + ioBuffer = Irp->AssociatedIrp.SystemBuffer; + inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; + outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; + + + switch (irpStack->MajorFunction) + { + case IRP_MJ_CREATE: + + RtPrint(DBG_IOCTL, ("IPXROUTER: IRP_MJ_CREATE\n")); + dbgpktnr = 0x5000; + + break; + + case IRP_MJ_CLOSE: + + RtPrint(DBG_IOCTL, ("IPXROUTER: IRP_MJ_CLOSE\n")); + + break; + + case IRP_MJ_DEVICE_CONTROL: + + ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; + + switch (ioControlCode) + { + + case IOCTL_IPXROUTER_SNAPROUTES: + + Irp->IoStatus.Status = IoctlSnapRoutes(); + break; + + case IOCTL_IPXROUTER_GETNEXTROUTE: + + Irp->IoStatus.Status = IoctlGetNextRoute ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_CHECKNETNUMBER: + + Irp->IoStatus.Status = IoctlCheckNetNumber ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_SHOWNICINFO: + + Irp->IoStatus.Status = IoctlShowNicInfo ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_ZERONICSTATISTICS: + + Irp->IoStatus.Status = IoctlZeroNicStatistics ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_SHOWMEMSTATISTICS: + + Irp->IoStatus.Status = IoctlShowMemStatistics ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_GETWANINNACTIVITY: + + Irp->IoStatus.Status = IoctlGetWanInactivity ( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_SETWANGLOBALADDRESS: + + Irp->IoStatus.Status = IoctlSetWanGlobalNet( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + case IOCTL_IPXROUTER_DELETEWANGLOBALADDRESS: + + Irp->IoStatus.Status = IoctlDeleteWanGlobalAddress( + ioBuffer, + inputBufferLength, + outputBufferLength, + &Irp->IoStatus.Information + ); + break; + + default: + + RtPrint (DBG_INIT, ("IPXROUTER: unknown IRP_MJ_DEVICE_CONTROL\n")); + + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + + break; + + } + + break; + } + + + // + // DON'T get cute and try to use the status field of + // the irp in the return status. That IRP IS GONE as + // soon as you call IoCompleteRequest. + // + + ntStatus = Irp->IoStatus.Status; + + IoCompleteRequest(Irp, + IO_NO_INCREMENT); + + + // + // We never have pending operation so always return the status code. + // + + return ntStatus; +} + + + +VOID +RouterUnload( + IN PDRIVER_OBJECT DriverObject + ) +/*++ + +Routine Description: + + +Arguments: + + DriverObject - pointer to a driver object + +Return Value: + + +--*/ +{ + PNICCB niccbp; + USHORT i; + + RouterUnloading = TRUE; + + // stop the global timer + StopRtTimer(); + + // stop the rip timer. If the rip timer work item has already been scheduled + // wait until it completes + StopRipTimer(); + + // stop the routing functionality + RouterStop(); + + // close all nics + for(i=0; iNicClosedEvent, + Executive, + KernelMode, + FALSE, + (PLARGE_INTEGER)NULL + ); + } + } + + // free resources allocated by all nics + for(i=0; iNicClosedEvent, + Executive, + KernelMode, + FALSE, + (PLARGE_INTEGER)NULL + ); + } + } + + // at this point, all rcv pkts are returned to the pool and no new packets + // can be allocated. + // all send packets have been freed and no new send requests are permitted. + + // unbind from the IPX driver + UnbindFromIpxDriver(); + + // free the allocated memory + DestroyNicCbs(); + DestroyRcvPktPool(); + + // + // Delete the device object + // + + RtPrint(DBG_UNLOAD, ("IPXROUTER: unloading\n")); + + IoDeleteDevice (DriverObject->DeviceObject); +} + +LIST_ENTRY displayroutes; + +NTSTATUS +IoctlGetNextRoute(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + PIPX_ROUTE_ENTRY rtep, drtep; + PLIST_ENTRY lep; + + ASSERT(outbufflen >= sizeof(IPX_ROUTE_ENTRY)); + + if(IsListEmpty(&displayroutes)) { + + return STATUS_NO_MORE_ENTRIES; + } + + lep = RemoveHeadList(&displayroutes); + + rtep = CONTAINING_RECORD(lep, IPX_ROUTE_ENTRY, PRIVATE.Linkage); + drtep = (PIPX_ROUTE_ENTRY)iobufferp; + + *drtep = *rtep; + *bytestransfp = sizeof(IPX_ROUTE_ENTRY); + + ExFreePool(rtep); + + return STATUS_SUCCESS; +} + +NTSTATUS +IoctlSnapRoutes(VOID) +{ + PIPX_ROUTE_ENTRY rtep, drtep; + UINT i; + KIRQL oldirql; + + InitializeListHead(&displayroutes); + + for(i=0; iPRIVATE.Linkage); + + while((rtep = IpxGetNextRoute(i)) != NULL) { + + drtep = ExAllocatePool(NonPagedPool, sizeof(IPX_ROUTE_ENTRY)); + *drtep = *rtep; + InsertTailList(&displayroutes, &drtep->PRIVATE.Linkage); + } + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[i], oldirql); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +IoctlCheckNetNumber(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + UINT seg; + UCHAR CheckNetwork[4]; + KIRQL oldirql; + + ASSERT(outbufflen >= sizeof(ULONG)); + + memcpy(CheckNetwork, iobufferp, 4); + + // set the output to no-conflict + *(PULONG)iobufferp = 1; + + seg = IpxGetSegment(CheckNetwork); + + // LOCK THE ROUTING TABLE + ExAcquireSpinLock(&SegmentLocksTable[seg], &oldirql); + + if(IpxGetRoute(seg, CheckNetwork)) { + + *(PULONG)iobufferp = 0; + } + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + *bytestransfp = sizeof(ULONG); + return STATUS_SUCCESS; +} + +NTSTATUS +IoctlShowNicInfo(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + PNICCB niccbp; + USHORT index; + USHORT i; + PSHOW_NIC_INFO nisp; + + ASSERT(outbufflen >= sizeof(SHOW_NIC_INFO)); + + index = *(PUSHORT)iobufferp; + + for(i=0; iDeviceType == IPX_ROUTER_INVALID_DEVICE_TYPE) { + + // skip the non configured nic + continue; + } + + // configured nic + if(index--) { + + // skip this + continue; + } + + // configured nic and index == 0 + nisp = (PSHOW_NIC_INFO)iobufferp; + + nisp->NicId = niccbp->NicId; + + if(niccbp->DeviceType == NdisMediumWan) { + + nisp->DeviceType = SHOW_NIC_WAN; + } + else + { + nisp->DeviceType = SHOW_NIC_LAN; + } + + nisp->NicState = niccbp->NicState; + memcpy(nisp->Network, niccbp->Network, 4); + memcpy(nisp->Node, niccbp->Node, 6); + nisp->TickCount = niccbp->TickCount; + nisp->StatBadReceived = niccbp->StatBadReceived; + nisp->StatRipReceived = niccbp->StatRipReceived; + nisp->StatRipSent = niccbp->StatRipSent; + nisp->StatRoutedReceived = niccbp->StatRoutedReceived; + nisp->StatRoutedSent = niccbp->StatRoutedSent; + nisp->StatType20Received = niccbp->StatType20Received; + nisp->StatType20Sent = niccbp->StatType20Sent; + + *bytestransfp = sizeof(SHOW_NIC_INFO); + return STATUS_SUCCESS; + } + + return STATUS_NO_MORE_ENTRIES; +} + +NTSTATUS +IoctlZeroNicStatistics(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + PNICCB niccbp; + USHORT i; + + for(i=0; iDeviceType == IPX_ROUTER_INVALID_DEVICE_TYPE) { + + // skip the non configured nic + continue; + } + + // configured nic + ZeroNicStatistics(niccbp); + } + + StatMemPeakCount = 0; + + return STATUS_SUCCESS; +} + +NTSTATUS +IoctlShowMemStatistics(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + PSHOW_MEM_STAT smsp; + + smsp = (PSHOW_MEM_STAT)iobufferp; + + smsp->PeakPktAllocCount = StatMemPeakCount; + smsp->CurrentPktAllocCount = StatMemAllocCount; + smsp->CurrentPktPoolCount = RcvPktCount; + smsp->PacketSize = UlongMaxFrameSize * sizeof(ULONG); + + *bytestransfp = sizeof(SHOW_MEM_STAT); + + return STATUS_SUCCESS; +} + +NTSTATUS +IoctlGetWanInactivity(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + PGET_WAN_INNACTIVITY pgwi; + PNICCB niccbp; + USHORT i; + + pgwi = (PGET_WAN_INNACTIVITY)iobufferp; + + // check that we have a valid NicId + if(pgwi->NicId == 0xFFFF) { + + // get the valid NicId for this remote node + for(i=0; iDeviceType == NdisMediumWan) && + (niccbp->NicState == NIC_ACTIVE)) { + + // check if this is the one we look for + if(!memcmp(pgwi->RemoteNode, niccbp->RemoteNode, 6)) { + + // this is the one + pgwi->NicId = niccbp->NicId; + break; + } + } + } + + // check that we have found the nic + if(pgwi->NicId == 0xFFFF) { + + // ERROR: no nic coresponding to this remote node + goto WanInactivityExit; + } + } + else + { + // check that we have a valid handle indeed + if(pgwi->NicId < MaximumNicCount) { + + // Nic id looks valid + niccbp = NicCbPtrTab[pgwi->NicId]; + + if(memcmp(pgwi->RemoteNode, niccbp->RemoteNode, 6)) { + + // ERROR: this nic id has a wrong remote node + // reset the nic id to indicate the error + pgwi->NicId = 0xFFFF; + + goto WanInactivityExit; + } + } + else + { + // ERROR: wrong nic id -> too big + // reset the nicid to indicate the error + pgwi->NicId = 0xFFFF; + + goto WanInactivityExit; + } + } + + // we got the correct nic id + pgwi->WanInnactivityCount = IpxGetWanInactivity(niccbp->NicId); + +WanInactivityExit: + + *bytestransfp = sizeof(GET_WAN_INNACTIVITY); + + return STATUS_SUCCESS; +} + +//*** +// +// Function: IoctlSetWanGlobalNet +// +// Descr: Called by ipxcp when the dll gets loaded, if configured with +// global wan net option. +// It generates a net number using the last four bytes of the address of +// the first lan net, checks that the net number is unique and then adds it +// to the routing table and marks the route as wan global. +// Returns the wan global net number to the caller. +// +//*** + +NTSTATUS +IoctlSetWanGlobalNet(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + UCHAR wnet[4]; // wan global net number + USHORT i; + PNICCB niccbp; + UINT seg; + KIRQL oldirql; + PIPX_ROUTE_ENTRY rtep; + PSET_WAN_GLOBAL_ADDRESS wgap; + BOOLEAN statconfig; // TRUE -> static net config + // FALSE -> dynamic net config + ULONG wnetnumber; + LARGE_INTEGER tickcount; + + // check if we have already been called to configure the router for a WanGlobalNet. + // If this has hapened, clean up before seting the new wan global network number + DeleteGlobalWanNet(); + + // get the wnet desired value from the ioctl request + wgap = (PSET_WAN_GLOBAL_ADDRESS)iobufferp; + memcpy(wnet, wgap->WanGlobalNetwork, 4); + + // assume success and set the final error code + wgap->ErrorCode = 0; + *bytestransfp = sizeof(SET_WAN_GLOBAL_ADDRESS); + + // check if this is a static value or dynamic config is wanted + if(!memcmp(wnet, nulladdress, 4)) { + + // wnet is null -> we are requested to make the address + // get the node address of the first LAN card and make the net address with its last + // four bytes + + // Put the tick count value in case we don't find a LAN card ! + KeQueryTickCount(&tickcount); + PUTULONG2LONG(wnet, tickcount.LowPart); + + statconfig = FALSE; + + for(i=0; iDeviceType != IPX_ROUTER_INVALID_DEVICE_TYPE) && // configured nic + (niccbp->DeviceType != NdisMediumWan)) { // LAN nic + + memcpy(wnet, &niccbp->Node[2], 4); + break; + } + } + + } + else + { + // wnet is the number the user requests + statconfig = TRUE; + } + + // Check that the static/dynamic wan global net nr is a unique net number + seg = IpxGetSegment(wnet); + + // LOCK THE ROUTING TABLE + ExAcquireSpinLock(&SegmentLocksTable[seg], &oldirql); + + while(IpxGetRoute(seg, wnet)) { + + // the network number exists -> we are allowed to resolve the conflict only in + // the case we are configuring dynamically + if(!statconfig) { + + // increment the number and try again + GETLONG2ULONG(&wnetnumber, wnet); + wnetnumber++; + PUTULONG2LONG(wnet, wnetnumber); + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + seg = IpxGetSegment(wnet); + // RELOCK THE ROUTING TABLE + ExAcquireSpinLock(&SegmentLocksTable[seg], &oldirql); + } + else + { + // return and report the error + wgap->ErrorCode = ERROR_IPXCP_NETWORK_NUMBER_IN_USE; + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + return STATUS_SUCCESS; + } + } + + // there is no such net, add it + if((rtep = ExAllocatePool(NonPagedPool, sizeof(IPX_ROUTE_ENTRY))) == NULL) { + + // can't allocate the route entry -> return + wgap->ErrorCode = ERROR_IPXCP_MEMORY_ALLOCATION_FAILURE; + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + return STATUS_SUCCESS; + } + + // set up the new route entry + memcpy(rtep->Network, wnet, IPX_NET_LEN); + + rtep->NicId = 0xFFFE; // that's what we use for the global wan net + + memcpy(rtep->NextRouter, nulladdress, IPX_NODE_LEN); + rtep->Flags = IPX_ROUTER_LOCAL_NET | IPX_ROUTER_PERMANENT_ENTRY | IPX_ROUTER_GLOBAL_WAN_NET; + rtep->Timer = 0; // TTL of this route entry is 3 min + rtep->Segment = seg; + rtep->TickCount = DEFAULT_WAN_GLOBAL_NET_TICKCOUNT; + rtep->HopCount = 1; + + InitializeListHead(&rtep->AlternateRoute); + + RtPrint(DBG_INIT, ("IpxRouter: IoctlSetWanGlobalNet: Adding route entry for global WAN net %x-%x-%x-%x \n", + wnet[0], + wnet[1], + wnet[2], + wnet[3])); + + IpxAddRoute(seg, rtep); + + // set our global variable to indicate we have a global wan net + WanGlobalNetworkEnabled = TRUE; + memcpy(WanGlobalNetwork, rtep->Network, 4); + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + // Broadcast the new route entry on all the LAN segments + BroadcastWanNetUpdate(rtep, NULL, NULL); + + // copy the net and return + memcpy(wgap->WanGlobalNetwork, wnet, IPX_NET_LEN); + + return STATUS_SUCCESS; +} + +VOID +DeleteGlobalWanNet(VOID) +{ + UINT seg; + KIRQL oldirql; + PIPX_ROUTE_ENTRY rtep; + + // if configured with a wan global network, delete and free the route entry now + if(WanGlobalNetworkEnabled) { + + WanGlobalNetworkEnabled = FALSE; + + seg = IpxGetSegment(WanGlobalNetwork); + + // LOCK THE ROUTING TABLE + ExAcquireSpinLock(&SegmentLocksTable[seg], &oldirql); + + if(rtep = IpxGetRoute(seg, WanGlobalNetwork)) { + + IpxDeleteRoute(seg, rtep); + + RtPrint(DBG_INIT, ("IpxRouter: DeleteGlobalWanNet: Deleted wan global net route entry\n")); + } + + // UNLOCK THE ROUTING TABLE + ExReleaseSpinLock(&SegmentLocksTable[seg], oldirql); + + if(rtep) { + + ExFreePool(rtep); + } + } +} + +NTSTATUS +IoctlDeleteWanGlobalAddress(PVOID iobufferp, + ULONG inbufflen, + ULONG outbufflen, + PULONG bytestransfp) +{ + // If we are called with this IOCtl, it means IPXCP has been reconfigured to + // to use static/dynamic wan nets allocation and NOT the global wan net. + // If the router had been configured previously for the global wan net, delete the + // net and reconfigure now. + DeleteGlobalWanNet(); + + return STATUS_SUCCESS; +} -- cgit v1.2.3