ReactOS  0.4.14-dev-614-gbfd8a84
interface.c
Go to the documentation of this file.
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 #include <ntifs.h>
15 #include <ipifcons.h>
16 
18 
20  ULONG TargetType,
21  PULONG Address ) {
22  switch( TargetType ) {
23  case ADE_UNICAST:
24  *Address = Interface->Unicast.Address.IPv4Address;
25  break;
26 
27  case ADE_ADDRMASK:
28  *Address = Interface->Netmask.Address.IPv4Address;
29  break;
30 
31  case ADE_BROADCAST:
32  *Address = Interface->Broadcast.Address.IPv4Address;
33  break;
34 
35  case ADE_POINTOPOINT:
36  *Address = Interface->PointToPoint.Address.IPv4Address;
37  break;
38 
39  default:
40  return STATUS_UNSUCCESSFUL;
41  }
42 
43  return STATUS_SUCCESS;
44 }
45 
47  ULONG Count = 0;
48  KIRQL OldIrql;
49  IF_LIST_ITER(CurrentIF);
50 
52 
53  ForEachInterface(CurrentIF) {
54  Count++;
55  } EndFor(CurrentIF);
56 
58 
59  return Count;
60 }
61 
64 
65  *Speed = IF->Speed;
66 
67  return STATUS_SUCCESS;
68 }
69 
71  PCHAR NameBuffer,
72  UINT Len ) {
73  ULONG ResultSize = 0;
75  RtlUnicodeToMultiByteN( NameBuffer,
76  Len,
77  &ResultSize,
78  Interface->Name.Buffer,
79  Interface->Name.Length );
80 
81  if( NT_SUCCESS(Status) )
82  NameBuffer[ResultSize] = 0;
83  else
84  NameBuffer[0] = 0;
85 
86  return Status;
87 }
88 
90  PIP_ADDRESS MatchAddress)
91 {
92  KIRQL OldIrql;
93  PIP_INTERFACE RetIF = NULL;
94  IF_LIST_ITER(CurrentIF);
95 
97 
98  ForEachInterface(CurrentIF) {
99  if( AddrIsEqual( &CurrentIF->Unicast, MatchAddress ) ||
100  AddrIsEqual( &CurrentIF->Broadcast, MatchAddress ) ) {
101  RetIF = CurrentIF;
102  break;
103  }
104  } EndFor(CurrentIF);
105 
107 
108  return RetIF;
109 }
110 
114  UINT Length)
115 /*
116  * FUNCTION: Determines wether an address has an given prefix
117  * ARGUMENTS:
118  * Address = Pointer to address to use
119  * Prefix = Pointer to prefix to check for
120  * Length = Length of prefix
121  * RETURNS:
122  * TRUE if the address has the prefix, FALSE if not
123  * NOTES:
124  * The two addresses must be of the same type
125  */
126 {
127  PUCHAR pAddress = (PUCHAR)&Address->Address;
128  PUCHAR pPrefix = (PUCHAR)&Prefix->Address;
129 
130  TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length));
131 
132 #if 0
133  TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) Prefix (%s).\n",
134  A2S(Address), A2S(Prefix)));
135 #endif
136 
137  /* Don't report matches for empty prefixes */
138  if (Length == 0) {
139  return FALSE;
140  }
141 
142  /* Check that initial integral bytes match */
143  while (Length > 8) {
144  if (*pAddress++ != *pPrefix++)
145  return FALSE;
146  Length -= 8;
147  }
148 
149  /* Check any remaining bits */
150  if ((Length > 0) && ((*pAddress >> (8 - Length)) != (*pPrefix >> (8 - Length))))
151  return FALSE;
152 
153  return TRUE;
154 }
155 
157 {
158  KIRQL OldIrql;
159  ULONG Index = 0;
160  ULONG IfStatus;
161 
162  IF_LIST_ITER(CurrentIF);
163 
165  /* DHCP hack: Always return the adapter without an IP address */
166  ForEachInterface(CurrentIF) {
167  if (CurrentIF->Context && AddrIsUnspecified(&CurrentIF->Unicast)) {
169 
170  GetInterfaceConnectionStatus(CurrentIF, &IfStatus);
171  if (IfStatus == MIB_IF_OPER_STATUS_OPERATIONAL) {
172  return CurrentIF;
173  }
174 
176  }
177  } EndFor(CurrentIF);
178 
179  /* Try to continue from the next adapter */
180  ForEachInterface(CurrentIF) {
181  if (CurrentIF->Context && (Index++ == NextDefaultAdapter)) {
183 
184  GetInterfaceConnectionStatus(CurrentIF, &IfStatus);
185  if (IfStatus == MIB_IF_OPER_STATUS_OPERATIONAL) {
187  return CurrentIF;
188  }
189 
191  }
192  } EndFor(CurrentIF);
193 
194  /* No luck, so we'll choose the first adapter this time */
195  Index = 0;
196  ForEachInterface(CurrentIF) {
197  if (CurrentIF->Context) {
198  Index++;
200 
201  GetInterfaceConnectionStatus(CurrentIF, &IfStatus);
202  if (IfStatus == MIB_IF_OPER_STATUS_OPERATIONAL) {
204  return CurrentIF;
205  }
206 
208  }
209  } EndFor(CurrentIF);
210 
211  /* Even that didn't work, so we'll just go with loopback */
212  NextDefaultAdapter = 0;
214 
215  /* There are no physical interfaces on the system
216  * so we must pick the loopback interface */
217 
218  return Loopback;
219 }
220 
222 /*
223  * FUNCTION: Checks all on-link prefixes to find out if an address is on-link
224  * ARGUMENTS:
225  * Address = Pointer to address to check
226  * RETURNS:
227  * Pointer to interface if address is on-link, NULL if not
228  */
229 {
230  KIRQL OldIrql;
231  IF_LIST_ITER(CurrentIF);
232 
233  TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X)\n", Address));
234  TI_DbgPrint(DEBUG_ROUTER, ("Address (%s)\n", A2S(Address)));
235 
237  return GetDefaultInterface();
238 
240 
241  ForEachInterface(CurrentIF) {
242  if (HasPrefix(Address, &CurrentIF->Unicast,
243  AddrCountPrefixBits(&CurrentIF->Netmask))) {
245  return CurrentIF;
246  }
247  } EndFor(CurrentIF);
248 
250 
251  return NULL;
252 }
253 
255 {
256  PLAN_ADAPTER Adapter = Interface->Context;
257 
258  /* Loopback has no adapter context */
259  if (Adapter == NULL || Adapter->State == LAN_STATE_STARTED) {
261  }
262  else {
264  }
265 }
BOOLEAN AddrIsUnspecified(PIP_ADDRESS Address)
Definition: address.c:113
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS GetInterfaceIPv4Address(PIP_INTERFACE Interface, ULONG TargetType, PULONG Address)
Definition: interface.c:19
PVOID Context
Definition: lan.h:64
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
PIP_INTERFACE AddrLocateInterface(PIP_ADDRESS MatchAddress)
Definition: interface.c:89
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
unsigned char * PUCHAR
Definition: retypes.h:3
KSPIN_LOCK InterfaceListLock
Definition: ip.c:18
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN HasPrefix(PIP_ADDRESS Address, PIP_ADDRESS Prefix, UINT Length)
Definition: interface.c:111
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
UINT Speed
Definition: lan.h:79
#define IF_LIST_ITER(n)
Definition: tilists.h:5
VOID TcpipReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL Irql)
Definition: lock.c:26
VOID TcpipAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL Irql)
Definition: lock.c:18
#define MIB_IF_OPER_STATUS_DISCONNECTED
Definition: ipifcons.h:248
PIP_INTERFACE Loopback
Definition: loopback.c:13
Definition: ip.h:23
#define ADE_BROADCAST
Definition: ip.h:111
VOID GetInterfaceConnectionStatus(PIP_INTERFACE Interface, PULONG Result)
Definition: interface.c:254
UCHAR KIRQL
Definition: env_spec_w32.h:591
PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
Definition: interface.c:221
#define ADE_POINTOPOINT
Definition: ip.h:113
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define ForEachInterface(n)
Definition: tilists.h:9
static WCHAR Address[46]
Definition: ping.c:68
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
PIP_INTERFACE GetDefaultInterface(VOID)
Definition: interface.c:156
NTSTATUS GetInterfaceSpeed(PIP_INTERFACE Interface, PUINT Speed)
Definition: interface.c:62
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
struct LAN_ADAPTER * PLAN_ADAPTER
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const UCHAR Index[8]
Definition: usbohci.c:18
#define Len
Definition: deflate.h:82
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSYSAPI NTSTATUS NTAPI RtlUnicodeToMultiByteN(PCHAR MbString, ULONG MbSize, PULONG ResultSize, PCWCH UnicodeString, ULONG UnicodeSize)
BOOLEAN AddrIsEqual(PIP_ADDRESS Address1, PIP_ADDRESS Address2)
Definition: address.c:221
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define ADE_ADDRMASK
Definition: ip.h:112
UINT AddrCountPrefixBits(PIP_ADDRESS Netmask)
Definition: address.c:64
Status
Definition: gdiplustypes.h:24
#define EndFor(n)
Definition: tilists.h:20
NTSTATUS GetInterfaceName(PIP_INTERFACE Interface, PCHAR NameBuffer, UINT Len)
Definition: interface.c:70
UINT CountInterfaces()
Definition: interface.c:46
UCHAR State
Definition: lan.h:62
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
unsigned int ULONG
Definition: retypes.h:1
#define LAN_STATE_STARTED
Definition: lan.h:113
#define ADE_UNICAST
Definition: ip.h:110
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define DEBUG_ROUTER
Definition: debug.h:30
#define MIB_IF_OPER_STATUS_OPERATIONAL
Definition: ipifcons.h:251
ULONG NextDefaultAdapter
Definition: interface.c:17
unsigned int * PUINT
Definition: ndis.h:50
PCHAR A2S(PIP_ADDRESS Address)
Definition: address.c:17