Skip to main content

Overview

The ProtoCounters function retrieves network statistics for various protocols at the system level. This provides detailed counters for protocol-specific metrics like packets, errors, and retransmissions.
Platform Availability: Not implemented on FreeBSD, Windows, OpenBSD, and Darwin (macOS).

Functions

func ProtoCounters(protocols []string) ([]ProtoCountersStat, error)
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error)

Parameters

protocols
[]string
required
List of protocol names to query. If empty, all available protocols are returned.Available protocols:
  • "ip" - Internet Protocol statistics
  • "icmp" - Internet Control Message Protocol
  • "icmpmsg" - ICMP message type statistics
  • "tcp" - Transmission Control Protocol
  • "udp" - User Datagram Protocol
  • "udplite" - UDP-Lite protocol
ctx
context.Context
Context for cancellation and timeout control

Returns

Returns a slice of ProtoCountersStat structures containing protocol statistics.

ProtoCountersStat Structure

The ProtoCountersStat struct contains statistics for a specific network protocol.
type ProtoCountersStat struct {
    Protocol string           // Protocol name
    Stats    map[string]int64 // Protocol-specific statistics
}

Fields

Protocol
string
The name of the protocol (e.g., “tcp”, “udp”, “ip”, “icmp”).
Stats
map[string]int64
Map of statistic names to their values. The available statistics vary by protocol.

Protocol Statistics

TCP Statistics

Common TCP statistics include:
  • RtoAlgorithm - Retransmission timeout algorithm
  • RtoMin - Minimum RTO value
  • RtoMax - Maximum RTO value
  • MaxConn - Maximum number of connections
  • ActiveOpens - Number of active connection openings
  • PassiveOpens - Number of passive connection openings
  • AttemptFails - Number of failed connection attempts
  • EstabResets - Number of resets on established connections
  • CurrEstab - Current established connections
  • InSegs - Segments received
  • OutSegs - Segments sent
  • RetransSegs - Segments retransmitted
  • InErrs - Segments received with errors
  • OutRsts - Reset segments sent

UDP Statistics

Common UDP statistics include:
  • InDatagrams - Datagrams received
  • NoPorts - Datagrams to unknown ports
  • InErrors - Datagram receive errors
  • OutDatagrams - Datagrams sent
  • RcvbufErrors - Receive buffer errors
  • SndbufErrors - Send buffer errors

IP Statistics

Common IP statistics include:
  • Forwarding - IP forwarding status
  • DefaultTTL - Default time-to-live
  • InReceives - Packets received
  • InHdrErrors - Packets with header errors
  • InAddrErrors - Packets with address errors
  • ForwDatagrams - Packets forwarded
  • InUnknownProtos - Packets with unknown protocols
  • InDiscards - Packets discarded
  • InDelivers - Packets delivered
  • OutRequests - Packets sent
  • OutDiscards - Outgoing packets discarded
  • OutNoRoutes - Packets discarded due to no route

ICMP Statistics

Common ICMP statistics include:
  • InMsgs - Messages received
  • InErrors - Messages with errors
  • InDestUnreachs - Destination unreachable messages
  • InTimeExcds - Time exceeded messages
  • InEchos - Echo requests received
  • InEchoReps - Echo replies received
  • OutMsgs - Messages sent
  • OutErrors - Messages with errors
  • OutDestUnreachs - Destination unreachable messages sent
  • OutEchos - Echo requests sent
  • OutEchoReps - Echo replies sent

Usage Examples

Get All Protocol Statistics

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    // Get statistics for all protocols
    stats, err := net.ProtoCounters([]string{})
    if err != nil {
        panic(err)
    }
    
    for _, stat := range stats {
        fmt.Printf("\n%s Protocol Statistics:\n", stat.Protocol)
        fmt.Println("------------------------")
        for key, value := range stat.Stats {
            fmt.Printf("  %s: %d\n", key, value)
        }
    }
}

Get TCP Statistics Only

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    stats, err := net.ProtoCounters([]string{"tcp"})
    if err != nil {
        panic(err)
    }
    
    if len(stats) > 0 {
        tcp := stats[0]
        fmt.Printf("TCP Statistics:\n")
        fmt.Printf("  Current Connections: %d\n", tcp.Stats["CurrEstab"])
        fmt.Printf("  Active Opens: %d\n", tcp.Stats["ActiveOpens"])
        fmt.Printf("  Passive Opens: %d\n", tcp.Stats["PassiveOpens"])
        fmt.Printf("  Segments Received: %d\n", tcp.Stats["InSegs"])
        fmt.Printf("  Segments Sent: %d\n", tcp.Stats["OutSegs"])
        fmt.Printf("  Segments Retransmitted: %d\n", tcp.Stats["RetransSegs"])
    }
}

