f78d4b400626ece4ce4e582bda39a19e3ca07207
[reactos.git] / reactos / drivers / network / tcpip / tcpip / ninfo.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/ninfo.c
5 * PURPOSE: Network information
6 * PROGRAMMERS: Art Yerkes
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 #define IP_ROUTE_TYPE_ADD 3
14 #define IP_ROUTE_TYPE_DEL 2
15
16
17
18 /* Get IPRouteEntry s for each of the routes in the system */
19 TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUINT BufferSize ) {
20 TDI_STATUS Status;
21 KIRQL OldIrql;
22 UINT RtCount = CountFIBs(IF);
23 UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount;
24 PFIB_ENTRY RCache, RCacheCur;
25 PIPROUTE_ENTRY RouteEntries, RtCurrent;
26 UINT i;
27
28 TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d\n",
29 RtCount));
30
31 if (RtCount == 0)
32 return InfoCopyOut(NULL, 0, NULL, BufferSize);
33
34 RouteEntries = ExAllocatePool( NonPagedPool, Size );
35 RtCurrent = RouteEntries;
36
37 RCache = ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount );
38 RCacheCur = RCache;
39
40 if( !RCache || !RouteEntries ) {
41 if( RCache ) ExFreePool( RCache );
42 if( RouteEntries ) ExFreePool( RouteEntries );
43 return TDI_NO_RESOURCES;
44 }
45
46 RtlZeroMemory( RouteEntries, Size );
47
48 RtCount = CopyFIBs( IF, RCache );
49
50 while( RtCurrent < RouteEntries + RtCount ) {
51 ASSERT(RCacheCur->Router);
52
53 RtlCopyMemory( &RtCurrent->Dest,
54 &RCacheCur->NetworkAddress.Address,
55 sizeof(RtCurrent->Dest) );
56 RtlCopyMemory( &RtCurrent->Mask,
57 &RCacheCur->Netmask.Address,
58 sizeof(RtCurrent->Mask) );
59 RtlCopyMemory( &RtCurrent->Gw,
60 &RCacheCur->Router->Address.Address,
61 sizeof(RtCurrent->Gw) );
62
63 RtCurrent->Metric1 = RCacheCur->Metric;
64 RtCurrent->Type = TDI_ADDRESS_TYPE_IP;
65
66 TI_DbgPrint
67 (DEBUG_INFO,
68 ("%d: NA %08x NM %08x GW %08x MT %x\n",
69 RtCurrent - RouteEntries,
70 RtCurrent->Dest,
71 RtCurrent->Mask,
72 RtCurrent->Gw,
73 RtCurrent->Metric1 ));
74
75 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
76 for (i = 0; i < EntityCount; i++)
77 if (EntityList[i].context == IF)
78 break;
79
80 if (i < EntityCount)
81 RtCurrent->Index = EntityList[i].tei_instance;
82 else
83 RtCurrent->Index = 0;
84
85 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
86
87 RtCurrent++; RCacheCur++;
88 }
89
90 Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );
91
92 ExFreePool( RouteEntries );
93 ExFreePool( RCache );
94
95 TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
96
97 return Status;
98 }
99
100 TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID,
101 PNDIS_BUFFER Buffer,
102 PUINT BufferSize)
103 {
104 KIRQL OldIrql;
105 PIPADDR_ENTRY IPEntry;
106 PIP_INTERFACE CurrentIF;
107 UINT i;
108
109 TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
110
111
112 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
113
114 for (i = 0; i < EntityCount; i++)
115 {
116 if (EntityList[i].tei_entity == ID.tei_entity &&
117 EntityList[i].tei_instance == ID.tei_instance)
118 break;
119 }
120
121 if (i == EntityCount)
122 {
123 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
124 return TDI_INVALID_PARAMETER;
125 }
126
127 IPEntry = ExAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY));
128 if (!IPEntry)
129 {
130 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
131 return TDI_NO_RESOURCES;
132 }
133
134 CurrentIF = EntityList[i].context;
135
136 IPEntry->Index = CurrentIF->Index;
137 GetInterfaceIPv4Address(CurrentIF,
138 ADE_UNICAST,
139 &IPEntry->Addr);
140 GetInterfaceIPv4Address(CurrentIF,
141 ADE_ADDRMASK,
142 &IPEntry->Mask);
143 GetInterfaceIPv4Address(CurrentIF,
144 ADE_BROADCAST,
145 &IPEntry->BcastAddr);
146
147 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
148
149 InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY),
150 Buffer, BufferSize);
151
152 ExFreePool(IPEntry);
153
154 return TDI_SUCCESS;
155 }
156
157 TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
158 PIP_INTERFACE IF,
159 PNDIS_BUFFER Buffer,
160 PUINT BufferSize ) {
161 IPSNMP_INFO SnmpInfo;
162 UINT IfCount = CountInterfaces();
163 UINT RouteCount = CountFIBs(IF);
164 TDI_STATUS Status = TDI_INVALID_REQUEST;
165
166 TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
167
168 RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
169
170 SnmpInfo.NumIf = IfCount;
171 SnmpInfo.NumAddr = 1;
172 SnmpInfo.NumRoutes = RouteCount;
173
174 Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
175 Buffer, BufferSize );
176
177 TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
178
179 return Status;
180 }
181
182 TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize)
183 {
184 IP_ADDRESS Address, Netmask, Router;
185 PIPROUTE_ENTRY Route = Buffer;
186
187 AddrInitIPv4( &Address, Route->Dest );
188 AddrInitIPv4( &Netmask, Route->Mask );
189 AddrInitIPv4( &Router, Route->Gw );
190
191 if (!Buffer || BufferSize < sizeof(IPROUTE_ENTRY))
192 return TDI_INVALID_PARAMETER;
193
194 if (IF == Loopback)
195 {
196 DbgPrint("Failing attempt to add route to loopback adapter\n");
197 return TDI_INVALID_PARAMETER;
198 }
199
200 if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
201 TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
202 if (!RouterCreateRoute( &Address, &Netmask, &Router,
203 IF, Route->Metric1))
204 return TDI_NO_RESOURCES;
205
206 return TDI_SUCCESS;
207 } else if( Route->Type == IP_ROUTE_TYPE_DEL ) {
208 TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
209 if (NT_SUCCESS(RouterRemoveRoute( &Address, &Router )))
210 return TDI_SUCCESS;
211 else
212 return TDI_INVALID_PARAMETER;
213 }
214
215 return TDI_INVALID_REQUEST;
216 }
217