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 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 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 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 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 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 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 201c2c66affSColin Finck DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry) 202c2c66affSColin Finck { 203c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 204c2c66affSColin Finck } 205c2c66affSColin Finck 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); 222c2c66affSColin Finck } while (ptr && strncasecmp(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); 226c2c66affSColin Finck if (ptr && strncasecmp(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 333c2c66affSColin Finck DWORD getIPStats(PMIB_IPSTATS stats, DWORD family) 334c2c66affSColin Finck { 335c2c66affSColin Finck if (!stats) 336c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 337c2c66affSColin Finck return NO_ERROR; 338c2c66affSColin Finck } 339c2c66affSColin Finck 340c2c66affSColin Finck DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family) 341c2c66affSColin Finck { 342c2c66affSColin Finck if (!stats) 343c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 344c2c66affSColin Finck return NO_ERROR; 345c2c66affSColin Finck } 346c2c66affSColin Finck 347c2c66affSColin Finck DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family) 348c2c66affSColin Finck { 349c2c66affSColin Finck if (!stats) 350c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 351c2c66affSColin Finck return NO_ERROR; 352c2c66affSColin Finck } 353c2c66affSColin Finck 354c2c66affSColin Finck static DWORD getNumWithOneHeader(const char *filename) 355c2c66affSColin Finck { 356c2c66affSColin Finck return 0; 357c2c66affSColin Finck } 358c2c66affSColin Finck 359c2c66affSColin Finck DWORD getNumRoutes(void) 360c2c66affSColin Finck { 361c2c66affSColin Finck DWORD numEntities, numRoutes = 0; 362c2c66affSColin Finck TDIEntityID *entitySet; 363c2c66affSColin Finck HANDLE tcpFile; 364c2c66affSColin Finck int i; 365c2c66affSColin Finck NTSTATUS status; 366c2c66affSColin Finck 367c2c66affSColin Finck TRACE("called.\n"); 368c2c66affSColin Finck 369c2c66affSColin Finck status = openTcpFile( &tcpFile, FILE_READ_DATA ); 370c2c66affSColin Finck if( !NT_SUCCESS(status) ) { 3716c935922SSerge Gautherie ERR("openTcpFile returned 0x%08lx\n", status); 372c2c66affSColin Finck return 0; 373c2c66affSColin Finck } 374c2c66affSColin Finck 375c2c66affSColin Finck status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); 376c2c66affSColin Finck if( !NT_SUCCESS(status) ) { 3776c935922SSerge Gautherie ERR("tdiGetEntityIDSet returned 0x%08lx\n", status); 378c2c66affSColin Finck closeTcpFile( tcpFile ); 379c2c66affSColin Finck return 0; 380c2c66affSColin Finck } 381c2c66affSColin Finck 382c2c66affSColin Finck for( i = 0; i < numEntities; i++ ) { 383c2c66affSColin Finck if( isIpEntity( tcpFile, &entitySet[i] ) ) { 384c2c66affSColin Finck IPSNMPInfo isnmp; 385c2c66affSColin Finck memset( &isnmp, 0, sizeof( isnmp ) ); 386c2c66affSColin Finck status = tdiGetMibForIpEntity( tcpFile, &entitySet[i], &isnmp ); 387c2c66affSColin Finck if( !NT_SUCCESS(status) ) { 3886c935922SSerge Gautherie ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d", status, i); 389b6c060ceSSerge Gautherie numRoutes = 0; 390b6c060ceSSerge Gautherie break; 391c2c66affSColin Finck } 392c2c66affSColin Finck numRoutes += isnmp.ipsi_numroutes; 393c2c66affSColin Finck } 394c2c66affSColin Finck } 395c2c66affSColin Finck 3966c935922SSerge Gautherie TRACE("numRoutes = %lu\n", numRoutes); 397c2c66affSColin Finck 398182a3107SThomas Faber tdiFreeThingSet( entitySet ); 399c2c66affSColin Finck closeTcpFile( tcpFile ); 400c2c66affSColin Finck 401c2c66affSColin Finck return numRoutes; 402c2c66affSColin Finck } 403c2c66affSColin Finck 404c2c66affSColin Finck VOID HexDump( PCHAR Data, DWORD Len ) { 405c2c66affSColin Finck int i; 406c2c66affSColin Finck 407c2c66affSColin Finck for( i = 0; i < Len; i++ ) { 408c2c66affSColin Finck if( !(i & 0xf) ) { 409c2c66affSColin Finck if( i ) fprintf(stderr,"\n"); 410c2c66affSColin Finck fprintf(stderr,"%08x:", i); 411c2c66affSColin Finck } 412c2c66affSColin Finck fprintf( stderr, " %02x", Data[i] & 0xff ); 413c2c66affSColin Finck } 414c2c66affSColin Finck fprintf(stderr,"\n"); 415c2c66affSColin Finck } 416c2c66affSColin Finck 417c2c66affSColin Finck RouteTable *getRouteTable(void) 418c2c66affSColin Finck { 419c2c66affSColin Finck RouteTable *out_route_table; 420c2c66affSColin Finck DWORD numRoutes = getNumRoutes(), routesAdded = 0; 421c2c66affSColin Finck TDIEntityID ent; 422c2c66affSColin Finck HANDLE tcpFile; 423c2c66affSColin Finck NTSTATUS status = openTcpFile( &tcpFile, FILE_READ_DATA ); 424c2c66affSColin Finck int i; 425c2c66affSColin Finck 426c2c66affSColin Finck if( !NT_SUCCESS(status) ) 427c2c66affSColin Finck return 0; 428c2c66affSColin Finck 429c2c66affSColin Finck TRACE("GETTING ROUTE TABLE\n"); 430c2c66affSColin Finck 431c2c66affSColin Finck out_route_table = HeapAlloc( GetProcessHeap(), 0, 432c2c66affSColin Finck sizeof(RouteTable) + 433c2c66affSColin Finck (sizeof(RouteEntry) * (numRoutes - 1)) ); 434c2c66affSColin Finck if (!out_route_table) { 435c2c66affSColin Finck closeTcpFile(tcpFile); 436c2c66affSColin Finck return NULL; 437c2c66affSColin Finck } 438c2c66affSColin Finck 439c2c66affSColin Finck out_route_table->numRoutes = numRoutes; 440c2c66affSColin Finck 441c2c66affSColin Finck for( i = 0; routesAdded < out_route_table->numRoutes; i++ ) { 442c2c66affSColin Finck int j; 443c2c66affSColin Finck IPRouteEntry *route_set; 444c2c66affSColin Finck 445c2c66affSColin Finck getNthIpEntity( tcpFile, i, &ent ); 446c2c66affSColin Finck 447c2c66affSColin Finck tdiGetRoutesForIpEntity( tcpFile, &ent, &route_set, &numRoutes ); 448c2c66affSColin Finck 449c2c66affSColin Finck if( !route_set ) { 450c2c66affSColin Finck closeTcpFile( tcpFile ); 451c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, out_route_table ); 452c2c66affSColin Finck return 0; 453c2c66affSColin Finck } 454c2c66affSColin Finck 4556c935922SSerge Gautherie TRACE("%lu routes in instance %d\n", numRoutes, i); 456c2c66affSColin Finck #if 0 457c2c66affSColin Finck HexDump( route_set, 458c2c66affSColin Finck sizeof( IPRouteEntry ) * 459c2c66affSColin Finck snmpInfo.ipsi_numroutes ); 460c2c66affSColin Finck #endif 461c2c66affSColin Finck 462c2c66affSColin Finck for( j = 0; j < numRoutes; j++ ) { 463c2c66affSColin Finck int routeNum = j + routesAdded; 464c2c66affSColin Finck out_route_table->routes[routeNum].dest = 465c2c66affSColin Finck route_set[j].ire_dest; 466c2c66affSColin Finck out_route_table->routes[routeNum].mask = 467c2c66affSColin Finck route_set[j].ire_mask; 468c2c66affSColin Finck out_route_table->routes[routeNum].gateway = 469c2c66affSColin Finck route_set[j].ire_gw; 470c2c66affSColin Finck out_route_table->routes[routeNum].ifIndex = 471c2c66affSColin Finck route_set[j].ire_index; 472c2c66affSColin Finck out_route_table->routes[routeNum].metric = 473c2c66affSColin Finck route_set[j].ire_metric1; 474c2c66affSColin Finck } 475c2c66affSColin Finck 476c2c66affSColin Finck if( route_set ) tdiFreeThingSet( route_set ); 477c2c66affSColin Finck 478c2c66affSColin Finck routesAdded += numRoutes; 479c2c66affSColin Finck } 480c2c66affSColin Finck 481c2c66affSColin Finck closeTcpFile( tcpFile ); 482c2c66affSColin Finck 4836c935922SSerge Gautherie TRACE("status = 0x%08lx, out_route_table = 0x%p\n", status, out_route_table); 484c2c66affSColin Finck 485c2c66affSColin Finck return out_route_table; 486c2c66affSColin Finck } 487c2c66affSColin Finck 488c2c66affSColin Finck DWORD getNumArpEntries(void) 489c2c66affSColin Finck { 490c2c66affSColin Finck DWORD numEntities; 491c2c66affSColin Finck TDIEntityID *entitySet = NULL; 492c2c66affSColin Finck HANDLE tcpFile; 493c2c66affSColin Finck int i, totalNumber = 0; 494c2c66affSColin Finck NTSTATUS status; 495c2c66affSColin Finck PMIB_IPNETROW IpArpTable = NULL; 496c2c66affSColin Finck DWORD returnSize; 497c2c66affSColin Finck 498c2c66affSColin Finck TRACE("called.\n"); 499c2c66affSColin Finck 500c2c66affSColin Finck status = openTcpFile( &tcpFile, FILE_READ_DATA ); 501c2c66affSColin Finck if( !NT_SUCCESS(status) ) { 5026c935922SSerge Gautherie ERR("openTcpFile returned 0x%08lx\n", status); 503c2c66affSColin Finck return 0; 504c2c66affSColin Finck } 505c2c66affSColin Finck 506c2c66affSColin Finck status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); 507c2c66affSColin Finck 508c2c66affSColin Finck for( i = 0; i < numEntities; i++ ) { 509c2c66affSColin Finck if( isInterface( &entitySet[i] ) && 510c2c66affSColin Finck hasArp( tcpFile, &entitySet[i] ) ) { 511c2c66affSColin Finck 512c2c66affSColin Finck status = tdiGetSetOfThings( tcpFile, 513c2c66affSColin Finck INFO_CLASS_PROTOCOL, 514c2c66affSColin Finck INFO_TYPE_PROVIDER, 515c2c66affSColin Finck IP_MIB_ARPTABLE_ENTRY_ID, 516c2c66affSColin Finck AT_ENTITY, 517c2c66affSColin Finck entitySet[i].tei_instance, 518c2c66affSColin Finck 0, 519c2c66affSColin Finck sizeof(MIB_IPNETROW), 520c2c66affSColin Finck (PVOID *)&IpArpTable, 521c2c66affSColin Finck &returnSize ); 522c2c66affSColin Finck 523c2c66affSColin Finck if( status == STATUS_SUCCESS ) totalNumber += returnSize; 524c2c66affSColin Finck if( IpArpTable ) { 525c2c66affSColin Finck tdiFreeThingSet( IpArpTable ); 526c2c66affSColin Finck IpArpTable = NULL; 527c2c66affSColin Finck } 528c2c66affSColin Finck } 529c2c66affSColin Finck } 530c2c66affSColin Finck 531c2c66affSColin Finck closeTcpFile( tcpFile ); 532c2c66affSColin Finck if( IpArpTable ) tdiFreeThingSet( IpArpTable ); 533c2c66affSColin Finck if( entitySet ) tdiFreeThingSet( entitySet ); 534c2c66affSColin Finck return totalNumber; 535c2c66affSColin Finck } 536c2c66affSColin Finck 537c2c66affSColin Finck PMIB_IPNETTABLE getArpTable(void) 538c2c66affSColin Finck { 539c2c66affSColin Finck DWORD numEntities, returnSize; 540c2c66affSColin Finck TDIEntityID *entitySet; 541c2c66affSColin Finck HANDLE tcpFile; 542c2c66affSColin Finck int i, totalNumber, TmpIdx, CurrIdx = 0; 543c2c66affSColin Finck NTSTATUS status; 544c2c66affSColin Finck PMIB_IPNETTABLE IpArpTable = NULL; 545c2c66affSColin Finck PMIB_IPNETROW AdapterArpTable = NULL; 546c2c66affSColin Finck 547c2c66affSColin Finck TRACE("called.\n"); 548c2c66affSColin Finck 549c2c66affSColin Finck totalNumber = getNumArpEntries(); 550c2c66affSColin Finck 551c2c66affSColin Finck status = openTcpFile( &tcpFile, FILE_READ_DATA ); 552c2c66affSColin Finck if( !NT_SUCCESS(status) ) { 5536c935922SSerge Gautherie ERR("openTcpFile returned 0x%08lx\n", status); 554c2c66affSColin Finck return 0; 555c2c66affSColin Finck } 556c2c66affSColin Finck 557c2c66affSColin Finck IpArpTable = HeapAlloc 558c2c66affSColin Finck ( GetProcessHeap(), 0, 559c2c66affSColin Finck sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) ); 560c2c66affSColin Finck if (!IpArpTable) { 561c2c66affSColin Finck closeTcpFile(tcpFile); 562c2c66affSColin Finck return NULL; 563c2c66affSColin Finck } 564c2c66affSColin Finck 565c2c66affSColin Finck status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); 566c2c66affSColin Finck 567c2c66affSColin Finck for( i = 0; i < numEntities; i++ ) { 568c2c66affSColin Finck if( isInterface( &entitySet[i] ) && 569c2c66affSColin Finck hasArp( tcpFile, &entitySet[i] ) ) { 570c2c66affSColin Finck 571c2c66affSColin Finck status = tdiGetSetOfThings( tcpFile, 572c2c66affSColin Finck INFO_CLASS_PROTOCOL, 573c2c66affSColin Finck INFO_TYPE_PROVIDER, 574c2c66affSColin Finck IP_MIB_ARPTABLE_ENTRY_ID, 575c2c66affSColin Finck AT_ENTITY, 576c2c66affSColin Finck entitySet[i].tei_instance, 577c2c66affSColin Finck 0, 578c2c66affSColin Finck sizeof(MIB_IPNETROW), 579c2c66affSColin Finck (PVOID *)&AdapterArpTable, 580c2c66affSColin Finck &returnSize ); 581c2c66affSColin Finck 582c2c66affSColin Finck if( status == STATUS_SUCCESS ) { 583c2c66affSColin Finck for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ ) 584c2c66affSColin Finck IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx]; 585c2c66affSColin Finck tdiFreeThingSet( AdapterArpTable ); 586c2c66affSColin Finck } 587c2c66affSColin Finck } 588c2c66affSColin Finck } 589c2c66affSColin Finck 590c2c66affSColin Finck closeTcpFile( tcpFile ); 591c2c66affSColin Finck 592c2c66affSColin Finck tdiFreeThingSet( entitySet ); 593c2c66affSColin Finck IpArpTable->dwNumEntries = CurrIdx; 594c2c66affSColin Finck 595c2c66affSColin Finck return IpArpTable; 596c2c66affSColin Finck } 597c2c66affSColin Finck 598c2c66affSColin Finck DWORD getNumUdpEntries(void) 599c2c66affSColin Finck { 600c2c66affSColin Finck return getNumWithOneHeader("/proc/net/udp"); 601c2c66affSColin Finck } 602c2c66affSColin Finck 603c2c66affSColin Finck PMIB_UDPTABLE getUdpTable(void) 604c2c66affSColin Finck { 605c2c66affSColin Finck DWORD numEntries = getNumUdpEntries(); 606c2c66affSColin Finck PMIB_UDPTABLE ret; 607c2c66affSColin Finck 608c2c66affSColin Finck ret = (PMIB_UDPTABLE)calloc(1, sizeof(MIB_UDPTABLE) + 609c2c66affSColin Finck (numEntries - 1) * sizeof(MIB_UDPROW)); 610c2c66affSColin Finck if (ret) { 611c2c66affSColin Finck FILE *fp; 612c2c66affSColin Finck 613c2c66affSColin Finck /* get from /proc/net/udp, no error if can't */ 614c2c66affSColin Finck fp = fopen("/proc/net/udp", "r"); 615c2c66affSColin Finck if (fp) { 616c2c66affSColin Finck char buf[512] = { 0 }, *ptr; 617c2c66affSColin Finck 618c2c66affSColin Finck /* skip header line */ 619c2c66affSColin Finck ptr = fgets(buf, sizeof(buf), fp); 620c2c66affSColin Finck while (ptr && ret->dwNumEntries < numEntries) { 621c2c66affSColin Finck ptr = fgets(buf, sizeof(buf), fp); 622c2c66affSColin Finck if (ptr) { 623c2c66affSColin Finck char *endPtr; 624c2c66affSColin Finck 625c2c66affSColin Finck if (ptr && *ptr) { 626c2c66affSColin Finck strtoul(ptr, &endPtr, 16); /* skip */ 627c2c66affSColin Finck ptr = endPtr; 628c2c66affSColin Finck } 629c2c66affSColin Finck if (ptr && *ptr) { 630c2c66affSColin Finck ptr++; 631c2c66affSColin Finck ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr, 632c2c66affSColin Finck 16); 633c2c66affSColin Finck ptr = endPtr; 634c2c66affSColin Finck } 635c2c66affSColin Finck if (ptr && *ptr) { 636c2c66affSColin Finck ptr++; 637c2c66affSColin Finck ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr, 638c2c66affSColin Finck 16); 639c2c66affSColin Finck ptr = endPtr; 640c2c66affSColin Finck } 641c2c66affSColin Finck ret->dwNumEntries++; 642c2c66affSColin Finck } 643c2c66affSColin Finck } 644c2c66affSColin Finck fclose(fp); 645c2c66affSColin Finck } 646c2c66affSColin Finck } 647c2c66affSColin Finck return ret; 648c2c66affSColin Finck } 649c2c66affSColin Finck 650c2c66affSColin Finck DWORD getNumTcpEntries(void) 651c2c66affSColin Finck { 652*67820479SPierre Schweitzer DWORD numEntities; 653*67820479SPierre Schweitzer TDIEntityID *entitySet = NULL; 654*67820479SPierre Schweitzer HANDLE tcpFile; 655*67820479SPierre Schweitzer int i, totalNumber = 0; 656*67820479SPierre Schweitzer NTSTATUS status; 657*67820479SPierre Schweitzer PMIB_TCPROW IpTcpTable = NULL; 658*67820479SPierre Schweitzer DWORD returnSize; 659*67820479SPierre Schweitzer 660*67820479SPierre Schweitzer TRACE("called.\n"); 661*67820479SPierre Schweitzer 662*67820479SPierre Schweitzer status = openTcpFile( &tcpFile, FILE_READ_DATA ); 663*67820479SPierre Schweitzer if( !NT_SUCCESS(status) ) { 664*67820479SPierre Schweitzer ERR("openTcpFile returned 0x%08lx\n", status); 665*67820479SPierre Schweitzer return 0; 666*67820479SPierre Schweitzer } 667*67820479SPierre Schweitzer 668*67820479SPierre Schweitzer status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); 669*67820479SPierre Schweitzer 670*67820479SPierre Schweitzer for( i = 0; i < numEntities; i++ ) { 671*67820479SPierre Schweitzer if( isInterface( &entitySet[i] ) && 672*67820479SPierre Schweitzer hasArp( tcpFile, &entitySet[i] ) ) { 673*67820479SPierre Schweitzer 674*67820479SPierre Schweitzer status = tdiGetSetOfThings( tcpFile, 675*67820479SPierre Schweitzer INFO_CLASS_PROTOCOL, 676*67820479SPierre Schweitzer INFO_TYPE_PROVIDER, 677*67820479SPierre Schweitzer IP_MIB_ARPTABLE_ENTRY_ID, 678*67820479SPierre Schweitzer CO_TL_ENTITY, 679*67820479SPierre Schweitzer entitySet[i].tei_instance, 680*67820479SPierre Schweitzer 0, 681*67820479SPierre Schweitzer sizeof(MIB_TCPROW), 682*67820479SPierre Schweitzer (PVOID *)&IpTcpTable, 683*67820479SPierre Schweitzer &returnSize ); 684*67820479SPierre Schweitzer 685*67820479SPierre Schweitzer if( status == STATUS_SUCCESS ) totalNumber += returnSize; 686*67820479SPierre Schweitzer if( IpTcpTable ) { 687*67820479SPierre Schweitzer tdiFreeThingSet( IpTcpTable ); 688*67820479SPierre Schweitzer IpTcpTable = NULL; 689*67820479SPierre Schweitzer } 690*67820479SPierre Schweitzer } 691*67820479SPierre Schweitzer } 692*67820479SPierre Schweitzer 693*67820479SPierre Schweitzer closeTcpFile( tcpFile ); 694*67820479SPierre Schweitzer if( IpTcpTable ) tdiFreeThingSet( IpTcpTable ); 695*67820479SPierre Schweitzer if( entitySet ) tdiFreeThingSet( entitySet ); 696*67820479SPierre Schweitzer return totalNumber; 697c2c66affSColin Finck } 698c2c66affSColin Finck 699c2c66affSColin Finck PMIB_TCPTABLE getTcpTable(void) 700c2c66affSColin Finck { 701*67820479SPierre Schweitzer DWORD numEntities, returnSize; 702*67820479SPierre Schweitzer TDIEntityID *entitySet; 703*67820479SPierre Schweitzer HANDLE tcpFile; 704*67820479SPierre Schweitzer int i, totalNumber, TmpIdx, CurrIdx = 0; 705*67820479SPierre Schweitzer NTSTATUS status; 706*67820479SPierre Schweitzer PMIB_TCPTABLE IpTcpTable = NULL; 707*67820479SPierre Schweitzer PMIB_TCPROW AdapterTcpTable = NULL; 708*67820479SPierre Schweitzer 709*67820479SPierre Schweitzer TRACE("called.\n"); 710*67820479SPierre Schweitzer 711*67820479SPierre Schweitzer totalNumber = getNumTcpEntries(); 712*67820479SPierre Schweitzer 713*67820479SPierre Schweitzer status = openTcpFile( &tcpFile, FILE_READ_DATA ); 714*67820479SPierre Schweitzer if( !NT_SUCCESS(status) ) { 715*67820479SPierre Schweitzer ERR("openTcpFile returned 0x%08lx\n", status); 716c2c66affSColin Finck return 0; 717c2c66affSColin Finck } 718*67820479SPierre Schweitzer 719*67820479SPierre Schweitzer IpTcpTable = HeapAlloc 720*67820479SPierre Schweitzer ( GetProcessHeap(), 0, 721*67820479SPierre Schweitzer sizeof(DWORD) + (sizeof(MIB_TCPROW) * totalNumber) ); 722*67820479SPierre Schweitzer if (!IpTcpTable) { 723*67820479SPierre Schweitzer closeTcpFile(tcpFile); 724*67820479SPierre Schweitzer return NULL; 725*67820479SPierre Schweitzer } 726*67820479SPierre Schweitzer 727*67820479SPierre Schweitzer status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); 728*67820479SPierre Schweitzer 729*67820479SPierre Schweitzer for( i = 0; i < numEntities; i++ ) { 730*67820479SPierre Schweitzer if( isInterface( &entitySet[i] ) && 731*67820479SPierre Schweitzer hasArp( tcpFile, &entitySet[i] ) ) { 732*67820479SPierre Schweitzer 733*67820479SPierre Schweitzer status = tdiGetSetOfThings( tcpFile, 734*67820479SPierre Schweitzer INFO_CLASS_PROTOCOL, 735*67820479SPierre Schweitzer INFO_TYPE_PROVIDER, 736*67820479SPierre Schweitzer IP_MIB_ARPTABLE_ENTRY_ID, 737*67820479SPierre Schweitzer CO_TL_ENTITY, 738*67820479SPierre Schweitzer entitySet[i].tei_instance, 739*67820479SPierre Schweitzer 0, 740*67820479SPierre Schweitzer sizeof(MIB_TCPROW), 741*67820479SPierre Schweitzer (PVOID *)&AdapterTcpTable, 742*67820479SPierre Schweitzer &returnSize ); 743*67820479SPierre Schweitzer 744*67820479SPierre Schweitzer if( status == STATUS_SUCCESS ) { 745*67820479SPierre Schweitzer for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ ) 746*67820479SPierre Schweitzer IpTcpTable->table[CurrIdx] = AdapterTcpTable[TmpIdx]; 747*67820479SPierre Schweitzer tdiFreeThingSet( AdapterTcpTable ); 748*67820479SPierre Schweitzer } 749*67820479SPierre Schweitzer } 750*67820479SPierre Schweitzer } 751*67820479SPierre Schweitzer 752*67820479SPierre Schweitzer closeTcpFile( tcpFile ); 753*67820479SPierre Schweitzer 754*67820479SPierre Schweitzer tdiFreeThingSet( entitySet ); 755*67820479SPierre Schweitzer IpTcpTable->dwNumEntries = CurrIdx; 756*67820479SPierre Schweitzer 757*67820479SPierre Schweitzer return IpTcpTable; 758*67820479SPierre Schweitzer } 759