118d3e65eSAxel Dörfler /* 218d3e65eSAxel Dörfler * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 318d3e65eSAxel Dörfler * Distributed under the terms of the MIT License. 418d3e65eSAxel Dörfler */ 518d3e65eSAxel Dörfler 618d3e65eSAxel Dörfler 718d3e65eSAxel Dörfler #include "SystemInfo.h" 8*74158bb4SFrançois Revol #include "SystemInfoHandler.h" 918d3e65eSAxel Dörfler 103a4a2141SAxel Dörfler #include <net/if.h> 113a4a2141SAxel Dörfler #include <stdlib.h> 123a4a2141SAxel Dörfler #include <string.h> 13cbd4bc95SFrançois Revol #include <unistd.h> 143a4a2141SAxel Dörfler #include <sys/socket.h> 153a4a2141SAxel Dörfler #include <sys/sockio.h> 163a4a2141SAxel Dörfler 1718d3e65eSAxel Dörfler 18*74158bb4SFrançois Revol SystemInfo::SystemInfo(SystemInfoHandler *handler) 1918d3e65eSAxel Dörfler : 203a4a2141SAxel Dörfler fTime(system_time()), 21*74158bb4SFrançois Revol fRetrievedNetwork(false), 22*74158bb4SFrançois Revol fRunningApps(0) 2318d3e65eSAxel Dörfler { 2418d3e65eSAxel Dörfler get_system_info(&fSystemInfo); 25*74158bb4SFrançois Revol 26*74158bb4SFrançois Revol if (handler) { 27*74158bb4SFrançois Revol fRunningApps = handler->RunningApps(); 28*74158bb4SFrançois Revol } 2918d3e65eSAxel Dörfler } 3018d3e65eSAxel Dörfler 3118d3e65eSAxel Dörfler 3218d3e65eSAxel Dörfler SystemInfo::~SystemInfo() 3318d3e65eSAxel Dörfler { 3418d3e65eSAxel Dörfler } 3518d3e65eSAxel Dörfler 3618d3e65eSAxel Dörfler 3718d3e65eSAxel Dörfler uint64 3818d3e65eSAxel Dörfler SystemInfo::CachedMemory() const 3918d3e65eSAxel Dörfler { 40cbd4bc95SFrançois Revol #ifdef __HAIKU__ 4118d3e65eSAxel Dörfler return fSystemInfo.cached_pages * B_PAGE_SIZE; 42cbd4bc95SFrançois Revol #else 43cbd4bc95SFrançois Revol return 0LL; 44cbd4bc95SFrançois Revol #endif 4518d3e65eSAxel Dörfler } 4618d3e65eSAxel Dörfler 4718d3e65eSAxel Dörfler 4818d3e65eSAxel Dörfler uint64 4918d3e65eSAxel Dörfler SystemInfo::UsedMemory() const 5018d3e65eSAxel Dörfler { 5118d3e65eSAxel Dörfler return fSystemInfo.used_pages * B_PAGE_SIZE; 5218d3e65eSAxel Dörfler } 5318d3e65eSAxel Dörfler 5418d3e65eSAxel Dörfler 5518d3e65eSAxel Dörfler uint64 5618d3e65eSAxel Dörfler SystemInfo::MaxMemory() const 5718d3e65eSAxel Dörfler { 5818d3e65eSAxel Dörfler return fSystemInfo.max_pages * B_PAGE_SIZE; 5918d3e65eSAxel Dörfler } 6018d3e65eSAxel Dörfler 6118d3e65eSAxel Dörfler 6218d3e65eSAxel Dörfler uint32 6303aaa278SFrançois Revol SystemInfo::UsedSemaphores() const 6403aaa278SFrançois Revol { 6503aaa278SFrançois Revol return fSystemInfo.used_sems; 6603aaa278SFrançois Revol } 6703aaa278SFrançois Revol 6803aaa278SFrançois Revol 6903aaa278SFrançois Revol uint32 7003aaa278SFrançois Revol SystemInfo::MaxSemaphores() const 7103aaa278SFrançois Revol { 7203aaa278SFrançois Revol return fSystemInfo.max_sems; 7303aaa278SFrançois Revol } 7403aaa278SFrançois Revol 7503aaa278SFrançois Revol 7603aaa278SFrançois Revol uint32 7703aaa278SFrançois Revol SystemInfo::UsedPorts() const 7803aaa278SFrançois Revol { 7903aaa278SFrançois Revol return fSystemInfo.used_ports; 8003aaa278SFrançois Revol } 8103aaa278SFrançois Revol 8203aaa278SFrançois Revol 8303aaa278SFrançois Revol uint32 8403aaa278SFrançois Revol SystemInfo::MaxPorts() const 8503aaa278SFrançois Revol { 8603aaa278SFrançois Revol return fSystemInfo.max_ports; 8703aaa278SFrançois Revol } 8803aaa278SFrançois Revol 8903aaa278SFrançois Revol 9003aaa278SFrançois Revol uint32 9118d3e65eSAxel Dörfler SystemInfo::UsedThreads() const 9218d3e65eSAxel Dörfler { 9318d3e65eSAxel Dörfler return fSystemInfo.used_threads; 9418d3e65eSAxel Dörfler } 9518d3e65eSAxel Dörfler 9618d3e65eSAxel Dörfler 9718d3e65eSAxel Dörfler uint32 9818d3e65eSAxel Dörfler SystemInfo::MaxThreads() const 9918d3e65eSAxel Dörfler { 10018d3e65eSAxel Dörfler return fSystemInfo.max_threads; 10118d3e65eSAxel Dörfler } 10218d3e65eSAxel Dörfler 10318d3e65eSAxel Dörfler 10418d3e65eSAxel Dörfler uint32 10518d3e65eSAxel Dörfler SystemInfo::UsedTeams() const 10618d3e65eSAxel Dörfler { 10718d3e65eSAxel Dörfler return fSystemInfo.used_teams; 10818d3e65eSAxel Dörfler } 10918d3e65eSAxel Dörfler 11018d3e65eSAxel Dörfler 11118d3e65eSAxel Dörfler uint32 11218d3e65eSAxel Dörfler SystemInfo::MaxTeams() const 11318d3e65eSAxel Dörfler { 11418d3e65eSAxel Dörfler return fSystemInfo.max_teams; 11518d3e65eSAxel Dörfler } 1163a4a2141SAxel Dörfler 1173a4a2141SAxel Dörfler 118*74158bb4SFrançois Revol uint32 119*74158bb4SFrançois Revol SystemInfo::UsedRunningApps() const 120*74158bb4SFrançois Revol { 121*74158bb4SFrançois Revol return fRunningApps; 122*74158bb4SFrançois Revol } 123*74158bb4SFrançois Revol 124*74158bb4SFrançois Revol 125*74158bb4SFrançois Revol uint32 126*74158bb4SFrançois Revol SystemInfo::MaxRunningApps() const 127*74158bb4SFrançois Revol { 128*74158bb4SFrançois Revol return fSystemInfo.max_teams; 129*74158bb4SFrançois Revol } 130*74158bb4SFrançois Revol 131*74158bb4SFrançois Revol 1323a4a2141SAxel Dörfler void 1333a4a2141SAxel Dörfler SystemInfo::_RetrieveNetwork() 1343a4a2141SAxel Dörfler { 1353a4a2141SAxel Dörfler if (fRetrievedNetwork) 1363a4a2141SAxel Dörfler return; 1373a4a2141SAxel Dörfler 1383a4a2141SAxel Dörfler fBytesReceived = 0; 1393a4a2141SAxel Dörfler fBytesSent = 0; 1403a4a2141SAxel Dörfler fRetrievedNetwork = true; 1413a4a2141SAxel Dörfler 1423a4a2141SAxel Dörfler // we need a socket to talk to the networking stack 1433a4a2141SAxel Dörfler int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 1443a4a2141SAxel Dörfler if (socket < 0) 1453a4a2141SAxel Dörfler return; 1463a4a2141SAxel Dörfler 1473a4a2141SAxel Dörfler // get a list of all interfaces 1483a4a2141SAxel Dörfler 1493a4a2141SAxel Dörfler ifconf config; 1503a4a2141SAxel Dörfler config.ifc_len = sizeof(config.ifc_value); 1513a4a2141SAxel Dörfler if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0 1523a4a2141SAxel Dörfler || config.ifc_value == 0) { 1533a4a2141SAxel Dörfler close(socket); 1543a4a2141SAxel Dörfler return; 1553a4a2141SAxel Dörfler } 1563a4a2141SAxel Dörfler 1573a4a2141SAxel Dörfler uint32 count = (uint32)config.ifc_value; 1583a4a2141SAxel Dörfler 1593a4a2141SAxel Dörfler void *buffer = malloc(count * sizeof(struct ifreq)); 1603a4a2141SAxel Dörfler if (buffer == NULL) { 1613a4a2141SAxel Dörfler close(socket); 1623a4a2141SAxel Dörfler return; 1633a4a2141SAxel Dörfler } 1643a4a2141SAxel Dörfler 1653a4a2141SAxel Dörfler config.ifc_len = count * sizeof(struct ifreq); 1663a4a2141SAxel Dörfler config.ifc_buf = buffer; 1673a4a2141SAxel Dörfler if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { 1683a4a2141SAxel Dörfler close(socket); 1693a4a2141SAxel Dörfler return; 1703a4a2141SAxel Dörfler } 1713a4a2141SAxel Dörfler 1723a4a2141SAxel Dörfler ifreq *interface = (ifreq *)buffer; 1733a4a2141SAxel Dörfler 1743a4a2141SAxel Dörfler for (uint32 i = 0; i < count; i++) { 1753a4a2141SAxel Dörfler ifreq request; 1763a4a2141SAxel Dörfler strlcpy(request.ifr_name, interface->ifr_name, IF_NAMESIZE); 1773a4a2141SAxel Dörfler 178cbd4bc95SFrançois Revol #ifdef __HAIKU__ 1793a4a2141SAxel Dörfler if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) == 0) { 1803a4a2141SAxel Dörfler fBytesReceived += request.ifr_stats.receive.bytes; 1813a4a2141SAxel Dörfler fBytesSent += request.ifr_stats.send.bytes; 1823a4a2141SAxel Dörfler } 183cbd4bc95SFrançois Revol #endif 1843a4a2141SAxel Dörfler 1853a4a2141SAxel Dörfler interface = (ifreq *)((addr_t)interface + IF_NAMESIZE 1863a4a2141SAxel Dörfler + interface->ifr_addr.sa_len); 1873a4a2141SAxel Dörfler } 1883a4a2141SAxel Dörfler 1893a4a2141SAxel Dörfler free(buffer); 1903a4a2141SAxel Dörfler close(socket); 1913a4a2141SAxel Dörfler } 1923a4a2141SAxel Dörfler 1933a4a2141SAxel Dörfler 1943a4a2141SAxel Dörfler uint64 1953a4a2141SAxel Dörfler SystemInfo::NetworkReceived() 1963a4a2141SAxel Dörfler { 1973a4a2141SAxel Dörfler _RetrieveNetwork(); 1983a4a2141SAxel Dörfler return fBytesReceived; 1993a4a2141SAxel Dörfler } 2003a4a2141SAxel Dörfler 2013a4a2141SAxel Dörfler 2023a4a2141SAxel Dörfler uint64 2033a4a2141SAxel Dörfler SystemInfo::NetworkSent() 2043a4a2141SAxel Dörfler { 2053a4a2141SAxel Dörfler _RetrieveNetwork(); 2063a4a2141SAxel Dörfler return fBytesSent; 2073a4a2141SAxel Dörfler } 208