1c2c66affSColin Finck /* Copyright (C) 2003 Art Yerkes
2c2c66affSColin Finck  * A reimplementation of ifenum.c by Juan Lang
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17c2c66affSColin Finck  *
18c2c66affSColin Finck  * This file is implemented on the IOCTL_TCP_QUERY_INFORMATION_EX ioctl on
19c2c66affSColin Finck  * tcpip.sys
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #include "iphlpapi_private.h"
23c2c66affSColin Finck 
24c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
25c2c66affSColin Finck 
26c2c66affSColin Finck #ifndef TCPS_ESTABLISHED
27c2c66affSColin Finck # define TCPS_ESTABLISHED TCP_ESTABLISHED
28c2c66affSColin Finck #endif
29c2c66affSColin Finck #ifndef TCPS_SYN_SENT
30c2c66affSColin Finck # define TCPS_SYN_SENT TCP_SYN_SENT
31c2c66affSColin Finck #endif
32c2c66affSColin Finck #ifndef TCPS_SYN_RECEIVED
33c2c66affSColin Finck # define TCPS_SYN_RECEIVED TCP_SYN_RECV
34c2c66affSColin Finck #endif
35c2c66affSColin Finck #ifndef TCPS_FIN_WAIT_1
36c2c66affSColin Finck # define TCPS_FIN_WAIT_1 TCP_FIN_WAIT1
37c2c66affSColin Finck #endif
38c2c66affSColin Finck #ifndef TCPS_FIN_WAIT_2
39c2c66affSColin Finck # define TCPS_FIN_WAIT_2 TCP_FIN_WAIT2
40c2c66affSColin Finck #endif
41c2c66affSColin Finck #ifndef TCPS_TIME_WAIT
42c2c66affSColin Finck # define TCPS_TIME_WAIT TCP_TIME_WAIT
43c2c66affSColin Finck #endif
44c2c66affSColin Finck #ifndef TCPS_CLOSED
45c2c66affSColin Finck # define TCPS_CLOSED TCP_CLOSE
46c2c66affSColin Finck #endif
47c2c66affSColin Finck #ifndef TCPS_CLOSE_WAIT
48c2c66affSColin Finck # define TCPS_CLOSE_WAIT TCP_CLOSE_WAIT
49c2c66affSColin Finck #endif
50c2c66affSColin Finck #ifndef TCPS_LAST_ACK
51c2c66affSColin Finck # define TCPS_LAST_ACK TCP_LAST_ACK
52c2c66affSColin Finck #endif
53c2c66affSColin Finck #ifndef TCPS_LISTEN
54c2c66affSColin Finck # define TCPS_LISTEN TCP_LISTEN
55c2c66affSColin Finck #endif
56c2c66affSColin Finck #ifndef TCPS_CLOSING
57c2c66affSColin Finck # define TCPS_CLOSING TCP_CLOSING
58c2c66affSColin Finck #endif
59c2c66affSColin Finck 
isIpEntity(HANDLE tcpFile,TDIEntityID * ent)60c2c66affSColin Finck BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
61c2c66affSColin Finck     return (ent->tei_entity == CL_NL_ENTITY ||
62c2c66affSColin Finck             ent->tei_entity == CO_NL_ENTITY);
63c2c66affSColin Finck }
64c2c66affSColin Finck 
getNthIpEntity(HANDLE tcpFile,DWORD index,TDIEntityID * ent)65c2c66affSColin Finck NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
66c2c66affSColin Finck     DWORD numEntities = 0;
67c2c66affSColin Finck     DWORD numRoutes = 0;
68c2c66affSColin Finck     TDIEntityID *entitySet = 0;
69c2c66affSColin Finck     NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
70c2c66affSColin Finck     int i;
71c2c66affSColin Finck 
72c2c66affSColin Finck     if( !NT_SUCCESS(status) )
73c2c66affSColin Finck         return status;
74c2c66affSColin Finck 
75c2c66affSColin Finck     for( i = 0; i < numEntities; i++ ) {
76c2c66affSColin Finck         if( isIpEntity( tcpFile, &entitySet[i] ) ) {
77c2c66affSColin Finck             TRACE("Entity %d is an IP Entity\n", i);
78c2c66affSColin Finck             if( numRoutes == index ) break;
79c2c66affSColin Finck             else numRoutes++;
80c2c66affSColin Finck         }
81c2c66affSColin Finck     }
82c2c66affSColin Finck 
83c2c66affSColin Finck     if( numRoutes == index && i < numEntities ) {
846c935922SSerge Gautherie         TRACE("Index %lu is entity #%d - %04x:%08x\n", index, i,
85c2c66affSColin Finck               entitySet[i].tei_entity, entitySet[i].tei_instance);
86c2c66affSColin Finck         memcpy( ent, &entitySet[i], sizeof(*ent) );
87c2c66affSColin Finck         tdiFreeThingSet( entitySet );
88c2c66affSColin Finck         return STATUS_SUCCESS;
89c2c66affSColin Finck     } else {
90c2c66affSColin Finck         tdiFreeThingSet( entitySet );
91c2c66affSColin Finck         return STATUS_UNSUCCESSFUL;
92c2c66affSColin Finck     }
93c2c66affSColin Finck }
94c2c66affSColin Finck 
tdiGetMibForIpEntity(HANDLE tcpFile,TDIEntityID * ent,IPSNMPInfo * entry)95c2c66affSColin Finck NTSTATUS tdiGetMibForIpEntity
96c2c66affSColin Finck ( HANDLE tcpFile, TDIEntityID *ent, IPSNMPInfo *entry ) {
97c2c66affSColin Finck     TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
98c2c66affSColin Finck     NTSTATUS status = STATUS_SUCCESS;
99c2c66affSColin Finck     DWORD returnSize;
100c2c66affSColin Finck 
101c2c66affSColin Finck     memset( entry, 0, sizeof( *entry ) );
102c2c66affSColin Finck 
1036c935922SSerge Gautherie     TRACE("TdiGetMibForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
1046c935922SSerge Gautherie           tcpFile, ent->tei_instance);
105c2c66affSColin Finck 
106c2c66affSColin Finck     req.ID.toi_class                = INFO_CLASS_PROTOCOL;
107c2c66affSColin Finck     req.ID.toi_type                 = INFO_TYPE_PROVIDER;
108c2c66affSColin Finck     req.ID.toi_id                   = IP_MIB_STATS_ID;
109c2c66affSColin Finck     req.ID.toi_entity               = *ent;
110c2c66affSColin Finck 
111c2c66affSColin Finck     status = DeviceIoControl(tcpFile,
112c2c66affSColin Finck                              IOCTL_TCP_QUERY_INFORMATION_EX,
113c2c66affSColin Finck                              &req,
114c2c66affSColin Finck                              sizeof(req),
115c2c66affSColin Finck                              entry,
116c2c66affSColin Finck                              sizeof(*entry),
117c2c66affSColin Finck                              &returnSize,
118c2c66affSColin Finck                              NULL);
119c2c66affSColin Finck 
1206c935922SSerge Gautherie     TRACE("TdiGetMibForIpEntity() => status = 0x%08lx, entry = {\n"
1216c935922SSerge Gautherie            "  ipsi_forwarding ............ %lu\n"
1226c935922SSerge Gautherie            "  ipsi_defaultttl ............ %lu\n"
1236c935922SSerge Gautherie            "  ipsi_inreceives ............ %lu\n"
1246c935922SSerge Gautherie            "  ipsi_indelivers ............ %lu\n"
1256c935922SSerge Gautherie            "  ipsi_outrequests ........... %lu\n"
1266c935922SSerge Gautherie            "  ipsi_routingdiscards ....... %lu\n"
1276c935922SSerge Gautherie            "  ipsi_outdiscards ........... %lu\n"
1286c935922SSerge Gautherie            "  ipsi_outnoroutes ........... %lu\n"
1296c935922SSerge Gautherie            "  ipsi_numif ................. %lu\n"
1306c935922SSerge Gautherie            "  ipsi_numaddr ............... %lu\n"
1316c935922SSerge Gautherie            "  ipsi_numroutes ............. %lu\n"
1326c935922SSerge Gautherie            "}\n",
1336c935922SSerge Gautherie           status,
134c2c66affSColin Finck           entry->ipsi_forwarding,
135c2c66affSColin Finck           entry->ipsi_defaultttl,
136c2c66affSColin Finck           entry->ipsi_inreceives,
137c2c66affSColin Finck           entry->ipsi_indelivers,
138c2c66affSColin Finck           entry->ipsi_outrequests,
139c2c66affSColin Finck           entry->ipsi_routingdiscards,
140c2c66affSColin Finck           entry->ipsi_outdiscards,
141c2c66affSColin Finck           entry->ipsi_outnoroutes,
142c2c66affSColin Finck           entry->ipsi_numif,
143c2c66affSColin Finck           entry->ipsi_numaddr,
1446c935922SSerge Gautherie           entry->ipsi_numroutes);
145c2c66affSColin Finck 
146c2c66affSColin Finck     return status;
147c2c66affSColin Finck }
148c2c66affSColin Finck 
tdiGetRoutesForIpEntity(HANDLE tcpFile,TDIEntityID * ent,IPRouteEntry ** routes,PDWORD numRoutes)149c2c66affSColin Finck NTSTATUS tdiGetRoutesForIpEntity
150c2c66affSColin Finck ( HANDLE tcpFile, TDIEntityID *ent, IPRouteEntry **routes, PDWORD numRoutes ) {
151c2c66affSColin Finck     NTSTATUS status = STATUS_SUCCESS;
152c2c66affSColin Finck 
1536c935922SSerge Gautherie     TRACE("TdiGetRoutesForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
1546c935922SSerge Gautherie           tcpFile, ent->tei_instance);
155c2c66affSColin Finck 
156c2c66affSColin Finck     status = tdiGetSetOfThings(tcpFile,
157c2c66affSColin Finck                                INFO_CLASS_PROTOCOL,
158c2c66affSColin Finck                                INFO_TYPE_PROVIDER,
159c2c66affSColin Finck                                IP_MIB_ARPTABLE_ENTRY_ID,
160c2c66affSColin Finck                                CL_NL_ENTITY,
161c2c66affSColin Finck                                ent->tei_instance,
162c2c66affSColin Finck                                0,
163c2c66affSColin Finck                                sizeof(IPRouteEntry),
164c2c66affSColin Finck                                (PVOID *)routes,
165c2c66affSColin Finck                                numRoutes);
166c2c66affSColin Finck 
167c2c66affSColin Finck     return status;
168c2c66affSColin Finck }
169c2c66affSColin Finck 
tdiGetIpAddrsForIpEntity(HANDLE tcpFile,TDIEntityID * ent,IPAddrEntry ** addrs,PDWORD numAddrs)170c2c66affSColin Finck NTSTATUS tdiGetIpAddrsForIpEntity
171c2c66affSColin Finck ( HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs, PDWORD numAddrs ) {
172c2c66affSColin Finck     NTSTATUS status;
173c2c66affSColin Finck 
1746c935922SSerge Gautherie     TRACE("TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
1756c935922SSerge Gautherie           tcpFile, ent->tei_instance);
176c2c66affSColin Finck 
177c2c66affSColin Finck     status = tdiGetSetOfThings(tcpFile,
178c2c66affSColin Finck                                INFO_CLASS_PROTOCOL,
179c2c66affSColin Finck                                INFO_TYPE_PROVIDER,
180c2c66affSColin Finck                                IP_MIB_ADDRTABLE_ENTRY_ID,
181c2c66affSColin Finck                                CL_NL_ENTITY,
182c2c66affSColin Finck                                ent->tei_instance,
183c2c66affSColin Finck                                0,
184c2c66affSColin Finck                                sizeof(IPAddrEntry),
185c2c66affSColin Finck                                (PVOID *)addrs,
186c2c66affSColin Finck                                numAddrs);
187c2c66affSColin Finck 
188c2c66affSColin Finck     return status;
189c2c66affSColin Finck }
190c2c66affSColin Finck 
getInterfaceStatsByName(const char * name,PMIB_IFROW entry)191c2c66affSColin Finck DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
192c2c66affSColin Finck {
193c2c66affSColin Finck   if (!name)
194c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
195c2c66affSColin Finck   if (!entry)
196c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
197c2c66affSColin Finck 
198c2c66affSColin Finck   return NO_ERROR;
199c2c66affSColin Finck }
200c2c66affSColin Finck 
getInterfaceStatsByIndex(DWORD index,PMIB_IFROW entry)201c2c66affSColin Finck DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry)
202c2c66affSColin Finck {
203c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
204c2c66affSColin Finck }
205c2c66affSColin Finck 
getICMPStats(MIB_ICMP * stats)206c2c66affSColin Finck DWORD getICMPStats(MIB_ICMP *stats)
207c2c66affSColin Finck {
208c2c66affSColin Finck   FILE *fp;
209c2c66affSColin Finck 
210c2c66affSColin Finck   if (!stats)
211c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
212c2c66affSColin Finck 
213c2c66affSColin Finck   memset(stats, 0, sizeof(MIB_ICMP));
214c2c66affSColin Finck   /* get most of these stats from /proc/net/snmp, no error if can't */
215c2c66affSColin Finck   fp = fopen("/proc/net/snmp", "r");
216c2c66affSColin Finck   if (fp) {
217c2c66affSColin Finck     const char hdr[] = "Icmp:";
218c2c66affSColin Finck     char buf[512] = { 0 }, *ptr;
219c2c66affSColin Finck 
220c2c66affSColin Finck     do {
221c2c66affSColin Finck       ptr = fgets(buf, sizeof(buf), fp);
222*e4930be4STimo Kreuzer     } while (ptr && _strnicmp(buf, hdr, sizeof(hdr) - 1));
223c2c66affSColin Finck     if (ptr) {
224c2c66affSColin Finck       /* last line was a header, get another */
225c2c66affSColin Finck       ptr = fgets(buf, sizeof(buf), fp);
226*e4930be4STimo Kreuzer       if (ptr && _strnicmp(buf, hdr, sizeof(hdr) - 1) == 0) {
227c2c66affSColin Finck         char *endPtr;
228c2c66affSColin Finck 
229c2c66affSColin Finck         ptr += sizeof(hdr);
230c2c66affSColin Finck         if (ptr && *ptr) {
231c2c66affSColin Finck           stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
232c2c66affSColin Finck           ptr = endPtr;
233c2c66affSColin Finck         }
234c2c66affSColin Finck         if (ptr && *ptr) {
235c2c66affSColin Finck           stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
236c2c66affSColin Finck           ptr = endPtr;
237c2c66affSColin Finck         }
238c2c66affSColin Finck         if (ptr && *ptr) {
239c2c66affSColin Finck           stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
240c2c66affSColin Finck           ptr = endPtr;
241c2c66affSColin Finck         }
242c2c66affSColin Finck         if (ptr && *ptr) {
243c2c66affSColin Finck           stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
244c2c66affSColin Finck           ptr = endPtr;
245c2c66affSColin Finck         }
246c2c66affSColin Finck         if (ptr && *ptr) {
247c2c66affSColin Finck           stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
248c2c66affSColin Finck           ptr = endPtr;
249c2c66affSColin Finck         }
250c2c66affSColin Finck         if (ptr && *ptr) {
251c2c66affSColin Finck           stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
252c2c66affSColin Finck           ptr = endPtr;
253c2c66affSColin Finck         }
254c2c66affSColin Finck         if (ptr && *ptr) {
255c2c66affSColin Finck           stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
256c2c66affSColin Finck           ptr = endPtr;
257c2c66affSColin Finck         }
258c2c66affSColin Finck         if (ptr && *ptr) {
259c2c66affSColin Finck           stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
260c2c66affSColin Finck           ptr = endPtr;
261c2c66affSColin Finck         }
262c2c66affSColin Finck         if (ptr && *ptr) {
263c2c66affSColin Finck           stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
264c2c66affSColin Finck           ptr = endPtr;
265c2c66affSColin Finck         }
266c2c66affSColin Finck         if (ptr && *ptr) {
267c2c66affSColin Finck           stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
268c2c66affSColin Finck           ptr = endPtr;
269c2c66affSColin Finck         }
270c2c66affSColin Finck         if (ptr && *ptr) {
271c2c66affSColin Finck           stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
272c2c66affSColin Finck           ptr = endPtr;
273c2c66affSColin Finck         }
274c2c66affSColin Finck         if (ptr && *ptr) {
275c2c66affSColin Finck           stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
276c2c66affSColin Finck           ptr = endPtr;
277c2c66affSColin Finck         }
278c2c66affSColin Finck         if (ptr && *ptr) {
279c2c66affSColin Finck           stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
280c2c66affSColin Finck           ptr = endPtr;
281c2c66affSColin Finck         }
282c2c66affSColin Finck         if (ptr && *ptr) {
283c2c66affSColin Finck           stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
284c2c66affSColin Finck           ptr = endPtr;
285c2c66affSColin Finck         }
286c2c66affSColin Finck         if (ptr && *ptr) {
287c2c66affSColin Finck           stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
288c2c66affSColin Finck           ptr = endPtr;
289c2c66affSColin Finck         }
290c2c66affSColin Finck         if (ptr && *ptr) {
291c2c66affSColin Finck           stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
292c2c66affSColin Finck           ptr = endPtr;
293c2c66affSColin Finck         }
294c2c66affSColin Finck         if (ptr && *ptr) {
295c2c66affSColin Finck           stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
296c2c66affSColin Finck           ptr = endPtr;
297c2c66affSColin Finck         }
298c2c66affSColin Finck         if (ptr && *ptr) {
299c2c66affSColin Finck           stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
300c2c66affSColin Finck           ptr = endPtr;
301c2c66affSColin Finck         }
302c2c66affSColin Finck         if (ptr && *ptr) {
303c2c66affSColin Finck           stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
304c2c66affSColin Finck           ptr = endPtr;
305c2c66affSColin Finck         }
306c2c66affSColin Finck         if (ptr && *ptr) {
307c2c66affSColin Finck           stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
308c2c66affSColin Finck           ptr = endPtr;
309c2c66affSColin Finck         }
310c2c66affSColin Finck         if (ptr && *ptr) {
311c2c66affSColin Finck           stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
312c2c66affSColin Finck           ptr = endPtr;
313c2c66affSColin Finck         }
314c2c66affSColin Finck         if (ptr && *ptr) {
315c2c66affSColin Finck           stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
316c2c66affSColin Finck           ptr = endPtr;
317c2c66affSColin Finck         }
318c2c66affSColin Finck         if (ptr && *ptr) {
319c2c66affSColin Finck           stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
320c2c66affSColin Finck           ptr = endPtr;
321c2c66affSColin Finck         }
322c2c66affSColin Finck         if (ptr && *ptr) {
323c2c66affSColin Finck           stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
324c2c66affSColin Finck           ptr = endPtr;
325c2c66affSColin Finck         }
326c2c66affSColin Finck       }
327c2c66affSColin Finck     }
328c2c66affSColin Finck     fclose(fp);
329c2c66affSColin Finck   }
330c2c66affSColin Finck   return NO_ERROR;
331c2c66affSColin Finck }
332c2c66affSColin Finck 
getIPStats(PMIB_IPSTATS stats,DWORD family)333c2c66affSColin Finck DWORD getIPStats(PMIB_IPSTATS stats, DWORD family)
334c2c66affSColin Finck {
335c2c66affSColin Finck   if (!stats)
336c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
337da4e15f9SEric Kohl 
338da4e15f9SEric Kohl   if (family != AF_INET && family != AF_INET6)
339da4e15f9SEric Kohl     return ERROR_INVALID_PARAMETER;
340da4e15f9SEric Kohl 
341c2c66affSColin Finck   return NO_ERROR;
342c2c66affSColin Finck }
343c2c66affSColin Finck 
getTCPStats(MIB_TCPSTATS * stats,DWORD family)344c2c66affSColin Finck DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family)
345c2c66affSColin Finck {
346c2c66affSColin Finck   if (!stats)
347c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
348da4e15f9SEric Kohl 
349da4e15f9SEric Kohl   if (family != AF_INET && family != AF_INET6)
350da4e15f9SEric Kohl     return ERROR_INVALID_PARAMETER;
351da4e15f9SEric Kohl 
352c2c66affSColin Finck   return NO_ERROR;
353c2c66affSColin Finck }
354c2c66affSColin Finck 
getUDPStats(MIB_UDPSTATS * stats,DWORD family)355c2c66affSColin Finck DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family)
356c2c66affSColin Finck {
357c2c66affSColin Finck   if (!stats)
358c2c66affSColin Finck     return ERROR_INVALID_PARAMETER;
359da4e15f9SEric Kohl 
360da4e15f9SEric Kohl   if (family != AF_INET && family != AF_INET6)
361da4e15f9SEric Kohl     return ERROR_INVALID_PARAMETER;
362da4e15f9SEric Kohl 
363c2c66affSColin Finck   return NO_ERROR;
364c2c66affSColin Finck }
365c2c66affSColin Finck 
getNumRoutes(void)366c2c66affSColin Finck DWORD getNumRoutes(void)
367c2c66affSColin Finck {
368c2c66affSColin Finck     DWORD numEntities, numRoutes = 0;
369c2c66affSColin Finck     TDIEntityID *entitySet;
370c2c66affSColin Finck     HANDLE tcpFile;
371c2c66affSColin Finck     int i;
372c2c66affSColin Finck     NTSTATUS status;
373c2c66affSColin Finck 
374c2c66affSColin Finck     TRACE("called.\n");
375c2c66affSColin Finck 
376c2c66affSColin Finck     status = openTcpFile(&tcpFile, FILE_READ_DATA);
377a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
378a5360f54SJoachim Henze     {
3796c935922SSerge Gautherie         ERR("openTcpFile returned 0x%08lx\n", status);
380c2c66affSColin Finck         return 0;
381c2c66affSColin Finck     }
382c2c66affSColin Finck 
383c2c66affSColin Finck     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
384c2c66affSColin Finck     if (!NT_SUCCESS(status)) {
3856c935922SSerge Gautherie         ERR("tdiGetEntityIDSet returned 0x%08lx\n", status);
386c2c66affSColin Finck         closeTcpFile( tcpFile );
387c2c66affSColin Finck         return 0;
388c2c66affSColin Finck     }
389c2c66affSColin Finck 
390c2c66affSColin Finck     for (i = 0; i < numEntities; i++) {
391c2c66affSColin Finck         if (isIpEntity(tcpFile, &entitySet[i])) {
392c2c66affSColin Finck             IPSNMPInfo isnmp;
393c2c66affSColin Finck             memset(&isnmp, 0, sizeof(isnmp));
394c2c66affSColin Finck             status = tdiGetMibForIpEntity(tcpFile, &entitySet[i], &isnmp);
395c2c66affSColin Finck             if (!NT_SUCCESS(status)) {
39603422451SSerge Gautherie                 ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d\n", status, i);
397b6c060ceSSerge Gautherie                 numRoutes = 0;
398b6c060ceSSerge Gautherie                 break;
399c2c66affSColin Finck             }
400c2c66affSColin Finck             numRoutes += isnmp.ipsi_numroutes;
401c2c66affSColin Finck         }
402c2c66affSColin Finck     }
403c2c66affSColin Finck 
4046c935922SSerge Gautherie     TRACE("numRoutes = %lu\n", numRoutes);
405c2c66affSColin Finck 
406182a3107SThomas Faber     tdiFreeThingSet(entitySet);
407c2c66affSColin Finck     closeTcpFile(tcpFile);
408c2c66affSColin Finck 
409c2c66affSColin Finck     return numRoutes;
410c2c66affSColin Finck }
411c2c66affSColin Finck 
HexDump(PCHAR Data,DWORD Len)412c2c66affSColin Finck VOID HexDump( PCHAR Data, DWORD Len ) {
413c2c66affSColin Finck     int i;
414c2c66affSColin Finck 
415c2c66affSColin Finck     for( i = 0; i < Len; i++ ) {
416c2c66affSColin Finck         if( !(i & 0xf) ) {
417c2c66affSColin Finck             if( i ) fprintf(stderr,"\n");
418c2c66affSColin Finck             fprintf(stderr,"%08x:", i);
419c2c66affSColin Finck         }
420c2c66affSColin Finck         fprintf( stderr, " %02x", Data[i] & 0xff );
421c2c66affSColin Finck     }
422c2c66affSColin Finck     fprintf(stderr,"\n");
423c2c66affSColin Finck }
424c2c66affSColin Finck 
getRouteTable(void)425c2c66affSColin Finck RouteTable *getRouteTable(void)
426c2c66affSColin Finck {
427c2c66affSColin Finck     RouteTable *out_route_table;
428c2c66affSColin Finck     DWORD numRoutes = getNumRoutes(), routesAdded = 0;
429c2c66affSColin Finck     TDIEntityID ent;
430c2c66affSColin Finck     HANDLE tcpFile;
431c2c66affSColin Finck     NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
432c2c66affSColin Finck     int i;
433c2c66affSColin Finck 
434c2c66affSColin Finck     if (!NT_SUCCESS(status))
435c2c66affSColin Finck         return 0;
436c2c66affSColin Finck 
437c2c66affSColin Finck     TRACE("GETTING ROUTE TABLE\n");
438c2c66affSColin Finck 
439c2c66affSColin Finck     out_route_table = HeapAlloc(GetProcessHeap(), 0,
440c2c66affSColin Finck                                 sizeof(RouteTable) +
441c2c66affSColin Finck                                 (sizeof(RouteEntry) * (numRoutes - 1)));
442c2c66affSColin Finck     if (!out_route_table) {
443c2c66affSColin Finck         closeTcpFile(tcpFile);
444c2c66affSColin Finck         return NULL;
445c2c66affSColin Finck     }
446c2c66affSColin Finck 
447c2c66affSColin Finck     out_route_table->numRoutes = numRoutes;
448c2c66affSColin Finck 
449c2c66affSColin Finck     for (i = 0; routesAdded < out_route_table->numRoutes; i++) {
450c2c66affSColin Finck         int j;
451c2c66affSColin Finck         IPRouteEntry *route_set;
452c2c66affSColin Finck 
453c2c66affSColin Finck         getNthIpEntity(tcpFile, i, &ent);
454c2c66affSColin Finck 
455c2c66affSColin Finck         tdiGetRoutesForIpEntity(tcpFile, &ent, &route_set, &numRoutes);
456c2c66affSColin Finck         if (!route_set) {
457c2c66affSColin Finck             closeTcpFile(tcpFile);
458c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, out_route_table);
459c2c66affSColin Finck             return 0;
460c2c66affSColin Finck         }
461c2c66affSColin Finck 
4626c935922SSerge Gautherie         TRACE("%lu routes in instance %d\n", numRoutes, i);
463c2c66affSColin Finck #if 0
464c2c66affSColin Finck         HexDump(route_set,
465c2c66affSColin Finck                 sizeof(IPRouteEntry) *
466c2c66affSColin Finck                 snmpInfo.ipsi_numroutes);
467c2c66affSColin Finck #endif
468c2c66affSColin Finck 
469c2c66affSColin Finck         for (j = 0; j < numRoutes; j++) {
470c2c66affSColin Finck             int routeNum = j + routesAdded;
471c2c66affSColin Finck             out_route_table->routes[routeNum].dest =
472c2c66affSColin Finck                 route_set[j].ire_dest;
473c2c66affSColin Finck             out_route_table->routes[routeNum].mask =
474c2c66affSColin Finck                 route_set[j].ire_mask;
475c2c66affSColin Finck             out_route_table->routes[routeNum].gateway =
476c2c66affSColin Finck                 route_set[j].ire_gw;
477c2c66affSColin Finck             out_route_table->routes[routeNum].ifIndex =
478c2c66affSColin Finck                 route_set[j].ire_index;
479c2c66affSColin Finck             out_route_table->routes[routeNum].metric =
480c2c66affSColin Finck                 route_set[j].ire_metric1;
481c2c66affSColin Finck         }
482c2c66affSColin Finck 
483c2c66affSColin Finck         if (route_set) tdiFreeThingSet(route_set);
484c2c66affSColin Finck 
485c2c66affSColin Finck         routesAdded += numRoutes;
486c2c66affSColin Finck     }
487c2c66affSColin Finck 
488c2c66affSColin Finck     closeTcpFile(tcpFile);
4896c935922SSerge Gautherie     TRACE("status = 0x%08lx, out_route_table = 0x%p\n", status, out_route_table);
490c2c66affSColin Finck     return out_route_table;
491c2c66affSColin Finck }
492c2c66affSColin Finck 
getNumArpEntries(void)493c2c66affSColin Finck DWORD getNumArpEntries(void)
494c2c66affSColin Finck {
495c2c66affSColin Finck     DWORD numEntities;
496c2c66affSColin Finck     TDIEntityID *entitySet = NULL;
497c2c66affSColin Finck     HANDLE tcpFile;
498c2c66affSColin Finck     int i, totalNumber = 0;
499c2c66affSColin Finck     NTSTATUS status;
500c2c66affSColin Finck     PMIB_IPNETROW IpArpTable = NULL;
501c2c66affSColin Finck     DWORD returnSize;
502c2c66affSColin Finck 
503c2c66affSColin Finck     TRACE("called.\n");
504c2c66affSColin Finck 
505c2c66affSColin Finck     status = openTcpFile(&tcpFile, FILE_READ_DATA);
506a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
507a5360f54SJoachim Henze     {
5086c935922SSerge Gautherie         ERR("openTcpFile returned 0x%08lx\n", status);
509c2c66affSColin Finck         return 0;
510c2c66affSColin Finck     }
511c2c66affSColin Finck 
512c2c66affSColin Finck     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
513c2c66affSColin Finck 
514c2c66affSColin Finck     for (i = 0; i < numEntities; i++) {
515a5360f54SJoachim Henze         if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i]))
516a5360f54SJoachim Henze         {
517c2c66affSColin Finck             status = tdiGetSetOfThings(tcpFile,
518c2c66affSColin Finck                 INFO_CLASS_PROTOCOL,
519c2c66affSColin Finck                 INFO_TYPE_PROVIDER,
520c2c66affSColin Finck                 IP_MIB_ARPTABLE_ENTRY_ID,
521c2c66affSColin Finck                 AT_ENTITY,
522c2c66affSColin Finck                 entitySet[i].tei_instance,
523c2c66affSColin Finck                 0,
524c2c66affSColin Finck                 sizeof(MIB_IPNETROW),
525c2c66affSColin Finck                 (PVOID *)&IpArpTable,
526c2c66affSColin Finck                 &returnSize);
527c2c66affSColin Finck 
528c2c66affSColin Finck             if (status == STATUS_SUCCESS) totalNumber += returnSize;
529c2c66affSColin Finck             if (IpArpTable) {
530c2c66affSColin Finck                 tdiFreeThingSet(IpArpTable);
531c2c66affSColin Finck                 IpArpTable = NULL;
532c2c66affSColin Finck             }
533c2c66affSColin Finck         }
534c2c66affSColin Finck     }
535c2c66affSColin Finck 
536c2c66affSColin Finck     closeTcpFile(tcpFile);
537c2c66affSColin Finck     if (entitySet) tdiFreeThingSet(entitySet);
538c2c66affSColin Finck     return totalNumber;
539c2c66affSColin Finck }
540c2c66affSColin Finck 
getArpTable(void)541c2c66affSColin Finck PMIB_IPNETTABLE getArpTable(void)
542c2c66affSColin Finck {
543c2c66affSColin Finck     DWORD numEntities, returnSize;
544c2c66affSColin Finck     TDIEntityID *entitySet;
545c2c66affSColin Finck     HANDLE tcpFile;
546c2c66affSColin Finck     int i, totalNumber, TmpIdx, CurrIdx = 0;
547c2c66affSColin Finck     NTSTATUS status;
548c2c66affSColin Finck     PMIB_IPNETTABLE IpArpTable = NULL;
549c2c66affSColin Finck     PMIB_IPNETROW AdapterArpTable = NULL;
550c2c66affSColin Finck 
551c2c66affSColin Finck     TRACE("called.\n");
552c2c66affSColin Finck 
553c2c66affSColin Finck     totalNumber = getNumArpEntries();
554c2c66affSColin Finck 
555c2c66affSColin Finck     status = openTcpFile(&tcpFile, FILE_READ_DATA);
556a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
557a5360f54SJoachim Henze     {
5586c935922SSerge Gautherie         ERR("openTcpFile returned 0x%08lx\n", status);
559c2c66affSColin Finck         return 0;
560c2c66affSColin Finck     }
561c2c66affSColin Finck 
562a5360f54SJoachim Henze     IpArpTable = HeapAlloc(GetProcessHeap(), 0,
563c2c66affSColin Finck         sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber));
564c2c66affSColin Finck     if (!IpArpTable) {
565c2c66affSColin Finck         closeTcpFile(tcpFile);
566c2c66affSColin Finck         return NULL;
567c2c66affSColin Finck     }
568c2c66affSColin Finck 
569c2c66affSColin Finck     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
570c2c66affSColin Finck 
571c2c66affSColin Finck     for (i = 0; i < numEntities; i++) {
572a5360f54SJoachim Henze         if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i]))
573a5360f54SJoachim Henze         {
574c2c66affSColin Finck             status = tdiGetSetOfThings(tcpFile,
575c2c66affSColin Finck                 INFO_CLASS_PROTOCOL,
576c2c66affSColin Finck                 INFO_TYPE_PROVIDER,
577c2c66affSColin Finck                 IP_MIB_ARPTABLE_ENTRY_ID,
578c2c66affSColin Finck                 AT_ENTITY,
579c2c66affSColin Finck                 entitySet[i].tei_instance,
580c2c66affSColin Finck                 0,
581c2c66affSColin Finck                 sizeof(MIB_IPNETROW),
582c2c66affSColin Finck                 (PVOID *)&AdapterArpTable,
583c2c66affSColin Finck                 &returnSize);
584c2c66affSColin Finck 
585c2c66affSColin Finck             if (status == STATUS_SUCCESS) {
586c2c66affSColin Finck                 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
587c2c66affSColin Finck                     IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx];
588c2c66affSColin Finck                 tdiFreeThingSet(AdapterArpTable);
589c2c66affSColin Finck             }
590c2c66affSColin Finck         }
591c2c66affSColin Finck     }
592c2c66affSColin Finck 
593c2c66affSColin Finck     closeTcpFile(tcpFile);
594c2c66affSColin Finck     tdiFreeThingSet(entitySet);
595c2c66affSColin Finck     IpArpTable->dwNumEntries = CurrIdx;
596c2c66affSColin Finck     return IpArpTable;
597c2c66affSColin Finck }
598c2c66affSColin Finck 
599bf052e12SPierre Schweitzer struct _TABLE_CALL
600bf052e12SPierre Schweitzer {
601bf052e12SPierre Schweitzer     DWORD TOIID;
602bf052e12SPierre Schweitzer     SIZE_T UdpSize;
603bf052e12SPierre Schweitzer     SIZE_T TcpSize;
604bf052e12SPierre Schweitzer     SIZE_T UdpOffset;
605bf052e12SPierre Schweitzer     SIZE_T TcpOffset;
606bf052e12SPierre Schweitzer } UdpTcpTableCall[] = {
607bf052e12SPierre Schweitzer     {IP_MIB_ARPTABLE_ENTRY_ID, sizeof(MIB_UDPROW), sizeof(MIB_TCPROW), FIELD_OFFSET(MIB_UDPTABLE, table), FIELD_OFFSET(MIB_TCPTABLE, table)},
608bf052e12SPierre Schweitzer     {IP_MIB_ADDRTABLE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_PID), sizeof(MIB_TCPROW_OWNER_PID), FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table)},
609bf052e12SPierre Schweitzer     {IP_SPECIFIC_MODULE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_MODULE), sizeof(MIB_TCPROW_OWNER_MODULE), FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table)},
610bf052e12SPierre Schweitzer };
611bf052e12SPierre Schweitzer 
612bf052e12SPierre Schweitzer #define Add2Ptr(PTR, INC) (PVOID)((ULONG_PTR)(PTR) + (INC))
613bf052e12SPierre Schweitzer 
getNumUdpEntries(void)614c2c66affSColin Finck DWORD getNumUdpEntries(void)
615c2c66affSColin Finck {
616e3cb9697SPierre Schweitzer     DWORD numEntities;
617e3cb9697SPierre Schweitzer     TDIEntityID *entitySet = NULL;
618e3cb9697SPierre Schweitzer     HANDLE tcpFile;
619e3cb9697SPierre Schweitzer     int i, totalNumber = 0;
620e3cb9697SPierre Schweitzer     NTSTATUS status;
621e3cb9697SPierre Schweitzer     PMIB_UDPROW IpUdpTable = NULL;
622e3cb9697SPierre Schweitzer     DWORD returnSize;
623e3cb9697SPierre Schweitzer 
624e3cb9697SPierre Schweitzer     TRACE("called.\n");
625e3cb9697SPierre Schweitzer 
626e3cb9697SPierre Schweitzer     status = openTcpFile(&tcpFile, FILE_READ_DATA);
627a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
628a5360f54SJoachim Henze     {
629e3cb9697SPierre Schweitzer         ERR("openTcpFile returned 0x%08lx\n", status);
630e3cb9697SPierre Schweitzer         return 0;
631e3cb9697SPierre Schweitzer     }
632e3cb9697SPierre Schweitzer 
633e3cb9697SPierre Schweitzer     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
634e3cb9697SPierre Schweitzer 
635e3cb9697SPierre Schweitzer     for (i = 0; i < numEntities; i++) {
636a5360f54SJoachim Henze         if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
637a5360f54SJoachim Henze         {
638e3cb9697SPierre Schweitzer             status = tdiGetSetOfThings(tcpFile,
639e3cb9697SPierre Schweitzer                 INFO_CLASS_PROTOCOL,
640e3cb9697SPierre Schweitzer                 INFO_TYPE_PROVIDER,
641e3cb9697SPierre Schweitzer                 IP_MIB_ARPTABLE_ENTRY_ID,
642e3cb9697SPierre Schweitzer                 CL_TL_ENTITY,
643e3cb9697SPierre Schweitzer                 entitySet[i].tei_instance,
644e3cb9697SPierre Schweitzer                 0,
645e3cb9697SPierre Schweitzer                 sizeof(MIB_UDPROW),
646e3cb9697SPierre Schweitzer                 (PVOID *)&IpUdpTable,
647e3cb9697SPierre Schweitzer                 &returnSize);
648e3cb9697SPierre Schweitzer 
649e3cb9697SPierre Schweitzer             if (status == STATUS_SUCCESS) totalNumber += returnSize;
650e3cb9697SPierre Schweitzer             if (IpUdpTable) {
651e3cb9697SPierre Schweitzer                 tdiFreeThingSet(IpUdpTable);
652e3cb9697SPierre Schweitzer                 IpUdpTable = NULL;
653e3cb9697SPierre Schweitzer             }
654e3cb9697SPierre Schweitzer         }
655e3cb9697SPierre Schweitzer     }
656e3cb9697SPierre Schweitzer 
657e3cb9697SPierre Schweitzer     closeTcpFile(tcpFile);
658e3cb9697SPierre Schweitzer     if (entitySet) tdiFreeThingSet(entitySet);
659e3cb9697SPierre Schweitzer     return totalNumber;
660c2c66affSColin Finck }
661c2c66affSColin Finck 
getUdpTable(CLASS_TABLE Class)662bf052e12SPierre Schweitzer PVOID getUdpTable(CLASS_TABLE Class)
663c2c66affSColin Finck {
664e3cb9697SPierre Schweitzer     DWORD numEntities, returnSize;
665e3cb9697SPierre Schweitzer     TDIEntityID *entitySet;
666e3cb9697SPierre Schweitzer     HANDLE tcpFile;
667e3cb9697SPierre Schweitzer     int i, totalNumber, TmpIdx, CurrIdx = 0;
668e3cb9697SPierre Schweitzer     NTSTATUS status;
669e3cb9697SPierre Schweitzer     PMIB_UDPTABLE IpUdpTable = NULL;
670bf052e12SPierre Schweitzer     PVOID AdapterUdpTable = NULL;
671c2c66affSColin Finck 
672e3cb9697SPierre Schweitzer     TRACE("called.\n");
673c2c66affSColin Finck 
674d18b1fe2SPierre Schweitzer     totalNumber = getNumUdpEntries();
675c2c66affSColin Finck 
676e3cb9697SPierre Schweitzer     status = openTcpFile(&tcpFile, FILE_READ_DATA);
677a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
678a5360f54SJoachim Henze     {
679e3cb9697SPierre Schweitzer         ERR("openTcpFile returned 0x%08lx\n", status);
680e3cb9697SPierre Schweitzer         return 0;
681e3cb9697SPierre Schweitzer     }
682c2c66affSColin Finck 
683a5360f54SJoachim Henze     IpUdpTable = HeapAlloc(GetProcessHeap(), 0,
684bf052e12SPierre Schweitzer         UdpTcpTableCall[Class].UdpOffset + (UdpTcpTableCall[Class].UdpSize * totalNumber));
685e3cb9697SPierre Schweitzer     if (!IpUdpTable) {
686e3cb9697SPierre Schweitzer         closeTcpFile(tcpFile);
687e3cb9697SPierre Schweitzer         return NULL;
688c2c66affSColin Finck     }
689e3cb9697SPierre Schweitzer 
690e3cb9697SPierre Schweitzer     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
691e3cb9697SPierre Schweitzer 
692e3cb9697SPierre Schweitzer     for (i = 0; i < numEntities; i++) {
693a5360f54SJoachim Henze         if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
694a5360f54SJoachim Henze         {
695e3cb9697SPierre Schweitzer             status = tdiGetSetOfThings(tcpFile,
696e3cb9697SPierre Schweitzer                 INFO_CLASS_PROTOCOL,
697e3cb9697SPierre Schweitzer                 INFO_TYPE_PROVIDER,
698bf052e12SPierre Schweitzer                 UdpTcpTableCall[Class].TOIID,
699e3cb9697SPierre Schweitzer                 CL_TL_ENTITY,
700e3cb9697SPierre Schweitzer                 entitySet[i].tei_instance,
701e3cb9697SPierre Schweitzer                 0,
702bf052e12SPierre Schweitzer                 UdpTcpTableCall[Class].UdpSize,
703bf052e12SPierre Schweitzer                 &AdapterUdpTable,
704e3cb9697SPierre Schweitzer                 &returnSize);
705e3cb9697SPierre Schweitzer 
706e3cb9697SPierre Schweitzer             if (status == STATUS_SUCCESS) {
707e3cb9697SPierre Schweitzer                 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
708bf052e12SPierre Schweitzer                     CopyMemory(Add2Ptr(IpUdpTable, UdpTcpTableCall[Class].UdpOffset + UdpTcpTableCall[Class].UdpSize * CurrIdx),
709bf052e12SPierre Schweitzer                                Add2Ptr(AdapterUdpTable, UdpTcpTableCall[Class].UdpSize * TmpIdx),
710bf052e12SPierre Schweitzer                                UdpTcpTableCall[Class].UdpSize);
711e3cb9697SPierre Schweitzer                 tdiFreeThingSet(AdapterUdpTable);
712c2c66affSColin Finck             }
713c2c66affSColin Finck         }
714c2c66affSColin Finck     }
715e3cb9697SPierre Schweitzer 
716e3cb9697SPierre Schweitzer     closeTcpFile(tcpFile);
717e3cb9697SPierre Schweitzer     tdiFreeThingSet(entitySet);
718e3cb9697SPierre Schweitzer     IpUdpTable->dwNumEntries = CurrIdx;
719e3cb9697SPierre Schweitzer     return IpUdpTable;
720c2c66affSColin Finck }
721c2c66affSColin Finck 
getNumTcpEntries(void)722c2c66affSColin Finck DWORD getNumTcpEntries(void)
723c2c66affSColin Finck {
72467820479SPierre Schweitzer     DWORD numEntities;
72567820479SPierre Schweitzer     TDIEntityID *entitySet = NULL;
72667820479SPierre Schweitzer     HANDLE tcpFile;
72767820479SPierre Schweitzer     int i, totalNumber = 0;
72867820479SPierre Schweitzer     NTSTATUS status;
72967820479SPierre Schweitzer     PMIB_TCPROW IpTcpTable = NULL;
73067820479SPierre Schweitzer     DWORD returnSize;
73167820479SPierre Schweitzer 
73267820479SPierre Schweitzer     TRACE("called.\n");
73367820479SPierre Schweitzer 
73467820479SPierre Schweitzer     status = openTcpFile(&tcpFile, FILE_READ_DATA);
735a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
736a5360f54SJoachim Henze     {
73767820479SPierre Schweitzer         ERR("openTcpFile returned 0x%08lx\n", status);
73867820479SPierre Schweitzer         return 0;
73967820479SPierre Schweitzer     }
74067820479SPierre Schweitzer 
74167820479SPierre Schweitzer     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
74267820479SPierre Schweitzer 
74367820479SPierre Schweitzer     for (i = 0; i < numEntities; i++) {
744a5360f54SJoachim Henze         if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
745a5360f54SJoachim Henze         {
74667820479SPierre Schweitzer             status = tdiGetSetOfThings(tcpFile,
74767820479SPierre Schweitzer                 INFO_CLASS_PROTOCOL,
74867820479SPierre Schweitzer                 INFO_TYPE_PROVIDER,
74967820479SPierre Schweitzer                 IP_MIB_ARPTABLE_ENTRY_ID,
75067820479SPierre Schweitzer                 CO_TL_ENTITY,
75167820479SPierre Schweitzer                 entitySet[i].tei_instance,
75267820479SPierre Schweitzer                 0,
75367820479SPierre Schweitzer                 sizeof(MIB_TCPROW),
75467820479SPierre Schweitzer                 (PVOID *)&IpTcpTable,
75567820479SPierre Schweitzer                 &returnSize);
75667820479SPierre Schweitzer 
75767820479SPierre Schweitzer             if (status == STATUS_SUCCESS) totalNumber += returnSize;
75867820479SPierre Schweitzer             if (IpTcpTable) {
75967820479SPierre Schweitzer                 tdiFreeThingSet(IpTcpTable);
76067820479SPierre Schweitzer                 IpTcpTable = NULL;
76167820479SPierre Schweitzer             }
76267820479SPierre Schweitzer         }
76367820479SPierre Schweitzer     }
76467820479SPierre Schweitzer 
76567820479SPierre Schweitzer     closeTcpFile(tcpFile);
76667820479SPierre Schweitzer     if (entitySet) tdiFreeThingSet(entitySet);
76767820479SPierre Schweitzer     return totalNumber;
768c2c66affSColin Finck }
769c2c66affSColin Finck 
getTcpTable(CLASS_TABLE Class)770bf052e12SPierre Schweitzer PVOID getTcpTable(CLASS_TABLE Class)
771c2c66affSColin Finck {
77267820479SPierre Schweitzer     DWORD numEntities, returnSize;
77367820479SPierre Schweitzer     TDIEntityID *entitySet;
77467820479SPierre Schweitzer     HANDLE tcpFile;
77567820479SPierre Schweitzer     int i, totalNumber, TmpIdx, CurrIdx = 0;
77667820479SPierre Schweitzer     NTSTATUS status;
77767820479SPierre Schweitzer     PMIB_TCPTABLE IpTcpTable = NULL;
778bf052e12SPierre Schweitzer     PVOID AdapterTcpTable = NULL;
77967820479SPierre Schweitzer 
78067820479SPierre Schweitzer     TRACE("called.\n");
78167820479SPierre Schweitzer 
78267820479SPierre Schweitzer     totalNumber = getNumTcpEntries();
78367820479SPierre Schweitzer 
78467820479SPierre Schweitzer     status = openTcpFile(&tcpFile, FILE_READ_DATA);
785a5360f54SJoachim Henze     if (!NT_SUCCESS(status))
786a5360f54SJoachim Henze     {
78767820479SPierre Schweitzer         ERR("openTcpFile returned 0x%08lx\n", status);
788c2c66affSColin Finck         return 0;
789c2c66affSColin Finck     }
79067820479SPierre Schweitzer 
791a5360f54SJoachim Henze     IpTcpTable = HeapAlloc(GetProcessHeap(), 0,
792bf052e12SPierre Schweitzer         UdpTcpTableCall[Class].TcpOffset + (UdpTcpTableCall[Class].TcpSize * totalNumber));
79367820479SPierre Schweitzer     if (!IpTcpTable) {
79467820479SPierre Schweitzer         closeTcpFile(tcpFile);
79567820479SPierre Schweitzer         return NULL;
79667820479SPierre Schweitzer     }
79767820479SPierre Schweitzer 
79867820479SPierre Schweitzer     status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
79967820479SPierre Schweitzer 
80067820479SPierre Schweitzer     for (i = 0; i < numEntities; i++) {
801a5360f54SJoachim Henze         if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
802a5360f54SJoachim Henze         {
80367820479SPierre Schweitzer             status = tdiGetSetOfThings(tcpFile,
80467820479SPierre Schweitzer                 INFO_CLASS_PROTOCOL,
80567820479SPierre Schweitzer                 INFO_TYPE_PROVIDER,
806bf052e12SPierre Schweitzer                 UdpTcpTableCall[Class].TOIID,
80767820479SPierre Schweitzer                 CO_TL_ENTITY,
80867820479SPierre Schweitzer                 entitySet[i].tei_instance,
80967820479SPierre Schweitzer                 0,
810bf052e12SPierre Schweitzer                 UdpTcpTableCall[Class].TcpSize,
811bf052e12SPierre Schweitzer                 &AdapterTcpTable,
81267820479SPierre Schweitzer                 &returnSize);
81367820479SPierre Schweitzer 
81467820479SPierre Schweitzer             if (status == STATUS_SUCCESS) {
81567820479SPierre Schweitzer                 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
816bf052e12SPierre Schweitzer                     CopyMemory(Add2Ptr(IpTcpTable, UdpTcpTableCall[Class].TcpOffset + UdpTcpTableCall[Class].TcpSize * CurrIdx),
817bf052e12SPierre Schweitzer                                Add2Ptr(AdapterTcpTable, UdpTcpTableCall[Class].TcpSize * TmpIdx),
818bf052e12SPierre Schweitzer                                UdpTcpTableCall[Class].TcpSize);
81967820479SPierre Schweitzer                 tdiFreeThingSet(AdapterTcpTable);
82067820479SPierre Schweitzer             }
82167820479SPierre Schweitzer         }
82267820479SPierre Schweitzer     }
82367820479SPierre Schweitzer 
82467820479SPierre Schweitzer     closeTcpFile(tcpFile);
82567820479SPierre Schweitzer     tdiFreeThingSet(entitySet);
82667820479SPierre Schweitzer     IpTcpTable->dwNumEntries = CurrIdx;
82767820479SPierre Schweitzer     return IpTcpTable;
82867820479SPierre Schweitzer }
829