Index: uspace/app/meson.build
===================================================================
--- uspace/app/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/app/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -74,4 +74,6 @@
 	'nterm',
 	'ofw',
+	'pcapcat',
+	'pcapctl',
 	'pci',
 	'ping',
Index: uspace/app/pcapcat/doc/doxygroups.h
===================================================================
--- uspace/app/pcapcat/doc/doxygroups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/doc/doxygroups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,4 @@
+/** @addtogroup pcapcat pcapcat
+ * @brief Command-line utility for printing files of PCAP format.
+ * @ingroup apps
+ */
Index: uspace/app/pcapcat/eth_parser.c
===================================================================
--- uspace/app/pcapcat/eth_parser.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/eth_parser.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup pcapcat
+ * @{
+ */
+/** @file Implementation of functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET).
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <str.h>
+#include <pcap.h>
+#include "eth_parser.h"
+
+#define ETH_ADDR_SIZE       6
+#define IPV4_ADDR_SIZE      4
+#define TCP_PORT_SIZE       2
+
+#define ETHER_TYPE_ARP      0x0806
+#define ETHER_TYPE_IP4      0x0800
+#define ETHER_TYPE_IP6      0x86DD
+
+#define BYTE_SIZE           8
+#define HDR_SIZE_COEF       4
+#define LOWER_4_BITS        0xf
+
+#define IP_PROTOCOL_TCP     0x06
+#define IP_PROTOCOL_UDP     0x11
+#define IP_PROTOCOL_ICMP    0x01
+
+#define TCP_TEXT            "TCP"
+#define IP_TEXT             "IP"
+#define MAC_TEXT            "MAC"
+#define ARP_TEXT            "ARP"
+#define IPV4_TEXT           "IPv4"
+#define IPV6_TEXT           "IPv6"
+#define MALFORMED_PACKET    "packet is malformed.\n"
+
+#define PRINT_IP(msg, ip_addr, spaces) printf("%s %s: %d.%d.%d.%d%s", msg, IP_TEXT, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces)
+#define PRINT_MAC(msg, mac, spaces) printf("%s %s: %02x:%02x:%02x:%02x:%02x:%02x%s", msg, MAC_TEXT, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], spaces)
+#define BIG_END_16(buffer, idx) buffer[idx] << BYTE_SIZE | buffer[idx + 1]
+
+/** Offsets of interesting fields in packet. */
+
+#define ARP_SENDER_MAC      22
+#define ARP_SENDER_IP       28
+#define ARP_TARGET_MAC      32
+#define ARP_TARGET_IP       38
+
+#define TCP_SRC_PORT        34
+#define TCP_DST_PORT        36
+
+#define IP_HEADER_LEN       14
+#define IP_TOTAL_LEN        16
+#define IP_PROTOCOL         23
+#define IP_SRC_ADDR         26
+#define IP_DST_ADDR         30
+
+/** Read count bytes from char buffer.
+ *  @param buffer       of bytes to read from.
+ *  @param start_idx    index of the first byte to read.
+ *  @param count        number of byte to read.
+ *  @param dst          destination buffer.
+ */
+static void read_from_buffer(unsigned char *buffer, size_t start_idx, size_t count, uint8_t *dst)
+{
+	for (size_t i = start_idx; i < start_idx + count; ++i) {
+		dst[i - start_idx] = buffer[i];
+	}
+}
+
+/** Parse ARP packet and print out addresses.
+ *  @param buffer   ARP packet.
+ *  @param size     Size of the packet.
+ */
+static void parse_arp(unsigned char *buffer, size_t size)
+{
+	if (size < ARP_TARGET_IP + IPV4_ADDR_SIZE) {
+		printf("%s %s", ARP_TEXT, MALFORMED_PACKET);
+		return;
+	}
+
+	uint8_t sender_mac[ETH_ADDR_SIZE];
+	uint8_t sender_ip[IPV4_ADDR_SIZE];
+	uint8_t target_mac[ETH_ADDR_SIZE];
+	uint8_t target_ip[IPV4_ADDR_SIZE];
+
+	read_from_buffer(buffer, ARP_SENDER_MAC, ETH_ADDR_SIZE, sender_mac);
+	read_from_buffer(buffer, ARP_SENDER_IP, IPV4_ADDR_SIZE, sender_ip);
+	read_from_buffer(buffer, ARP_TARGET_MAC, ETH_ADDR_SIZE, target_mac);
+	read_from_buffer(buffer, ARP_TARGET_IP, IPV4_ADDR_SIZE, target_ip);
+
+	PRINT_MAC("Sender", sender_mac, ", ");
+	PRINT_IP("Sender", sender_ip, "  ");
+	PRINT_MAC("Target", target_mac, ", ");
+	PRINT_IP("Target", target_ip, "\n");
+}
+
+/** Parce TCP and print ports.
+ *  @param buffer   TCP segment.
+ *  @param size     of the buffer.
+ */
+static void parse_tcp(unsigned char *buffer, size_t size)
+{
+	if (size < TCP_DST_PORT + TCP_PORT_SIZE) {
+		printf("%s %s\n", TCP_TEXT, MALFORMED_PACKET);
+		return;
+	}
+
+	uint16_t src_port = BIG_END_16(buffer, TCP_SRC_PORT);
+	uint16_t dst_port = BIG_END_16(buffer, TCP_DST_PORT);
+	printf("      [%s] source port: %d, destination port: %d\n", TCP_TEXT, src_port, dst_port);
+}
+
+/** Parse IP and print interesting parts.
+ *  @param buffer   IP packet.
+ *  @param size     size of the buffer.
+ *  @param verbose  verbosity flag.
+ */
+static void parse_ip(unsigned char *buffer, size_t size, bool verbose)
+{
+	uint16_t total_length;
+	uint8_t header_length;
+	uint16_t payload_length;
+	uint8_t ip_protocol;
+	uint8_t src_ip[IPV4_ADDR_SIZE];
+	uint8_t dst_ip[IPV4_ADDR_SIZE];
+
+	if (size < IP_DST_ADDR + IPV4_ADDR_SIZE) {
+		printf("%s %s", IP_TEXT, MALFORMED_PACKET);
+		return;
+	}
+
+	header_length = (buffer[IP_HEADER_LEN] & LOWER_4_BITS) * HDR_SIZE_COEF;
+	total_length = BIG_END_16(buffer, IP_TOTAL_LEN);
+	payload_length = total_length - header_length;
+	ip_protocol = buffer[IP_PROTOCOL];
+
+	read_from_buffer(buffer, IP_SRC_ADDR, IPV4_ADDR_SIZE, src_ip);
+	read_from_buffer(buffer, IP_DST_ADDR, IPV4_ADDR_SIZE, dst_ip);
+
+	printf("%s header: %dB, payload: %dB, protocol: 0x%x, ", IP_TEXT, header_length, payload_length, ip_protocol);
+	PRINT_IP("Source", src_ip, ", ");
+	PRINT_IP("Destination", dst_ip, "\n");
+
+	if (verbose && ip_protocol == IP_PROTOCOL_TCP) {
+		parse_tcp(buffer, size);
+	}
+}
+
+/** Parse ethernnet frame based on eth_type of the frame.
+ *  @param data         Ethernet frame.
+ *  @param size         Size of the frame.
+ *  @param verbose_flag Verbosity flag.
+ */
+static void parse_eth_frame(void *data, size_t size, bool verbose_flag)
+{
+	unsigned char *buffer = (unsigned char *)data;
+
+	size_t eth_type_offset = 12;
+	uint16_t protocol = BIG_END_16(buffer, eth_type_offset);
+
+	switch (protocol) {
+	case ETHER_TYPE_ARP:
+		printf("[%s] ", ARP_TEXT);
+		parse_arp(buffer, size);
+		break;
+	case ETHER_TYPE_IP4:
+		printf("[%s] ", IPV4_TEXT);
+		parse_ip(buffer, size, verbose_flag);
+		break;
+	case ETHER_TYPE_IP6:
+		printf("[%s]\n", IPV6_TEXT);
+		break;
+	default:
+		printf("[0x%x]\n", protocol);
+		break;
+	}
+}
+
+/** Parse file header of PCAP file.
+ *  @param hdr  PCAP header structure.
+ */
+void eth_parse_header(pcap_file_header_t *hdr)
+{
+	printf("LinkType: %d\n", hdr->additional);
+	printf("Magic number:  0x%x\n", hdr->magic_number);
+}
+
+/** Parse PCAP file.
+ *  @param pcap_file    file of PCAP format with dumped packets.
+ *  @param count        number of packets to be parsed and printed from file (if -1 all packets are printed).
+ *  @param verbose_flag verbosity flag.
+ */
+void eth_parse_frames(FILE *pcap_file, int count, bool verbose_flag)
+{
+	pcap_packet_header_t hdr;
+
+	size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file);
+	int packet_index = 1;
+	while (read_bytes > 0) {
+		if (read_bytes < sizeof(pcap_packet_header_t)) {
+			printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes);
+			return;
+		}
+
+		printf("%04d) ", packet_index++);
+
+		void *data = malloc(hdr.captured_length);
+		read_bytes = fread(data, 1, (size_t)hdr.captured_length, pcap_file);
+		if (read_bytes < (size_t)hdr.captured_length) {
+			printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes);
+			return;
+		}
+		parse_eth_frame(data, (size_t)hdr.captured_length, verbose_flag);
+		free(data);
+
+		//Read first count packets from file.
+		if (count != -1 && count == packet_index - 1) {
+			return;
+		}
+
+		memset(&hdr, 0, sizeof(pcap_packet_header_t));
+		read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file);
+	}
+}
+
+/** @}
+ */
Index: uspace/app/pcapcat/eth_parser.h
===================================================================
--- uspace/app/pcapcat/eth_parser.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/eth_parser.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup pcapcat
+ * @{
+ */
+/** @file Functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET).
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <str.h>
+#include <pcap.h>
+
+extern void eth_parse_frames(FILE *, int, bool);
+extern void eth_parse_header(pcap_file_header_t *);
+
+/** @}
+ */
Index: uspace/app/pcapcat/linktype_parser.h
===================================================================
--- uspace/app/pcapcat/linktype_parser.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/linktype_parser.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup pcapcat
+ * @{
+ */
+/** @file Structure for parsing PCAP file.
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <str.h>
+#include <pcap.h>
+
+typedef struct {
+	uint32_t linktype;
+	void (*parse_file_header)(pcap_file_header_t *);
+	void (*parse_packets)(FILE *, int, bool);
+} linktype_parser_t;
+
+/** @}
+ */
Index: uspace/app/pcapcat/main.c
===================================================================
--- uspace/app/pcapcat/main.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/main.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <str.h>
+#include <getopt.h>
+#include <io/log.h>
+#include <pcap.h>
+
+#include "linktype_parser.h"
+#include "eth_parser.h"
+
+#define NAME "pcapcat"
+
+static const linktype_parser_t eth_parser = {
+	.parse_packets = &eth_parse_frames,
+	.parse_file_header = &eth_parse_header,
+	.linktype = PCAP_LINKTYPE_ETHERNET
+};
+
+static const linktype_parser_t parsers[1] = { eth_parser };
+
+static int parse_file(const char *file_path, int packet_count, bool verbose_flag)
+{
+	FILE *f = fopen(file_path, "rb");
+	if (f == NULL) {
+		printf("File %s does not exist.\n", file_path);
+		return 1;
+	}
+
+	pcap_file_header_t hdr;
+	memset(&hdr, 0, sizeof(pcap_file_header_t));
+
+	size_t bytes_read = fread(&hdr, 1, sizeof(pcap_file_header_t), f);
+	if (bytes_read < sizeof(pcap_file_header_t)) {
+		printf("Error: Could not read enough bytes (read %zu bytes)\n", bytes_read);
+		fclose(f);
+		return 1;
+	}
+
+	int parser_count = sizeof(parsers) / sizeof(linktype_parser_t);
+	int parser_index = -1;
+	for (int i = 0; i < parser_count; ++i) {
+		if (parsers[i].linktype == hdr.additional) {
+			parser_index = i;
+			break;
+		}
+	}
+
+	if (parser_index == -1) {
+		printf("There is no parser for Linktype %d.\n", hdr.additional);
+		return 1;
+	}
+
+	parsers[parser_index].parse_file_header(&hdr);
+	parsers[parser_index].parse_packets(f, packet_count, verbose_flag);
+
+	fclose(f);
+	return 0;
+}
+
+static void usage()
+{
+	printf("HelenOS cat utility for PCAP file format.\n"
+	    "Can run during dumping process.\n"
+	    "Usage:\n"
+	    NAME " <filename>\n"
+	    "\tPrint all packets from file <filename>.\n"
+	    NAME " --count= | -c <number> <filename>\n"
+	    "\tPrint first <number> packets from <filename>.\n"
+	    NAME " --verbose | -v <filename>\n"
+	    "\tPrint verbose description (with TCP ports) of packets.\n");
+}
+
+static struct option options[] = {
+	{ "count", required_argument, 0, 'c' },
+	{ "verbose", no_argument, 0, 'v' },
+	{ 0, 0, 0, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+	int ret = 0;
+	int idx = 0;
+	int count = -1;
+	bool verbose = false;
+	const char *filename = "";
+	if (argc == 1) {
+		usage();
+		return 0;
+	}
+
+	while (ret != -1) {
+		ret = getopt_long(argc, argv, "c:v", options, &idx);
+		switch (ret) {
+		case 'c':
+			count = atoi(optarg);
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		case '?':
+			printf("Unknown option or missing argument.\n");
+			return 1;
+		default:
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		filename = argv[optind];
+	}
+
+	int ret_val = parse_file(filename, count, verbose);
+
+	return ret_val;
+}
Index: uspace/app/pcapcat/meson.build
===================================================================
--- uspace/app/pcapcat/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapcat/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2024 Nataliia Korop
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+deps = ['pcap']
+src = files('main.c', 'eth_parser.c')
Index: uspace/app/pcapctl/doc/doxygroups.h
===================================================================
--- uspace/app/pcapctl/doc/doxygroups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapctl/doc/doxygroups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,4 @@
+/** @addtogroup pcapctl pcapctl
+ * @brief Command-line utility for dumping packets.
+ * @ingroup apps
+ */
Index: uspace/app/pcapctl/main.c
===================================================================
--- uspace/app/pcapctl/main.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapctl/main.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup pcapctl
+ * @{
+ */
+/** @file pcapctl command-line utility.
+ */
+
+#include <stdio.h>
+#include <str.h>
+#include <errno.h>
+#include <arg_parse.h>
+#include <getopt.h>
+#include <vfs/vfs.h>
+
+#include "pcapdump_client.h"
+
+#define NAME 				"pcapctl"
+#define DEFAULT_DEV_NUM 	0
+#define DECIMAL_SYSTEM 		10
+
+/* Default writer operations for dumper, must be consistent with array defined in /uspace/lib/pcap/pcap_dumper.c */
+#define DEFAULT_FILE_OPS 	0
+#define SHORT_FILE_OPS 		1
+#define APPEND_FILE_OPS 	2
+#define USB_FILE_OPS 		3
+
+/** Create async session and send start request.
+ *  @param dev_number index of the device that can dump packets.
+ *  @param name of the output buffer.
+ *  @param ops_index index of the writer operations for the dumper.
+ *  @return EOK if all parameters are valid and start request was sent successfully, error code otherwise.
+ */
+static errno_t start_dumping(int *dev_number, const char *name, int *ops_index)
+{
+	pcapctl_sess_t *sess = NULL;
+	errno_t rc = pcapctl_dump_open(dev_number, &sess);
+	if (rc != EOK) {
+		return 1;
+	}
+
+	rc = pcapctl_is_valid_ops_number(ops_index, sess);
+	if (rc != EOK) {
+		printf("Wrong number of ops: %d.\n", *ops_index);
+		pcapctl_dump_close(sess);
+		return rc;
+	}
+
+	rc = pcapctl_dump_start(name, ops_index, sess);
+	if (rc != EOK) {
+		if (rc == EBUSY) {
+			printf("Dumping for device %d is in progress, stop to start dumping to file %s.\n", *dev_number, name);
+		}
+		printf("Starting the dumping was not successful.\n");
+	}
+	pcapctl_dump_close(sess);
+	return EOK;
+}
+
+/** Create async session and send stop dumping request.
+ *  @param dev_numbe index of the device on which the dumping will be stopped.
+ *  @return EOK if request was sent successfully, error code otherwise.
+ */
+static errno_t stop_dumping(int *dev_number)
+{
+	pcapctl_sess_t *sess = NULL;
+	errno_t rc = pcapctl_dump_open(dev_number, &sess);
+	if (rc != EOK) {
+		return 1;
+	}
+	rc = pcapctl_dump_stop(sess);
+	if (rc != EOK) {
+		printf("Stoping the dumping was not successful.\n");
+	}
+	pcapctl_dump_close(sess);
+	return EOK;
+}
+
+/** Print devices that can dump packets. */
+static void list_devs(void)
+{
+	pcapctl_list();
+}
+
+/**
+ * Array of supported commandline options
+ */
+static const struct option opts[] = {
+	{ "append", required_argument, 0, 'A' }, /* file as argument and ops 0 if not exist and 2 if exists */
+	{ "new", required_argument, 0, 'N' }, /* file name as argument */
+	{ "truncated", required_argument, 0, 'T' }, /* file as an argument with device 0 and dump truncated packets (for debugging purposes) */
+	{ "usb", required_argument, 0, 'U' }, /* dump usb packets (not fully implemnted) */
+	{ "device", required_argument, 0, 'd' },
+	{ "list", no_argument, 0, 'l' },
+	{ "help", no_argument, 0, 'h' },
+	{ "outfile", required_argument, 0, 'o' },
+	{ "start", no_argument, 0, 'r' },
+	{ "stop", no_argument, 0, 't' },
+	{ "ops", required_argument, 0, 'p' },
+	{ "force", no_argument, 0, 'f' },
+	{ 0, 0, 0, 0 }
+};
+
+/** Check if the file exists.
+ *  @param path of the file to check.
+ *  @return true if exists, false otherwise.
+ */
+static bool file_exists(const char *path)
+{
+	vfs_stat_t stats;
+	if (vfs_stat_path(path, &stats) != EOK) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+static void usage(void)
+{
+	printf("HelenOS Packet Dumping utility.\n"
+	    "Usage:\n"
+	    NAME " --list | -l \n"
+	    "\tList of devices\n"
+	    NAME " --new= | -N <outfile>\n"
+	    "\tStart dumping with ops - 0, on device - 0\n"
+	    NAME " --append= | -A <outfile>\n"
+	    "\tContinue dumping on device - 0 to already existing file\n"
+	    NAME " --truncated= | -T <outfile>\n"
+	    "\tStart dumping truncated packets to file on device - 0\n"
+	    NAME " --start | -r --device= | -d <device number from list> --outfile= | -o <outfile> --ops= | p <ops index>\n"
+	    "\tPackets dumped from device will be written to <outfile>\n"
+	    NAME " --stop | -t --device= | -d <device number from list>\n"
+	    "\tDumping from <device> stops\n"
+	    NAME " --start | -r --outfile= | -o <outfile>\n"
+	    "\tPackets dumped from the 0. device from the list will be written to <outfile>\n"
+	    NAME " --help | -h\n"
+	    "\tShow this application help.\n"
+	    NAME " --force | -f"
+	    "\tTo open existing file and write to it.\n");
+}
+
+int main(int argc, char *argv[])
+{
+	bool start = false;
+	bool stop = false;
+	int dev_number = DEFAULT_DEV_NUM;
+	int ops_number = DEFAULT_FILE_OPS;
+	bool forced = false;
+	const char *output_file_name = "";
+	int idx = 0;
+	int ret = 0;
+	if (argc == 1) {
+		usage();
+		return 0;
+	}
+	while (ret != -1) {
+		ret = getopt_long(argc, argv, "A:N:T:U:d:lho:rtp:f", opts, &idx);
+		switch (ret) {
+		case 'd':
+			char *rest;
+			long dev_result = strtol(optarg, &rest, DECIMAL_SYSTEM);
+			dev_number = (int)dev_result;
+			errno_t rc = pcapctl_is_valid_device(&dev_number);
+			if (rc != EOK) {
+				printf("Device with index %d not found\n", dev_number);
+				return 1;
+			}
+			break;
+		case 'A':
+			start = true;
+			output_file_name = optarg;
+			if (file_exists(output_file_name)) {
+				ops_number = APPEND_FILE_OPS;
+			}
+			break;
+		case 'N':
+			start = true;
+			output_file_name = optarg;
+			break;
+		case 'T':
+			start = true;
+			output_file_name = optarg;
+			ops_number = SHORT_FILE_OPS;
+			break;
+		case 'U':
+			start = true;
+			output_file_name = optarg;
+			ops_number = USB_FILE_OPS;
+			break;
+		case 'l':
+			list_devs();
+			return 0;
+		case 'h':
+			usage();
+			return 0;
+		case 'o':
+			output_file_name = optarg;
+			break;
+		case 'r':
+			start = true;
+			break;
+		case 't':
+			stop = true;
+			break;
+		case 'p':
+			char *ops_inval;
+			long ops_result = strtol(optarg, &ops_inval, DECIMAL_SYSTEM);
+			ops_number = (int)ops_result;
+			break;
+		case 'f':
+			forced = true;
+			break;
+		}
+	}
+
+	if (!str_cmp(output_file_name, "") && start) {
+		printf("Dumping destination was not specified. Specify with --outfile | -o\n");
+		return 1;
+	}
+
+	if (start) {
+
+		if (file_exists(output_file_name) && !forced && ops_number != 2) {
+			printf("File %s already exists. If you want to overwrite it, then use flag --force.\n", output_file_name);
+			return 0;
+		}
+
+		printf("Start dumping on device - %d, ops - %d.\n", dev_number, ops_number);
+
+		/* start with dev number and name */
+		start_dumping(&dev_number, output_file_name, &ops_number);
+	} else if (stop) {
+		/* stop with dev number */
+		printf("Stop dumping on device - %d.\n", dev_number);
+		stop_dumping(&dev_number);
+	} else {
+		usage();
+		return 1;
+	}
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/pcapctl/meson.build
===================================================================
--- uspace/app/pcapctl/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/app/pcapctl/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2023 Nataliia Korop
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+deps = ['pcap']
+src = files('main.c')
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/e1k/e1k.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -175,4 +175,5 @@
 	/** Lock for EEPROM access */
 	fibril_mutex_t eeprom_lock;
+
 } e1000_t;
 
@@ -1192,4 +1193,5 @@
 		if (frame != NULL) {
 			memcpy(frame->data, e1000->rx_frame_virt[next_tail], frame_size);
+
 			nic_received_frame(nic, frame);
 		} else {
@@ -2201,12 +2203,12 @@
 		goto err_fun_bind;
 
-	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
-	if (rc != EOK)
-		goto err_add_to_cat;
-
+	rc = nic_fun_add_to_cats(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to categories");
+		ddf_fun_unbind(fun);
+		return rc;
+	}
 	return EOK;
 
-err_add_to_cat:
-	ddf_fun_unbind(fun);
 err_fun_bind:
 err_rx_structure:
@@ -2388,5 +2390,4 @@
 
 	memcpy(e1000->tx_frame_virt[tdt], data, size);
-
 	tx_descriptor_addr->phys_addr = PTR_TO_U64(e1000->tx_frame_phys[tdt]);
 	tx_descriptor_addr->length = size;
Index: uspace/drv/nic/e1k/meson.build
===================================================================
--- uspace/drv/nic/e1k/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/e1k/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'nic' ]
+deps = [ 'nic' , 'pcap' ]
 src = files('e1k.c')
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -44,4 +44,5 @@
 #include <str_error.h>
 #include <async.h>
+#include <ddf/log.h>
 #include "dp8390.h"
 
@@ -450,8 +451,8 @@
 	}
 
-	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	rc = nic_fun_add_to_cats(fun);
 	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to categories");
 		ddf_fun_unbind(fun);
-		ddf_fun_destroy(fun);
 		return rc;
 	}
@@ -497,4 +498,5 @@
 	nic_driver_implement(&ne2k_driver_ops, &ne2k_dev_ops, &ne2k_nic_iface);
 
+	ddf_log_init(NAME);
 	return ddf_driver_main(&ne2k_driver);
 }
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/rtl8139/driver.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -1313,8 +1313,10 @@
 		goto err_fun_create;
 	}
-	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+
+	rc = nic_fun_add_to_cats(fun);
 	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed adding function to category");
-		goto err_fun_bind;
+		ddf_msg(LVL_ERROR, "Failed adding function to categories");
+		ddf_fun_unbind(fun);
+		return rc;
 	}
 
@@ -1324,6 +1326,6 @@
 	return EOK;
 
-err_fun_bind:
-	ddf_fun_unbind(fun);
+	// err_fun_bind:
+	// ddf_fun_unbind(fun);
 err_fun_create:
 	ddf_fun_destroy(fun);
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/rtl8169/driver.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -461,8 +461,9 @@
 	}
 
