352d8cf1ba54d24b7e73f748fc448af3265b2acf
[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( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
20 TDI_STATUS Status;
21 KIRQL OldIrql;
22 UINT RtCount = CountFIBs();
23 UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount;
24 PFIB_ENTRY RCache =
25 exAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ),
26 RCacheCur = RCache;
27 PIPROUTE_ENTRY RouteEntries = exAllocatePool( NonPagedPool, Size ),
28 RtCurrent = RouteEntries;
29
30 TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d, RCache = %08x\n",
31 RtCount, RCache));
32
33 if( !RCache || !RouteEntries ) {
34 if( RCache ) exFreePool( RCache );
35 if( RouteEntries ) exFreePool( RouteEntries );
36 return TDI_NO_RESOURCES;
37 }
38
39 RtlZeroMemory( RouteEntries, Size );
40
41 RtCount = CopyFIBs( RCache );
42
43 while( RtCurrent < RouteEntries + RtCount ) {
44 ASSERT(RCacheCur->Router);
45
46 RtlCopyMemory( &RtCurrent->Dest,
47 &RCacheCur->NetworkAddress.Address,
48 sizeof(RtCurrent->Dest) );
49 RtlCopyMemory( &RtCurrent->Mask,
50 &RCacheCur->Netmask.Address,
51 sizeof(RtCurrent->Mask) );
52 RtlCopyMemory( &RtCurrent->Gw,
53 &RCacheCur->Router->Address.Address,
54 sizeof(RtCurrent->Gw) );
55
56 RtCurrent->Metric1 = RCacheCur->Metric;
57 RtCurrent->Type = TDI_ADDRESS_TYPE_IP;
58
59 TI_DbgPrint
60 (DEBUG_INFO,
61 ("%d: NA %08x NM %08x GW %08x MT %x\n",
62 RtCurrent - RouteEntries,
63 RtCurrent->Dest,
64 RtCurrent->Mask,
65 RtCurrent->Gw,
66 RtCurrent->Metric1 ));
67
68 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
69 for( RtCurrent->Index = EntityCount;
70 RtCurrent->Index > 0 &&
71 RCacheCur->Router->Interface !=
72 EntityList[RtCurrent->Index - 1].context;
73 RtCurrent->Index-- );
74
75 RtCurrent->Index = EntityList[RtCurrent->Index - 1].tei_instance;
76 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
77
78 RtCurrent++; RCacheCur++;
79 }
80
81 Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );
82
83 exFreePool( RouteEntries );
84 exFreePool( RCache );
85
86 TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
87
88 return Status;
89 }
90
91 TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID,
92 PNDIS_BUFFER Buffer,
93 PUINT BufferSize)
94 {
95 KIRQL OldIrql;
96 PIPADDR_ENTRY IPEntry;
97 PIP_INTERFACE CurrentIF;
98 UINT i;
99
100 TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
101
102
103 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
104
105 for (i = 0; i < EntityCount; i++)
106 {
107 if (EntityList[i].tei_entity == ID.tei_entity &&
108 EntityList[i].tei_instance == ID.tei_instance)
109 break;
110 }
111
112 if (i == EntityCount)
113 {
114 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
115 return TDI_INVALID_PARAMETER;
116 }
117
118 IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY));
119 if (!IPEntry)
120 {
121 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
122 return TDI_NO_RESOURCES;
123 }
124
125 CurrentIF = EntityList[i].context;
126
127 IPEntry->Index = CurrentIF->Index;
128 GetInterfaceIPv4Address(CurrentIF,
129 ADE_UNICAST,
130 &IPEntry->Addr);
131 GetInterfaceIPv4Address(CurrentIF,
132 ADE_ADDRMASK,
133 &IPEntry->Mask);
134 GetInterfaceIPv4Address(CurrentIF,
135 ADE_BROADCAST,
136 &IPEntry->BcastAddr);
137
138 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
139
140 InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY),
141 Buffer, BufferSize);
142
143 exFreePool(IPEntry);
144
145 return TDI_SUCCESS;
146 }
147
148 TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
149 PNDIS_BUFFER Buffer,
150 PUINT BufferSize ) {
151 IPSNMP_INFO SnmpInfo;
152 UINT IfCount = CountInterfaces();
153 UINT RouteCount = CountFIBs();
154 TDI_STATUS Status = TDI_INVALID_REQUEST;
155
156 TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
157
158 RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
159
160 SnmpInfo.NumIf = IfCount;
161 SnmpInfo.NumAddr = 1;
162 SnmpInfo.NumRoutes = RouteCount;
163
164 Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
165 Buffer, BufferSize );
166
167 TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
168
169 return Status;
170 }
171
172 TDI_STATUS InfoTdiSetRoute(PIPROUTE_ENTRY Route)
173 {
174 IP_ADDRESS Address, Netmask, Router;
175 PNEIGHBOR_CACHE_ENTRY NCE;
176
177 AddrInitIPv4( &Address, Route->Dest );
178 AddrInitIPv4( &Netmask, Route->Mask );
179 AddrInitIPv4( &Router, Route->Gw );
180
181 if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
182 TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
183 /* Find the existing route this belongs to */
184 NCE = RouterGetRoute( &Router );
185 if (!NCE) return TDI_INVALID_PARAMETER;
186
187 /* Really add the route */
188 if (!RouterCreateRoute( &Address, &Netmask, &Router,
189 NCE->Interface, Route->Metric1))
190 return TDI_NO_RESOURCES;
191
192 return TDI_SUCCESS;
193 } else if( Route->Type == IP_ROUTE_TYPE_DEL ) {
194 TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
195 if (NT_SUCCESS(RouterRemoveRoute( &Address, &Router )))
196 return TDI_SUCCESS;
197 else
198 return TDI_INVALID_PARAMETER;
199 }
200
201 return TDI_INVALID_REQUEST;
202 }
203