diff --git a/bpf/flow.h b/bpf/flow.h
index fa06e1d8f5645c2e4be60fabde459703666ef57e..f36ce12d673450977d971070aa50eead85a67a45 100644
--- a/bpf/flow.h
+++ b/bpf/flow.h
@@ -45,6 +45,9 @@ typedef struct flow_id_t {
     u16 src_port;
     u16 dst_port;
     u8 transport_protocol;
+    // ICMP protocol
+    u8  icmp_type;
+    u8  icmp_code;
     // OS interface index
     u32 if_index;
 } __attribute__((packed)) flow_id;
diff --git a/bpf/flows.c b/bpf/flows.c
index bee299da2f6325d467cfc798d9b342e0c534dfea..40ea1a1c6bceeeff4bf811a2d4821a2aa53b85ff 100644
--- a/bpf/flows.c
+++ b/bpf/flows.c
@@ -13,7 +13,6 @@
             until an entry is available.
         4) When hash collision is detected, we send the new entry to userpace via ringbuffer.
 */
-
 #include <linux/bpf.h>
 #include <linux/in.h>
 #include <linux/if_packet.h>
@@ -55,6 +54,15 @@
 #define FIN_ACK_FLAG 0x200
 #define RST_ACK_FLAG 0x400
 
+// SCTP protocol header structure, its defined here because its not
+// exported by the kernel headers like other protocols.
+struct sctphdr {
+    __be16 source;
+    __be16 dest;
+    __be32 vtag;
+    __le32 checksum;
+};
+
 // Common Ringbuffer as a conduit for ingress/egress flows to userspace
 struct {
     __uint(type, BPF_MAP_TYPE_RINGBUF);
@@ -104,71 +112,111 @@ static inline void set_flags(struct tcphdr *th, u16 *flags) {
         *flags |= CWR_FLAG;
     }
 }