-	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	rc = nic_fun_add_to_cats(fun);
 	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed adding function to category");
-		goto err_fun_bind;
+		ddf_msg(LVL_ERROR, "Failed adding function to categories");
+		ddf_fun_unbind(fun);
+		return rc;
 	}
 
@@ -471,6 +472,6 @@
 	return EOK;
 
-err_fun_bind:
-	ddf_fun_unbind(fun);
+	// err_fun_bind:
+	// ddf_fun_unbind(fun);
 err_fun_create:
 	ddf_fun_destroy(fun);
Index: uspace/drv/nic/virtio-net/virtio-net.c
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/drv/nic/virtio-net/virtio-net.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -428,8 +428,9 @@
 	}
 
-	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	rc = nic_fun_add_to_cats(fun);
 	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed adding function to category");
-		goto unbind;
+		ddf_msg(LVL_ERROR, "Failed adding function to categories");
+		ddf_fun_unbind(fun);
+		return rc;
 	}
 
@@ -439,6 +440,6 @@
 	return EOK;
 
-unbind:
-	ddf_fun_unbind(fun);
+	// unbind:
+	// ddf_fun_unbind(fun);
 destroy:
 	ddf_fun_destroy(fun);
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/c/include/ipc/services.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -67,5 +67,4 @@
 #define SERVICE_NAME_VBD      "vbd"
 #define SERVICE_NAME_VOLSRV   "volsrv"
