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