github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/icmp/endpoint.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package icmp
     6  
     7  import (
     8  	"net"
     9  	"runtime"
    10  	"syscall"
    11  	"time"
    12  
    13  	"golang.org/x/net/ipv4"
    14  	"golang.org/x/net/ipv6"
    15  )
    16  
    17  var _ net.PacketConn = &PacketConn{}
    18  
    19  // A PacketConn represents a packet network endpoint that uses either
    20  // ICMPv4 or ICMPv6.
    21  type PacketConn struct {
    22  	c  net.PacketConn
    23  	p4 *ipv4.PacketConn
    24  	p6 *ipv6.PacketConn
    25  }
    26  
    27  func (c *PacketConn) ok() bool { return c != nil && c.c != nil }
    28  
    29  // IPv4PacketConn returns the ipv4.PacketConn of c.
    30  // It returns nil when c is not created as the endpoint for ICMPv4.
    31  func (c *PacketConn) IPv4PacketConn() *ipv4.PacketConn {
    32  	if !c.ok() {
    33  		return nil
    34  	}
    35  	return c.p4
    36  }
    37  
    38  // IPv6PacketConn returns the ipv6.PacketConn of c.
    39  // It returns nil when c is not created as the endpoint for ICMPv6.
    40  func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {
    41  	if !c.ok() {
    42  		return nil
    43  	}
    44  	return c.p6
    45  }
    46  
    47  // ReadFrom reads an ICMP message from the connection.
    48  func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
    49  	if !c.ok() {
    50  		return 0, nil, syscall.EINVAL
    51  	}
    52  	// Please be informed that ipv4.NewPacketConn enables
    53  	// IP_STRIPHDR option by default on Darwin.
    54  	// See golang.org/issue/9395 for futher information.
    55  	if runtime.GOOS == "darwin" && c.p4 != nil {
    56  		n, _, peer, err := c.p4.ReadFrom(b)
    57  		return n, peer, err
    58  	}
    59  	return c.c.ReadFrom(b)
    60  }
    61  
    62  // WriteTo writes the ICMP message b to dst.
    63  // Dst must be net.UDPAddr when c is a non-privileged
    64  // datagram-oriented ICMP endpoint. Otherwise it must be net.IPAddr.
    65  func (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) {
    66  	if !c.ok() {
    67  		return 0, syscall.EINVAL
    68  	}
    69  	return c.c.WriteTo(b, dst)
    70  }
    71  
    72  // Close closes the endpoint.
    73  func (c *PacketConn) Close() error {
    74  	if !c.ok() {
    75  		return syscall.EINVAL
    76  	}
    77  	return c.c.Close()
    78  }
    79  
    80  // LocalAddr returns the local network address.
    81  func (c *PacketConn) LocalAddr() net.Addr {
    82  	if !c.ok() {
    83  		return nil
    84  	}
    85  	return c.c.LocalAddr()
    86  }
    87  
    88  // SetDeadline sets the read and write deadlines associated with the
    89  // endpoint.
    90  func (c *PacketConn) SetDeadline(t time.Time) error {
    91  	if !c.ok() {
    92  		return syscall.EINVAL
    93  	}
    94  	return c.c.SetDeadline(t)
    95  }
    96  
    97  // SetReadDeadline sets the read deadline associated with the
    98  // endpoint.
    99  func (c *PacketConn) SetReadDeadline(t time.Time) error {
   100  	if !c.ok() {
   101  		return syscall.EINVAL
   102  	}
   103  	return c.c.SetReadDeadline(t)
   104  }
   105  
   106  // SetWriteDeadline sets the write deadline associated with the
   107  // endpoint.
   108  func (c *PacketConn) SetWriteDeadline(t time.Time) error {
   109  	if !c.ok() {
   110  		return syscall.EINVAL
   111  	}
   112  	return c.c.SetWriteDeadline(t)
   113  }