-
 #endif
 
Index: uspace/lib/meson.build
===================================================================
--- uspace/lib/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -84,4 +84,5 @@
 	'nettl',
 	'ofw',
+	'pcap',
 	'pcm',
 	'pcut',
Index: uspace/lib/nic/include/nic.h
===================================================================
--- uspace/lib/nic/include/nic.h	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/include/nic.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -44,4 +44,5 @@
 #include <device/hw_res_parsed.h>
 #include <ops/nic.h>
+#include <pcap_dumper.h>
 
 #define DEVICE_CATEGORY_NIC "nic"
@@ -278,4 +279,9 @@
 extern void nic_sw_period_stop(nic_t *);
 
+/* pcapdump interface */
+extern pcap_dumper_t *nic_get_pcap_dumper(nic_t *);
+
+extern errno_t nic_fun_add_to_cats(ddf_fun_t *fun);
+
 #endif // __NIC_H__
 
Index: uspace/lib/nic/include/nic_driver.h
===================================================================
--- uspace/lib/nic/include/nic_driver.h	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/include/nic_driver.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -46,4 +46,5 @@
 #include <nic/nic.h>
 #include <async.h>
+#include <pcapdump_srv.h>
 
 #include "nic.h"
@@ -195,4 +196,8 @@
 	 */
 	poll_request_handler on_poll_request;
