endpoint.go 2.6 KB

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