- Revert 44301
[reactos.git] / lib / drivers / ip / network / ports.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/ports.c
5 * PURPOSE: Port allocation
6 * PROGRAMMERS: arty (ayerkes@speakeasy.net)
7 * REVISIONS:
8 * arty 20041114 Created
9 */
10
11 #include "precomp.h"
12
13 NTSTATUS PortsStartup( PPORT_SET PortSet,
14 UINT StartingPort,
15 UINT PortsToManage ) {
16 PortSet->StartingPort = StartingPort;
17 PortSet->PortsToOversee = PortsToManage;
18
19 PortSet->ProtoBitBuffer =
20 ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
21 PORT_SET_TAG );
22 if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
23 RtlInitializeBitMap( &PortSet->ProtoBitmap,
24 PortSet->ProtoBitBuffer,
25 PortSet->PortsToOversee );
26 RtlClearAllBits( &PortSet->ProtoBitmap );
27 ExInitializeFastMutex( &PortSet->Mutex );
28 return STATUS_SUCCESS;
29 }
30
31 VOID PortsShutdown( PPORT_SET PortSet ) {
32 ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG );
33 }
34
35 VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
36 Port = htons(Port);
37 ASSERT(Port >= PortSet->StartingPort);
38 ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
39
40 ExAcquireFastMutex( &PortSet->Mutex );
41 RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
42 ExReleaseFastMutex( &PortSet->Mutex );
43 }
44
45 BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
46 BOOLEAN Clear;
47
48 Port = htons(Port);
49
50 if ((Port < PortSet->StartingPort) ||
51 (Port >= PortSet->StartingPort + PortSet->PortsToOversee))
52 {
53 return FALSE;
54 }
55
56 Port -= PortSet->StartingPort;
57
58 ExAcquireFastMutex( &PortSet->Mutex );
59 Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 );
60 if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 );
61 ExReleaseFastMutex( &PortSet->Mutex );
62
63 return Clear;
64 }
65
66 ULONG AllocateAnyPort( PPORT_SET PortSet ) {
67 ULONG AllocatedPort;
68
69 ExAcquireFastMutex( &PortSet->Mutex );
70 AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 );
71 if( AllocatedPort != (ULONG)-1 ) {
72 RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
73 AllocatedPort += PortSet->StartingPort;
74 ExReleaseFastMutex( &PortSet->Mutex );
75 return htons(AllocatedPort);
76 }
77 ExReleaseFastMutex( &PortSet->Mutex );
78
79 return -1;
80 }
81
82 ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
83 ULONG AllocatedPort;
84
85 if ((Lowest < PortSet->StartingPort) ||
86 (Highest >= PortSet->StartingPort + PortSet->PortsToOversee))
87 {
88 return -1;
89 }
90
91 Lowest -= PortSet->StartingPort;
92 Highest -= PortSet->StartingPort;
93
94 ExAcquireFastMutex( &PortSet->Mutex );
95 AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Lowest );
96 if( AllocatedPort != (ULONG)-1 && AllocatedPort <= Highest) {
97 RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
98 AllocatedPort += PortSet->StartingPort;
99 ExReleaseFastMutex( &PortSet->Mutex );
100 return htons(AllocatedPort);
101 }
102 ExReleaseFastMutex( &PortSet->Mutex );
103
104 return -1;
105 }