+
+	/** Packets dumper. */
+	pcap_dumper_t dumper;
+
 	/** Data specific for particular driver */
 	void *specific;
Index: uspace/lib/nic/include/nic_impl.h
===================================================================
--- uspace/lib/nic/include/nic_impl.h	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/include/nic_impl.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -87,6 +87,4 @@
 extern void nic_close_impl(ddf_fun_t *fun);
 
-extern void nic_device_added_impl(ddf_dev_t *dev);
-
 #endif
 
Index: uspace/lib/nic/meson.build
===================================================================
--- uspace/lib/nic/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'drv' ]
+deps = [ 'drv' , 'pcap' ]
 c_args = [ '-DLIBNIC_INTERNAL', ]
 src = files(
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/src/nic_driver.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -47,4 +47,5 @@
 #include <ops/nic.h>
 #include <errno.h>
+#include <pcapdump_drv_iface.h>
 
 #include "nic_driver.h"
@@ -522,4 +523,5 @@
 	 * 		 calls it inside send_frame handler (with locked main lock)
 	 */
+	pcapdump_packet(nic_get_pcap_dumper(nic_data), frame->data, frame->size);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_frame_type_t frame_type;
@@ -560,4 +562,5 @@
 		fibril_rwlock_write_unlock(&nic_data->stats_lock);
 	}
+	//pcapdump_packet(nic_get_pcap_dumper(nic_data), frame->data, frame->size);
 	nic_release_frame(nic_data, frame);
 }
@@ -648,4 +651,9 @@
 	nic_data->dev = device;
 
+	errno_t pcap_rc  = pcapdump_init(nic_get_pcap_dumper(nic_data));
+	if (pcap_rc != EOK) {
+		printf("Failed creating pcapdump port\n");
+	}
+
 	return nic_data;
 }
@@ -1133,4 +1141,9 @@
 }
 
+pcap_dumper_t *nic_get_pcap_dumper(nic_t *nic_data)
+{
+	return &nic_data->dumper;
+}
+
 /** @}
  */
Index: uspace/lib/nic/src/nic_impl.c
===================================================================
--- uspace/lib/nic/src/nic_impl.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/lib/nic/src/nic_impl.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -40,4 +40,5 @@
 #include <ipc/services.h>
 #include <ns.h>
+#include <pcapdump_drv_iface.h>
 #include "nic_driver.h"
 #include "nic_ev.h"
@@ -179,5 +180,5 @@
 		return EBUSY;
 	}
-
+	pcapdump_packet(nic_get_pcap_dumper(nic_data), data, size);
 	nic_data->send_frame(nic_data, data, size);
 	fibril_rwlock_read_unlock(&nic_data->main_lock);
@@ -843,4 +844,18 @@
 }
 
