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.
 
 
 

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