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 }