endpoint.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. "syscall"
  8. "time"
  9. "golang.org/x/net/ipv4"
  10. "golang.org/x/net/ipv6"
  11. )
  12. var _ net.PacketConn = &PacketConn{}
  13. type ipc interface{}
  14. // A PacketConn represents a packet network endpoint that uses either
  15. // ICMPv4 or ICMPv6.
  16. type PacketConn struct {
  17. c net.PacketConn
  18. ipc // either ipv4.PacketConn or 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. p, _ := c.ipc.(*ipv4.PacketConn)
  28. return p
  29. }
  30. // IPv6PacketConn returns the ipv6.PacketConn of c.
  31. // It returns nil when c is not created as the endpoint for ICMPv6.
  32. func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {
  33. if !c.ok() {
  34. return nil
  35. }
  36. p, _ := c.ipc.(*ipv6.PacketConn)
  37. return p
  38. }
  39. // ReadFrom reads an ICMP message from the connection.
  40. func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
  41. if !c.ok() {
  42. return 0, nil, syscall.EINVAL
  43. }
  44. return c.c.ReadFrom(b)
  45. }
  46. // WriteTo writes the ICMP message b to dst.
  47. // Dst must be net.UDPAddr when c is a non-privileged
  48. // datagram-oriented ICMP endpoint. Otherwise it must be net.IPAddr.
  49. func (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) {
  50. if !c.ok() {
  51. return 0, syscall.EINVAL
  52. }
  53. return c.c.WriteTo(b, dst)
  54. }
  55. // Close closes the endpoint.
  56. func (c *PacketConn) Close() error {
  57. if !c.ok() {
  58. return syscall.EINVAL
  59. }
  60. return c.c.Close()
  61. }
  62. // LocalAddr returns the local network address.
  63. func (c *PacketConn) LocalAddr() net.Addr {
  64. if !c.ok() {
  65. return nil
  66. }
  67. return c.c.LocalAddr()
  68. }
  69. // SetDeadline sets the read and write deadlines associated with the
  70. // endpoint.
  71. func (c *PacketConn) SetDeadline(t time.Time) error {
  72. if !c.ok() {
  73. return syscall.EINVAL
  74. }
  75. return c.c.SetDeadline(t)
  76. }
  77. // SetReadDeadline sets the read deadline associated with the
  78. // endpoint.
  79. func (c *PacketConn) SetReadDeadline(t time.Time) error {
  80. if !c.ok() {
  81. return syscall.EINVAL
  82. }
  83. return c.c.SetReadDeadline(t)
  84. }
  85. // SetWriteDeadline sets the write deadline associated with the
  86. // endpoint.
  87. func (c *PacketConn) SetWriteDeadline(t time.Time) error {
  88. if !c.ok() {
  89. return syscall.EINVAL
  90. }
  91. return c.c.SetWriteDeadline(t)
  92. }