route.go 4.3 KB

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