+errno_t nic_fun_add_to_cats(ddf_fun_t *fun)
+{
+	errno_t rc;
+	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	if (rc != EOK)
+		return rc;
+
+	rc = ddf_fun_add_to_category(fun, "pcap");
+	if (rc != EOK) {
+		return rc;
+	}
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/pcap/doc/doxygoups.h
===================================================================
--- uspace/lib/pcap/doc/doxygoups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/doc/doxygoups.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,3 @@
+/** @addtogroup libpcap libpcap
+ * @ingroup libs
+ */
Index: uspace/lib/pcap/include/pcap.h
===================================================================
--- uspace/lib/pcap/include/pcap.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcap.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file
+ * @brief Headers and functions for PCAP format and packets to be dumped.
+ */
+
+#ifndef PCAP_H_
+#define PCAP_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <str_error.h>
+#include <time.h>
+#include <stdbool.h>
+#include <errno.h>
+
+#define PCAP_MAGIC_MICRO 0xA1B2C3D4 /** Sets time in seconds and microseconds in packet records. */
+#define PCAP_MAGIC_NANO 0xA1B23C4D /** Sets time in seconds and nanoseconds in packet records. */
+#define PCAP_MAJOR_VERSION 0x0002  /** Major version of the PCAP format. */
+#define PCAP_MINOR_VERSION 0x0004  /** Miner version of the PCAP format. */
+#define PCAP_SNAP_LEN 0x00040000  /** Maximum number of bytes that can be captured for one packet record. */
+
+#define PCAP_LINKTYPE_ETHERNET 1    /* IEEE 802.3 Ethernet */
+#define PCAP_LINKTYPE_IP_RAW 101	/* Raw IP packet */
+#define PCAP_LINKTYPE_IEEE802_11_RADIO 127
+#define PCAP_LINKTYPE_USB_LINUX_MMAPPED 220
+
+/** Header of the .pcap file. */
+typedef struct {
+	uint32_t magic_number;
+	uint16_t major_v;
+	uint16_t minor_v;
+	uint32_t reserved1;
+	uint32_t reserved2;
+	uint32_t snaplen;
+	uint32_t additional; /** The LinkType and additional information field is in the form */
+} pcap_file_header_t;
+
+/** Header of the packet to be dumped to .pcap file. */
+typedef struct pcap_packet_header {
+	uint32_t seconds_stamp;
+	uint32_t magic_stamp;
+	uint32_t captured_length;
+	uint32_t original_length;
+} pcap_packet_header_t;
+
+typedef struct pcap_writer pcap_writer_t;
+
+/** Writing operations for destination buffer. */
+typedef struct {
+	errno_t (*open)(pcap_writer_t *, const char *);
+	size_t (*write_u32)(pcap_writer_t *, uint32_t);
+	size_t (*write_u16)(pcap_writer_t *, uint16_t);
+	size_t (*write_buffer)(pcap_writer_t *, const void *, size_t);
+	void (*close)(pcap_writer_t *);
+} pcap_writer_ops_t;
+
+/** Structure for writing data to the destination buffer. */
+struct pcap_writer {
+	/** Writing buffer. */
+	void *data;
+	/** Writing operations for working with the buffer. */
+	pcap_writer_ops_t *ops;
+};
+
+extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype);
+extern void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size);
+extern void pcap_set_time(pcap_packet_header_t *header);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/include/pcap_dumper.h
===================================================================
--- uspace/lib/pcap/include/pcap_dumper.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcap_dumper.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libpcap
+ * @{
+ */
+/** @file Pcap dumper. Structure is a part of every device that is in category PCAP and can dump packets.
+ */
+
+#ifndef PCAP_IFACE_H_
+#define PCAP_IFACE_H_
+
+#include <errno.h>
+#include <fibril_synch.h>
+#include "pcap.h"
+
+/** Packet dumper structure that is responsible for dumping packets. */
+typedef struct pcap_dumper {
+	fibril_mutex_t mutex;
+	/** Flag that indicates, whether the packet should be dumped or ignored. */
+	bool to_dump;
+	/** Writer structure that is responsible for writing data to the destination buffer. */
+	pcap_writer_t writer;
+} pcap_dumper_t;
+
+extern errno_t pcap_dumper_start(pcap_dumper_t *, const char *);
+extern void pcap_dumper_stop(pcap_dumper_t *);
+extern int pcap_dumper_get_ops_number(void);
+extern errno_t pcap_dumper_set_ops(pcap_dumper_t *, int);
+extern void pcap_dumper_add_packet(pcap_dumper_t *, const void *data, size_t size);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/include/pcapdump_client.h
===================================================================
--- uspace/lib/pcap/include/pcapdump_client.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcapdump_client.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file Client side of the IPC communication for pcapctl.
+ *
+ */
+
+#ifndef _PCAPDUMP_CLIENT_H_
+#define _PCAPDUMP_CLIENT_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <async.h>
+#include <loc.h>
+#include <fibril_synch.h>
+
+/** IPC session structure for pcapctl utility. */
+typedef struct {
+	async_sess_t *sess;
+} pcapctl_sess_t;
+
+extern errno_t pcapctl_dump_open(int *, pcapctl_sess_t **);
+extern errno_t pcapctl_dump_close(pcapctl_sess_t *);
+
+extern errno_t pcapctl_dump_start(const char *, int *, pcapctl_sess_t *);
+extern errno_t pcapctl_dump_stop(pcapctl_sess_t *);
+extern errno_t pcapctl_list(void);
+extern errno_t pcapctl_is_valid_device(int *);
+extern errno_t pcapctl_is_valid_ops_number(int *, pcapctl_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/include/pcapdump_drv_iface.h
===================================================================
--- uspace/lib/pcap/include/pcapdump_drv_iface.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcapdump_drv_iface.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file Driver interface. Functions that are used in drivers that can dump packets.
+ *
+ */
+
+#ifndef _PCAPDUMP_DRV_IFACE_H_
+#define _PCAPDUMP_DRV_IFACE_H_
+
+#include <errno.h>
+#include "pcap_dumper.h"
+
+extern errno_t pcapdump_init(pcap_dumper_t *);
+extern void pcapdump_packet(pcap_dumper_t *, const void *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/include/pcapdump_ipc.h
===================================================================
--- uspace/lib/pcap/include/pcapdump_ipc.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcapdump_ipc.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file IPC requests defined for pcap category.
+ *
+ */
+
+#ifndef _PCAPDUMP_IPC_H_
+#define _PCAPDUMP_IPC_H_
+
+#include <ipc/common.h>
+
+/** IPC requests for INTERFACE_PCAP_CONTROL interface. */
+typedef enum {
+	PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD,
+	PCAP_CONTROL_SET_STOP,
+	PCAP_CONTROL_GET_OPS_NUM,
+} pcap_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/include/pcapdump_srv.h
===================================================================
--- uspace/lib/pcap/include/pcapdump_srv.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/include/pcapdump_srv.h	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file Server side of the IPC communication for dumping packets framework.
+ *
+ */
+
+#ifndef _PCAPDUMP_IFACE_H_
+#define _PCAPDUMP_IFACE_H_
+
+#include <errno.h>
+
+extern void pcapdump_conn(ipc_call_t *, void *);
+#endif
+
+/** @}
+ */
Index: uspace/lib/pcap/meson.build
===================================================================
--- uspace/lib/pcap/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2023 Nataliia Korop
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+src = files(
+    'src/pcap.c',
+    'src/pcap_dumper.c',
+    'src/pcapdump_srv.c',
+    'src/pcapdump_client.c',
+    'src/pcapdump_drv_iface.c',
+)
Index: uspace/lib/pcap/src/pcap.c
===================================================================
--- uspace/lib/pcap/src/pcap.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/src/pcap.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file
+ * @brief Headers and functions for .pcap file and packets to be dumped
+ */
+
+#include "pcap.h"
+
+/** Set time in seconds and microseconds for the packet header .
+ *
+ * @param header Header of the packet to be dumped.
+ *
+ */
+void pcap_set_time(pcap_packet_header_t *header)
+{
+	struct timespec ts;
+	getrealtime(&ts);
+	header->seconds_stamp = (uint32_t)ts.tv_sec;
+	header->magic_stamp = (uint32_t)ts.tv_sec / 1000;
+}
+
+/** Add pcap file header to the new .pcap file.
+ *
+ * @param writer 	Writer that has destination buffer and ops to write to destination buffer.
+ * @param linktype 	Linktype for the file header.
+ */
+void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype)
+{
+	pcap_file_header_t file_header = { (uint32_t)PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION,
+		0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, linktype };
+	writer->ops->write_buffer(writer, &file_header, sizeof(file_header));
+}
+
+/** Add packet to the .pcap file.
+ *
+ * @param writer 			Writer that has destination buffer and ops to write to destination buffer.
+ * @param captured_packet 	Packet to be dumped
+ * @param size 				Size of the captured packet
+ *
+ */
+void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size)
+{
+
+	pcap_packet_header_t pcap_packet;
+	pcap_set_time(&pcap_packet);
+	pcap_packet.original_length = size;
+
+	if (PCAP_SNAP_LEN < size) {
+		pcap_packet.captured_length = PCAP_SNAP_LEN;
+	} else {
+		pcap_packet.captured_length = size;
+	}
+	writer->ops->write_buffer(writer, &pcap_packet, sizeof(pcap_packet));
+	writer->ops->write_buffer(writer, captured_packet, pcap_packet.captured_length);
+
+}
+
+/** @}
+ */
Index: uspace/lib/pcap/src/pcap_dumper.c
===================================================================
--- uspace/lib/pcap/src/pcap_dumper.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/src/pcap_dumper.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libpcap
+ * @{
+ */
+/** @file Pcap dumper. Structure is a part of every device that is in category PCAP and can dump packets.
+ */
+
+#include <errno.h>
+#include <str.h>
+#include <io/log.h>
+#include "pcap_dumper.h"
+
+#define SHORT_OPS_BYTE_COUNT 0x3C
+
+/** Initialize writing to .pcap file.
+ *
+ * @param writer    Interface for writing data.
+ * @param filename  Name of the file for dumping packets.
+ * @return          EOK on success, otherwise an error code.
+ *
+ */
+static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename)
+{
+	/** For overwriting file if already exists. */
+	writer->data = fopen(filename, "w");
+	if (writer->data == NULL) {
+		return EINVAL;
+	}
+	fclose(writer->data);
+
+	writer->data = fopen(filename, "a");
+	if (writer->data == NULL) {
+		return EINVAL;
+	}
+	pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET);
+
+	return EOK;
+}
+
+/** Open file for appending to the end of it.
+ *  @param writer 	Interface for writing data.
+ *  @param filename Path to the file.
+ *  @return 		EOK on success, error code otherwise.
+ */
+static errno_t pcap_writer_to_file_init_append(pcap_writer_t *writer, const char *filename)
+{
+	writer->data = fopen(filename, "a");
+	if (writer->data == NULL) {
+		return EINVAL;
+	}
+
+	return EOK;
+}
+
+/** Initialize file for dumping usb packets.
+ *  @param writer 	Interface for writing data.
+ *  @param filename Path to the file.
+ *  @return 		EOK on success, error code otherwise.
+ */
+static errno_t pcap_writer_to_file_usb_init(pcap_writer_t *writer, const char *filename)
+{
+	/** For overwriting file if already exists. */
+	writer->data = fopen(filename, "w");
+	if (writer->data == NULL) {
+		return EINVAL;
+	}
+	fclose(writer->data);
+
+	writer->data = fopen(filename, "a");
+	if (writer->data == NULL) {
+		return EINVAL;
+	}
+	pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED);
+
+	return EOK;
+}
+
+/** Write 4B to the file.
+ *  @param writer 	Interface for writing data.
+ *  @param data 	Bytes to write.
+ *  @return 		Size of successfully witten data.
+ */
+static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data)
+{
+	return fwrite(&data, 1, 4, (FILE *)writer->data);
+}
+
+/** Write 2B to the file.
+ *  @param writer 	Interface for writing data.
+ *  @param data 	Bytes to write.
+ *  @return 		Size of successfully witten data.
+ */
+static size_t pcap_file_w16(pcap_writer_t *writer, uint16_t data)
+{
+	return fwrite(&data, 1, 2, (FILE *)writer->data);
+}
+
+/** Write block of bytes to the file.
+ *  @param writer 	Interface for writing data.
+ *  @param data 	Bytes to write.
+ *  @param size		Size of block of bytes.
+ *  @return 		Size of successfully witten data.
+ */
+static size_t pcap_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size)
+{
+	assert(writer->data);
+	return fwrite(data, 1, size, (FILE *)writer->data);
+}
+
+/** Close file for writing.
+ *  @param writer 	Interaface for writing data.
+ */
+static void pcap_file_close(pcap_writer_t *writer)
+{
+	fclose((FILE *)writer->data);
+	writer->data = NULL;
+}
+
+/** Write <= 60B of block of bytes.
+ *  @param writer 	Interface for writing data.
+ *  @param data 	Bytes to write.
+ *  @param size		Size of block of bytes.
+ *  @return 		Size of successfully witten data.
+ */
+static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size)
+{
+	return fwrite(data, 1, size < SHORT_OPS_BYTE_COUNT ? size : SHORT_OPS_BYTE_COUNT, (FILE *)writer->data);
+}
+
+/** Standard writer operations for writing data to a newly created file. */
+static const pcap_writer_ops_t file_ops = {
+	.open = &pcap_writer_to_file_init,
+	.write_u32 = &pcap_file_w32,
+	.write_u16 = &pcap_file_w16,
+	.write_buffer = &pcap_file_wbuffer,
+	.close = &pcap_file_close
+};
+
+/** Truncated writer operations. Only first 60 bytes of the packet are written. */
+static const pcap_writer_ops_t short_file_ops = {
+	.open = &pcap_writer_to_file_init,
+	.write_u32 = &pcap_file_w32,
+	.write_u16 = &pcap_file_w16,
+	.write_buffer = &pcap_short_file_wbuffer,
+	.close = &pcap_file_close
+
+};
+
+/** Append writer operations. Instead of creating new file open existing file and append packets. */
+static const pcap_writer_ops_t append_file_ops = {
+	.open = &pcap_writer_to_file_init_append,
+	.write_u32 = &pcap_file_w32,
+	.write_u16 = &pcap_file_w16,
+	.write_buffer = &pcap_file_wbuffer,
+	.close = &pcap_file_close
+};
+
+/** USB writer operations. Writing USB packets to the file. */
+static const pcap_writer_ops_t usb_file_ops = {
+	.open = &pcap_writer_to_file_usb_init,
+	.write_u32 = &pcap_file_w32,
+	.write_u16 = &pcap_file_w16,
+	.write_buffer = &pcap_file_wbuffer,
+	.close = &pcap_file_close
+};
+
+/** Default array of operations. Must be consistens with constants in /uspace/app/pcapctl/main.c */
+static pcap_writer_ops_t ops[4] = { file_ops, short_file_ops, append_file_ops, usb_file_ops };
+
+/** Get number of writer operations in @ref ops */
+int pcap_dumper_get_ops_number(void)
+{
+	return (int)(sizeof(ops) / sizeof(pcap_writer_ops_t));
+}
+
+/** Open destination buffer for writing and set flag for dumping.
+ *  @param dumper	Structure responsible for dumping packets. Part of the driver.
+ *  @param name		Name of the destination buffer to dump packets to.
+ *  @return 		EOK if successful, erro code otherwise.
+ */
+errno_t pcap_dumper_start(pcap_dumper_t *dumper, const char *name)
+{
+	fibril_mutex_lock(&dumper->mutex);
+
+	errno_t rc = dumper->writer.ops->open(&dumper->writer, name);
+	if (rc == EOK) {
+		dumper->to_dump = true;
+	}
+
+	fibril_mutex_unlock(&dumper->mutex);
+	return rc;
+}
+
+/** Set writer options for the writer.
+ *  @param dumper 	Structure responsible for dumping packets. Part of the driver.
+ *  @param index	Index of the writer operations from array @ref ops.
+ *  @return 		EOK if successful, erro code otherwise.
+ */
+errno_t pcap_dumper_set_ops(pcap_dumper_t *dumper, int index)
+{
+	fibril_mutex_lock(&dumper->mutex);
+	dumper->writer.ops = &ops[index];
+	fibril_mutex_unlock(&dumper->mutex);
+	return EOK;
+}
+
+/** Write packet to destination buffer.
+ *  @param dumper	Structure responsible for dumping packets. Part of the driver.
+ *  @param data		Packet data to write.
+ *  @param size		Size of the packet.
+ */
+void pcap_dumper_add_packet(pcap_dumper_t *dumper, const void *data, size_t size)
+{
+	fibril_mutex_lock(&dumper->mutex);
+
+	if (!dumper->to_dump) {
+		fibril_mutex_unlock(&dumper->mutex);
+		return;
+	}
+
+	pcap_writer_add_packet(&dumper->writer, data, size);
+	fibril_mutex_unlock(&dumper->mutex);
+}
+
+/** Close destination buffer for writing and unset flag for dumping.
+ *  @param dumper	Structure responsible for dumping packets. Part of the driver.
+ */
+void pcap_dumper_stop(pcap_dumper_t *dumper)
+{
+	fibril_mutex_lock(&dumper->mutex);
+
+	/** If want to stop, when already stopped, do nothing */
+	if (!dumper->to_dump) {
+		fibril_mutex_unlock(&dumper->mutex);
+		return;
+	}
+	dumper->to_dump = false;
+	dumper->writer.ops->close(&dumper->writer);
+	fibril_mutex_unlock(&dumper->mutex);
+}
+
+/** @}
+ */
Index: uspace/lib/pcap/src/pcapdump_client.c
===================================================================
--- uspace/lib/pcap/src/pcapdump_client.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/src/pcapdump_client.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libpcap
+ * @{
+ */
+/** @file Client side of the pcapctl. Functions are called from the app pcapctl.
+ */
+
+#include <errno.h>
+#include <async.h>
+#include <str.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "pcapdump_client.h"
+#include "pcapdump_ipc.h"
+
+/** Finish an async exchange on the pcapctl session
+ *
+ * @param exch  Exchange to be finished
+ */
+static void pcapctl_dump_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
+}
+
+/** Get service based on the index of the device.
+ *  @param index of the device.
+ *  @param svc placeholder for service ide.
+ *  @return EOK if successful, error code otherwise.
+ */
+static errno_t pcapctl_cat_get_svc(int *index, service_id_t *svc)
+{
+	errno_t rc;
+	category_id_t pcap_cat;
+	size_t count;
+	service_id_t *pcap_svcs = NULL;
+
+	rc = loc_category_get_id("pcap", &pcap_cat, 0);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving category 'pcap'.\n");
+		return rc;
+	}
+
+	rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving list of pcap services.\n");
+		free(pcap_svcs);
+		return rc;
+	}
+	if (*index < (int)count) {
+		*svc =  pcap_svcs[*index];
+		free(pcap_svcs);
+		return EOK;
+	}
+
+	return ENOENT;
+}
+
+/** Check if the index is an index of valid device.
+ *  @param index to check.
+ *  @return EOK if device is valid, error code otherwise.
+ */
+errno_t pcapctl_is_valid_device(int *index)
+{
+	errno_t rc;
+	category_id_t pcap_cat;
+	size_t count;
+	service_id_t *pcap_svcs = NULL;
+
+	rc = loc_category_get_id("pcap", &pcap_cat, 0);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving category pcap.\n");
+		return rc;
+	}
+
+	rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving list of pcap services.\n");
+		free(pcap_svcs);
+		return rc;
+	}
+	if (*index + 1 > (int)count || *index < 0) {
+		return EINVAL;
+	}
+	return EOK;
+}
+
+/** Check if the index is an index of valid writer operations.
+ * @param index to check.
+ * @param sess 	pcapctl session for IPC communictaion.
+ */
+errno_t pcapctl_is_valid_ops_number(int *index, pcapctl_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess->sess);
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, PCAP_CONTROL_GET_OPS_NUM, &answer);
+
+	async_exchange_end(exch);
+
+	errno_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK) {
+		return retval;
+	}
+
+	int ops_count = (int)ipc_get_arg1(&answer);
+	if (*index + 1 > ops_count || *index < 0) {
+		return EINVAL;
+	}
+	return EOK;
+}
+
+/** Get all devices that can dump packets. */
+errno_t pcapctl_list(void)
+{
+	errno_t rc;
+	category_id_t pcap_cat;
+	size_t count;
+	service_id_t *pcap_svcs = NULL;
+
+	rc = loc_category_get_id("pcap", &pcap_cat, 0);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving category pcap.\n");
+		return rc;
+	}
+
+	rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count);
+	if (rc != EOK) {
+		fprintf(stderr, "Error resolving list of pcap services.\n");
+		free(pcap_svcs);
+		return rc;
+	}
+
+	fprintf(stdout, "Devices:\n");
+	for (unsigned i = 0; i < count; ++i) {
+		char *name = NULL;
+		loc_service_get_name(pcap_svcs[i], &name);
+		fprintf(stdout, "%d. %s\n", i, name);
+	}
+	free(pcap_svcs);
+	return EOK;
+}
+
+/** Start pcapctl IPC session.
+ *  @param index 	index of the device which can dump packets.
+ *  @param rsess 	placeholder for the session.
+ *  @return			EOK if successful, error code otherwise.
+ */
+errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess)
+{
+	errno_t rc;
+	service_id_t svc;
+	pcapctl_sess_t *sess = calloc(1, sizeof(pcapctl_sess_t));
+	if (sess == NULL)
+		return ENOMEM;
+
+	if (*index == -1) {
+		*index = 0;
+	}
+
+	rc  = pcapctl_cat_get_svc(index, &svc);
+	if (rc != EOK) {
+		fprintf(stderr, "Error finding the device with index: %d\n", *index);
+		goto error;
+	}
+
+	async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0);
+	if (new_session == NULL) {
+		fprintf(stderr, "Error connecting to service.\n");
+		rc =  EREFUSED;
+		goto error;
+	}
+
+	sess->sess = new_session;
+	*rsess = sess;
+	return EOK;
+error:
+	pcapctl_dump_close(sess);
+	return rc;
+}
+
+/** Close pcapctl IPC session.
+ *  @param sess Session to close.
+ *  @return EOK if successful, error code otherwise.
+ */
+errno_t pcapctl_dump_close(pcapctl_sess_t *sess)
+{
+	free(sess);
+	return EOK;
+}
+
+/** Send start request via IPC to start dumping.
+ *
+ * @param name 	Name of the destination buffer to dump packets to.
+ * @param sess 	Session that is used for communication.
+ * @return 		EOK on success or an error code.
+ */
+errno_t pcapctl_dump_start(const char *name, int *ops_index, pcapctl_sess_t *sess)
+{
+	errno_t rc;
+	async_exch_t *exch = async_exchange_begin(sess->sess);
+
+	size_t size = str_size(name);
+	aid_t req = async_send_1(exch, PCAP_CONTROL_SET_START, *ops_index, NULL);
+
+	rc = async_data_write_start(exch, name, size);
+
+	pcapctl_dump_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	errno_t retval;
+	async_wait_for(req, &retval);
+	return retval;
+}
+
+/** Send stop request via IPC to start dumping.
+ *
+ * @param sess 	Session that is used for communication.
+ * @return 		EOK on success or an error code.
+ */
+errno_t pcapctl_dump_stop(pcapctl_sess_t *sess)
+{
+	errno_t rc;
+	async_exch_t *exch = async_exchange_begin(sess->sess);
+	rc = async_req_0_0(exch, PCAP_CONTROL_SET_STOP);
+
+	pcapctl_dump_exchange_end(exch);
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/pcap/src/pcapdump_drv_iface.c
===================================================================
--- uspace/lib/pcap/src/pcapdump_drv_iface.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/src/pcapdump_drv_iface.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file Functions that are called inside driver that can dump packets/
+ *
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fibril_synch.h>
+#include <str.h>
+#include <io/log.h>
+
+#include "pcapdump_srv.h"
+#include "pcapdump_drv_iface.h"
+
+#define NAME "pcap"
+
+/** Initialize interface for dumping packets.
+ * @param dumper 	Device dumping interface.
+ * @return 			EOK if successful, error code otherwise.
+ */
+static errno_t pcapdump_drv_dumper_init(pcap_dumper_t *dumper)
+{
+	fibril_mutex_initialize(&dumper->mutex);
+	dumper->to_dump = false;
+	dumper->writer.ops = NULL;
+
+	errno_t rc = log_init(NAME);
+	if (rc != EOK) {
+		printf("%s : Failed to initialize log.\n", NAME);
+		return 1;
+	}
+	return EOK;
+}
+
+/** Initialize driver dumping functionality.
+ *  @param dumper 	Dumping interface of the driver.
+ * 	@return 		EOK if successful, error code otherwise.
+ */
+errno_t pcapdump_init(pcap_dumper_t *dumper)
+{
+	port_id_t port;
+	errno_t rc;
+
+	rc = pcapdump_drv_dumper_init(dumper);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Failed initializing pcap dumper: %s", str_error(rc));
+		return rc;
+	}
+
+	rc = async_create_port(INTERFACE_PCAP_CONTROL, pcapdump_conn, dumper, &port);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Failed creating port for pcap dumper: %s", str_error(rc));
+		return rc;
+	}
+	return EOK;
+}
+
+/** Dumping function for driver.
+ *
+ * Called every time, the packet is sent/recieved by the device.
+ *
+ * @param dumper 	Dumping interface.
+ * @param data 		The packet
+ * @param size 		Size of the packet.
+ *
+ */
+void pcapdump_packet(pcap_dumper_t *dumper, const void *data, size_t size)
+{
+	if (dumper == NULL) {
+		return;
+	}
+	pcap_dumper_add_packet(dumper, data, size);
+}
Index: uspace/lib/pcap/src/pcapdump_srv.c
===================================================================
--- uspace/lib/pcap/src/pcapdump_srv.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
+++ uspace/lib/pcap/src/pcapdump_srv.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2023 Nataliia Korop
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libpcap
+ * @{
+ */
+/**
+ * @file
+ * @brief Server side of the pcapctl
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fibril_synch.h>
+#include <str.h>
+#include <io/log.h>
+
+#include "pcap_dumper.h"
+#include "pcapdump_srv.h"
+#include "pcapdump_ipc.h"
+
+/** Start dumping.
+ * 	@param icall 	IPC call with request to start.
+ *  @param dumper 	Dumping interface of the driver.
+ */
+static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper)
+{
+	char *data;
+	size_t size;
+	int ops_index = (int)ipc_get_arg1(icall);
+	errno_t rc = async_data_write_accept((void **) &data, true, 0, 0, 0, &size);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	assert(str_length(data) == size && "Data were damaged during transmission.\n");
+
+	// Deadlock solution when trying to start dump while dumping (to the same device)
+	if (dumper->to_dump) {
+		free(data);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Trying to start dumping while dumping.\n");
+		async_answer_0(icall, EBUSY);
+		return;
+	}
+
+	rc = pcap_dumper_set_ops(dumper, ops_index);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Setting ops for dumper was not successful.\n");
+		free(data);
+		async_answer_0(icall, EOK);
+		return;
+	}
+
+	rc = pcap_dumper_start(dumper, (const char *)data);
+	free(data);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Starting the dumping was not successful.\n");
+	}
+	async_answer_0(icall, EOK);
+}
+
+/** Stop dumping
+ * 	@param icall 	IPC call with request to stop.
+ *  @param dumper 	Dumping interface of the driver.
+ */
+static void pcapdump_stop_srv(ipc_call_t *icall, pcap_dumper_t *dumper)
+{
+	pcap_dumper_stop(dumper);
+	async_answer_0(icall, EOK);
+}
+
+/** Get number of accessibke writer operations.
+ * 	@param icall 	IPC call with request to get number of accessible writer operations.
+ */
+static void pcapdump_get_ops_num_srv(ipc_call_t *icall)
+{
+	size_t count = pcap_dumper_get_ops_number();
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Getting number of ops.\n");
+
+	async_answer_1(icall, EOK, count);
+}
+
+/** Callback connection function. Accepts requests and processes them.
+ * 	@param icall 	IPC call with request.
+ *  @param arg	 	Dumping interface of the driver.
+ */
+void pcapdump_conn(ipc_call_t *icall, void *arg)
+{
+	pcap_dumper_t *dumper = (pcap_dumper_t *)arg;
+
+	assert((dumper != NULL) && "pcapdump requires pcap dumper\n");
+
+	/* Accept connection */
+	async_accept_0(icall);
+
+	while (true) {
+		ipc_call_t call;
+		async_get_call(&call);
+		sysarg_t method = ipc_get_imethod(&call);
+		if (!method) {
+			/* The other side has hung up */
+			async_answer_0(&call, EOK);
+			break;
+		}
+		switch (method) {
+		case PCAP_CONTROL_SET_START:
+			pcapdump_start_srv(&call, dumper);
+			break;
+		case PCAP_CONTROL_SET_STOP:
+			pcapdump_stop_srv(&call, dumper);
+			break;
+		case PCAP_CONTROL_GET_OPS_NUM:
+			pcapdump_get_ops_num_srv(&call);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			break;
+		}
+	}
+}
+
+/** @}
+ */
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/srv/locsrv/locsrv.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -1393,4 +1393,6 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("pcap");
+	categ_dir_add_cat(&cdir, cat);
 	return true;
 }
