ping

package module
v0.0.0-...-3945d75 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 7, 2018 License: MIT Imports: 14 Imported by: 0

README

ping

GoDoc Go Report Card pipeline status coverage report

ICMP ping library for Go.

This is a fork of the speedup branch of github.com/getlantern/go-ping, which is itself based on github.com/sparrc/go-ping.

Installation

go get github.com/smlx/ping

Usage

See the documentation linked above. In cmd/ping, there is a sample implementation of the standard unix ping command.

Privileged ping

By default this library attempts to use a raw socket which requires elevated privileges on most systems.

On linux you can use setcap to assign the relevant capabilities to your binary:

setcap cap_net_raw=+ep /usr/local/ping

You can also just run as root, though this is not recommended.

Unprivileged ping

You can also send an "unprivileged" ping which is supported by Linux kernels since 2.6.39. See the icmp(7) man page for details on the ping_group_range /proc interface, and the Go icmp library documentation for more.

E.g. to allow all GIDs to send unprivileged pings:

sudo sysctl -w net.ipv4.ping_group_range="0   2147483647"

Note that even root cannot send unprivileged pings until this sysctl knob is tweaked.

Tests

Tests require privileges as detailed above. To run all tests, tweak the sysctl knob and then run:

go test -c -o ./ping-test && sudo setcap cap_net_raw=+ep ./ping-test && ./ping-test

Documentation

Overview

Package ping is an ICMP echo library providing basic functionality along the lines of the unix "ping" command.

Example

Here is a very simple example that sends & receives 3 packets. For a full ping example, see "cmd/ping/ping.go".

package main

import (
	"fmt"
	"sort"

	"gitlab.com/smlx/ping"
)

func main() {
	// Create a new Pinger.
	p, err := ping.NewPinger()
	if err != nil {
		panic(err)
	}
	// Close must be called on a privileged Pinger to avoid leaking resources.
	defer p.Close()

	// Ping the given host.
	s, err := p.Ping("www.google.com", ping.Count(3))
	if err != nil {
		panic(err)
	}

	// Use the statistics.
	fmt.Printf("Packets sent: %v", s.PktsSent)
	sort.Slice(s.RTTs, func(i, j int) bool { return s.RTTs[i] < s.RTTs[j] })
	fmt.Printf("Median RTT: %v", s.RTTs[len(s.RTTs)/2])
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrPingerClosed indicates that the Pinger was closed while running pings.
	ErrPingerClosed = errors.New("pinger closed")
	// ErrPingerInvalid indicates that the Pinger was not constructed via
	// NewPinger(), or Close() has been called.
	ErrPingerInvalid = errors.New("invalid Pinger")
)

Functions

This section is empty.

Types

type IPNet

type IPNet string

IPNet represents an IP network type.

const (
	// IP represents either IPv4 or IPv6.
	IP IPNet = "ip"
	// IP4 represents IPv4.
	IP4 IPNet = "ip4"
	// IP6 represents IPv6.
	IP6 IPNet = "ip6"
)

type LogLvl

type LogLvl int

LogLvl indicates the level of logging.

const (
	// Debug logs are very verbose.
	Debug LogLvl = iota
	// Info is the default logging priority.
	Info
	// Warn indicates a recoverable failure.
	Warn
	// Error indicates an unrecoverable failure.
	Error
)

type Option

type Option func(*Ping)

Option represents a functional option to Pinger.Ping().

func Count

func Count(c uint) Option

Count sets the number of pings to send. Set to zero for unlimited pings. Default 3.

func IPNetwork

func IPNetwork(v IPNet) Option

IPNetwork sets the IP version used for host resolution. IP will use IPv4 or IPv6 depending on the result of host resolution. Default IP.

func Interval

func Interval(i time.Duration) Option

Interval sets the interval between pings. Default 1 second.

func OnRecv

func OnRecv(f func(rhost string, pkt *Packet, rtt time.Duration)) Option

OnRecv sets the function which is called on receipt of a packet. rhost is the first name obtained from the reverse lookup of the resolved IP address, pkt is the ping.Packet received, and rtt is the round-trip time. Default nil.

func OnResolv

func OnResolv(f func(host string, ipAddr *net.IPAddr, size int)) Option

OnResolv sets the function which is called on resolution of the host. host is the original string passed to Ping(), ipAddr is the resolved address, and size is requested size of the echo payload. Default nil.

func Size

func Size(s uint) Option

Size sets the size of the data payload on the ICMP echo packets. Default 0.

func Timeout

func Timeout(t time.Duration) Option

Timeout sets the overall ping job timeout. Default 8 seconds.

type Packet

type Packet struct {
	// From is the address from which the packet was received.
	From net.Addr
	// Seq is the ICMP sequence number of the echo request.
	Seq int
	// Rcvd is the time that the packet was received.
	Rcvd time.Time
	// Size is the number of bytes of the received packet.
	Size int
}

Packet represents a received and processed ICMP echo response.

type Ping

type Ping struct {
	// contains filtered or unexported fields
}

Ping contains options for the ping job.

type Pinger

type Pinger struct {
	// contains filtered or unexported fields
}

Pinger processes pings.

func NewPinger

func NewPinger(opts ...PingerOption) (p *Pinger, err error)

NewPinger returns a new pinger object.

If Privileged mode is used, only two sockets are opened for each of IPv4 and IPv6, and multiplexing ping jobs occurs using the ID in the packet.

In unprivileged mode, we cannot control the ID. Instead it is set by the kernel, which also does filtering to only send us ICMP traffic that belongs to us. In this case, NewPinger does not open any sockets. Instead, new sockets are opened on each call to Ping().

To dispose correctly of a privileged Pinger object (the default) without leaking resources, you must call Close().

func (*Pinger) Close

func (p *Pinger) Close()

Close closes the pinger.

func (*Pinger) Ping

func (p *Pinger) Ping(host string, opts ...Option) (*Statistics, error)

Ping pings the given host.

type PingerOption

type PingerOption func(*Pinger)

PingerOption represents a functional option to NewPinger().

func LogLevel

func LogLevel(l LogLvl) PingerOption

LogLevel sets the level of the logger on the Pinger. Default Info.

func Privileged

func Privileged(priv bool) PingerOption

Privileged determines whether raw sockets are used. Unprivileged operation is only available on modern-ish Linux kernels. Default true.

type Statistics

type Statistics struct {
	// PktsSent is the number of packets sent.
	PktsSent int
	// PktsRecv is the number of packets received.
	PktsRecv int
	// Host is the name of the host being pinged.
	Host string
	// IPAddr is the address of the host being pinged.
	IPAddr *net.IPAddr
	// RTTs is a list of the round-trip times sent via this Pinger.
	RTTs []time.Duration
	// BytesSent is the number of bytes sent in pings (including envelope).
	BytesSent int
	// BytesRecv is the number of bytes received in pings (including envelope).
	BytesRecv int
}

Statistics holds the results of a Ping().

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL