github.com/cilium/cilium@v1.16.2/pkg/hubble/testutils/payload_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package testutils
     5  
     6  import (
     7  	"encoding/hex"
     8  	"net"
     9  	"testing"
    10  
    11  	"github.com/google/gopacket"
    12  	"github.com/google/gopacket/layers"
    13  	"github.com/stretchr/testify/assert"
    14  
    15  	"github.com/cilium/cilium/pkg/monitor"
    16  	monitorAPI "github.com/cilium/cilium/pkg/monitor/api"
    17  )
    18  
    19  func decodeHex(s string) []byte {
    20  	b, err := hex.DecodeString(s)
    21  	if err != nil {
    22  		panic(err)
    23  	}
    24  	return b
    25  }
    26  
    27  func TestCreateL3L4Payload(t *testing.T) {
    28  	// These contain TraceNotify headers plus the ethernet header of the packet
    29  	packetv4Prefix := decodeHex("0403a80b8d4598d462000000620000006800000001000000000002000000000006e9183bb275129106e2221a080045000054bfe900003f019ae2")
    30  	packetv4802Prefix := decodeHex("0403a80b8d4598d462000000620000006800000001000000000002000000000006e9183bb275129106e2221a81000202080045000054bfe900003f019ae2")
    31  	packetv6Prefix := decodeHex("0405a80b5f16f2b85600000056000000680000000000000000000000000000003333ff00b3e5129106e2221a86dd6000000000203aff")
    32  	packetv6802Prefix := decodeHex("0405a80b5f16f2b85600000056000000680000000000000000000000000000003333ff00b3e5129106e2221a8100020286dd6000000000203aff")
    33  
    34  	// ICMPv4/v6 packets (with reversed src/dst IPs)
    35  	packetICMPv4 := decodeHex("010101010a107e4000003639225700051b7b415d0000000086bf050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637")
    36  	packetICMPv6Req := decodeHex("f00d0000000000000a10000000009195ff0200000000000000000001ff00b3e58700507500000000f00d0000000000000a1000000000b3e50101129106e2221a")
    37  	packetICMPv4Rev := decodeHex("0a107e400101010100003639225700051b7b415d0000000086bf050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637")
    38  	packetICMPv6Rev := decodeHex("ff0200000000000000000001ff00b3e5f00d0000000000000a100000000091958700507500000000f00d0000000000000a1000000000b3e50101129106e2221a")
    39  
    40  	// The following structs are decoded pieces of the above packets
    41  	traceNotifyIPv4 := monitor.TraceNotifyV0{
    42  		Type:     monitorAPI.MessageTypeTrace,
    43  		ObsPoint: monitorAPI.TraceToStack,
    44  		Source:   0xba8,
    45  		Hash:     0xd498458d,
    46  		OrigLen:  0x62,
    47  		CapLen:   0x62,
    48  		SrcLabel: 0x68,
    49  		DstLabel: 0x1,
    50  		Reason:   monitor.TraceReasonCtReply,
    51  	}
    52  	traceNotifyIPv6 := monitor.TraceNotifyV0{
    53  		Type:     monitorAPI.MessageTypeTrace,
    54  		ObsPoint: monitorAPI.TraceFromLxc,
    55  		Source:   0xba8,
    56  		Hash:     0xb8f2165f,
    57  		OrigLen:  0x56,
    58  		CapLen:   0x56,
    59  		SrcLabel: 0x68,
    60  		DstLabel: 0x0,
    61  		Reason:   monitor.TraceReasonPolicy,
    62  	}
    63  
    64  	etherIPv4 := &layers.Ethernet{
    65  		EthernetType: layers.EthernetTypeIPv4,
    66  		SrcMAC:       net.HardwareAddr{0x12, 0x91, 0x06, 0xe2, 0x22, 0x1a},
    67  		DstMAC:       net.HardwareAddr{0x06, 0xe9, 0x18, 0x3b, 0xb2, 0x75},
    68  	}
    69  
    70  	etherIPv6 := &layers.Ethernet{
    71  		EthernetType: layers.EthernetTypeIPv6,
    72  		SrcMAC:       net.HardwareAddr{0x12, 0x91, 0x6, 0xe2, 0x22, 0x1a},
    73  		DstMAC:       net.HardwareAddr{0x33, 0x33, 0xff, 0x0, 0xb3, 0xe5},
    74  	}
    75  	etherIPv4Dot1Q := &layers.Ethernet{
    76  		EthernetType: layers.EthernetTypeDot1Q,
    77  		SrcMAC:       net.HardwareAddr{0x12, 0x91, 0x06, 0xe2, 0x22, 0x1a},
    78  		DstMAC:       net.HardwareAddr{0x06, 0xe9, 0x18, 0x3b, 0xb2, 0x75},
    79  	}
    80  	etherIPv6Dot1Q := &layers.Ethernet{
    81  		EthernetType: layers.EthernetTypeDot1Q,
    82  		SrcMAC:       net.HardwareAddr{0x12, 0x91, 0x6, 0xe2, 0x22, 0x1a},
    83  		DstMAC:       net.HardwareAddr{0x33, 0x33, 0xff, 0x0, 0xb3, 0xe5},
    84  	}
    85  
    86  	dot1QIPv4 := &layers.Dot1Q{
    87  		Type:           layers.EthernetTypeIPv4,
    88  		VLANIdentifier: 0x0202,
    89  	}
    90  	dot1QIPv6 := &layers.Dot1Q{
    91  		Type:           layers.EthernetTypeIPv6,
    92  		VLANIdentifier: 0x0202,
    93  	}
    94  
    95  	ipv4 := &layers.IPv4{
    96  		Version:  0x4,
    97  		Id:       0xbfe9,
    98  		TTL:      63,
    99  		Protocol: layers.IPProtocolICMPv4,
   100  		Checksum: 0x9ae2,
   101  		SrcIP:    net.ParseIP("1.1.1.1"),
   102  		DstIP:    net.ParseIP("10.16.126.64"),
   103  	}
   104  	ipv4Rev := &layers.IPv4{
   105  		Version:  0x4,
   106  		Id:       0xbfe9,
   107  		TTL:      63,
   108  		Protocol: layers.IPProtocolICMPv4,
   109  		Checksum: 0x9ae2,
   110  		SrcIP:    net.ParseIP("10.16.126.64"),
   111  		DstIP:    net.ParseIP("1.1.1.1"),
   112  	}
   113  	ipv6 := &layers.IPv6{
   114  		Version:    0x6,
   115  		NextHeader: 0x3a,
   116  		HopLimit:   0xff,
   117  		SrcIP:      net.ParseIP("f00d::a10:0:0:9195"),
   118  		DstIP:      net.ParseIP("ff02::1:ff00:b3e5"),
   119  	}
   120  	ipv6Rev := &layers.IPv6{
   121  		Version:    0x6,
   122  		NextHeader: 0x3a,
   123  		HopLimit:   0xff,
   124  		SrcIP:      net.ParseIP("ff02::1:ff00:b3e5"),
   125  		DstIP:      net.ParseIP("f00d::a10:0:0:9195"),
   126  	}
   127  
   128  	icmpv4 := &layers.ICMPv4{
   129  		TypeCode: layers.ICMPv4TypeEchoReply,
   130  		Checksum: 0x3639,
   131  		Id:       0x2257,
   132  		Seq:      0x05,
   133  	}
   134  	icmpv4Payload := gopacket.Payload(decodeHex("1b7b415d0000000086bf050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637"))
   135  
   136  	icmpv6 := &layers.ICMPv6{
   137  		TypeCode: layers.ICMPv6TypeNeighborSolicitation << 8,
   138  		Checksum: 0x5075,
   139  	}
   140  	icmpv6Payload := &layers.ICMPv6NeighborSolicitation{
   141  		TargetAddress: net.ParseIP("f00d::a10:0:0:b3e5"),
   142  		Options: layers.ICMPv6Options{
   143  			layers.ICMPv6Option{
   144  				Type: layers.ICMPv6OptSourceAddress,
   145  				Data: []uint8{0x12, 0x91, 0x6, 0xe2, 0x22, 0x1a},
   146  			},
   147  		},
   148  	}
   149  
   150  	type args struct {
   151  		msg interface{}
   152  		l   []gopacket.SerializableLayer
   153  	}
   154  	tests := []struct {
   155  		name    string
   156  		args    args
   157  		wantErr bool
   158  		want    []byte
   159  	}{
   160  		{
   161  			name: "ICMPv4 Echo Reply",
   162  			args: args{
   163  				msg: traceNotifyIPv4,
   164  				l:   []gopacket.SerializableLayer{etherIPv4, ipv4, icmpv4, icmpv4Payload},
   165  			},
   166  			want: append(packetv4Prefix[:], packetICMPv4...),
   167  		},
   168  		{
   169  			name: "ICMPv6 Neighbor Solicitation",
   170  			args: args{
   171  				msg: traceNotifyIPv6,
   172  				l:   []gopacket.SerializableLayer{etherIPv6, ipv6, icmpv6, icmpv6Payload},
   173  			},
   174  			want: append(packetv6Prefix[:], packetICMPv6Req...),
   175  		},
   176  		{
   177  			name: "ICMPv4 Echo Reply Reversed",
   178  			args: args{
   179  				msg: traceNotifyIPv4,
   180  				l:   []gopacket.SerializableLayer{etherIPv4, ipv4Rev, icmpv4, icmpv4Payload},
   181  			},
   182  			want: append(packetv4Prefix[:], packetICMPv4Rev...),
   183  		},
   184  		{
   185  			name: "ICMPv6 Neighbor Solicitation Reversed",
   186  			args: args{
   187  				msg: traceNotifyIPv6,
   188  				l:   []gopacket.SerializableLayer{etherIPv6, ipv6Rev, icmpv6, icmpv6Payload},
   189  			},
   190  			want: append(packetv6Prefix[:], packetICMPv6Rev...),
   191  		},
   192  		{
   193  			name: "802.11q ICMPv4 Echo Reply",
   194  			args: args{
   195  				msg: traceNotifyIPv4,
   196  				l:   []gopacket.SerializableLayer{etherIPv4Dot1Q, dot1QIPv4, ipv4, icmpv4, icmpv4Payload},
   197  			},
   198  			want: append(packetv4802Prefix[:], packetICMPv4...),
   199  		},
   200  		{
   201  			name: "802.11q ICMPv6 Neighbor Solicitation",
   202  			args: args{
   203  				msg: traceNotifyIPv6,
   204  				l:   []gopacket.SerializableLayer{etherIPv6Dot1Q, dot1QIPv6, ipv6, icmpv6, icmpv6Payload},
   205  			},
   206  			want: append(packetv6802Prefix[:], packetICMPv6Req...),
   207  		},
   208  	}
   209  	for _, tt := range tests {
   210  		t.Run(tt.name, func(t *testing.T) {
   211  			pl, err := CreateL3L4Payload(tt.args.msg, tt.args.l...)
   212  			if (err != nil) != tt.wantErr {
   213  				t.Errorf("\"%s\" error = %v, wantErr %v", tt.name, err, tt.wantErr)
   214  				return
   215  			}
   216  			if err != nil {
   217  				return
   218  			}
   219  			assert.Equal(t, tt.want, pl)
   220  		})
   221  	}
   222  }