Index: uspace/srv/net/ethip/ethip.c
===================================================================
--- uspace/srv/net/ethip/ethip.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/srv/net/ethip/ethip.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -53,4 +53,5 @@
 
 #define NAME "ethip"
+/** Interface for dumping packets */
 
 static errno_t ethip_open(iplink_srv_t *srv);
@@ -197,5 +198,4 @@
 	if (rc != EOK)
 		return rc;
-
 	rc = ethip_nic_send(nic, data, size);
 	free(data);
Index: uspace/srv/net/ethip/meson.build
===================================================================
--- uspace/srv/net/ethip/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/srv/net/ethip/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'drv' ]
+deps = [ 'drv' , 'pcap' ]
 src = files(
 	'arp.c',
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -212,5 +212,4 @@
 
 	/* Route packet using source/destination addresses */
-
 	rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
 	if (rc != EOK)
@@ -547,5 +546,4 @@
 			dgram.data = packet->data;
 			dgram.size = packet->size;
-
 			return inet_recv_dgram_local(&dgram, packet->proto);
 		} else {
Index: uspace/srv/net/inetsrv/meson.build
===================================================================
--- uspace/srv/net/inetsrv/meson.build	(revision 3e41cc4ae595fc88a3e5e146b78f8aaa2cc37f88)
+++ uspace/srv/net/inetsrv/meson.build	(revision aefdccd0fe11be22f2d0516a50673f21541e5b55)
@@ -27,5 +27,6 @@
 #
 
-deps = [ 'inet', 'sif' ]
+deps = [ 'inet', 'sif', 'pcap' ]
+
 src = files(
 	'addrobj.c',
