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 }