You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.9 KiB

  1. // Copyright 2016 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. // +build darwin dragonfly freebsd netbsd openbsd
  5. // Package route provides basic functions for the manipulation of
  6. // packet routing facilities on BSD variants.
  7. //
  8. // The package supports any version of Darwin, any version of
  9. // DragonFly BSD, FreeBSD 7 through 11, NetBSD 6 and above, and
  10. // OpenBSD 5.6 and above.
  11. package route
  12. import (
  13. "errors"
  14. "os"
  15. "syscall"
  16. )
  17. var (
  18. errUnsupportedMessage = errors.New("unsupported message")
  19. errMessageMismatch = errors.New("message mismatch")
  20. errMessageTooShort = errors.New("message too short")
  21. errInvalidMessage = errors.New("invalid message")
  22. errInvalidAddr = errors.New("invalid address")
  23. errShortBuffer = errors.New("short buffer")
  24. )
  25. // A RouteMessage represents a message conveying an address prefix, a
  26. // nexthop address and an output interface.
  27. //
  28. // Unlike other messages, this message can be used to query adjacency
  29. // information for the given address prefix, to add a new route, and
  30. // to delete or modify the existing route from the routing information
  31. // base inside the kernel by writing and reading route messages on a
  32. // routing socket.
  33. //
  34. // For the manipulation of routing information, the route message must
  35. // contain appropriate fields that include:
  36. //
  37. // Version = <must be specified>
  38. // Type = <must be specified>
  39. // Flags = <must be specified>
  40. // Index = <must be specified if necessary>
  41. // ID = <must be specified>
  42. // Seq = <must be specified>
  43. // Addrs = <must be specified>
  44. //
  45. // The Type field specifies a type of manipulation, the Flags field
  46. // specifies a class of target information and the Addrs field
  47. // specifies target information like the following:
  48. //
  49. // route.RouteMessage{
  50. // Version: RTM_VERSION,
  51. // Type: RTM_GET,
  52. // Flags: RTF_UP | RTF_HOST,
  53. // ID: uintptr(os.Getpid()),
  54. // Seq: 1,
  55. // Addrs: []route.Addrs{
  56. // RTAX_DST: &route.Inet4Addr{ ... },
  57. // RTAX_IFP: &route.LinkAddr{ ... },
  58. // RTAX_BRD: &route.Inet4Addr{ ... },
  59. // },
  60. // }
  61. //
  62. // The values for the above fields depend on the implementation of
  63. // each operating system.
  64. //
  65. // The Err field on a response message contains an error value on the
  66. // requested operation. If non-nil, the requested operation is failed.
  67. type RouteMessage struct {
  68. Version int // message version
  69. Type int // message type
  70. Flags int // route flags
  71. Index int // interface index when atatched
  72. ID uintptr // sender's identifier; usually process ID
  73. Seq int // sequence number
  74. Err error // error on requested operation
  75. Addrs []Addr // addresses
  76. extOff int // offset of header extension
  77. raw []byte // raw message
  78. }
  79. // Marshal returns the binary encoding of m.
  80. func (m *RouteMessage) Marshal() ([]byte, error) {
  81. return m.marshal()
  82. }
  83. // A RIBType reprensents a type of routing information base.
  84. type RIBType int
  85. const (
  86. RIBTypeRoute RIBType = syscall.NET_RT_DUMP
  87. RIBTypeInterface RIBType = syscall.NET_RT_IFLIST
  88. )
  89. // FetchRIB fetches a routing information base from the operating
  90. // system.
  91. //
  92. // The provided af must be an address family.
  93. //
  94. // The provided arg must be a RIBType-specific argument.
  95. // When RIBType is related to routes, arg might be a set of route
  96. // flags. When RIBType is related to network interfaces, arg might be
  97. // an interface index or a set of interface flags. In most cases, zero
  98. // means a wildcard.
  99. func FetchRIB(af int, typ RIBType, arg int) ([]byte, error) {
  100. mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
  101. n := uintptr(0)
  102. if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
  103. return nil, os.NewSyscallError("sysctl", err)
  104. }
  105. if n == 0 {
  106. return nil, nil
  107. }
  108. b := make([]byte, n)
  109. if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil {
  110. return nil, os.NewSyscallError("sysctl", err)
  111. }
  112. return b[:n], nil
  113. }