-// sets flow fields from IPv4 header information
-static inline int fill_iphdr(struct iphdr *ip, void *data_end, flow_id *id, u16 *flags) {
-    if ((void *)ip + sizeof(*ip) > data_end) {
-        return DISCARD;
-    }
 
-    __builtin_memcpy(id->src_ip, ip4in6, sizeof(ip4in6));
-    __builtin_memcpy(id->dst_ip, ip4in6, sizeof(ip4in6));
-    __builtin_memcpy(id->src_ip + sizeof(ip4in6), &ip->saddr, sizeof(ip->saddr));
-    __builtin_memcpy(id->dst_ip + sizeof(ip4in6), &ip->daddr, sizeof(ip->daddr));
-    id->transport_protocol = ip->protocol;
-    id->src_port = 0;
-    id->dst_port = 0;
-    switch (ip->protocol) {
+// L4_info structure contains L4 headers parsed information.
+struct l4_info_t {
+    // TCP/UDP/SCTP source port in host byte order
+    u16 src_port;
+    // TCP/UDP/SCTP destination port in host byte order
+    u16 dst_port;
+    // ICMPv4/ICMPv6 type value
+    u8 icmp_type;
+    // ICMPv4/ICMPv6 code value
+    u8 icmp_code;
+    // TCP flags
+    u16 flags;
+};
+
+// Extract L4 info for the supported protocols
+static inline void fill_l4info(void *l4_hdr_start, void *data_end, u8 protocol,
+                               struct l4_info_t *l4_info) {
+	switch (protocol) {
     case IPPROTO_TCP: {
-        struct tcphdr *tcp = (void *)ip + sizeof(*ip);
+        struct tcphdr *tcp = l4_hdr_start;
         if ((void *)tcp + sizeof(*tcp) <= data_end) {
-            id->src_port = __bpf_ntohs(tcp->source);
-            id->dst_port = __bpf_ntohs(tcp->dest);
-            set_flags(tcp, flags);
+            l4_info->src_port = __bpf_ntohs(tcp->source);
+            l4_info->dst_port = __bpf_ntohs(tcp->dest);
+            set_flags(tcp, &l4_info->flags);
         }
     } break;
     case IPPROTO_UDP: {
-        struct udphdr *udp = (void *)ip + sizeof(*ip);
+        struct udphdr *udp = l4_hdr_start;
         if ((void *)udp + sizeof(*udp) <= data_end) {
-            id->src_port = __bpf_ntohs(udp->source);
-            id->dst_port = __bpf_ntohs(udp->dest);
+            l4_info->src_port = __bpf_ntohs(udp->source);
+            l4_info->dst_port = __bpf_ntohs(udp->dest);
+        }
+    } break;
+    case IPPROTO_SCTP: {
+        struct sctphdr *sctph = l4_hdr_start;
+        if ((void *)sctph + sizeof(*sctph) <= data_end) {
+            l4_info->src_port = __bpf_ntohs(sctph->source);
+            l4_info->dst_port = __bpf_ntohs(sctph->dest);
+        }
+    } break;
+    case IPPROTO_ICMP: {
+        struct icmphdr *icmph = l4_hdr_start;
+        if ((void *)icmph + sizeof(*icmph) <= data_end) {
+            l4_info->icmp_type = icmph->type;
+            l4_info->icmp_code = icmph->code;
+        }
+    } break;
+    case IPPROTO_ICMPV6: {
+        struct icmp6hdr *icmp6h = l4_hdr_start;
+         if ((void *)icmp6h + sizeof(*icmp6h) <= data_end) {
+            l4_info->icmp_type = icmp6h->icmp6_type;
+            l4_info->icmp_code = icmp6h->icmp6_code;
         }
     } break;
     default:
         break;
     }
+}
+
+// sets flow fields from IPv4 header information
+static inline int fill_iphdr(struct iphdr *ip, void *data_end, flow_id *id, u16 *flags) {
+    struct l4_info_t l4_info;
+    void *l4_hdr_start;
+
+    l4_hdr_start = (void *)ip + sizeof(*ip);
+    if (l4_hdr_start > data_end) {
+        return DISCARD;
+    }
+    __builtin_memset(&l4_info, 0, sizeof(l4_info));
+    __builtin_memcpy(id->src_ip, ip4in6, sizeof(ip4in6));
+    __builtin_memcpy(id->dst_ip, ip4in6, sizeof(ip4in6));
+    __builtin_memcpy(id->src_ip + sizeof(ip4in6), &ip->saddr, sizeof(ip->saddr));
+    __builtin_memcpy(id->dst_ip + sizeof(ip4in6), &ip->daddr, sizeof(ip->daddr));
+    id->transport_protocol = ip->protocol;
+    fill_l4info(l4_hdr_start, data_end, ip->protocol, &l4_info);
+    id->src_port = l4_info.src_port;
+    id->dst_port = l4_info.dst_port;
+    id->icmp_type = l4_info.icmp_type;
+    id->icmp_code = l4_info.icmp_code;
+    *flags = l4_info.flags;
+
     return SUBMIT;
 }
 
 // sets flow fields from IPv6 header information
 static inline int fill_ip6hdr(struct ipv6hdr *ip, void *data_end, flow_id *id, u16 *flags) {
-    if ((void *)ip + sizeof(*ip) > data_end) {
+    struct l4_info_t l4_info;
+    void *l4_hdr_start;
+
+    l4_hdr_start = (void *)ip + sizeof(*ip);
+    if (l4_hdr_start > data_end) {
         return DISCARD;
     }
-
+    __builtin_memset(&l4_info, 0, sizeof(l4_info));
     __builtin_memcpy(id->src_ip, ip->saddr.in6_u.u6_addr8, 16);
     __builtin_memcpy(id->dst_ip, ip->daddr.in6_u.u6_addr8, 16);
     id->transport_protocol = ip->nexthdr;
-    id->src_port = 0;
-    id->dst_port = 0;
-    switch (ip->nexthdr) {
-    case IPPROTO_TCP: {
-        struct tcphdr *tcp = (void *)ip + sizeof(*ip);
-        if ((void *)tcp + sizeof(*tcp) <= data_end) {
-            id->src_port = __bpf_ntohs(tcp->source);
-            id->dst_port = __bpf_ntohs(tcp->dest);
-            set_flags(tcp, flags);
-        }
-    } break;
-    case IPPROTO_UDP: {
-        struct udphdr *udp = (void *)ip + sizeof(*ip);
-        if ((void *)udp + sizeof(*udp) <= data_end) {
-            id->src_port = __bpf_ntohs(udp->source);
-            id->dst_port = __bpf_ntohs(udp->dest);
-        }
-    } break;
-    default:
-        break;
-    }
+    fill_l4info(l4_hdr_start, data_end, ip->nexthdr, &l4_info);
+    id->src_port = l4_info.src_port;
+    id->dst_port = l4_info.dst_port;
+    id->icmp_type = l4_info.icmp_type;
+    id->icmp_code = l4_info.icmp_code;
+    *flags = l4_info.flags;
+
     return SUBMIT;
 }
 // sets flow fields from Ethernet header information
@@ -207,6 +255,7 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
     void *data = (void *)(long)skb->data;
 
     flow_id id;
+    __builtin_memset(&id, 0, sizeof(id));
     u64 current_time = bpf_ktime_get_ns();
     struct ethhdr *eth = data;
     u16 flags = 0;
diff --git a/examples/flowlogs-dump/server/flowlogs-dump-collector.go b/examples/flowlogs-dump/server/flowlogs-dump-collector.go
index 3d2c8ab96c85ad139cda0157ce55e920cf109634..2728e0b3b1f07e184cffd4fb0eb99967377a364f 100644
--- a/examples/flowlogs-dump/server/flowlogs-dump-collector.go
+++ b/examples/flowlogs-dump/server/flowlogs-dump-collector.go
@@ -72,7 +72,7 @@ func main() {
 	for records := range receivedRecords {
 		for _, record := range records.Entries {
 			if record.EthProtocol == ipv6 {
-				log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s dir:%d bytes:%d packets:%d flags:%d ends: %v\n",
+				log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v\n",
 					ipProto[record.EthProtocol],
 					record.TimeFlowStart.AsTime().Local().Format("15:04:05.000000"),
 					record.Interface,
@@ -81,6 +81,8 @@ func main() {
 					net.IP(record.Network.GetDstAddr().GetIpv6()).To16(),
 					record.Transport.DstPort,
 					protocolByNumber[record.Transport.Protocol],
+					record.Icmp.IcmpType,
+					record.Icmp.IcmpCode,
 					record.Direction,
 					record.Bytes,
 					record.Packets,
@@ -88,7 +90,7 @@ func main() {
 					record.TimeFlowEnd.AsTime().Local().Format("15:04:05.000000"),
 				)
 			} else {
-				log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s dir:%d bytes:%d packets:%d flags:%d ends: %v\n",
+				log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v\n",
 					ipProto[record.EthProtocol],
 					record.TimeFlowStart.AsTime().Local().Format("15:04:05.000000"),
 					record.Interface,
@@ -97,6 +99,8 @@ func main() {
 					ipIntToNetIP(record.Network.GetDstAddr().GetIpv4()).String(),
 					record.Transport.DstPort,
 					protocolByNumber[record.Transport.Protocol],
+					record.Icmp.IcmpType,
+					record.Icmp.IcmpCode,
 					record.Direction,
 					record.Bytes,
 					record.Packets,
diff --git a/pkg/ebpf/bpf_bpfeb.go b/pkg/ebpf/bpf_bpfeb.go
index c228fd42eea13982ad58a332da01e0d20f599ed5..4eb412d706fd092ac7cdc4d8f0cb8b90d9ac4937 100644
--- a/pkg/ebpf/bpf_bpfeb.go
+++ b/pkg/ebpf/bpf_bpfeb.go
@@ -25,6 +25,8 @@ type BpfFlowIdT struct {
 	SrcPort           uint16
 	DstPort           uint16
 	TransportProtocol uint8
+	IcmpType          uint8
+	IcmpCode          uint8
 	IfIndex           uint32
 }
 
diff --git a/pkg/ebpf/bpf_bpfeb.o b/pkg/ebpf/bpf_bpfeb.o
index a758051fbf61c1587128bf00c17fba33dfdc0aac..047164e040edc9b3b37d4a583f3a9867b1da021b 100644
Binary files a/pkg/ebpf/bpf_bpfeb.o and b/pkg/ebpf/bpf_bpfeb.o differ
diff --git a/pkg/ebpf/bpf_bpfel.go b/pkg/ebpf/bpf_bpfel.go
index 6ada0f674c5890ebc15b46fa0baee1bebb135572..4de7b8d2616b2ed6d28a6c4663a1ad179c923ad2 100644
--- a/pkg/ebpf/bpf_bpfel.go
+++ b/pkg/ebpf/bpf_bpfel.go
@@ -25,6 +25,8 @@ type BpfFlowIdT struct {
 	SrcPort           uint16
 	DstPort           uint16
 	TransportProtocol uint8
+	IcmpType          uint8
+	IcmpCode          uint8
 	IfIndex           uint32
 }
 
diff --git a/pkg/ebpf/bpf_bpfel.o b/pkg/ebpf/bpf_bpfel.o
index 13db62889bf77cb980cc4979750485a58c059877..b33fe54eccf9a06693134fa5d8915af4b92e6a24 100644
Binary files a/pkg/ebpf/bpf_bpfel.o and b/pkg/ebpf/bpf_bpfel.o differ
diff --git a/pkg/ebpf/tracer.go b/pkg/ebpf/tracer.go
index e93fec387f822fd115c07452e28efd29facb6083..32b2641baf4dc7d1f12c91cabeae4426622a4c3d 100644
--- a/pkg/ebpf/tracer.go
+++ b/pkg/ebpf/tracer.go
@@ -6,6 +6,7 @@ import (
 	"io/fs"
 	"strings"
 
+	"github.com/cilium/ebpf"
 	"github.com/cilium/ebpf/ringbuf"
 	"github.com/cilium/ebpf/rlimit"
 	"github.com/netobserv/netobserv-ebpf-agent/pkg/ifaces"
@@ -72,6 +73,12 @@ func NewFlowFetcher(
 		return nil, fmt.Errorf("rewriting BPF constants definition: %w", err)
 	}
 	if err := spec.LoadAndAssign(&objects, nil); err != nil {
+		var ve *ebpf.VerifierError
+		if errors.As(err, &ve) {
+			// Using %+v will print the whole verifier error, not just the last
+			// few lines.
+			log.Infof("Verifier error: %+v", ve)
+		}
 		return nil, fmt.Errorf("loading and assigning BPF objects: %w", err)
 	}
 
diff --git a/pkg/exporter/ipfix.go b/pkg/exporter/ipfix.go
index 8b88ab2068f8941e2ee868d64e459365b6f34377..67f18adce907b26b80c257dd14a1d4a5c333e76b 100644
--- a/pkg/exporter/ipfix.go
+++ b/pkg/exporter/ipfix.go
@@ -122,6 +122,14 @@ func SendTemplateRecordv4(log *logrus.Entry, exporter *ipfixExporter.ExportingPr
 	if err != nil {
 		return 0, nil, err
 	}
+	err = addElementToTemplate(log, "icmpTypeIPv4", nil, &elements)
+	if err != nil {
+		return 0, nil, err
+	}
+	err = addElementToTemplate(log, "icmpCodeIPv4", nil, &elements)
+	if err != nil {
+		return 0, nil, err
+	}
 	err = AddRecordValuesToTemplate(log, &elements)
 	if err != nil {
 		return 0, nil, err
@@ -183,6 +191,14 @@ func SendTemplateRecordv6(log *logrus.Entry, exporter *ipfixExporter.ExportingPr
 	if err != nil {
 		return 0, nil, err
 	}
+	err = addElementToTemplate(log, "icmpTypeIPv6", nil, &elements)
+	if err != nil {
+		return 0, nil, err
+	}
+	err = addElementToTemplate(log, "icmpCodeIPv6", nil, &elements)
+	if err != nil {
+		return 0, nil, err
+	}
 	err = AddRecordValuesToTemplate(log, &elements)
 	if err != nil {
 		return 0, nil, err
@@ -299,6 +315,10 @@ func setIEValue(record *flow.Record, ieValPtr *entities.InfoElementWithValue) {
 		ieVal.SetUnsigned16Value(record.Id.SrcPort)
 	case "destinationTransportPort":
 		ieVal.SetUnsigned16Value(record.Id.DstPort)
+	case "icmpTypeIPv4", "icmpTypeIPv6":
+		ieVal.SetUnsigned8Value(record.Id.IcmpType)
+	case "icmpCodeIPv4", "icmpCodeIPv6":
+		ieVal.SetUnsigned8Value(record.Id.IcmpCode)
 	}
 }
 func setEntities(record *flow.Record, elements *[]entities.InfoElementWithValue) {
diff --git a/pkg/exporter/kafka_proto_test.go b/pkg/exporter/kafka_proto_test.go
index 5d7f94a68358e057be502602e1db6d58955c439c..884bd73ce4828c1e772edc544087c38f9863d618 100644
--- a/pkg/exporter/kafka_proto_test.go
+++ b/pkg/exporter/kafka_proto_test.go
@@ -34,6 +34,7 @@ func TestProtoConversion(t *testing.T) {
 	record.Id.DstIp = IPAddrFromNetIP(net.ParseIP("127.3.2.1"))
 	record.Id.SrcPort = 4321
 	record.Id.DstPort = 1234
+	record.Id.IcmpType = 8
 	record.Id.TransportProtocol = 210
 	record.TimeFlowStart = time.Now().Add(-5 * time.Second)
 	record.TimeFlowEnd = time.Now()
@@ -58,6 +59,7 @@ func TestProtoConversion(t *testing.T) {
 	assert.EqualValues(t, 4321, r.Transport.SrcPort)
 	assert.EqualValues(t, 1234, r.Transport.DstPort)
 	assert.EqualValues(t, 210, r.Transport.Protocol)
+	assert.EqualValues(t, 8, r.Icmp.IcmpType)
 	assert.Equal(t, record.TimeFlowStart.UnixMilli(), r.TimeFlowStart.AsTime().UnixMilli())
 	assert.Equal(t, record.TimeFlowEnd.UnixMilli(), r.TimeFlowEnd.AsTime().UnixMilli())
 	assert.EqualValues(t, 789, r.Bytes)
diff --git a/pkg/exporter/proto.go b/pkg/exporter/proto.go
index 991863b8884dacbdc71960bd82655029621b0111..94f9bcea02dfcab9f89ab7ffa927e571c63eaab5 100644
--- a/pkg/exporter/proto.go
+++ b/pkg/exporter/proto.go
@@ -54,6 +54,10 @@ func v4FlowToPB(fr *flow.Record) *pbflow.Record {
 			SrcPort:  uint32(fr.Id.SrcPort),
 			DstPort:  uint32(fr.Id.DstPort),
 		},
+		Icmp: &pbflow.Icmp{
+			IcmpType: uint32(fr.Id.IcmpType),
+			IcmpCode: uint32(fr.Id.IcmpCode),
+		},
 		Bytes: fr.Metrics.Bytes,
 		TimeFlowStart: &timestamppb.Timestamp{
 			Seconds: fr.TimeFlowStart.Unix(),
@@ -88,6 +92,10 @@ func v6FlowToPB(fr *flow.Record) *pbflow.Record {
 			SrcPort:  uint32(fr.Id.SrcPort),
 			DstPort:  uint32(fr.Id.DstPort),
 		},
+		Icmp: &pbflow.Icmp{
+			IcmpType: uint32(fr.Id.IcmpType),
+			IcmpCode: uint32(fr.Id.IcmpCode),
+		},
 		Bytes: fr.Metrics.Bytes,
 		TimeFlowStart: &timestamppb.Timestamp{
 			Seconds: fr.TimeFlowStart.Unix(),
diff --git a/pkg/flow/record_test.go b/pkg/flow/record_test.go
index dfbf8bf19be3c51195a19daf54f34ebf9b202b69..8f1fc59b087416a54044e5698c9a6eea9f2f0c75 100644
--- a/pkg/flow/record_test.go
+++ b/pkg/flow/record_test.go
@@ -23,6 +23,8 @@ func TestRecordBinaryEncoding(t *testing.T) {
 		0x0e, 0x0f, // transport: u16 src_port
 		0x10, 0x11, // transport: u16 dst_port
 		0x12,                   // transport: u8 transport_protocol
+		0x00,                   // icmp: u8 icmp_type
+		0x00,                   // icmp: u8 icmp_code
 		0x13, 0x14, 0x15, 0x16, // interface index
 		0x06, 0x07, 0x08, 0x09, // u32 packets
 		0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, // u64 bytes
@@ -45,6 +47,8 @@ func TestRecordBinaryEncoding(t *testing.T) {
 			SrcPort:           0x0f0e,
 			DstPort:           0x1110,
 			TransportProtocol: 0x12,
+			IcmpType:          0x00,
+			IcmpCode:          0x00,
 			IfIndex:           0x16151413,
 		},
 		Metrics: ebpf.BpfFlowMetrics{
diff --git a/pkg/grpc/grpc_test.go b/pkg/grpc/grpc_test.go
index faeb740e77d129db2d8f0bf2e4f4d00a757e97fa..efdd355bf08d3421784a8800c730faed5ac79681 100644
--- a/pkg/grpc/grpc_test.go
+++ b/pkg/grpc/grpc_test.go
@@ -162,6 +162,10 @@ func BenchmarkIPv4GRPCCommunication(b *testing.B) {
 			SrcPort:  23000,
 			DstPort:  443,
 		},
+		Icmp: &pbflow.Icmp{
+			IcmpType: 8,
+			IcmpCode: 10,
+		},
 	}
 	records := &pbflow.Records{}
 	for i := 0; i < 100; i++ {
@@ -211,6 +215,10 @@ func BenchmarkIPv6GRPCCommunication(b *testing.B) {
 			SrcPort:  23000,
 			DstPort:  443,
 		},
+		Icmp: &pbflow.Icmp{
+			IcmpType: 8,
+			IcmpCode: 10,
+		},
 	}
 	records := &pbflow.Records{}
 	for i := 0; i < 100; i++ {
diff --git a/pkg/pbflow/flow.pb.go b/pkg/pbflow/flow.pb.go
index 903e6f68e8599f35448e5135d729a04ef78402cf..af4bee082e66fafb30603ec9590c47271ec89791 100644
--- a/pkg/pbflow/flow.pb.go
+++ b/pkg/pbflow/flow.pb.go
@@ -179,6 +179,7 @@ type Record struct {
 	// Agent IP address to help identifying the source of the flow
 	AgentIp *IP    `protobuf:"bytes,12,opt,name=agent_ip,json=agentIp,proto3" json:"agent_ip,omitempty"`
 	Flags   uint32 `protobuf:"varint,13,opt,name=flags,proto3" json:"flags,omitempty"`
+	Icmp    *Icmp  `protobuf:"bytes,14,opt,name=icmp,proto3" json:"icmp,omitempty"`
 }
 
 func (x *Record) Reset() {
@@ -304,6 +305,13 @@ func (x *Record) GetFlags() uint32 {
 	return 0
 }
 
+func (x *Record) GetIcmp() *Icmp {
+	if x != nil {
+		return x.Icmp
+	}
+	return nil
+}
+
 type DataLink struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -559,6 +567,61 @@ func (x *Transport) GetProtocol() uint32 {
 	return 0
 }
 
+type Icmp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	IcmpType uint32 `protobuf:"varint,1,opt,name=icmp_type,json=icmpType,proto3" json:"icmp_type,omitempty"`
+	IcmpCode uint32 `protobuf:"varint,2,opt,name=icmp_code,json=icmpCode,proto3" json:"icmp_code,omitempty"`
+}
+
+func (x *Icmp) Reset() {
+	*x = Icmp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_proto_flow_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Icmp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Icmp) ProtoMessage() {}
+
+func (x *Icmp) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_flow_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Icmp.ProtoReflect.Descriptor instead.
+func (*Icmp) Descriptor() ([]byte, []int) {
+	return file_proto_flow_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *Icmp) GetIcmpType() uint32 {
+	if x != nil {
+		return x.IcmpType
+	}
+	return 0
+}
+
+func (x *Icmp) GetIcmpCode() uint32 {
+	if x != nil {
+		return x.IcmpCode
+	}
+	return 0
+}
+
 var File_proto_flow_proto protoreflect.FileDescriptor
 
 var file_proto_flow_proto_rawDesc = []byte{
@@ -570,7 +633,7 @@ var file_proto_flow_proto_rawDesc = []byte{
 	0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72,
 	0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x66, 0x6c,
 	0x6f, 0x77, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69,
-	0x65, 0x73, 0x22, 0x94, 0x04, 0x0a, 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a,
+	0x65, 0x73, 0x22, 0xb6, 0x04, 0x0a, 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a,
 	0x0c, 0x65, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20,
 	0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
 	0x12, 0x2f, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
@@ -603,34 +666,40 @@ var file_proto_flow_proto_rawDesc = []byte{
 	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a,
 	0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x49, 0x50, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e,
 	0x74, 0x49, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x01,
-	0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x3c, 0x0a, 0x08, 0x44, 0x61, 0x74,
-	0x61, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x72, 0x63, 0x5f, 0x6d, 0x61, 0x63,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x72, 0x63, 0x4d, 0x61, 0x63, 0x12, 0x17,
-	0x0a, 0x07, 0x64, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x06, 0x64, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x22, 0x57, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f,
-	0x72, 0x6b, 0x12, 0x25, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x49, 0x50,
-	0x52, 0x07, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x08, 0x64, 0x73, 0x74,
-	0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62,
-	0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x49, 0x50, 0x52, 0x07, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72,
-	0x22, 0x3d, 0x0a, 0x02, 0x49, 0x50, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x07, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14, 0x0a, 0x04,
-	0x69, 0x70, 0x76, 0x36, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70,
-	0x76, 0x36, 0x42, 0x0b, 0x0a, 0x09, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22,
-	0x5d, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08,
-	0x73, 0x72, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
-	0x73, 0x72, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x70,
-	0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, 0x6f,
-	0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2a, 0x24,
-	0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49,
-	0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x47, 0x52, 0x45,
-	0x53, 0x53, 0x10, 0x01, 0x32, 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f,
-	0x72, 0x12, 0x31, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x66, 0x6c,
-	0x6f, 0x77, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x66,
-	0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x70,
-	0x6c, 0x79, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x63, 0x6d,
+	0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77,
+	0x2e, 0x49, 0x63, 0x6d, 0x70, 0x52, 0x04, 0x69, 0x63, 0x6d, 0x70, 0x22, 0x3c, 0x0a, 0x08, 0x44,
+	0x61, 0x74, 0x61, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x72, 0x63, 0x5f, 0x6d,
+	0x61, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x72, 0x63, 0x4d, 0x61, 0x63,
+	0x12, 0x17, 0x0a, 0x07, 0x64, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x04, 0x52, 0x06, 0x64, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x22, 0x57, 0x0a, 0x07, 0x4e, 0x65, 0x74,
+	0x77, 0x6f, 0x72, 0x6b, 0x12, 0x25, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e,
+	0x49, 0x50, 0x52, 0x07, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x08, 0x64,
+	0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e,
+	0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x49, 0x50, 0x52, 0x07, 0x64, 0x73, 0x74, 0x41, 0x64,
+	0x64, 0x72, 0x22, 0x3d, 0x0a, 0x02, 0x49, 0x50, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14,
+	0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04,
+	0x69, 0x70, 0x76, 0x36, 0x42, 0x0b, 0x0a, 0x09, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c,
+	0x79, 0x22, 0x5d, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x19,
+	0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x07, 0x73, 0x72, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74,
+	0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74,
+	0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x22, 0x40, 0x0a, 0x04, 0x49, 0x63, 0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x63, 0x6d, 0x70,
+	0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, 0x63, 0x6d,
+	0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x63, 0x6d, 0x70, 0x5f, 0x63, 0x6f,
+	0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, 0x63, 0x6d, 0x70, 0x43, 0x6f,
+	0x64, 0x65, 0x2a, 0x24, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+	0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06,
+	0x45, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x32, 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x0f, 0x2e,
+	0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x1a, 0x16,
+	0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f,
+	0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x62,
+	0x66, 0x6c, 0x6f, 0x77, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -646,7 +715,7 @@ func file_proto_flow_proto_rawDescGZIP() []byte {
 }
 
 var file_proto_flow_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_proto_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_proto_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
 var file_proto_flow_proto_goTypes = []interface{}{
 	(Direction)(0),                // 0: pbflow.Direction
 	(*CollectorReply)(nil),        // 1: pbflow.CollectorReply
@@ -656,26 +725,28 @@ var file_proto_flow_proto_goTypes = []interface{}{
 	(*Network)(nil),               // 5: pbflow.Network
 	(*IP)(nil),                    // 6: pbflow.IP
 	(*Transport)(nil),             // 7: pbflow.Transport
-	(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
+	(*Icmp)(nil),                  // 8: pbflow.Icmp
+	(*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp
 }
 var file_proto_flow_proto_depIdxs = []int32{
 	3,  // 0: pbflow.Records.entries:type_name -> pbflow.Record
 	0,  // 1: pbflow.Record.direction:type_name -> pbflow.Direction
-	8,  // 2: pbflow.Record.time_flow_start:type_name -> google.protobuf.Timestamp
-	8,  // 3: pbflow.Record.time_flow_end:type_name -> google.protobuf.Timestamp
+	9,  // 2: pbflow.Record.time_flow_start:type_name -> google.protobuf.Timestamp
+	9,  // 3: pbflow.Record.time_flow_end:type_name -> google.protobuf.Timestamp
 	4,  // 4: pbflow.Record.data_link:type_name -> pbflow.DataLink
 	5,  // 5: pbflow.Record.network:type_name -> pbflow.Network
 	7,  // 6: pbflow.Record.transport:type_name -> pbflow.Transport
 	6,  // 7: pbflow.Record.agent_ip:type_name -> pbflow.IP
-	6,  // 8: pbflow.Network.src_addr:type_name -> pbflow.IP
-	6,  // 9: pbflow.Network.dst_addr:type_name -> pbflow.IP
-	2,  // 10: pbflow.Collector.Send:input_type -> pbflow.Records
-	1,  // 11: pbflow.Collector.Send:output_type -> pbflow.CollectorReply
-	11, // [11:12] is the sub-list for method output_type
-	10, // [10:11] is the sub-list for method input_type
-	10, // [10:10] is the sub-list for extension type_name
-	10, // [10:10] is the sub-list for extension extendee
-	0,  // [0:10] is the sub-list for field type_name
+	8,  // 8: pbflow.Record.icmp:type_name -> pbflow.Icmp
+	6,  // 9: pbflow.Network.src_addr:type_name -> pbflow.IP
+	6,  // 10: pbflow.Network.dst_addr:type_name -> pbflow.IP
+	2,  // 11: pbflow.Collector.Send:input_type -> pbflow.Records
+	1,  // 12: pbflow.Collector.Send:output_type -> pbflow.CollectorReply
+	12, // [12:13] is the sub-list for method output_type
+	11, // [11:12] is the sub-list for method input_type
+	11, // [11:11] is the sub-list for extension type_name
+	11, // [11:11] is the sub-list for extension extendee
+	0,  // [0:11] is the sub-list for field type_name
 }
 
 func init() { file_proto_flow_proto_init() }
@@ -768,6 +839,18 @@ func file_proto_flow_proto_init() {
 				return nil
 			}
 		}
+		file_proto_flow_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Icmp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	file_proto_flow_proto_msgTypes[5].OneofWrappers = []interface{}{
 		(*IP_Ipv4)(nil),
@@ -779,7 +862,7 @@ func file_proto_flow_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_proto_flow_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   7,
+			NumMessages:   8,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/proto/flow.proto b/proto/flow.proto
index 9e291f7292d0ed72ba6bbcd528355e752f1d9bc6..c7b459a1d1c489221093d17721769de1478a4121 100644
--- a/proto/flow.proto
+++ b/proto/flow.proto
@@ -41,6 +41,7 @@ message Record {
   // Agent IP address to help identifying the source of the flow
   IP agent_ip = 12;
   uint32 flags = 13;
+  Icmp   icmp = 14;
 }
 
 message DataLink {
@@ -68,6 +69,11 @@ message Transport {
   uint32 protocol = 3;
 }
 
+message Icmp {
+  uint32 icmp_type = 1;
+  uint32 icmp_code = 2;
+}
+
 // as defined by field 61 in
 // https://www.iana.org/assignments/ipfix/ipfix.xhtml
 enum Direction {