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.
 
 
 

234 lines
5.0 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
  6. import (
  7. "os"
  8. "syscall"
  9. "testing"
  10. "time"
  11. )
  12. func TestFetchAndParseRIB(t *testing.T) {
  13. for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
  14. for _, typ := range []RIBType{sysNET_RT_DUMP, sysNET_RT_IFLIST} {
  15. ms, err := fetchAndParseRIB(af, typ)
  16. if err != nil {
  17. t.Error(err)
  18. continue
  19. }
  20. ss, err := msgs(ms).validate()
  21. if err != nil {
  22. t.Errorf("%v %d %v", addrFamily(af), typ, err)
  23. continue
  24. }
  25. for _, s := range ss {
  26. t.Log(s)
  27. }
  28. }
  29. }
  30. }
  31. var (
  32. rtmonSock int
  33. rtmonErr error
  34. )
  35. func init() {
  36. // We need to keep rtmonSock alive to avoid treading on
  37. // recycled socket descriptors.
  38. rtmonSock, rtmonErr = syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
  39. }
  40. // TestMonitorAndParseRIB leaks a worker goroutine and a socket
  41. // descriptor but that's intentional.
  42. func TestMonitorAndParseRIB(t *testing.T) {
  43. if testing.Short() || os.Getuid() != 0 {
  44. t.Skip("must be root")
  45. }
  46. if rtmonErr != nil {
  47. t.Fatal(rtmonErr)
  48. }
  49. // We suppose that using an IPv4 link-local address and the
  50. // dot1Q ID for Token Ring and FDDI doesn't harm anyone.
  51. pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
  52. if err := pv.configure(1002); err != nil {
  53. t.Skip(err)
  54. }
  55. if err := pv.setup(); err != nil {
  56. t.Skip(err)
  57. }
  58. pv.teardown()
  59. go func() {
  60. b := make([]byte, os.Getpagesize())
  61. for {
  62. // There's no easy way to unblock this read
  63. // call because the routing message exchange
  64. // over routing socket is a connectionless
  65. // message-oriented protocol, no control plane
  66. // for signaling connectivity, and we cannot
  67. // use the net package of standard library due
  68. // to the lack of support for routing socket
  69. // and circular dependency.
  70. n, err := syscall.Read(rtmonSock, b)
  71. if err != nil {
  72. return
  73. }
  74. ms, err := ParseRIB(0, b[:n])
  75. if err != nil {
  76. t.Error(err)
  77. return
  78. }
  79. ss, err := msgs(ms).validate()
  80. if err != nil {
  81. t.Error(err)
  82. return
  83. }
  84. for _, s := range ss {
  85. t.Log(s)
  86. }
  87. }
  88. }()
  89. for _, vid := range []int{1002, 1003, 1004, 1005} {
  90. pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
  91. if err := pv.configure(vid); err != nil {
  92. t.Fatal(err)
  93. }
  94. if err := pv.setup(); err != nil {
  95. t.Fatal(err)
  96. }
  97. time.Sleep(200 * time.Millisecond)
  98. if err := pv.teardown(); err != nil {
  99. t.Fatal(err)
  100. }
  101. time.Sleep(200 * time.Millisecond)
  102. }
  103. }
  104. func TestParseRIBWithFuzz(t *testing.T) {
  105. for _, fuzz := range []string{
  106. "0\x00\x05\x050000000000000000" +
  107. "00000000000000000000" +
  108. "00000000000000000000" +
  109. "00000000000000000000" +
  110. "0000000000000\x02000000" +
  111. "00000000",
  112. "\x02\x00\x05\f0000000000000000" +
  113. "0\x0200000000000000",
  114. "\x02\x00\x05\x100000000000000\x1200" +
  115. "0\x00\xff\x00",
  116. "\x02\x00\x05\f0000000000000000" +
  117. "0\x12000\x00\x02\x0000",
  118. "\x00\x00\x00\x01\x00",
  119. "00000",
  120. } {
  121. for typ := RIBType(0); typ < 256; typ++ {
  122. ParseRIB(typ, []byte(fuzz))
  123. }
  124. }
  125. }
  126. func TestRouteMessage(t *testing.T) {
  127. s, err := syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
  128. if err != nil {
  129. t.Fatal(err)
  130. }
  131. defer syscall.Close(s)
  132. var ms []RouteMessage
  133. for _, af := range []int{sysAF_INET, sysAF_INET6} {
  134. rs, err := fetchAndParseRIB(af, sysNET_RT_DUMP)
  135. if err != nil || len(rs) == 0 {
  136. continue
  137. }
  138. switch af {
  139. case sysAF_INET:
  140. ms = append(ms, []RouteMessage{
  141. {
  142. Type: sysRTM_GET,
  143. Addrs: []Addr{
  144. &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
  145. nil,
  146. nil,
  147. nil,
  148. &LinkAddr{},
  149. &Inet4Addr{},
  150. nil,
  151. &Inet4Addr{},
  152. },
  153. },
  154. {
  155. Type: sysRTM_GET,
  156. Addrs: []Addr{
  157. &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
  158. },
  159. },
  160. }...)
  161. case sysAF_INET6:
  162. ms = append(ms, []RouteMessage{
  163. {
  164. Type: sysRTM_GET,
  165. Addrs: []Addr{
  166. &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
  167. nil,
  168. nil,
  169. nil,
  170. &LinkAddr{},
  171. &Inet6Addr{},
  172. nil,
  173. &Inet6Addr{},
  174. },
  175. },
  176. {
  177. Type: sysRTM_GET,
  178. Addrs: []Addr{
  179. &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
  180. },
  181. },
  182. }...)
  183. }
  184. }
  185. for i, m := range ms {
  186. m.ID = uintptr(os.Getpid())
  187. m.Seq = i + 1
  188. wb, err := m.Marshal()
  189. if err != nil {
  190. t.Fatalf("%v: %v", m, err)
  191. }
  192. if _, err := syscall.Write(s, wb); err != nil {
  193. t.Fatalf("%v: %v", m, err)
  194. }
  195. rb := make([]byte, os.Getpagesize())
  196. n, err := syscall.Read(s, rb)
  197. if err != nil {
  198. t.Fatalf("%v: %v", m, err)
  199. }
  200. rms, err := ParseRIB(0, rb[:n])
  201. if err != nil {
  202. t.Fatalf("%v: %v", m, err)
  203. }
  204. for _, rm := range rms {
  205. err := rm.(*RouteMessage).Err
  206. if err != nil {
  207. t.Errorf("%v: %v", m, err)
  208. }
  209. }
  210. ss, err := msgs(rms).validate()
  211. if err != nil {
  212. t.Fatalf("%v: %v", m, err)
  213. }
  214. for _, s := range ss {
  215. t.Log(s)
  216. }
  217. }
  218. }