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  }