mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 15:10:53 +00:00
110 lines
3.2 KiB
C
110 lines
3.2 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS TCP/IP protocol driver
|
|
* FILE: tcpip/ports.c
|
|
* PURPOSE: Port allocation
|
|
* PROGRAMMERS: arty (ayerkes@speakeasy.net)
|
|
* REVISIONS:
|
|
* arty 20041114 Created
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
NTSTATUS PortsStartup( PPORT_SET PortSet,
|
|
UINT StartingPort,
|
|
UINT PortsToManage ) {
|
|
PortSet->StartingPort = StartingPort;
|
|
PortSet->PortsToOversee = PortsToManage;
|
|
|
|
PortSet->ProtoBitBuffer =
|
|
ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
|
|
PORT_SET_TAG );
|
|
if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
|
|
RtlInitializeBitMap( &PortSet->ProtoBitmap,
|
|
PortSet->ProtoBitBuffer,
|
|
PortSet->PortsToOversee );
|
|
RtlClearAllBits( &PortSet->ProtoBitmap );
|
|
KeInitializeSpinLock( &PortSet->Lock );
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID PortsShutdown( PPORT_SET PortSet ) {
|
|
ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG );
|
|
}
|
|
|
|
VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
|
|
KIRQL OldIrql;
|
|
|
|
Port = htons(Port);
|
|
ASSERT(Port >= PortSet->StartingPort);
|
|
ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
|
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
|
RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
}
|
|
|
|
BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
|
|
BOOLEAN Clear;
|
|
KIRQL OldIrql;
|
|
|
|
Port = htons(Port);
|
|
|
|
if ((Port < PortSet->StartingPort) ||
|
|
(Port >= PortSet->StartingPort + PortSet->PortsToOversee))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
Port -= PortSet->StartingPort;
|
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
|
Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 );
|
|
if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 );
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
|
|
return Clear;
|
|
}
|
|
|
|
ULONG AllocateAnyPort( PPORT_SET PortSet ) {
|
|
ULONG AllocatedPort;
|
|
KIRQL OldIrql;
|
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
|
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 );
|
|
if( AllocatedPort != (ULONG)-1 ) {
|
|
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
|
|
AllocatedPort += PortSet->StartingPort;
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
return htons(AllocatedPort);
|
|
}
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
|
|
return -1;
|
|
}
|
|
|
|
ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
|
|
ULONG AllocatedPort;
|
|
KIRQL OldIrql;
|
|
|
|
if ((Lowest < PortSet->StartingPort) ||
|
|
(Highest >= PortSet->StartingPort + PortSet->PortsToOversee))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
Lowest -= PortSet->StartingPort;
|
|
Highest -= PortSet->StartingPort;
|
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
|
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Lowest );
|
|
if( AllocatedPort != (ULONG)-1 && AllocatedPort <= Highest) {
|
|
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
|
|
AllocatedPort += PortSet->StartingPort;
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
return htons(AllocatedPort);
|
|
}
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
|
|
|
return -1;
|
|
}
|