func()

in pcap-cli/internal/transformer/json_translator.go [484:555]


func (t *JSONPcapTranslator) translateICMPv6L3HeaderLayer(
	ctx context.Context, json fmt.Stringer, icmp6 *layers.ICMPv6,
) fmt.Stringer {
	// see: https://github.com/google/gopacket/blob/master/layers/icmp6msg.go#L97-L104

	_json, ICMP6 := t.asICMPv6(ctx, json)

	IPv6, _ := ICMP6.Object("IPv6")

	ipHeader := icmp6.LayerPayload()[4:]

	// IPv6 header 1st 32 bits ( 4 bytes )
	ipHeaderBytes0to3 := binary.BigEndian.Uint32(ipHeader[:4])

	// Version: from bit 0 to 3 ( 4 bits )
	//   - bin mask: 11110000000000000000000000000000
	//   - hex mask: 0xF0000000
	//   - must be shifted 28 positions to the right to discard `TrafficClass` (8 bits) and `FlowLabel` (20 bits)
	version := ipHeaderBytes0to3 & uint32(0xF0000000) >> 28
	IPv6.Set(version, "v")

	// FlowLabel: from bit 12 to 31 ( 20 bits )
	//   - bin mask: 00000000000011111111111111111111
	//   - hex mask: 0x000FFFFF
	flowLabel := ipHeaderBytes0to3 & uint32(0x000FFFFF)
	IPv6.Set(flowLabel, "lbl")

	// TrafficClass: from bit 4 to 11 ( 6+2 bits )
	//   - bin mask: 00001111111100000000000000000000
	//   - hex mask: 0x0FF00000
	//   - must be shifted 20 positions to the right to discard `FlowLabel` bits
	trafficClass := (ipHeaderBytes0to3 & uint32(0x0FF00000)) >> 20
	// The six most-significant bits hold the differentiated services field
	//   - DS field mask: `11111100` or `0xFC`
	//   - must be shifted 2 bits to the right to remove bits from ECN
	IPv6.Set((trafficClass&0xFC)>>2, "dsf")
	// The remaining two bits are used for Explicit Congestion Notification
	//   - ECN mask: `00000011` or `0x03`
	IPv6.Set((trafficClass & 0x03), "ecn")

	// HopLimit (aka TTL): 8 bits, 7th byte
	IPv6.Set(uint32(ipHeader[7]), "ttl")

	var ipBytes [16]byte

	copy(ipBytes[:], ipHeader[8:24])
	srcIP := netip.AddrFrom16(ipBytes)
	IPv6.Set(srcIP.String(), "src")

	copy(ipBytes[:], ipHeader[24:40])
	dstIP := netip.AddrFrom16(ipBytes)
	IPv6.Set(dstIP.String(), "dst")

	atDebugVerbosity(ctx,
		t.pcapTranslator,
		func(
			ctx context.Context,
			translator *pcapTranslator,
		) {
			nextHeader := uint8(ipHeader[6])
			switch nextHeader {
			default:
				IPv6.Set(nextHeader, "proto")
			case 0x06: // TCP
				IPv6.Set("TCP", "proto")
			case 0x11: // UDP
				IPv6.Set("UDP", "proto")
			}
		})

	return _json
}