github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/tests/utils/utils.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package utils holds common testing utilities for tcpip.
    16  package utils
    17  
    18  import (
    19  	"net"
    20  	"testing"
    21  
    22  	"github.com/SagerNet/gvisor/pkg/tcpip"
    23  	"github.com/SagerNet/gvisor/pkg/tcpip/buffer"
    24  	"github.com/SagerNet/gvisor/pkg/tcpip/header"
    25  	"github.com/SagerNet/gvisor/pkg/tcpip/link/channel"
    26  	"github.com/SagerNet/gvisor/pkg/tcpip/link/ethernet"
    27  	"github.com/SagerNet/gvisor/pkg/tcpip/link/nested"
    28  	"github.com/SagerNet/gvisor/pkg/tcpip/link/pipe"
    29  	"github.com/SagerNet/gvisor/pkg/tcpip/network/ipv4"
    30  	"github.com/SagerNet/gvisor/pkg/tcpip/network/ipv6"
    31  	"github.com/SagerNet/gvisor/pkg/tcpip/stack"
    32  	"github.com/SagerNet/gvisor/pkg/tcpip/transport/icmp"
    33  )
    34  
    35  // Common NIC IDs used by tests.
    36  const (
    37  	Host1NICID   = 1
    38  	RouterNICID1 = 2
    39  	RouterNICID2 = 3
    40  	Host2NICID   = 4
    41  )
    42  
    43  // Common link addresses used by tests.
    44  const (
    45  	LinkAddr1 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x06")
    46  	LinkAddr2 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x07")
    47  	LinkAddr3 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x08")
    48  	LinkAddr4 = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x09")
    49  )
    50  
    51  // Common IP addresses used by tests.
    52  var (
    53  	Ipv4Addr = tcpip.AddressWithPrefix{
    54  		Address:   tcpip.Address(net.ParseIP("192.168.1.58").To4()),
    55  		PrefixLen: 24,
    56  	}
    57  	Ipv4Subnet      = Ipv4Addr.Subnet()
    58  	Ipv4SubnetBcast = Ipv4Subnet.Broadcast()
    59  
    60  	Ipv6Addr = tcpip.AddressWithPrefix{
    61  		Address:   tcpip.Address(net.ParseIP("200a::1").To16()),
    62  		PrefixLen: 64,
    63  	}
    64  	Ipv6Subnet      = Ipv6Addr.Subnet()
    65  	Ipv6SubnetBcast = Ipv6Subnet.Broadcast()
    66  
    67  	Ipv4Addr1 = tcpip.ProtocolAddress{
    68  		Protocol: ipv4.ProtocolNumber,
    69  		AddressWithPrefix: tcpip.AddressWithPrefix{
    70  			Address:   tcpip.Address(net.ParseIP("192.168.0.1").To4()),
    71  			PrefixLen: 24,
    72  		},
    73  	}
    74  	Ipv4Addr2 = tcpip.ProtocolAddress{
    75  		Protocol: ipv4.ProtocolNumber,
    76  		AddressWithPrefix: tcpip.AddressWithPrefix{
    77  			Address:   tcpip.Address(net.ParseIP("192.168.0.2").To4()),
    78  			PrefixLen: 8,
    79  		},
    80  	}
    81  	Ipv4Addr3 = tcpip.ProtocolAddress{
    82  		Protocol: ipv4.ProtocolNumber,
    83  		AddressWithPrefix: tcpip.AddressWithPrefix{
    84  			Address:   tcpip.Address(net.ParseIP("192.168.0.3").To4()),
    85  			PrefixLen: 8,
    86  		},
    87  	}
    88  	Ipv6Addr1 = tcpip.ProtocolAddress{
    89  		Protocol: ipv6.ProtocolNumber,
    90  		AddressWithPrefix: tcpip.AddressWithPrefix{
    91  			Address:   tcpip.Address(net.ParseIP("a::1").To16()),
    92  			PrefixLen: 64,
    93  		},
    94  	}
    95  	Ipv6Addr2 = tcpip.ProtocolAddress{
    96  		Protocol: ipv6.ProtocolNumber,
    97  		AddressWithPrefix: tcpip.AddressWithPrefix{
    98  			Address:   tcpip.Address(net.ParseIP("a::2").To16()),
    99  			PrefixLen: 64,
   100  		},
   101  	}
   102  	Ipv6Addr3 = tcpip.ProtocolAddress{
   103  		Protocol: ipv6.ProtocolNumber,
   104  		AddressWithPrefix: tcpip.AddressWithPrefix{
   105  			Address:   tcpip.Address(net.ParseIP("a::3").To16()),
   106  			PrefixLen: 64,
   107  		},
   108  	}
   109  
   110  	// Remote addrs.
   111  	RemoteIPv4Addr = tcpip.Address(net.ParseIP("10.0.0.1").To4())
   112  	RemoteIPv6Addr = tcpip.Address(net.ParseIP("200b::1").To16())
   113  )
   114  
   115  // Common ports for testing.
   116  const (
   117  	RemotePort = 5555
   118  	LocalPort  = 80
   119  )
   120  
   121  // Common IP addresses used for testing.
   122  var (
   123  	Host1IPv4Addr = tcpip.ProtocolAddress{
   124  		Protocol: ipv4.ProtocolNumber,
   125  		AddressWithPrefix: tcpip.AddressWithPrefix{
   126  			Address:   tcpip.Address(net.ParseIP("192.168.0.2").To4()),
   127  			PrefixLen: 24,
   128  		},
   129  	}
   130  	RouterNIC1IPv4Addr = tcpip.ProtocolAddress{
   131  		Protocol: ipv4.ProtocolNumber,
   132  		AddressWithPrefix: tcpip.AddressWithPrefix{
   133  			Address:   tcpip.Address(net.ParseIP("192.168.0.1").To4()),
   134  			PrefixLen: 24,
   135  		},
   136  	}
   137  	RouterNIC2IPv4Addr = tcpip.ProtocolAddress{
   138  		Protocol: ipv4.ProtocolNumber,
   139  		AddressWithPrefix: tcpip.AddressWithPrefix{
   140  			Address:   tcpip.Address(net.ParseIP("10.0.0.1").To4()),
   141  			PrefixLen: 8,
   142  		},
   143  	}
   144  	Host2IPv4Addr = tcpip.ProtocolAddress{
   145  		Protocol: ipv4.ProtocolNumber,
   146  		AddressWithPrefix: tcpip.AddressWithPrefix{
   147  			Address:   tcpip.Address(net.ParseIP("10.0.0.2").To4()),
   148  			PrefixLen: 8,
   149  		},
   150  	}
   151  	Host1IPv6Addr = tcpip.ProtocolAddress{
   152  		Protocol: ipv6.ProtocolNumber,
   153  		AddressWithPrefix: tcpip.AddressWithPrefix{
   154  			Address:   tcpip.Address(net.ParseIP("a::2").To16()),
   155  			PrefixLen: 64,
   156  		},
   157  	}
   158  	RouterNIC1IPv6Addr = tcpip.ProtocolAddress{
   159  		Protocol: ipv6.ProtocolNumber,
   160  		AddressWithPrefix: tcpip.AddressWithPrefix{
   161  			Address:   tcpip.Address(net.ParseIP("a::1").To16()),
   162  			PrefixLen: 64,
   163  		},
   164  	}
   165  	RouterNIC2IPv6Addr = tcpip.ProtocolAddress{
   166  		Protocol: ipv6.ProtocolNumber,
   167  		AddressWithPrefix: tcpip.AddressWithPrefix{
   168  			Address:   tcpip.Address(net.ParseIP("b::1").To16()),
   169  			PrefixLen: 64,
   170  		},
   171  	}
   172  	Host2IPv6Addr = tcpip.ProtocolAddress{
   173  		Protocol: ipv6.ProtocolNumber,
   174  		AddressWithPrefix: tcpip.AddressWithPrefix{
   175  			Address:   tcpip.Address(net.ParseIP("b::2").To16()),
   176  			PrefixLen: 64,
   177  		},
   178  	}
   179  )
   180  
   181  // NewEthernetEndpoint returns an ethernet link endpoint that wraps an inner
   182  // link endpoint and checks the destination link address before delivering
   183  // network packets to the network dispatcher.
   184  //
   185  // See ethernet.Endpoint for more details.
   186  func NewEthernetEndpoint(ep stack.LinkEndpoint) *EndpointWithDestinationCheck {
   187  	var e EndpointWithDestinationCheck
   188  	e.Endpoint.Init(ethernet.New(ep), &e)
   189  	return &e
   190  }
   191  
   192  // EndpointWithDestinationCheck is a link endpoint that checks the destination
   193  // link address before delivering network packets to the network dispatcher.
   194  type EndpointWithDestinationCheck struct {
   195  	nested.Endpoint
   196  }
   197  
   198  var _ stack.NetworkDispatcher = (*EndpointWithDestinationCheck)(nil)
   199  var _ stack.LinkEndpoint = (*EndpointWithDestinationCheck)(nil)
   200  
   201  // DeliverNetworkPacket implements stack.NetworkDispatcher.
   202  func (e *EndpointWithDestinationCheck) DeliverNetworkPacket(src, dst tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
   203  	if dst == e.Endpoint.LinkAddress() || dst == header.EthernetBroadcastAddress || header.IsMulticastEthernetAddress(dst) {
   204  		e.Endpoint.DeliverNetworkPacket(src, dst, proto, pkt)
   205  	}
   206  }
   207  
   208  // SetupRoutedStacks creates the NICs, sets forwarding, adds addresses and sets
   209  // the route tables for the passed stacks.
   210  func SetupRoutedStacks(t *testing.T, host1Stack, routerStack, host2Stack *stack.Stack) {
   211  	host1NIC, routerNIC1 := pipe.New(LinkAddr1, LinkAddr2)
   212  	routerNIC2, host2NIC := pipe.New(LinkAddr3, LinkAddr4)
   213  
   214  	if err := host1Stack.CreateNIC(Host1NICID, NewEthernetEndpoint(host1NIC)); err != nil {
   215  		t.Fatalf("host1Stack.CreateNIC(%d, _): %s", Host1NICID, err)
   216  	}
   217  	if err := routerStack.CreateNIC(RouterNICID1, NewEthernetEndpoint(routerNIC1)); err != nil {
   218  		t.Fatalf("routerStack.CreateNIC(%d, _): %s", RouterNICID1, err)
   219  	}
   220  	if err := routerStack.CreateNIC(RouterNICID2, NewEthernetEndpoint(routerNIC2)); err != nil {
   221  		t.Fatalf("routerStack.CreateNIC(%d, _): %s", RouterNICID2, err)
   222  	}
   223  	if err := host2Stack.CreateNIC(Host2NICID, NewEthernetEndpoint(host2NIC)); err != nil {
   224  		t.Fatalf("host2Stack.CreateNIC(%d, _): %s", Host2NICID, err)
   225  	}
   226  
   227  	if err := routerStack.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true); err != nil {
   228  		t.Fatalf("routerStack.SetForwardingDefaultAndAllNICs(%d): %s", ipv4.ProtocolNumber, err)
   229  	}
   230  	if err := routerStack.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil {
   231  		t.Fatalf("routerStack.SetForwardingDefaultAndAllNICs(%d): %s", ipv6.ProtocolNumber, err)
   232  	}
   233  
   234  	if err := host1Stack.AddProtocolAddress(Host1NICID, Host1IPv4Addr); err != nil {
   235  		t.Fatalf("host1Stack.AddProtocolAddress(%d, %#v): %s", Host1NICID, Host1IPv4Addr, err)
   236  	}
   237  	if err := routerStack.AddProtocolAddress(RouterNICID1, RouterNIC1IPv4Addr); err != nil {
   238  		t.Fatalf("routerStack.AddProtocolAddress(%d, %#v): %s", RouterNICID1, RouterNIC1IPv4Addr, err)
   239  	}
   240  	if err := routerStack.AddProtocolAddress(RouterNICID2, RouterNIC2IPv4Addr); err != nil {
   241  		t.Fatalf("routerStack.AddProtocolAddress(%d, %#v): %s", RouterNICID2, RouterNIC2IPv4Addr, err)
   242  	}
   243  	if err := host2Stack.AddProtocolAddress(Host2NICID, Host2IPv4Addr); err != nil {
   244  		t.Fatalf("host2Stack.AddProtocolAddress(%d, %#v): %s", Host2NICID, Host2IPv4Addr, err)
   245  	}
   246  	if err := host1Stack.AddProtocolAddress(Host1NICID, Host1IPv6Addr); err != nil {
   247  		t.Fatalf("host1Stack.AddProtocolAddress(%d, %#v): %s", Host1NICID, Host1IPv6Addr, err)
   248  	}
   249  	if err := routerStack.AddProtocolAddress(RouterNICID1, RouterNIC1IPv6Addr); err != nil {
   250  		t.Fatalf("routerStack.AddProtocolAddress(%d, %#v): %s", RouterNICID1, RouterNIC1IPv6Addr, err)
   251  	}
   252  	if err := routerStack.AddProtocolAddress(RouterNICID2, RouterNIC2IPv6Addr); err != nil {
   253  		t.Fatalf("routerStack.AddProtocolAddress(%d, %#v): %s", RouterNICID2, RouterNIC2IPv6Addr, err)
   254  	}
   255  	if err := host2Stack.AddProtocolAddress(Host2NICID, Host2IPv6Addr); err != nil {
   256  		t.Fatalf("host2Stack.AddProtocolAddress(%d, %#v): %s", Host2NICID, Host2IPv6Addr, err)
   257  	}
   258  
   259  	host1Stack.SetRouteTable([]tcpip.Route{
   260  		{
   261  			Destination: Host1IPv4Addr.AddressWithPrefix.Subnet(),
   262  			NIC:         Host1NICID,
   263  		},
   264  		{
   265  			Destination: Host1IPv6Addr.AddressWithPrefix.Subnet(),
   266  			NIC:         Host1NICID,
   267  		},
   268  		{
   269  			Destination: Host2IPv4Addr.AddressWithPrefix.Subnet(),
   270  			Gateway:     RouterNIC1IPv4Addr.AddressWithPrefix.Address,
   271  			NIC:         Host1NICID,
   272  		},
   273  		{
   274  			Destination: Host2IPv6Addr.AddressWithPrefix.Subnet(),
   275  			Gateway:     RouterNIC1IPv6Addr.AddressWithPrefix.Address,
   276  			NIC:         Host1NICID,
   277  		},
   278  	})
   279  	routerStack.SetRouteTable([]tcpip.Route{
   280  		{
   281  			Destination: RouterNIC1IPv4Addr.AddressWithPrefix.Subnet(),
   282  			NIC:         RouterNICID1,
   283  		},
   284  		{
   285  			Destination: RouterNIC1IPv6Addr.AddressWithPrefix.Subnet(),
   286  			NIC:         RouterNICID1,
   287  		},
   288  		{
   289  			Destination: RouterNIC2IPv4Addr.AddressWithPrefix.Subnet(),
   290  			NIC:         RouterNICID2,
   291  		},
   292  		{
   293  			Destination: RouterNIC2IPv6Addr.AddressWithPrefix.Subnet(),
   294  			NIC:         RouterNICID2,
   295  		},
   296  	})
   297  	host2Stack.SetRouteTable([]tcpip.Route{
   298  		{
   299  			Destination: Host2IPv4Addr.AddressWithPrefix.Subnet(),
   300  			NIC:         Host2NICID,
   301  		},
   302  		{
   303  			Destination: Host2IPv6Addr.AddressWithPrefix.Subnet(),
   304  			NIC:         Host2NICID,
   305  		},
   306  		{
   307  			Destination: Host1IPv4Addr.AddressWithPrefix.Subnet(),
   308  			Gateway:     RouterNIC2IPv4Addr.AddressWithPrefix.Address,
   309  			NIC:         Host2NICID,
   310  		},
   311  		{
   312  			Destination: Host1IPv6Addr.AddressWithPrefix.Subnet(),
   313  			Gateway:     RouterNIC2IPv6Addr.AddressWithPrefix.Address,
   314  			NIC:         Host2NICID,
   315  		},
   316  	})
   317  }
   318  
   319  func rxICMPv4Echo(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8, ty header.ICMPv4Type) {
   320  	totalLen := header.IPv4MinimumSize + header.ICMPv4MinimumSize
   321  	hdr := buffer.NewPrependable(totalLen)
   322  	pkt := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
   323  	pkt.SetType(ty)
   324  	pkt.SetCode(header.ICMPv4UnusedCode)
   325  	pkt.SetChecksum(0)
   326  	pkt.SetChecksum(^header.Checksum(pkt, 0))
   327  	ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
   328  	ip.Encode(&header.IPv4Fields{
   329  		TotalLength: uint16(totalLen),
   330  		Protocol:    uint8(icmp.ProtocolNumber4),
   331  		TTL:         ttl,
   332  		SrcAddr:     src,
   333  		DstAddr:     dst,
   334  	})
   335  	ip.SetChecksum(^ip.CalculateChecksum())
   336  
   337  	e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   338  		Data: hdr.View().ToVectorisedView(),
   339  	}))
   340  }
   341  
   342  // RxICMPv4EchoRequest constructs and injects an ICMPv4 echo request packet on
   343  // the provided endpoint.
   344  func RxICMPv4EchoRequest(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) {
   345  	rxICMPv4Echo(e, src, dst, ttl, header.ICMPv4Echo)
   346  }
   347  
   348  // RxICMPv4EchoReply constructs and injects an ICMPv4 echo reply packet on
   349  // the provided endpoint.
   350  func RxICMPv4EchoReply(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) {
   351  	rxICMPv4Echo(e, src, dst, ttl, header.ICMPv4EchoReply)
   352  }
   353  
   354  func rxICMPv6Echo(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8, ty header.ICMPv6Type) {
   355  	totalLen := header.IPv6MinimumSize + header.ICMPv6MinimumSize
   356  	hdr := buffer.NewPrependable(totalLen)
   357  	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6MinimumSize))
   358  	pkt.SetType(ty)
   359  	pkt.SetCode(header.ICMPv6UnusedCode)
   360  	pkt.SetChecksum(0)
   361  	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
   362  		Header: pkt,
   363  		Src:    src,
   364  		Dst:    dst,
   365  	}))
   366  	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
   367  	ip.Encode(&header.IPv6Fields{
   368  		PayloadLength:     header.ICMPv6MinimumSize,
   369  		TransportProtocol: icmp.ProtocolNumber6,
   370  		HopLimit:          ttl,
   371  		SrcAddr:           src,
   372  		DstAddr:           dst,
   373  	})
   374  
   375  	e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   376  		Data: hdr.View().ToVectorisedView(),
   377  	}))
   378  }
   379  
   380  // RxICMPv6EchoRequest constructs and injects an ICMPv6 echo request packet on
   381  // the provided endpoint.
   382  func RxICMPv6EchoRequest(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) {
   383  	rxICMPv6Echo(e, src, dst, ttl, header.ICMPv6EchoRequest)
   384  }
   385  
   386  // RxICMPv6EchoReply constructs and injects an ICMPv6 echo reply packet on
   387  // the provided endpoint.
   388  func RxICMPv6EchoReply(e *channel.Endpoint, src, dst tcpip.Address, ttl uint8) {
   389  	rxICMPv6Echo(e, src, dst, ttl, header.ICMPv6EchoReply)
   390  }