github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/net/packet/payload_test.go (about)

     1  package packet
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  )
     8  
     9  var icmp4RequestBuffer = []byte{
    10  	// IP header up to checksum
    11  	0x45, 0x00, 0x00, 0x27, 0xde, 0xad, 0x00, 0x00, 0x40, 0x01, 0x8c, 0x15,
    12  	// source IP
    13  	0x01, 0x02, 0x03, 0x04,
    14  	// destination IP
    15  	0x05, 0x06, 0x07, 0x08,
    16  	// ICMP header
    17  	0x08, 0x00, 0x7d, 0x22,
    18  	// "request_payload"
    19  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    20  }
    21  
    22  var malformedPacketLengthIPv4 = []byte{
    23  	0x45, 0x74, 0x00, 0x00, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    24  }
    25  
    26  var malformedPacketInvalidIPVersion = []byte{
    27  	0x25, 0x74, 0x00, 0x00, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    28  }
    29  
    30  var tcp4PacketPayload = []byte{
    31  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    32  }
    33  
    34  var tcp4Packet = []byte{
    35  	// IP header up to checksum
    36  	0x45, 0x00, 0x00, 0x37, 0xde, 0xad, 0x00, 0x00, 0x40, 0x06, 0x49, 0x5f,
    37  	// source IP
    38  	0x01, 0x02, 0x03, 0x04,
    39  	// destination IP
    40  	0x05, 0x06, 0x07, 0x08,
    41  	// TCP header with SYN, ACK set
    42  	0x00, 0x7b, 0x02, 0x37, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00,
    43  	0x50, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    44  	// "request_payload"
    45  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    46  }
    47  
    48  var tcp6PacketPayload = []byte{
    49  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    50  }
    51  
    52  var tcp6Packet = []byte{
    53  	// IPv6 header up to hop limit
    54  	0x60, 0x06, 0xef, 0xcc, 0x00, 0x23, 0x06, 0x40,
    55  	// Src addr
    56  	0x20, 0x01, 0x05, 0x59, 0xbc, 0x13, 0x54, 0x00, 0x17, 0x49, 0x46, 0x28, 0x39, 0x34, 0x0e, 0x1b,
    57  	// Dst addr
    58  	0x26, 0x07, 0xf8, 0xb0, 0x40, 0x0a, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0e,
    59  	// TCP header with SYN, ACK set
    60  	0x00, 0x7b, 0x02, 0x37, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00,
    61  	0x50, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    62  	// "request_payload"
    63  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    64  }
    65  
    66  var udp4RequestPayload = []byte{
    67  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    68  }
    69  
    70  var udp4Request = []byte{
    71  	// IP header up to checksum
    72  	0x45, 0x00, 0x00, 0x2b, 0xde, 0xad, 0x00, 0x00, 0x40, 0x11, 0x8c, 0x01,
    73  	// source IP
    74  	0x01, 0x02, 0x03, 0x04,
    75  	// destination IP
    76  	0x05, 0x06, 0x07, 0x08,
    77  	// UDP header
    78  	0x00, 0x7b, 0x02, 0x37, 0x00, 0x17, 0x72, 0x1d,
    79  	// "request_payload"
    80  	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
    81  }
    82  
    83  var udp6RequestPayload = []byte{
    84  	0x5c, 0x06, 0xae, 0x85, 0x02, 0xf5, 0xdb, 0x90, 0xe0, 0xe0, 0x93, 0xed, 0x9a, 0xd9, 0x92, 0x69, 0xbe, 0x36, 0x8a, 0x7d, 0xd7, 0xce, 0xd0, 0x8a, 0xf2, 0x51, 0x95, 0xff, 0xb6, 0x92, 0x70, 0x10, 0xd7,
    85  }
    86  
    87  var udp6Request = []byte{
    88  	// IPv6 header up to hop limit
    89  	0x60, 0x0e, 0xc9, 0x67, 0x00, 0x29, 0x11, 0x40,
    90  	// Src addr
    91  	0x20, 0x01, 0x05, 0x59, 0xbc, 0x13, 0x54, 0x00, 0x17, 0x49, 0x46, 0x28, 0x39, 0x34, 0x0e, 0x1b,
    92  	// Dst addr
    93  	0x26, 0x07, 0xf8, 0xb0, 0x40, 0x0a, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0e,
    94  	// UDP header
    95  	0xd4, 0x04, 0x01, 0xbb, 0x00, 0x29, 0x96, 0x84,
    96  	// Payload
    97  	0x5c, 0x06, 0xae, 0x85, 0x02, 0xf5, 0xdb, 0x90, 0xe0, 0xe0, 0x93, 0xed, 0x9a, 0xd9, 0x92, 0x69, 0xbe, 0x36, 0x8a, 0x7d, 0xd7, 0xce, 0xd0, 0x8a, 0xf2, 0x51, 0x95, 0xff, 0xb6, 0x92, 0x70, 0x10, 0xd7,
    98  }
    99  
   100  func TestExtractPayload(t *testing.T) {
   101  	type testCase struct {
   102  		title               string
   103  		data                []byte
   104  		expectedError       error
   105  		expectedPayload     []byte
   106  		expectedSubProtocol SubProtocol
   107  	}
   108  
   109  	testCases := []testCase{
   110  		{
   111  			title:         "unsupported sub protocol",
   112  			data:          icmp4RequestBuffer,
   113  			expectedError: ErrUnsupportedSubProtocol,
   114  		},
   115  		{
   116  			title:         "malformed ipv4 packet length",
   117  			data:          malformedPacketLengthIPv4,
   118  			expectedError: ErrOffsetBiggerThanData,
   119  		},
   120  		{
   121  			title:         "malformed ip packet unsupported ip version",
   122  			data:          malformedPacketInvalidIPVersion,
   123  			expectedError: ErrUnsupportedIPVersion,
   124  		},
   125  		{
   126  			title:               "ipv4 tcp request",
   127  			data:                tcp4Packet,
   128  			expectedPayload:     tcp4PacketPayload,
   129  			expectedSubProtocol: SubProtocolTCP,
   130  		},
   131  		{
   132  			title:               "ipv4 udp request",
   133  			data:                udp4Request,
   134  			expectedPayload:     udp4RequestPayload,
   135  			expectedSubProtocol: SubProtocolUDP,
   136  		},
   137  		{
   138  			title:               "ipv6 tcp request",
   139  			data:                tcp6Packet,
   140  			expectedPayload:     tcp6PacketPayload,
   141  			expectedSubProtocol: SubProtocolTCP,
   142  		},
   143  		{
   144  			title:               "ipv6 udp request",
   145  			data:                udp6Request,
   146  			expectedPayload:     udp6RequestPayload,
   147  			expectedSubProtocol: SubProtocolUDP,
   148  		},
   149  	}
   150  
   151  	for _, test := range testCases {
   152  		t.Run(test.title, func(t *testing.T) {
   153  			payload, subProtocol, err := ExtractPayload(test.data)
   154  			if test.expectedError != nil {
   155  				require.ErrorIs(t, err, test.expectedError)
   156  				require.Equal(t, UnsupportedSubProtocol, subProtocol)
   157  				return
   158  			} else {
   159  				require.NoError(t, err)
   160  			}
   161  			require.Equal(t, test.expectedPayload, payload)
   162  			require.Equal(t, test.expectedSubProtocol, subProtocol)
   163  		})
   164  	}
   165  }
   166  
   167  var sinkPayload []byte
   168  
   169  func BenchmarkDecode(b *testing.B) {
   170  	type benchmark struct {
   171  		title string
   172  		data  []byte
   173  	}
   174  
   175  	benchmarks := []benchmark{
   176  		{
   177  			title: "tcp4",
   178  			data:  tcp4Packet,
   179  		},
   180  		{
   181  			title: "tcp6",
   182  			data:  tcp6Packet,
   183  		},
   184  		{
   185  			title: "udp4",
   186  			data:  udp4Request,
   187  		},
   188  		{
   189  			title: "udp6",
   190  			data:  udp6Request,
   191  		},
   192  	}
   193  
   194  	for _, bench := range benchmarks {
   195  		b.Run(bench.title, func(b *testing.B) {
   196  			b.ReportAllocs()
   197  			b.ResetTimer()
   198  
   199  			for i := 0; i < b.N; i++ {
   200  				sinkPayload, _, _ = ExtractPayload(bench.data)
   201  			}
   202  		})
   203  	}
   204  }