in pcap-cli/internal/transformer/json_translator.go [369:420]
func (t *JSONPcapTranslator) translateICMPv4Layer(ctx context.Context, icmp4 *layers.ICMPv4) fmt.Stringer {
// see: https://github.com/google/gopacket/blob/master/layers/icmp4.go#L208-L215
json := gabs.New()
ICMP4, _ := json.Object("ICMP")
ICMP4.Set(icmp4.TypeCode.Type(), "type")
ICMP4.Set(icmp4.TypeCode.Code(), "code")
ICMP4.Set(icmp4.Checksum, "xsum")
// see: https://github.com/google/gopacket/blob/master/layers/icmp4.go#L78-L153
ICMP4.Set(icmp4.TypeCode.String(), "msg")
switch icmp4.TypeCode.Type() {
case layers.ICMPv4TypeEchoRequest, layers.ICMPv4TypeEchoReply:
ICMP4.Set(icmp4.Id, "id")
ICMP4.Set(icmp4.Seq, "seq")
case layers.ICMPv4TypeTimeExceeded, layers.ICMPv4TypeDestinationUnreachable, layers.ICMPv4TypeRedirect:
IPv4, _ := ICMP4.Object("IPv4")
// original IPv4 header starts from offset 8
// reference:
// - https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Time_exceeded
// - https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Destination_unreachable
ipHeader := icmp4.LayerPayload()
IPv4.Set(binary.BigEndian.Uint16(ipHeader[4:6]), "id")
IPv4.Set(uint8(ipHeader[8]), "ttl")
IPv4.Set(uint8(ipHeader[9]), "proto")
IPv4.Set(binary.BigEndian.Uint16(ipHeader[10:12]), "xsum")
// IP addresses are represented as bigendian []byte slices in Go
var ipBytes [4]byte
copy(ipBytes[:], ipHeader[12:16])
srcIP := netip.AddrFrom4(ipBytes)
IPv4.Set(srcIP.String(), "src")
copy(ipBytes[:], ipHeader[16:20])
dstIP := netip.AddrFrom4(ipBytes)
IPv4.Set(dstIP.String(), "dst")
if icmp4.TypeCode.Type() == layers.ICMPv4TypeRedirect {
// see: https://github.com/google/gopacket/blob/master/layers/icmp4.go#L230
copy(ipBytes[:], icmp4.LayerContents()[4:8])
ICMP4.Set(netip.AddrFrom4(ipBytes).String(), "tgt")
}
}
return json
}