2004-11-14 21:28:21 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2008-09-06 22:21:56 +00:00
|
|
|
NTSTATUS PortsStartup( PPORT_SET PortSet,
|
2004-11-14 21:28:21 +00:00
|
|
|
UINT StartingPort,
|
|
|
|
UINT PortsToManage ) {
|
|
|
|
PortSet->StartingPort = StartingPort;
|
|
|
|
PortSet->PortsToOversee = PortsToManage;
|
2008-10-27 05:16:14 +00:00
|
|
|
|
2005-05-08 02:16:32 +00:00
|
|
|
PortSet->ProtoBitBuffer =
|
2009-11-21 23:53:43 +00:00
|
|
|
ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
|
|
|
|
PORT_SET_TAG );
|
2008-09-06 22:21:56 +00:00
|
|
|
if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
|
2005-05-08 02:16:32 +00:00
|
|
|
RtlInitializeBitMap( &PortSet->ProtoBitmap,
|
2004-11-14 21:28:21 +00:00
|
|
|
PortSet->ProtoBitBuffer,
|
|
|
|
PortSet->PortsToOversee );
|
2005-03-16 21:03:51 +00:00
|
|
|
RtlClearAllBits( &PortSet->ProtoBitmap );
|
2010-01-08 18:21:52 +00:00
|
|
|
KeInitializeSpinLock( &PortSet->Lock );
|
2008-09-06 22:21:56 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-11-14 21:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID PortsShutdown( PPORT_SET PortSet ) {
|
2009-11-21 23:53:43 +00:00
|
|
|
ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG );
|
2004-11-14 21:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
|
2010-01-08 18:21:52 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
|
2005-03-13 21:41:44 +00:00
|
|
|
Port = htons(Port);
|
2005-03-16 21:03:51 +00:00
|
|
|
ASSERT(Port >= PortSet->StartingPort);
|
|
|
|
ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
|
2009-08-04 23:35:50 +00:00
|
|
|
|
2010-01-08 18:21:52 +00:00
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
2005-03-16 21:03:51 +00:00
|
|
|
RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2004-11-14 21:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
|
|
|
|
BOOLEAN Clear;
|
2010-01-08 18:21:52 +00:00
|
|
|
KIRQL OldIrql;
|
2004-11-14 21:28:21 +00:00
|
|
|
|
2005-03-13 21:41:44 +00:00
|
|
|
Port = htons(Port);
|
2008-10-27 05:16:14 +00:00
|
|
|
|
|
|
|
if ((Port < PortSet->StartingPort) ||
|
|
|
|
(Port >= PortSet->StartingPort + PortSet->PortsToOversee))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-11-14 21:28:21 +00:00
|
|
|
Port -= PortSet->StartingPort;
|
|
|
|
|
2010-01-08 18:21:52 +00:00
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
2004-11-14 21:28:21 +00:00
|
|
|
Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 );
|
|
|
|
if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 );
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2004-11-14 21:28:21 +00:00
|
|
|
|
|
|
|
return Clear;
|
|
|
|
}
|
|
|
|
|
|
|
|
ULONG AllocateAnyPort( PPORT_SET PortSet ) {
|
|
|
|
ULONG AllocatedPort;
|
2010-01-08 18:21:52 +00:00
|
|
|
KIRQL OldIrql;
|
2004-11-14 21:28:21 +00:00
|
|
|
|
2010-01-08 18:21:52 +00:00
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
2008-10-27 05:16:14 +00:00
|
|
|
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 );
|
2004-11-14 21:28:21 +00:00
|
|
|
if( AllocatedPort != (ULONG)-1 ) {
|
2004-12-11 16:36:06 +00:00
|
|
|
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
|
|
|
|
AllocatedPort += PortSet->StartingPort;
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2008-10-27 05:16:14 +00:00
|
|
|
return htons(AllocatedPort);
|
2004-12-11 16:36:06 +00:00
|
|
|
}
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2004-12-11 16:36:06 +00:00
|
|
|
|
2008-10-27 05:16:14 +00:00
|
|
|
return -1;
|
2004-12-11 16:36:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
|
|
|
|
ULONG AllocatedPort;
|
2010-01-08 18:21:52 +00:00
|
|
|
KIRQL OldIrql;
|
2004-12-11 16:36:06 +00:00
|
|
|
|
2008-10-27 05:16:14 +00:00
|
|
|
if ((Lowest < PortSet->StartingPort) ||
|
|
|
|
(Highest >= PortSet->StartingPort + PortSet->PortsToOversee))
|
|
|
|
{
|
|
|
|
return -1;
|
2005-12-22 11:44:16 +00:00
|
|
|
}
|
2008-10-27 05:16:14 +00:00
|
|
|
|
2004-12-11 16:36:06 +00:00
|
|
|
Lowest -= PortSet->StartingPort;
|
|
|
|
Highest -= PortSet->StartingPort;
|
|
|
|
|
2010-01-08 18:21:52 +00:00
|
|
|
KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
|
2008-10-27 05:16:14 +00:00
|
|
|
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Lowest );
|
|
|
|
if( AllocatedPort != (ULONG)-1 && AllocatedPort <= Highest) {
|
2004-12-11 16:36:06 +00:00
|
|
|
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
|
2004-11-14 21:28:21 +00:00
|
|
|
AllocatedPort += PortSet->StartingPort;
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2008-10-27 05:16:14 +00:00
|
|
|
return htons(AllocatedPort);
|
2004-11-14 21:28:21 +00:00
|
|
|
}
|
2010-01-08 18:21:52 +00:00
|
|
|
KeReleaseSpinLock( &PortSet->Lock, OldIrql );
|
2004-11-14 21:28:21 +00:00
|
|
|
|
2008-10-27 05:16:14 +00:00
|
|
|
return -1;
|
2004-11-14 21:28:21 +00:00
|
|
|
}
|