github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/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  	"time"
    11  
    12  	"github.com/hxx258456/ccgo/net/ipv4"
    13  	"github.com/hxx258456/ccgo/net/ipv6"
    14  )
    15  
    16  var _ net.PacketConn = &PacketConn{}
    17  
    18  // A PacketConn represents a packet network endpoint that uses either
    19  // ICMPv4 or ICMPv6.
    20  type PacketConn struct {
    21  	c  net.PacketConn
    22  	p4 *ipv4.PacketConn
    23  	p6 *ipv6.PacketConn
    24  }
    25  
    26  func (c *PacketConn) ok() bool { return c != nil && c.c != nil }
    27  
    28  // IPv4PacketConn returns the ipv4.PacketConn of c.
    29  // It returns nil when c is not created as the endpoint for ICMPv4.
    30  func (c *PacketConn) IPv4PacketConn() *ipv4.PacketConn {
    31  	if !c.ok() {
    32  		return nil
    33  	}
    34  	return c.p4
    35  }
    36  
    37  // IPv6PacketConn returns the ipv6.PacketConn of c.
    38  // It returns nil when c is not created as the endpoint for ICMPv6.
    39  func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {
    40  	if !c.ok() {
    41  		return nil
    42  	}
    43  	return c.p6
    44  }
    45  
    46  // ReadFrom reads an ICMP message from the connection.
    47  func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
    48  	if !c.ok() {
    49  		return 0, nil, errInvalidConn
    50  	}
    51  	// Please be informed that ipv4.NewPacketConn enables
    52  	// IP_STRIPHDR option by default on Darwin.
    53  	// See golang.org/issue/9395 for further information.
    54  	if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && c.p4 != nil {
    55  		n, _, peer, err := c.p4.ReadFrom(b)
    56  		return n, peer, err
    57  	}
    58  	return c.c.ReadFrom(b)
    59  }
    60  
    61  // WriteTo writes the ICMP message b to dst.
    62  // The provided dst must be net.UDPAddr when c is a non-privileged
    63  // datagram-oriented ICMP endpoint.
    64  // 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, errInvalidConn
    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 errInvalidConn
    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 errInvalidConn
    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 errInvalidConn
   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 errInvalidConn
   111  	}
   112  	return c.c.SetWriteDeadline(t)
   113  }