Monitor UDP Traffic

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    stats, err := net.ProtoCounters([]string{"udp"})
    if err != nil {
        panic(err)
    }
    
    if len(stats) > 0 {
        udp := stats[0]
        fmt.Printf("UDP Statistics:\n")
        fmt.Printf("  Datagrams Received: %d\n", udp.Stats["InDatagrams"])
        fmt.Printf("  Datagrams Sent: %d\n", udp.Stats["OutDatagrams"])
        fmt.Printf("  Receive Errors: %d\n", udp.Stats["InErrors"])
        fmt.Printf("  Unknown Port Errors: %d\n", udp.Stats["NoPorts"])
    }
}

Get Multiple Protocol Statistics

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    // Get TCP and UDP statistics
    stats, err := net.ProtoCounters([]string{"tcp", "udp"})
    if err != nil {
        panic(err)
    }
    
    for _, stat := range stats {
        fmt.Printf("\n%s:\n", stat.Protocol)
        
        switch stat.Protocol {
        case "tcp":
            fmt.Printf("  Connections: %d\n", stat.Stats["CurrEstab"])
            fmt.Printf("  Retransmissions: %d\n", stat.Stats["RetransSegs"])
        case "udp":
            fmt.Printf("  Datagrams In: %d\n", stat.Stats["InDatagrams"])
            fmt.Printf("  Datagrams Out: %d\n", stat.Stats["OutDatagrams"])
        }
    }
}

Calculate Retransmission Rate

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    stats, err := net.ProtoCounters([]string{"tcp"})
    if err != nil {
        panic(err)
    }
    
    if len(stats) > 0 {
        tcp := stats[0]
        outSegs := float64(tcp.Stats["OutSegs"])
        retransSegs := float64(tcp.Stats["RetransSegs"])
        
        if outSegs > 0 {
            retransRate := (retransSegs / outSegs) * 100
            fmt.Printf("TCP Retransmission Rate: %.2f%%\n", retransRate)
            fmt.Printf("  Total Segments: %.0f\n", outSegs)
            fmt.Printf("  Retransmitted: %.0f\n", retransSegs)
        }
    }
}

Using Context

package main

import (
    "context"
    "fmt"
    "time"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    stats, err := net.ProtoCountersWithContext(ctx, []string{"tcp", "udp"})
    if err != nil {
        panic(err)
    }
    
    for _, stat := range stats {
        fmt.Printf("%s: %d stats\n", stat.Protocol, len(stat.Stats))
    }
}

Check for Network Errors

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/net"
)

func main() {
    stats, err := net.ProtoCounters([]string{"tcp", "udp", "ip"})
    if err != nil {
        panic(err)
    }
    
    fmt.Println("Network Error Summary:")
    
    for _, stat := range stats {
        fmt.Printf("\n%s:\n", stat.Protocol)
        
        // Look for error-related statistics
        for key, value := range stat.Stats {
            if value > 0 && (contains(key, "Err") || contains(key, "Error") || 
                             contains(key, "Drop") || contains(key, "Discard")) {
                fmt.Printf("  %s: %d\n", key, value)
            }
        }
    }
}

func contains(s, substr string) bool {
    return len(s) >= len(substr) && 
           (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr)
}

Platform Support

Supported

  • Linux
  • Solaris
  • AIX

Not Supported

  • FreeBSD
  • OpenBSD
  • Darwin (macOS)
  • Windows

Data Source

On Linux, protocol statistics are typically read from /proc/net/snmp and /proc/net/netstat.

Common Use Cases

  • Network performance monitoring
  • Detecting packet loss and retransmissions
  • Analyzing protocol-specific errors
  • Network troubleshooting and diagnostics
  • Capacity planning based on protocol usage
  • Security monitoring (unusual ICMP activity)

Error Handling

stats, err := net.ProtoCounters([]string{"tcp"})
if err != nil {
    // Check if platform is unsupported
    fmt.Printf("Error getting protocol counters: %v\n", err)
    return
}

if len(stats) == 0 {
    fmt.Println("No protocol statistics available")
    return
}

See Also

Build docs developers (and LLMs) love