Documentation ¶
Overview ¶
Example (Traceroute) ¶
dst := net.IPv4(8, 8, 8, 8) p, err := New(nil) if err != nil { fmt.Println(err) return } defer p.Close() ctx, cancel := context.WithCancel(context.Background()) var g errgroup.Group g.Go(func() error { return p.Listen(ctx) }) defer func() { cancel() if err := g.Wait(); !errors.Is(err, context.Canceled) { fmt.Println(err) } }() for ttl := uint8(1); ttl < math.MaxUint8-1; ttl++ { fmt.Printf("%3d: ", ttl) r, err := p.PingContextTimeout(ctx, dst, 1*time.Second, TTL(ttl)) if errors.Is(err, context.DeadlineExceeded) { // no answer from current hop fmt.Println("...") continue } from := dst switch err := err.(type) { case nil: case TimeExceededError: from = err.From() default: fmt.Println(err) return } fmt.Printf("%-15s %s\n", from, r.RTT) if err == nil { return } } fmt.Println("TTL maxed out")
Output:
Index ¶
- func HopLimit(hl uint8) *unixx.ValueSockOpt[uint32]
- func MTU(mtu int32) *unixx.ValueSockOpt[int32]
- func MTU6(mtu int32) *unixx.ValueSockOpt[int32]
- func Mark(m uint32) *unixx.ValueSockOpt[uint32]
- func TTL(ttl uint8) *unixx.ValueSockOpt[uint32]
- func TrafficClass(tc uint8) *unixx.ValueSockOpt[uint32]
- type DestinationUnreachableError
- type DstUnreachableCode
- type ICMPError
- type Pinger
- func (p *Pinger) Close() error
- func (p *Pinger) Get(opts ...unixx.SockOpt) error
- func (p *Pinger) IsIPv6() bool
- func (p *Pinger) Listen(ctx context.Context) error
- func (p *Pinger) Ping(dst net.IP, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingCh(dst net.IP, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChContext(ctx context.Context, dst net.IP, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChContextInterval(ctx context.Context, dst net.IP, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChContextIntervalTimeout(ctx context.Context, dst net.IP, interval, timeout time.Duration, ...) <-chan Reply
- func (p *Pinger) PingChContextPayload(ctx context.Context, dst net.IP, payload []byte, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChContextPayloadInterval(ctx context.Context, dst net.IP, payload []byte, interval time.Duration, ...) <-chan Reply
- func (p *Pinger) PingChContextPayloadIntervalTimeout(ctx context.Context, payload []byte, dst net.IP, ...) <-chan Reply
- func (p *Pinger) PingChContextPayloadTimeout(ctx context.Context, dst net.IP, payload []byte, timeout time.Duration, ...) <-chan Reply
- func (p *Pinger) PingChContextTimeout(ctx context.Context, dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChInterval(dst net.IP, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChPayload(dst net.IP, payload []byte, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChPayloadInterval(dst net.IP, payload []byte, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChPayloadTimeout(dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingChTimeout(dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
- func (p *Pinger) PingContext(ctx context.Context, dst net.IP, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingContextPayload(ctx context.Context, dst net.IP, payload []byte, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingContextPayloadTimeout(ctx context.Context, dst net.IP, payload []byte, timeout time.Duration, ...) (Reply, error)
- func (p *Pinger) PingContextTimeout(ctx context.Context, dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingN(dst net.IP, n int, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingNContext(ctx context.Context, dst net.IP, n int, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingNContextInterval(ctx context.Context, dst net.IP, n int, interval time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNContextPayload(ctx context.Context, dst net.IP, n int, payload []byte, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingNContextPayloadInterval(ctx context.Context, dst net.IP, n int, payload []byte, interval time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNContextPayloadIntervalTimeout(ctx context.Context, dst net.IP, n int, payload []byte, ...) (Replies, error)
- func (p *Pinger) PingNContextPayloadTimeout(ctx context.Context, dst net.IP, n int, payload []byte, timeout time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNContextTimeout(ctx context.Context, dst net.IP, n int, timeout time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNInterval(dst net.IP, n int, interval time.Duration, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingNPayload(dst net.IP, n int, payload []byte, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingNPayloadInterval(dst net.IP, n int, payload []byte, interval time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNPayloadTimeout(dst net.IP, n int, payload []byte, timeout time.Duration, ...) (Replies, error)
- func (p *Pinger) PingNTimeout(dst net.IP, n int, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
- func (p *Pinger) PingPayload(dst net.IP, payload []byte, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingPayloadTimeout(dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) PingTimeout(dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
- func (p *Pinger) Send(typ icmp.Type, code uint8, body icmp.MessageBody, dst net.IP, ...) error
- func (p *Pinger) Set(opts ...unixx.SockOpt) error
- type Replies
- type Reply
- type TimeExceededError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HopLimit ¶ added in v1.1.0
func HopLimit(hl uint8) *unixx.ValueSockOpt[uint32]
TTL is <SOL_IPV6, IPV6_HOPLIMIT>
func MTU6 ¶ added in v1.1.0
func MTU6(mtu int32) *unixx.ValueSockOpt[int32]
MTU6 is <SOL_IPV6, IPV6_MTU>
func Mark ¶ added in v1.1.0
func Mark(m uint32) *unixx.ValueSockOpt[uint32]
Mark is <SOL_SOCKET, SO_MARK>
func TrafficClass ¶ added in v1.1.0
func TrafficClass(tc uint8) *unixx.ValueSockOpt[uint32]
TrafficClass is <SOL_IPV6, IPV6_TCLASS>
Types ¶
type DestinationUnreachableError ¶ added in v1.1.0
type DestinationUnreachableError struct {
// contains filtered or unexported fields
}
func NewDestinationUnreachableError ¶ added in v1.1.0
func NewDestinationUnreachableError(from net.IP, code DstUnreachableCode) DestinationUnreachableError
func (DestinationUnreachableError) Error ¶ added in v1.1.0
func (e DestinationUnreachableError) Error() string
func (DestinationUnreachableError) From ¶ added in v1.1.0
func (e DestinationUnreachableError) From() net.IP
func (DestinationUnreachableError) Unwrap ¶ added in v1.1.0
func (e DestinationUnreachableError) Unwrap() error
type DstUnreachableCode ¶ added in v1.1.0
type DstUnreachableCode uint8
const ( NetUnreachable DstUnreachableCode = iota HostUnreachable ProtocolUnreachable PortUnreachable FragmentationNeeded SourceRouteFailed )
func (DstUnreachableCode) Error ¶ added in v1.1.0
func (c DstUnreachableCode) Error() string
type Pinger ¶
type Pinger struct {
// contains filtered or unexported fields
}
func New ¶
New creates a new Pinger with given local address to bind to. If laddr is nil or laddr.IP is nil, then it will be bound to 0.0.0.0. opts are setsockopt(2) options to set on the underlying socket.
To enable receiving packets, Listen() should be called on returned Pinger. Close() should be called after Listen() returns.
func (*Pinger) Close ¶
Close releases resources allocated for Pinger. In particular, it closes the underlying socket.
func (*Pinger) Get ¶ added in v1.1.0
Get gets given options from the underlying socket with getsockopt(2)
func (*Pinger) Listen ¶
Listen handles receiving of incomming replies and dispatches them into calling Pinger.Ping* method, so *no* Pinger.Ping*() methods should be called before Listen and after it returns.
NOTE: It is a blocking call, so it should be run as a separate goroutine. It returns a non-nil error if context is done or an error occured while receiving on sokcet.
func (*Pinger) PingChContext ¶
PingChContext is like PingChContextPayload, but with no payload.
func (*Pinger) PingChContextInterval ¶
func (p *Pinger) PingChContextInterval(ctx context.Context, dst net.IP, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextInterval is like PingChContextPayloadInterval, but with no payload.
func (*Pinger) PingChContextIntervalTimeout ¶
func (p *Pinger) PingChContextIntervalTimeout(ctx context.Context, dst net.IP, interval, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextIntervalTimeout is like PingChContextPayloadIntervalTimeout, but with no payload.
func (*Pinger) PingChContextPayload ¶ added in v1.1.0
func (p *Pinger) PingChContextPayload(ctx context.Context, dst net.IP, payload []byte, opts ...unixx.SockOpt) <-chan Reply
PingChContextPayload is the same as PingChContextPayloadTimeout, but with no timeout, so it waits for each reply until context is done.
func (*Pinger) PingChContextPayloadInterval ¶ added in v1.1.0
func (p *Pinger) PingChContextPayloadInterval(ctx context.Context, dst net.IP, payload []byte, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextPayloadInterval is the same as PingChContextIntervalTimeout, but with timeout equal to the interval, so it waits for reply to each request until interval has passed.
func (*Pinger) PingChContextPayloadIntervalTimeout ¶ added in v1.1.0
func (p *Pinger) PingChContextPayloadIntervalTimeout(ctx context.Context, payload []byte, dst net.IP, interval, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextPayloadIntervalTimeout sends ICMP Echo Requests with given payload periodically with given interval (zero interval means send next packet righ after the reply to the previuos one has been recieved) and waits for every reply until given context is done or non-zero timeout is passed. It returns a channel, where replies are sent to. The channel is closed when the context is done, so the caller should receive on that channel until it is closed.
func (*Pinger) PingChContextPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingChContextPayloadTimeout(ctx context.Context, dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextPayloadTimeout is the same as PingChContextPayloadIntervalTimeout, but echo requests are sent one by one, without waiting for interval to pass.
func (*Pinger) PingChContextTimeout ¶
func (p *Pinger) PingChContextTimeout(ctx context.Context, dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChContextTimeout is like PingChContextPayloadTimeout, but with no payload.
func (*Pinger) PingChInterval ¶
func (p *Pinger) PingChInterval(dst net.IP, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChInterval is like PingChPayloadInterval, but with no payload.
func (*Pinger) PingChPayload ¶ added in v1.1.0
PingChPayload is the same as PingChContextPayload, but with background context, so it pings forever.
func (*Pinger) PingChPayloadInterval ¶ added in v1.1.0
func (p *Pinger) PingChPayloadInterval(dst net.IP, payload []byte, interval time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChPayloadInterval is the same as PingChContextPayloadInterval, but with background timeout, so it pings forever.
func (*Pinger) PingChPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingChPayloadTimeout(dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChPayloadTimeout is the same as PingChContextPayloadTimeout, but with background context, so it pings forever.
func (*Pinger) PingChTimeout ¶
func (p *Pinger) PingChTimeout(dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) <-chan Reply
PingChTimeout is like PingChPayloadTimeout, but with no payload
func (*Pinger) PingContext ¶
PingContext is like PingContextPayload, but with no payload.
func (*Pinger) PingContextPayload ¶ added in v1.1.0
func (p *Pinger) PingContextPayload(ctx context.Context, dst net.IP, payload []byte, opts ...unixx.SockOpt) (Reply, error)
PingContextPayload sends one ICMP Echo Request to given destination with given payload and waits for the reply until the given context is done. opts can be used to set per-packet sendmsg(2) options
On success, it returns the reply. Otherwise, it returns an error occured while sending on underlying socket, ctx.Err() or ICMPError. If the returned error is ICMPError, then the returned Reply contains valid fields and has the same Err.
Example ¶
p, err := New(nil) if err != nil { fmt.Println(err) return } defer p.Close() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) var g errgroup.Group g.Go(func() error { return p.Listen(ctx) }) defer func() { cancel() if err := g.Wait(); !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) { fmt.Println(err) } }() payload := "HELLO, ARE YOU THERE?" r, err := p.PingContextPayload(ctx, net.IPv4(8, 8, 8, 8), []byte(payload)) switch err.(type) { case nil: fmt.Printf("RTT: %s, TTL: %d, payload: %s\n", r.RTT, r.TTL, string(r.Data)) case ICMPError: fmt.Printf("RTT: %s, TTL: %d, ICMP error: %s\n", r.RTT, r.TTL, err) default: fmt.Println(err) }
Output:
func (*Pinger) PingContextPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingContextPayloadTimeout(ctx context.Context, dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
PingContextTimeoutPayload is like PingContextPayload, but it waits for the reply until timeout is passed or given context id done. Zero timeout means no timeout, so PingContextTimeout(ctx, dst, 0) is equialent to PingContext(ctx, dst)
func (*Pinger) PingContextTimeout ¶
func (p *Pinger) PingContextTimeout(ctx context.Context, dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
PingContextTimeout is like PingContextPayloadTimeout, but with no payload.
func (*Pinger) PingNContext ¶
func (p *Pinger) PingNContext(ctx context.Context, dst net.IP, n int, opts ...unixx.SockOpt) (Replies, error)
PingNContext is like PingNContextPayload, but with no payload.
func (*Pinger) PingNContextInterval ¶
func (p *Pinger) PingNContextInterval(ctx context.Context, dst net.IP, n int, interval time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNContextInterval is like PingNContextPayloadInterval, but with no payload.
Example ¶
p, err := New(nil) if err != nil { fmt.Println(err) return } defer p.Close() ctx, cancel := context.WithCancel(context.Background()) var g errgroup.Group g.Go(func() error { return p.Listen(ctx) }) defer func() { cancel() if err := g.Wait(); !errors.Is(err, context.Canceled) { fmt.Println(err) } }() const send = 3 rs, err := p.PingNContextInterval(ctx, net.IPv4(8, 8, 8, 8), send, 1*time.Second) if err != nil { fmt.Println(err) return } fmt.Printf("packet loss: %.2f%%, avg RTT: %s\n", 100*float32(send-len(rs))/float32(send), rs.AvgRTT())
Output:
func (*Pinger) PingNContextPayload ¶ added in v1.1.0
func (p *Pinger) PingNContextPayload(ctx context.Context, dst net.IP, n int, payload []byte, opts ...unixx.SockOpt) (Replies, error)
PingNContextPayload is the same as PingNContextPayloadTimeout, but with no timeout, so it waits for each reply until context is done.
func (*Pinger) PingNContextPayloadInterval ¶ added in v1.1.0
func (p *Pinger) PingNContextPayloadInterval(ctx context.Context, dst net.IP, n int, payload []byte, interval time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNContextInterval is the same as PingNContextIntervalTimeout, but with timeout equal to the interval, so it waits for reply to each request until interval has passed.
func (*Pinger) PingNContextPayloadIntervalTimeout ¶ added in v1.1.0
func (p *Pinger) PingNContextPayloadIntervalTimeout(ctx context.Context, dst net.IP, n int, payload []byte, interval, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNContextPayloadIntervalTimeout sends at most n ICMP Echo Requests with a given payload and interval (zero interval means send packets one by one and do not wait for interval to pass) and returns slice of received Replies until the first occurred connection error if there was any. Zero timeout means wait for each reply until the context is done.
func (*Pinger) PingNContextPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingNContextPayloadTimeout(ctx context.Context, dst net.IP, n int, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNContextPayloadTimeout is the same as PingNContextPayloadIntervalTimeout, but echo requests are sent one by one, without waiting for interval to pass.
func (*Pinger) PingNContextTimeout ¶
func (p *Pinger) PingNContextTimeout(ctx context.Context, dst net.IP, n int, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNContextTimeout is like PingNContextPayloadTimeout, but with no payload.
func (*Pinger) PingNInterval ¶
func (p *Pinger) PingNInterval(dst net.IP, n int, interval time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNInterval is like PingNPayloadInterval, but with no payload.
func (*Pinger) PingNPayload ¶ added in v1.1.0
func (p *Pinger) PingNPayload(dst net.IP, n int, payload []byte, opts ...unixx.SockOpt) (Replies, error)
PingNPayload is the same as PingNContextPayload, but with background context, so it tries to ping exactly n times.
func (*Pinger) PingNPayloadInterval ¶ added in v1.1.0
func (p *Pinger) PingNPayloadInterval(dst net.IP, n int, payload []byte, interval time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNPayloadInterval is the same as PingNPayloadTimeoutInterval, but with background context, so it tries to ping exactly n times.
func (*Pinger) PingNPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingNPayloadTimeout(dst net.IP, n int, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNPayloadTimeout is the same as PingNContextPayloadTimeout, but with background context, so it tries to ping exactly n times.
func (*Pinger) PingNTimeout ¶
func (p *Pinger) PingNTimeout(dst net.IP, n int, timeout time.Duration, opts ...unixx.SockOpt) (Replies, error)
PingNTimeout is like PingNPayloadTimeout, but wuth no payload.
func (*Pinger) PingPayload ¶ added in v1.1.0
PingPayload is like PingContextPayload, but with background context.
func (*Pinger) PingPayloadTimeout ¶ added in v1.1.0
func (p *Pinger) PingPayloadTimeout(dst net.IP, payload []byte, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
PingPayloadTimeout is like PingContextPayloadTimeout, but with background context.
func (*Pinger) PingTimeout ¶
func (p *Pinger) PingTimeout(dst net.IP, timeout time.Duration, opts ...unixx.SockOpt) (Reply, error)
PingTimeout is like PingPayloadTimeout, but no payload.
func (*Pinger) Send ¶ added in v1.2.0
func (p *Pinger) Send(typ icmp.Type, code uint8, body icmp.MessageBody, dst net.IP, opts ...unixx.SockOpt) error
Send just sends ICMP packet with given type, code and body to dst, ignoring sequence number management and timestamping, so it would not interfere with Ping* methods. opts can be used to set per-packet sendmsg(2) options.
type Replies ¶ added in v1.1.0
type Replies []Reply
type Reply ¶
type Reply struct { // From is the sender IP address of recevied reply. From net.IP // RTT is a round trip time: the time interval between sending // an ICMP Echo Request and receiving ICMP Echo Reply. RTT time.Duration // TTL is time-to-live field from the recieved IP packet TTL uint8 // Data is a reply payload Data []byte // Err is not nil if ICMP error was received. // Other fields are valid even if Err is not nil. Err ICMPError }
type TimeExceededError ¶ added in v1.1.0
func NewTimeExceededError ¶ added in v1.1.0
func NewTimeExceededError(from net.IP) TimeExceededError
func (TimeExceededError) Error ¶ added in v1.1.0
func (e TimeExceededError) Error() string
func (TimeExceededError) From ¶ added in v1.1.0
func (e TimeExceededError) From() net.IP