Getting network statistics on macOS

Hello,

I am trying to get network statistics using Swift on macOS. I am attempting to obtain:

  • total input bytes
  • total output bytes
  • total input packets
  • total output packets

The following code works in the app as far as I can tell so far, but... the for-loop is a hack that I'd like to correct by properly iterating over all the interfaces.

import Foundation
import OSLog

struct NetworkStatisticsData {
    var totalInputBytes: UInt64 = 0
    var totalOutputBytes: UInt64 = 0
    var totalInputPackets: UInt64 = 0
    var totalOutputPackets: UInt64 = 0
}

final class NetworkStatistics: Sendable {

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!,
                                       category: "SwiftNetworkInformation")

    func getNetworkStatistics() -> NetworkStatisticsData {
        var networkStatisticsData = NetworkStatisticsData()
        for i in 1..<24 { // <- this for-loop should be iterating over a list of interfaces. NET_RT_IFLIST2 ?
            var keys: [Int32] = [ CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, Int32(i), IFDATA_GENERAL ]
            var mibData: ifmibdata = ifmibdata()
            var mibDataSize: size_t = MemoryLayout<ifmibdata>.size
            if sysctl(&keys, u_int(keys.count), &mibData, &mibDataSize, nil, 0) < 0 {
                logger.error("sysctl error getting mib data: \(String(describing: strerror(errno)))")
            }
            networkStatisticsData.totalInputPackets += mibData.ifmd_data.ifi_ipackets
            networkStatisticsData.totalOutputPackets += mibData.ifmd_data.ifi_opackets
            networkStatisticsData.totalInputBytes += mibData.ifmd_data.ifi_ibytes
            networkStatisticsData.totalOutputBytes += mibData.ifmd_data.ifi_obytes
        }
        return networkStatisticsData
    }
}

Any thoughts on how to iterate over all of the network interfaces (maybe using NET_RT_IFLIST2)? When I run ifconfig in the terminal, there are 24 interfaces, hence the reason for 24 in the for-loop.

Answered by DTS Engineer in 787776022

I have some general background to this in the Network Interface Statistics post hanging off Extra-ordinary Networking. That post also has links to other posts about iterating the interface list.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

I have some general background to this in the Network Interface Statistics post hanging off Extra-ordinary Networking. That post also has links to other posts about iterating the interface list.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Getting network statistics on macOS
 
 
Q