Send delayed ACKs after 200ms instead of 2500ms
[reactos.git] / reactos / drivers / lib / ip / network / interface.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/interface.c
5 * PURPOSE: Convenient abstraction for getting and setting information
6 * in IP_INTERFACE.
7 * PROGRAMMERS: Art Yerkes
8 * REVISIONS:
9 * CSH 01/08-2000 Created
10 */
11
12 #include "precomp.h"
13
14 NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface,
15 ULONG TargetType,
16 PULONG Address ) {
17 switch( TargetType ) {
18 case ADE_UNICAST:
19 *Address = Interface->Unicast.Address.IPv4Address;
20 break;
21
22 case ADE_ADDRMASK:
23 *Address = Interface->Netmask.Address.IPv4Address;
24 break;
25
26 case ADE_BROADCAST:
27 *Address = Interface->Broadcast.Address.IPv4Address;
28 break;
29
30 case ADE_POINTOPOINT:
31 *Address = Interface->PointToPoint.Address.IPv4Address;
32 break;
33
34 default:
35 return STATUS_UNSUCCESSFUL;
36 }
37
38 return STATUS_SUCCESS;
39 }
40
41 UINT CountInterfaces() {
42 DWORD Count = 0;
43 KIRQL OldIrql;
44 IF_LIST_ITER(CurrentIF);
45
46 TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
47
48 ForEachInterface(CurrentIF) {
49 Count++;
50 } EndFor(CurrentIF);
51
52 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
53
54 return Count;
55 }
56
57 NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ) {
58 PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
59
60 *Speed = IF->Speed;
61
62 return STATUS_SUCCESS;
63 }
64
65 NTSTATUS GetInterfaceName( PIP_INTERFACE Interface,
66 PCHAR NameBuffer,
67 UINT Len ) {
68 ULONG ResultSize = 0;
69 NTSTATUS Status =
70 RtlUnicodeToMultiByteN( NameBuffer,
71 Len,
72 &ResultSize,
73 Interface->Name.Buffer,
74 Interface->Name.Length );
75
76 if( NT_SUCCESS(Status) )
77 NameBuffer[ResultSize] = 0;
78 else
79 NameBuffer[0] = 0;
80
81 return Status;
82 }
83
84 /*
85 * FUNCTION: Locates and returns an address entry using IPv4 adress as argument
86 * ARGUMENTS:
87 * Address = Raw IPv4 address
88 * RETURNS:
89 * Pointer to address entry if found, NULL if not found
90 * NOTES:
91 * Only unicast addresses are considered.
92 * If found, the address is referenced
93 */
94 BOOLEAN AddrLocateADEv4(
95 IPv4_RAW_ADDRESS MatchAddress, PIP_ADDRESS Address)
96 {
97 KIRQL OldIrql;
98 BOOLEAN Matched = FALSE;
99 IF_LIST_ITER(CurrentIF);
100
101 TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
102
103 ForEachInterface(CurrentIF) {
104 if( AddrIsEqualIPv4( &CurrentIF->Unicast, MatchAddress ) ) {
105 Address->Address.IPv4Address = MatchAddress;
106 Matched = TRUE; break;
107 }
108 } EndFor(CurrentIF);
109
110 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
111
112 return Matched;
113 }
114
115 BOOLEAN IPGetDefaultAddress( PIP_ADDRESS Address ) {
116 KIRQL OldIrql;
117 BOOLEAN Matched = FALSE;
118 IF_LIST_ITER(CurrentIF);
119
120 TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
121
122 /* Find the first 'real' interface */
123 ForEachInterface(CurrentIF) {
124 if( CurrentIF->Context ) {
125 *Address = CurrentIF->Unicast;
126 Matched = TRUE; break;
127 }
128 } EndFor(CurrentIF);
129
130 /* Not matched, use the first one */
131 if( !Matched ) {
132 ForEachInterface(CurrentIF) {
133 *Address = CurrentIF->Unicast;
134 Matched = TRUE; break;
135 } EndFor(CurrentIF);
136 }
137
138 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
139
140 return Matched;
141 }
142
143 BOOLEAN HasPrefix(
144 PIP_ADDRESS Address,
145 PIP_ADDRESS Prefix,
146 UINT Length)
147 /*
148 * FUNCTION: Determines wether an address has an given prefix
149 * ARGUMENTS:
150 * Address = Pointer to address to use
151 * Prefix = Pointer to prefix to check for
152 * Length = Length of prefix
153 * RETURNS:
154 * TRUE if the address has the prefix, FALSE if not
155 * NOTES:
156 * The two addresses must be of the same type
157 */
158 {
159 PUCHAR pAddress = (PUCHAR)&Address->Address;
160 PUCHAR pPrefix = (PUCHAR)&Prefix->Address;
161
162 TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length));
163
164 #if 0
165 TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) Prefix (%s).\n",
166 A2S(Address), A2S(Prefix)));
167 #endif
168
169 /* Check that initial integral bytes match */
170 while (Length > 8) {
171 if (*pAddress++ != *pPrefix++)
172 return FALSE;
173 Length -= 8;
174 }
175
176 /* Check any remaining bits */
177 if ((Length > 0) && ((*pAddress >> (8 - Length)) != (*pPrefix >> (8 - Length))))
178 return FALSE;
179
180 return TRUE;
181 }
182
183 PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
184 /*
185 * FUNCTION: Checks all on-link prefixes to find out if an address is on-link
186 * ARGUMENTS:
187 * Address = Pointer to address to check
188 * RETURNS:
189 * Pointer to interface if address is on-link, NULL if not
190 */
191 {
192 KIRQL OldIrql;
193 IF_LIST_ITER(CurrentIF);
194
195 TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X)\n", Address));
196 TI_DbgPrint(DEBUG_ROUTER, ("Address (%s)\n", A2S(Address)));
197
198 TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
199
200 ForEachInterface(CurrentIF) {
201 if (HasPrefix(Address, &CurrentIF->Unicast,
202 AddrCountPrefixBits(&CurrentIF->Netmask))) {
203 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
204 return CurrentIF;
205 }
206 } EndFor(CurrentIF);
207
208 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
209
210 return NULL;
211 }
212
213 NTSTATUS GetInterfaceConnectionStatus
214 ( PIP_INTERFACE Interface, PDWORD Result ) {
215 NTSTATUS Status = TcpipLanGetDwordOid
216 ( Interface, OID_GEN_HARDWARE_STATUS, Result );
217 if( NT_SUCCESS(Status) ) switch( *Result ) {
218 case NdisHardwareStatusReady:
219 *Result = MIB_IF_OPER_STATUS_OPERATIONAL;
220 break;
221 case NdisHardwareStatusInitializing:
222 *Result = MIB_IF_OPER_STATUS_CONNECTING;
223 break;
224 case NdisHardwareStatusReset:
225 *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
226 break;
227 case NdisHardwareStatusNotReady:
228 *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
229 break;
230 case NdisHardwareStatusClosing:
231 default:
232 *Result = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
233 break;
234 }
235 return Status;
236 }