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