From 17a8fcf31720aa3335c630aa4ccdcdfb52b92eaa Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Wed, 13 Dec 2023 09:35:34 +0100 Subject: [PATCH 01/39] Packet capture prototype --- abi/include/abi/ipc/interfaces.h | 4 +- uspace/app/meson.build | 1 + uspace/app/pcapctl/doc/doxygroups.h | 4 + uspace/app/pcapctl/main.c | 100 ++++++++++++++ uspace/app/pcapctl/meson.build | 29 ++++ uspace/drv/nic/e1k/e1k.c | 19 ++- uspace/drv/nic/e1k/meson.build | 2 +- uspace/lib/c/include/ipc/services.h | 2 +- uspace/lib/meson.build | 1 + uspace/lib/pcap/doc/doxygoups.h | 3 + uspace/lib/pcap/include/pcap.h | 103 +++++++++++++++ uspace/lib/pcap/include/pcap_iface.h | 55 ++++++++ uspace/lib/pcap/include/pcapctl_dump.h | 58 ++++++++ uspace/lib/pcap/include/pcapdump_iface.h | 55 ++++++++ uspace/lib/pcap/meson.build | 34 +++++ uspace/lib/pcap/src/pcap.c | 119 +++++++++++++++++ uspace/lib/pcap/src/pcap_iface.c | 107 +++++++++++++++ uspace/lib/pcap/src/pcapctl_dump.c | 138 +++++++++++++++++++ uspace/lib/pcap/src/pcapdump_iface.c | 161 +++++++++++++++++++++++ uspace/srv/locsrv/locsrv.c | 2 + 20 files changed, 993 insertions(+), 4 deletions(-) create mode 100644 uspace/app/pcapctl/doc/doxygroups.h create mode 100644 uspace/app/pcapctl/main.c create mode 100644 uspace/app/pcapctl/meson.build create mode 100644 uspace/lib/pcap/doc/doxygoups.h create mode 100644 uspace/lib/pcap/include/pcap.h create mode 100644 uspace/lib/pcap/include/pcap_iface.h create mode 100644 uspace/lib/pcap/include/pcapctl_dump.h create mode 100644 uspace/lib/pcap/include/pcapdump_iface.h create mode 100644 uspace/lib/pcap/meson.build create mode 100644 uspace/lib/pcap/src/pcap.c create mode 100644 uspace/lib/pcap/src/pcap_iface.c create mode 100644 uspace/lib/pcap/src/pcapctl_dump.c create mode 100644 uspace/lib/pcap/src/pcapdump_iface.c diff --git a/abi/include/abi/ipc/interfaces.h b/abi/include/abi/ipc/interfaces.h index fb72d49da4..1781a52c37 100644 --- a/abi/include/abi/ipc/interfaces.h +++ b/abi/include/abi/ipc/interfaces.h @@ -205,7 +205,9 @@ typedef enum { INTERFACE_SYSTEM = FOURCC_COMPACT('s', 's', 't', 'm') | IFACE_EXCHANGE_SERIALIZE, INTERFACE_SYSTEM_CB = - FOURCC_COMPACT('s', 's', 't', 'm') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK + FOURCC_COMPACT('s', 's', 't', 'm') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK, + INTERFACE_PCAP_CONTROL = + FOURCC_COMPACT('p', 'c', 't', 'l') | IFACE_EXCHANGE_SERIALIZE, } iface_t; #endif diff --git a/uspace/app/meson.build b/uspace/app/meson.build index 7505a71473..71263d3955 100644 --- a/uspace/app/meson.build +++ b/uspace/app/meson.build @@ -71,6 +71,7 @@ apps = [ 'nic', 'nterm', 'ofw', + 'pcapctl', 'pci', 'ping', 'pkg', diff --git a/uspace/app/pcapctl/doc/doxygroups.h b/uspace/app/pcapctl/doc/doxygroups.h new file mode 100644 index 0000000000..64f848ec60 --- /dev/null +++ b/uspace/app/pcapctl/doc/doxygroups.h @@ -0,0 +1,4 @@ +/** @addtogroup pcapctl pcapctl + * @brief Dump network packets + * @ingroup apps + */ diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c new file mode 100644 index 0000000000..4c81889bb5 --- /dev/null +++ b/uspace/app/pcapctl/main.c @@ -0,0 +1,100 @@ +/* + * 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 app + */ + +#include +#include +#include + +#include "pcapctl_dump.h" + +#define NAME "pcapctl" + +#define LOGGER(msg, ...) \ + fprintf(stderr, \ + "[PCAP %s:%d]: " msg "\n", \ + __FILE__, __LINE__, \ + ##__VA_ARGS__\ + ) + +pcapctl_sess_t sess; + +static void start_dumping(const char *name) +{ + pcapctl_dump_start(name, &sess); +} + +static void stop_dumping(void) +{ + pcapctl_dump_stop(&sess); +} + +static void usage(const char *progname) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s start : Packets will be written to \n", progname); + fprintf(stderr, " %s stop: Dumping stops\n", progname); + +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + usage(argv[0]); + return 1; + } else { + errno_t rc = pcapctl_dump_init(&sess); + if (rc != EOK) { + fprintf(stderr, "Error initializing ...\n"); + return 1; + } + if (str_cmp(argv[1], "start") == 0) { + if (argc != 3) { + usage(argv[0]); + return 1; + } + start_dumping(argv[2]); + } else if (str_cmp(argv[1], "stop") == 0) { + stop_dumping(); + fprintf(stdout, "Dumping was stopped\n"); + return EOK; + } else { + usage(argv[0]); + return 1; + } + } + return 0; +} + +/** @} + */ diff --git a/uspace/app/pcapctl/meson.build b/uspace/app/pcapctl/meson.build new file mode 100644 index 0000000000..e9d54819e1 --- /dev/null +++ b/uspace/app/pcapctl/meson.build @@ -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') \ No newline at end of file diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index cd8b2f874c..f944898ad4 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -50,6 +50,8 @@ #include #include "e1k.h" +#include "pcapdump_iface.h" +#include "pcap_iface.h" #define NAME "e1k" #define E1000_DEFAULT_INTERRUPT_INTERVAL_USEC 250 @@ -173,6 +175,10 @@ typedef struct { /** Lock for EEPROM access */ fibril_mutex_t eeprom_lock; + + /** Interface for dumping packets */ + pcap_iface_t pcapdump; + } e1000_t; /** Global mutex for work with shared irq structure */ @@ -1188,6 +1194,8 @@ static void e1000_receive_frames(nic_t *nic) nic_frame_t *frame = nic_alloc_frame(nic, frame_size); if (frame != NULL) { memcpy(frame->data, e1000->rx_frame_virt[next_tail], frame_size); + pcapdump_packet(&e1000->pcapdump, frame->data, frame->size); + nic_received_frame(nic, frame); } else { ddf_msg(LVL_ERROR, "Memory allocation failed. Frame dropped."); @@ -2201,6 +2209,15 @@ errno_t e1000_dev_add(ddf_dev_t *dev) if (rc != EOK) goto err_add_to_cat; + errno_t pcap_rc = pcapdump_init(&e1000->pcapdump); + + if (pcap_rc != EOK) { + printf("Failed creating pcapdump port\n"); + } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) + goto err_add_to_cat; + return EOK; err_add_to_cat: @@ -2364,7 +2381,7 @@ static void e1000_send_frame(nic_t *nic, void *data, size_t size) } memcpy(e1000->tx_frame_virt[tdt], data, size); - + pcapdump_packet(&e1000->pcapdump, data, size); tx_descriptor_addr->phys_addr = PTR_TO_U64(e1000->tx_frame_phys[tdt]); tx_descriptor_addr->length = size; diff --git a/uspace/drv/nic/e1k/meson.build b/uspace/drv/nic/e1k/meson.build index 847cb2e8c7..d6980678f7 100644 --- a/uspace/drv/nic/e1k/meson.build +++ b/uspace/drv/nic/e1k/meson.build @@ -26,5 +26,5 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -deps = [ 'nic' ] +deps = [ 'nic' , 'pcap' ] src = files('e1k.c') diff --git a/uspace/lib/c/include/ipc/services.h b/uspace/lib/c/include/ipc/services.h index 34ed1531f1..e10b592090 100644 --- a/uspace/lib/c/include/ipc/services.h +++ b/uspace/lib/c/include/ipc/services.h @@ -66,7 +66,7 @@ typedef enum { #define SERVICE_NAME_TCP "net/tcp" #define SERVICE_NAME_VBD "vbd" #define SERVICE_NAME_VOLSRV "volsrv" - +#define SERVICE_NAME_DUMPPCAP "dumppcap" #endif /** @} diff --git a/uspace/lib/meson.build b/uspace/lib/meson.build index 0433bf9089..0008675e60 100644 --- a/uspace/lib/meson.build +++ b/uspace/lib/meson.build @@ -82,6 +82,7 @@ libs = [ 'minix', 'nettl', 'ofw', + 'pcap', 'pcm', 'pcut', 'pixconv', diff --git a/uspace/lib/pcap/doc/doxygoups.h b/uspace/lib/pcap/doc/doxygoups.h new file mode 100644 index 0000000000..fe5d716a84 --- /dev/null +++ b/uspace/lib/pcap/doc/doxygoups.h @@ -0,0 +1,3 @@ +/** @addtogroup libpcap libpcap + * @ingroup libs + */ diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h new file mode 100644 index 0000000000..c9cf50f3af --- /dev/null +++ b/uspace/lib/pcap/include/pcap.h @@ -0,0 +1,103 @@ +/* + * 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 file and packets to be dumped + */ + +#ifndef PCAP_H_ +#define PCAP_H_ + +#include +#include +#include +#include +#include +#include + +#define PCAP_MAGIC_MICRO 0xA1B2C3D4 +#define PCAP_MAGIC_NANO 0xA1B23C4D +#define PCAP_MAJOR_VERSION 0x0002 +#define PCAP_MINOR_VERSION 0x0004 +#define PCAP_SNAP_LEN 0x00040000 + +#define PCAP_LINKTYPE_ETHERNET 1 /* IEEE 802.3 Ethernet*/ + +/** 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 */ +} __attribute__((packed, aligned(4))) pcap_file_header_t; + +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; + +typedef struct { + size_t (*write_u32)(struct pcap_writer *, uint32_t); + size_t (*write_u16)(struct pcap_writer *, uint16_t); + size_t (*write_buffer)(struct pcap_writer *, const void *, size_t); + void (*close)(struct pcap_writer *); + +} pcap_writer_ops_t; + +/** Interface for working with .pcap file + */ +typedef struct pcap_writer { + void *data; + pcap_writer_ops_t *ops; +} pcap_writer_t; + +errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename); + +extern void pcap_writer_add_header(pcap_writer_t *); +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, bool nano); + +#endif + +/** @} + */ diff --git a/uspace/lib/pcap/include/pcap_iface.h b/uspace/lib/pcap/include/pcap_iface.h new file mode 100644 index 0000000000..ca660a3922 --- /dev/null +++ b/uspace/lib/pcap/include/pcap_iface.h @@ -0,0 +1,55 @@ +/* + * 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 interface + */ + +#ifndef PCAP_IFACE_H_ +#define PCAP_IFACE_H_ + +#include +#include "pcap.h" + +typedef struct pcap_iface { + bool to_dump; + errno_t (*init)(const char *); + void (*add_packet)(const void *data, size_t size); + void (*fini)(void); +} pcap_iface_t; + +extern void pcap_close_file(void); +extern errno_t pcap_iface_init(pcap_iface_t *); +extern errno_t pcap_init(const char *); +extern void pcap_add_packet(const void *data, size_t size); + +#endif +/** @} + */ diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h new file mode 100644 index 0000000000..0655c80814 --- /dev/null +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -0,0 +1,58 @@ +/* + * 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 + * + */ + +#ifndef _PCAPCTL_DUMP_H_ +#define _PCAPCTL_DUMP_H_ + +#include +#include +#include +#include +#include + +typedef struct { + async_sess_t *sess; +} pcapctl_sess_t; + +extern errno_t pcapctl_dump_init(pcapctl_sess_t *); +extern errno_t pcapctl_dump_start(const char *, pcapctl_sess_t *); +extern errno_t pcapctl_dump_stop(pcapctl_sess_t *); + +#endif + +/** @} + */ diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_iface.h new file mode 100644 index 0000000000..8192dc0fa2 --- /dev/null +++ b/uspace/lib/pcap/include/pcapdump_iface.h @@ -0,0 +1,55 @@ +/* + * 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 + * + */ + +#ifndef _PCAPDUMP_IFACE_H_ +#define _PCAPDUMP_IFACE_H_ + +#include +#include "pcap_iface.h" + +typedef enum { + PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, + PCAP_CONTROL_SET_STOP +} pcap_request_t; + +extern errno_t pcapdump_init(pcap_iface_t *); +extern void pcapdump_packet(pcap_iface_t *, const void *, size_t); + +#endif + +/** @} + */ diff --git a/uspace/lib/pcap/meson.build b/uspace/lib/pcap/meson.build new file mode 100644 index 0000000000..bb70637845 --- /dev/null +++ b/uspace/lib/pcap/meson.build @@ -0,0 +1,34 @@ +# +# 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_iface.c', + 'src/pcapdump_iface.c', + 'src/pcapctl_dump.c', +) diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c new file mode 100644 index 0000000000..8bca9a4283 --- /dev/null +++ b/uspace/lib/pcap/src/pcap.c @@ -0,0 +1,119 @@ +/* + * 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 file and packets to be dumped + */ + +#define LOGGER(msg, ...) \ + fprintf(stderr, \ + "[PCAP %s:%d]: " msg "\n", \ + __FILE__, __LINE__, \ + ##__VA_ARGS__\ + ) + +#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, bool nano) // maybe without bool nano as nano is in pcapng +{ + time_t sec = time(NULL); + header->seconds_stamp = (uint32_t)sec; + header->magic_stamp = nano ? header->seconds_stamp / 1000000000 : header->seconds_stamp / 1000000; +} + +/** Add pcap file header to the new .pcap file. + * + * @param writer + * + */ +void pcap_writer_add_header(pcap_writer_t *writer) +{ + pcap_file_header_t file_header = { PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, + 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_ETHERNET }; + writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); +} + +/** Add packet to the .pcap file. + * + * @param writer + * @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) +{ + if (!writer->data) + return; + pcap_packet_header_t pcap_packet; + pcap_set_time(&pcap_packet, false); + pcap_packet.original_length = (uint32_t)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); + +} + +/** Initialize writing to .pcap file. + * + * @param writer Interface for working with .pcap file + * @param filename Name of the file for dumping packets + * @return EOK on success or an error code + * + */ +errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) +{ + errno_t rc; + writer->data = fopen(filename, "a"); + if (writer->data == NULL) { + rc = EINVAL; + LOGGER("Failed to create %s: %s.", filename, str_error(rc)); + return rc; + } + pcap_writer_add_header(writer); + + rc = EOK; + return rc; +} + +/** @} + */ diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c new file mode 100644 index 0000000000..e27b423dc3 --- /dev/null +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -0,0 +1,107 @@ +/* + * 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 pcap inteface: Dumping interface for the device which packets we want to dump + */ + +#include +#include "pcap_iface.h" + +static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data) +{ + return fwrite(&data, 1, 4, (FILE *)writer->data); +} + +static size_t pcap_file_w16(pcap_writer_t *writer, uint16_t data) +{ + return fwrite(&data, 1, 2, (FILE *)writer->data); +} + +static size_t pcap_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) +{ + return fwrite(data, 1, size, (FILE *)writer->data); +} + +static void pcap_file_close(pcap_writer_t *writer) +{ + fclose((FILE *)writer->data); +} + +static pcap_writer_ops_t file_ops = { + + .write_u32 = &pcap_file_w32, + .write_u16 = &pcap_file_w16, + .write_buffer = &pcap_file_wbuffer, + .close = &pcap_file_close +}; + +static pcap_writer_t pcap_writer = { + .ops = &file_ops, +}; + +errno_t pcap_init(const char *name) +{ + errno_t rc = pcap_writer_to_file_init(&pcap_writer, name); + return rc; +} + +void pcap_add_packet(const void *data, size_t size) +{ + if (&pcap_writer.data == NULL) + return; + pcap_writer_add_packet(&pcap_writer, data, size); +} + +void pcap_close_file() +{ + pcap_writer.ops->close(&pcap_writer); + pcap_writer.data = NULL; +} + +/** Initialize interface for dumping packets + * + * @param iface Device dumping interface + * + */ +errno_t pcap_iface_init(pcap_iface_t *iface) +{ + + iface->to_dump = false; + iface->add_packet = pcap_add_packet; + iface->init = pcap_init; + iface->fini = pcap_close_file; + + return EOK; +} + +/** @} + */ diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c new file mode 100644 index 0000000000..aa2ce69b6a --- /dev/null +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -0,0 +1,138 @@ +/* + * 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 Client side of the pcapctl. Functions are called from the app pcapctl + */ + +#include +#include +#include +#include + +#include "pcapctl_dump.h" +#include "pcapdump_iface.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); +} + +errno_t pcapctl_dump_init(pcapctl_sess_t *sess) +{ + errno_t rc; + char *svc_name; + 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) { + printf("Error resolving category 'pcap'.\n"); + return rc; + } + + rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); + if (rc != EOK) { + printf("Error resolving list of pcap services.\n"); + return rc; + } + assert((count > 0) && "TODO: not implemented when no services are available\n"); + + rc = loc_service_get_name(pcap_svcs[0], &svc_name); // Note: for now [0], because only one driver is in pcap_svcs and there is no need to find particular + if (rc != EOK) { + printf("Error getting service name.\n"); + goto error; + } + printf("Using device: %s\n", svc_name); + + async_sess_t *new_session = loc_service_connect(pcap_svcs[0], INTERFACE_PCAP_CONTROL, 0); + if (new_session == NULL) { + printf("Error connecting to service.\n"); + rc = EREFUSED; + goto error; + } + sess->sess = new_session; + rc = EOK; +error: + free(pcap_svcs); + return rc; +} + +/** Starting a new session for pcapctl + * + * @param name Name of the file to dump packets to + * @param sess session to start + * @return EOK on success or an error code + */ +errno_t pcapctl_dump_start(const char *name, 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_0(exch, PCAP_CONTROL_SET_START, NULL); + + rc = async_data_write_start(exch, (void *) 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; +} + +/** Finish current session for pcapctl + * + * @param sess Session to finish + * @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; +} + +/** @} + */ diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_iface.c new file mode 100644 index 0000000000..0696ad289e --- /dev/null +++ b/uspace/lib/pcap/src/pcapdump_iface.c @@ -0,0 +1,161 @@ +/* + * 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 +#include +#include + +#include "pcapdump_iface.h" + +FIBRIL_MUTEX_INITIALIZE(to_dump_mutex); + +static void pcapdump_start_srv(ipc_call_t *icall, pcap_iface_t *iface) +{ + char *data; + size_t size; + errno_t rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size); + if (rc != EOK) { + async_answer_0(icall, rc); + return; + } + + /** When try to start when already started, close current and starts new */ + if (iface->to_dump == true) { + iface->fini(); + } + iface->init((const char *)data); + + fibril_mutex_lock(&to_dump_mutex); + iface->to_dump = true; + fibril_mutex_unlock(&to_dump_mutex); + + async_answer_0(icall, rc); +} + +static void pcapdump_stop_srv(ipc_call_t *icall, pcap_iface_t *iface) +{ + /** If want to stop, when already stopped, do nothing */ + if (iface->to_dump == false) { + async_answer_0(icall, EOK); + return; + } + + fibril_mutex_lock(&to_dump_mutex); + iface->to_dump = false; + fibril_mutex_unlock(&to_dump_mutex); + + iface->fini(); + async_answer_0(icall, EOK); +} + +static void pcapdump_conn(ipc_call_t *icall, void *arg) +{ + pcap_iface_t *iface = (pcap_iface_t *)arg; + + assert((iface != NULL) && "pcapdump requires pcap interface\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, iface); + break; + case PCAP_CONTROL_SET_STOP: + pcapdump_stop_srv(&call, iface); + break; + default: + async_answer_0(&call, EINVAL); + break; + } + } +} + +errno_t pcapdump_init(pcap_iface_t *iface) +{ + port_id_t port; + errno_t rc; + + rc = pcap_iface_init(iface); + + if (rc != EOK) { + printf("Failed creating pcap interface: %s", str_error(rc)); + return rc; + } + + rc = async_create_port(INTERFACE_PCAP_CONTROL, + pcapdump_conn, iface, &port); + if (rc != EOK) { + return rc; + } + return EOK; +} + +/** Dumping function for driver + * + * Called every time, the packet is sent/recieved by the device + * + * @param iface Dumping interface + * @param data The packet + * @param size Size of the packet + * + */ +void pcapdump_packet(pcap_iface_t *iface, const void *data, size_t size) +{ + + if (iface == NULL) { + return; + } + + if (!iface->to_dump) { + return; + } + + iface->add_packet(data, size); +} + +/** @} + */ diff --git a/uspace/srv/locsrv/locsrv.c b/uspace/srv/locsrv/locsrv.c index 16cc0cbcc6..b3e1f647c2 100644 --- a/uspace/srv/locsrv/locsrv.c +++ b/uspace/srv/locsrv/locsrv.c @@ -1392,6 +1392,8 @@ static bool loc_init(void) cat = category_new("pci"); categ_dir_add_cat(&cdir, cat); + cat = category_new("pcap"); + categ_dir_add_cat(&cdir, cat); return true; } From 9eb21d1ce4c2e105b6697a045405be86e0b23d76 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Tue, 19 Dec 2023 15:05:46 +0100 Subject: [PATCH 02/39] pcapdump moved to nic_t struct --- uspace/drv/nic/e1k/e1k.c | 8 +++----- uspace/lib/nic/include/nic.h | 5 +++++ uspace/lib/nic/include/nic_driver.h | 5 +++++ uspace/lib/nic/meson.build | 2 +- uspace/lib/nic/src/nic_driver.c | 5 +++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index f944898ad4..4ffc02f930 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -176,8 +176,6 @@ typedef struct { /** Lock for EEPROM access */ fibril_mutex_t eeprom_lock; - /** Interface for dumping packets */ - pcap_iface_t pcapdump; } e1000_t; @@ -1194,7 +1192,7 @@ static void e1000_receive_frames(nic_t *nic) nic_frame_t *frame = nic_alloc_frame(nic, frame_size); if (frame != NULL) { memcpy(frame->data, e1000->rx_frame_virt[next_tail], frame_size); - pcapdump_packet(&e1000->pcapdump, frame->data, frame->size); + pcapdump_packet(nic_get_pcap_iface(nic), frame->data, frame->size); nic_received_frame(nic, frame); } else { @@ -2209,7 +2207,7 @@ errno_t e1000_dev_add(ddf_dev_t *dev) if (rc != EOK) goto err_add_to_cat; - errno_t pcap_rc = pcapdump_init(&e1000->pcapdump); + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic)); if (pcap_rc != EOK) { printf("Failed creating pcapdump port\n"); @@ -2381,7 +2379,7 @@ static void e1000_send_frame(nic_t *nic, void *data, size_t size) } memcpy(e1000->tx_frame_virt[tdt], data, size); - pcapdump_packet(&e1000->pcapdump, data, size); + pcapdump_packet(nic_get_pcap_iface(nic), data, size); tx_descriptor_addr->phys_addr = PTR_TO_U64(e1000->tx_frame_phys[tdt]); tx_descriptor_addr->length = size; diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index fe832c71d0..a7f71bffee 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -44,6 +44,8 @@ #include #include +#include "pcap_iface.h" + #define DEVICE_CATEGORY_NIC "nic" struct nic; @@ -277,6 +279,9 @@ extern uint64_t nic_query_mcast_hash(nic_t *); extern void nic_sw_period_start(nic_t *); extern void nic_sw_period_stop(nic_t *); +/* pcapdump interface */ +extern pcap_iface_t* nic_get_pcap_iface(nic_t *); + #endif // __NIC_H__ /** @} diff --git a/uspace/lib/nic/include/nic_driver.h b/uspace/lib/nic/include/nic_driver.h index 019741ab4f..378817b5b4 100644 --- a/uspace/lib/nic/include/nic_driver.h +++ b/uspace/lib/nic/include/nic_driver.h @@ -49,6 +49,7 @@ #include "nic.h" #include "nic_rx_control.h" #include "nic_wol_virtues.h" +#include "pcap/include/pcapdump_iface.h" struct sw_poll_info { fid_t fibril; @@ -194,6 +195,10 @@ struct nic { * The implementation is optional. */ poll_request_handler on_poll_request; + + /** Interface for dumping packets */ + pcap_iface_t pcapdump; + /** Data specific for particular driver */ void *specific; }; diff --git a/uspace/lib/nic/meson.build b/uspace/lib/nic/meson.build index 5241065dad..0ec1788cd8 100644 --- a/uspace/lib/nic/meson.build +++ b/uspace/lib/nic/meson.build @@ -26,7 +26,7 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -deps = [ 'drv' ] +deps = [ 'drv' , 'pcap' ] c_args = [ '-DLIBNIC_INTERNAL', ] src = files( 'src/nic_driver.c', diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index ba11079988..8d39010338 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -1132,5 +1132,10 @@ void nic_sw_period_stop(nic_t *nic_data) nic_data->sw_poll_info.running = 0; } +pcap_iface_t* nic_get_pcap_iface(nic_t *nic_data) { + + return &nic_data->pcapdump; +} + /** @} */ From a2700269a26215d1d65e027459823e351f3f4553 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Mon, 19 Feb 2024 07:27:40 +0100 Subject: [PATCH 03/39] small typos and ccheck --- uspace/drv/nic/e1k/e1k.c | 1 - uspace/lib/nic/include/nic.h | 2 +- uspace/lib/nic/src/nic_driver.c | 4 ++-- uspace/lib/pcap/src/pcap.c | 7 ++++--- uspace/lib/pcap/src/pcap_iface.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index 4ffc02f930..09fb64f13c 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -176,7 +176,6 @@ typedef struct { /** Lock for EEPROM access */ fibril_mutex_t eeprom_lock; - } e1000_t; /** Global mutex for work with shared irq structure */ diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index a7f71bffee..d751e788ed 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -280,7 +280,7 @@ extern void nic_sw_period_start(nic_t *); extern void nic_sw_period_stop(nic_t *); /* pcapdump interface */ -extern pcap_iface_t* nic_get_pcap_iface(nic_t *); +extern pcap_iface_t *nic_get_pcap_iface(nic_t *); #endif // __NIC_H__ diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 8d39010338..ea1878efde 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -1132,8 +1132,8 @@ void nic_sw_period_stop(nic_t *nic_data) nic_data->sw_poll_info.running = 0; } -pcap_iface_t* nic_get_pcap_iface(nic_t *nic_data) { - +pcap_iface_t *nic_get_pcap_iface(nic_t *nic_data) +{ return &nic_data->pcapdump; } diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 8bca9a4283..1bd6e58ffa 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -51,9 +51,10 @@ */ void pcap_set_time(pcap_packet_header_t *header, bool nano) // maybe without bool nano as nano is in pcapng { - time_t sec = time(NULL); - header->seconds_stamp = (uint32_t)sec; - header->magic_stamp = nano ? header->seconds_stamp / 1000000000 : header->seconds_stamp / 1000000; + struct timespec ts; + getrealtime(&ts); + header->seconds_stamp = (uint32_t)ts.tv_sec; + header->magic_stamp = (uint32_t)ts.tv_nsec / 1000; } /** Add pcap file header to the new .pcap file. diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c index e27b423dc3..b160f676b3 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -76,7 +76,7 @@ errno_t pcap_init(const char *name) void pcap_add_packet(const void *data, size_t size) { - if (&pcap_writer.data == NULL) + if (pcap_writer.data == NULL) return; pcap_writer_add_packet(&pcap_writer, data, size); } From 2dac5a9f54889337e36b6b2a94454a418e5b55c1 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 24 Feb 2024 20:54:31 +0100 Subject: [PATCH 04/39] framework added to virtio-net --- uspace/drv/nic/virtio-net/virtio-net.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/uspace/drv/nic/virtio-net/virtio-net.c b/uspace/drv/nic/virtio-net/virtio-net.c index fcef69619d..8bfe935e22 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.c +++ b/uspace/drv/nic/virtio-net/virtio-net.c @@ -42,7 +42,8 @@ #include #include - +#include "pcapdump_iface.h" +#include "pcap_iface.h" #define NAME "virtio-net" #define VIRTIO_NET_NUM_QUEUES 3 @@ -96,6 +97,7 @@ static void virtio_net_irq_handler(ipc_call_t *icall, void *arg) nic_frame_t *frame = nic_alloc_frame(nic, len - sizeof(*hdr)); if (frame) { memcpy(frame->data, &hdr[1], len - sizeof(*hdr)); + pcapdump_packet(nic_get_pcap_iface(nic), frame->data, frame->size); nic_received_frame(nic, frame); } else { ddf_msg(LVL_WARN, @@ -356,7 +358,7 @@ static void virtio_net_send(nic_t *nic, void *data, size_t size) /* Copy packet data into the buffer just past the header */ memcpy(&hdr[1], data, size); - + pcapdump_packet(nic_get_pcap_iface(nic), data, size); /* * Set the descriptor, put it into the virtqueue and notify the device */ @@ -436,6 +438,15 @@ static errno_t virtio_net_dev_add(ddf_dev_t *dev) ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", ddf_dev_get_name(dev)); + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic)); + + if (pcap_rc != EOK) { + printf("Failed creating pcapdump port\n"); + } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) + goto unbind; + return EOK; unbind: From 91042127f2ad6c1d235bbb43f9bc5d97affb41c5 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Mon, 4 Mar 2024 09:47:50 +0100 Subject: [PATCH 05/39] long name without mapping ok --- uspace/app/pcapctl/main.c | 48 +++++++++++++----- uspace/lib/pcap/include/pcapctl_dump.h | 3 +- uspace/lib/pcap/include/pcapdump_iface.h | 3 +- uspace/lib/pcap/src/pcapctl_dump.c | 63 +++++++++++++++++++----- 4 files changed, 91 insertions(+), 26 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 4c81889bb5..2a82cc80fd 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -49,21 +49,38 @@ pcapctl_sess_t sess; -static void start_dumping(const char *name) +static errno_t start_dumping(const char *drv_name, const char *name) { + errno_t rc = pcapctl_dump_init(&sess, drv_name); + if (rc != EOK) { + //fprintf(stderr, "Error initializing ...\n"); + return 1; + } pcapctl_dump_start(name, &sess); + return EOK; } -static void stop_dumping(void) +/** Session might */ +static errno_t stop_dumping(const char *drv_name) { + errno_t rc = pcapctl_dump_init(&sess, drv_name); + if (rc != EOK) { + fprintf(stderr, "Error initializing ...\n"); + return 1; + } pcapctl_dump_stop(&sess); + return EOK; +} + +static void list_devs(void) { + pcapctl_list(); } static void usage(const char *progname) { fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s start : Packets will be written to \n", progname); - fprintf(stderr, " %s stop: Dumping stops\n", progname); + fprintf(stderr, " %s start : Packets dumped from will be written to \n", progname); + fprintf(stderr, " %s stop : Dumping from stops\n", progname); } @@ -73,19 +90,24 @@ int main(int argc, char *argv[]) usage(argv[0]); return 1; } else { - errno_t rc = pcapctl_dump_init(&sess); - if (rc != EOK) { - fprintf(stderr, "Error initializing ...\n"); - return 1; - } - if (str_cmp(argv[1], "start") == 0) { - if (argc != 3) { + if (str_cmp(argv[1], "--help") == 0 || str_cmp(argv[1], "-h") == 0) { + usage(argv[0]); + return 0; + } else if (str_cmp(argv[1], "list") == 0) { + list_devs(); + return 0; + } else if (str_cmp(argv[1], "start") == 0) { + if (argc != 4) { usage(argv[0]); return 1; } - start_dumping(argv[2]); + start_dumping(argv[2], argv[3]); } else if (str_cmp(argv[1], "stop") == 0) { - stop_dumping(); + if (argc != 3) { + usage(argv[0]); + return 1; + } + stop_dumping(argv[2]); fprintf(stdout, "Dumping was stopped\n"); return EOK; } else { diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h index 0655c80814..09e926f386 100644 --- a/uspace/lib/pcap/include/pcapctl_dump.h +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -48,9 +48,10 @@ typedef struct { async_sess_t *sess; } pcapctl_sess_t; -extern errno_t pcapctl_dump_init(pcapctl_sess_t *); +extern errno_t pcapctl_dump_init(pcapctl_sess_t *, const char *); extern errno_t pcapctl_dump_start(const char *, pcapctl_sess_t *); extern errno_t pcapctl_dump_stop(pcapctl_sess_t *); +extern errno_t pcapctl_list(void); #endif diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_iface.h index 8192dc0fa2..8d64211652 100644 --- a/uspace/lib/pcap/include/pcapdump_iface.h +++ b/uspace/lib/pcap/include/pcapdump_iface.h @@ -43,7 +43,8 @@ typedef enum { PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, - PCAP_CONTROL_SET_STOP + PCAP_CONTROL_SET_STOP, + PCAP_CONTROL_GET_NAME } pcap_request_t; extern errno_t pcapdump_init(pcap_iface_t *); diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index aa2ce69b6a..be842065a1 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -50,10 +50,8 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -errno_t pcapctl_dump_init(pcapctl_sess_t *sess) -{ +static errno_t pcapctl_cat_has_drv(const char *drv_name, service_id_t* svc) { errno_t rc; - char *svc_name; category_id_t pcap_cat; size_t count; service_id_t *pcap_svcs = NULL; @@ -69,25 +67,68 @@ errno_t pcapctl_dump_init(pcapctl_sess_t *sess) printf("Error resolving list of pcap services.\n"); return rc; } - assert((count > 0) && "TODO: not implemented when no services are available\n"); - rc = loc_service_get_name(pcap_svcs[0], &svc_name); // Note: for now [0], because only one driver is in pcap_svcs and there is no need to find particular + for (unsigned i = 0; i < count; ++i) { + char *name = NULL; + loc_service_get_name(pcap_svcs[i], &name); + if (!str_cmp(drv_name, name)) { + *svc = pcap_svcs[i]; + return EOK; + } + } + free(pcap_svcs); + return 1; +} + +extern 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) { - printf("Error getting service name.\n"); - goto error; + printf("Error resolving category 'pcap'.\n"); + return rc; } - printf("Using device: %s\n", svc_name); - async_sess_t *new_session = loc_service_connect(pcap_svcs[0], INTERFACE_PCAP_CONTROL, 0); + rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); + if (rc != EOK) { + printf("Error resolving list of pcap services.\n"); + return rc; + } + + assert((count > 0) && "TODO: not implemented when no services are available\n"); + + fprintf(stdout, "Drivers:\n"); + for (unsigned i = 0; i < count; ++i) { + char *name = NULL; + loc_service_get_name(pcap_svcs[i], &name); + + fprintf(stdout, "driver: %s\n", name); + } + return EOK; +} + +errno_t pcapctl_dump_init(pcapctl_sess_t *sess, const char *drv_name) +{ + errno_t rc; + service_id_t svc; + rc = pcapctl_cat_has_drv(drv_name, &svc); + if (rc != EOK) { + fprintf(stderr, "No such driver was found.\n"); + return 1; + } + async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { - printf("Error connecting to service.\n"); + fprintf(stderr, "Error connecting to service.\n"); rc = EREFUSED; goto error; } sess->sess = new_session; rc = EOK; error: - free(pcap_svcs); return rc; } From 9ce251c74d72d98ab1ef0bb0ad1918f2d725a836 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Mar 2024 10:38:44 +0100 Subject: [PATCH 06/39] moved to nic, fixed all except addressing --- uspace/app/pcapctl/main.c | 7 ------- uspace/drv/nic/e1k/e1k.c | 14 ++++---------- uspace/drv/nic/virtio-net/virtio-net.c | 16 ++++++---------- uspace/lib/nic/include/nic.h | 3 +-- uspace/lib/nic/src/nic_driver.c | 8 ++++++++ uspace/lib/nic/src/nic_impl.c | 3 ++- uspace/lib/pcap/include/pcap.h | 2 +- uspace/lib/pcap/src/pcap.c | 8 -------- uspace/lib/pcap/src/pcap_iface.c | 2 +- 9 files changed, 23 insertions(+), 40 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 2a82cc80fd..716a1c597b 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -40,13 +40,6 @@ #define NAME "pcapctl" -#define LOGGER(msg, ...) \ - fprintf(stderr, \ - "[PCAP %s:%d]: " msg "\n", \ - __FILE__, __LINE__, \ - ##__VA_ARGS__\ - ) - pcapctl_sess_t sess; static errno_t start_dumping(const char *drv_name, const char *name) diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index 09fb64f13c..454819ede9 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -48,10 +48,9 @@ #include #include #include +#include #include "e1k.h" -#include "pcapdump_iface.h" -#include "pcap_iface.h" #define NAME "e1k" #define E1000_DEFAULT_INTERRUPT_INTERVAL_USEC 250 @@ -1191,7 +1190,6 @@ static void e1000_receive_frames(nic_t *nic) nic_frame_t *frame = nic_alloc_frame(nic, frame_size); if (frame != NULL) { memcpy(frame->data, e1000->rx_frame_virt[next_tail], frame_size); - pcapdump_packet(nic_get_pcap_iface(nic), frame->data, frame->size); nic_received_frame(nic, frame); } else { @@ -2206,14 +2204,11 @@ errno_t e1000_dev_add(ddf_dev_t *dev) if (rc != EOK) goto err_add_to_cat; - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic)); - - if (pcap_rc != EOK) { - printf("Failed creating pcapdump port\n"); - } rc = ddf_fun_add_to_category(fun, "pcap"); - if (rc != EOK) + if (rc != EOK) { + ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); goto err_add_to_cat; + } return EOK; @@ -2378,7 +2373,6 @@ static void e1000_send_frame(nic_t *nic, void *data, size_t size) } memcpy(e1000->tx_frame_virt[tdt], data, size); - pcapdump_packet(nic_get_pcap_iface(nic), data, size); tx_descriptor_addr->phys_addr = PTR_TO_U64(e1000->tx_frame_phys[tdt]); tx_descriptor_addr->length = size; diff --git a/uspace/drv/nic/virtio-net/virtio-net.c b/uspace/drv/nic/virtio-net/virtio-net.c index 8bfe935e22..010bf1fa8c 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.c +++ b/uspace/drv/nic/virtio-net/virtio-net.c @@ -42,8 +42,8 @@ #include #include -#include "pcapdump_iface.h" -#include "pcap_iface.h" +#include + #define NAME "virtio-net" #define VIRTIO_NET_NUM_QUEUES 3 @@ -97,7 +97,6 @@ static void virtio_net_irq_handler(ipc_call_t *icall, void *arg) nic_frame_t *frame = nic_alloc_frame(nic, len - sizeof(*hdr)); if (frame) { memcpy(frame->data, &hdr[1], len - sizeof(*hdr)); - pcapdump_packet(nic_get_pcap_iface(nic), frame->data, frame->size); nic_received_frame(nic, frame); } else { ddf_msg(LVL_WARN, @@ -358,7 +357,7 @@ static void virtio_net_send(nic_t *nic, void *data, size_t size) /* Copy packet data into the buffer just past the header */ memcpy(&hdr[1], data, size); - pcapdump_packet(nic_get_pcap_iface(nic), data, size); + /* * Set the descriptor, put it into the virtqueue and notify the device */ @@ -438,14 +437,11 @@ static errno_t virtio_net_dev_add(ddf_dev_t *dev) ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", ddf_dev_get_name(dev)); - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic)); - - if (pcap_rc != EOK) { - printf("Failed creating pcapdump port\n"); - } rc = ddf_fun_add_to_category(fun, "pcap"); - if (rc != EOK) + if (rc != EOK) { + ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); goto unbind; + } return EOK; diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index d751e788ed..470f9930f5 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -43,8 +43,7 @@ #include #include #include - -#include "pcap_iface.h" +#include #define DEVICE_CATEGORY_NIC "nic" diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index ea1878efde..9d670672e1 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "nic_driver.h" #include "nic_ev.h" @@ -521,6 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ + pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); fibril_rwlock_read_lock(&nic_data->rxc_lock); nic_frame_type_t frame_type; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -559,6 +561,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) } fibril_rwlock_write_unlock(&nic_data->stats_lock); } + //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); nic_release_frame(nic_data, frame); } @@ -646,6 +649,11 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) return NULL; nic_data->dev = device; + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + + if (pcap_rc != EOK) { + printf("Failed creating pcapdump port\n"); + } return nic_data; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index d3595471be..e6285ab8bd 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "nic_driver.h" #include "nic_ev.h" #include "nic_impl.h" @@ -178,7 +179,7 @@ errno_t nic_send_frame_impl(ddf_fun_t *fun, void *data, size_t size) fibril_rwlock_read_unlock(&nic_data->main_lock); return EBUSY; } - + pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); nic_data->send_frame(nic_data, data, size); fibril_rwlock_read_unlock(&nic_data->main_lock); return EOK; diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index c9cf50f3af..1e8089fbb8 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -63,7 +63,7 @@ typedef struct { uint32_t reserved2; uint32_t snaplen; uint32_t additional; /** The LinkType and additional information field is in the form */ -} __attribute__((packed, aligned(4))) pcap_file_header_t; +} pcap_file_header_t; typedef struct pcap_packet_header { uint32_t seconds_stamp; diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 1bd6e58ffa..cf8c791c6f 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -35,13 +35,6 @@ * @brief Headers and functions for .pcap file and packets to be dumped */ -#define LOGGER(msg, ...) \ - fprintf(stderr, \ - "[PCAP %s:%d]: " msg "\n", \ - __FILE__, __LINE__, \ - ##__VA_ARGS__\ - ) - #include "pcap.h" /** Set time in seconds and microseconds for the packet header . @@ -107,7 +100,6 @@ errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) writer->data = fopen(filename, "a"); if (writer->data == NULL) { rc = EINVAL; - LOGGER("Failed to create %s: %s.", filename, str_error(rc)); return rc; } pcap_writer_add_header(writer); diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c index b160f676b3..3618eaddbf 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -81,7 +81,7 @@ void pcap_add_packet(const void *data, size_t size) pcap_writer_add_packet(&pcap_writer, data, size); } -void pcap_close_file() +void pcap_close_file(void) { pcap_writer.ops->close(&pcap_writer); pcap_writer.data = NULL; From 8765039294854af1b0b6929cb0be35078cc68207 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Mar 2024 12:40:30 +0100 Subject: [PATCH 07/39] ugly address --- uspace/app/pcapctl/main.c | 21 ++++++++------- uspace/lib/nic/include/nic_driver.h | 2 +- uspace/lib/nic/src/nic_driver.c | 2 +- uspace/lib/pcap/include/pcapctl_dump.h | 4 ++- uspace/lib/pcap/src/pcapctl_dump.c | 36 +++++++++++++++++--------- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 716a1c597b..281dca2712 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -40,28 +40,29 @@ #define NAME "pcapctl" -pcapctl_sess_t sess; +pcapctl_sess_t* sess; -static errno_t start_dumping(const char *drv_name, const char *name) +static errno_t start_dumping(const char *svc_name, const char *name) { - errno_t rc = pcapctl_dump_init(&sess, drv_name); + errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { - //fprintf(stderr, "Error initializing ...\n"); return 1; } - pcapctl_dump_start(name, &sess); + pcapctl_dump_start(name, sess); + pcapctl_dump_close(sess); return EOK; } /** Session might */ -static errno_t stop_dumping(const char *drv_name) +static errno_t stop_dumping(const char *svc_name) { - errno_t rc = pcapctl_dump_init(&sess, drv_name); + errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { - fprintf(stderr, "Error initializing ...\n"); return 1; } - pcapctl_dump_stop(&sess); + + pcapctl_dump_stop(sess); + pcapctl_dump_close(sess); return EOK; } @@ -72,9 +73,9 @@ static void list_devs(void) { static void usage(const char *progname) { fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s list: List of devices\n", progname); fprintf(stderr, " %s start : Packets dumped from will be written to \n", progname); fprintf(stderr, " %s stop : Dumping from stops\n", progname); - } int main(int argc, char *argv[]) diff --git a/uspace/lib/nic/include/nic_driver.h b/uspace/lib/nic/include/nic_driver.h index 378817b5b4..f99e5a0746 100644 --- a/uspace/lib/nic/include/nic_driver.h +++ b/uspace/lib/nic/include/nic_driver.h @@ -45,11 +45,11 @@ #include #include #include +#include #include "nic.h" #include "nic_rx_control.h" #include "nic_wol_virtues.h" -#include "pcap/include/pcapdump_iface.h" struct sw_poll_info { fid_t fibril; diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 9d670672e1..1437b86a27 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -649,8 +649,8 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) return NULL; nic_data->dev = device; - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); if (pcap_rc != EOK) { printf("Failed creating pcapdump port\n"); } diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h index 09e926f386..e1241803f3 100644 --- a/uspace/lib/pcap/include/pcapctl_dump.h +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -48,11 +48,13 @@ typedef struct { async_sess_t *sess; } pcapctl_sess_t; -extern errno_t pcapctl_dump_init(pcapctl_sess_t *, const char *); +extern errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess); +extern errno_t pcapctl_dump_close(pcapctl_sess_t *sess); extern errno_t pcapctl_dump_start(const char *, pcapctl_sess_t *); extern errno_t pcapctl_dump_stop(pcapctl_sess_t *); extern errno_t pcapctl_list(void); + #endif /** @} diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index be842065a1..df524badfd 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -50,7 +50,7 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -static errno_t pcapctl_cat_has_drv(const char *drv_name, service_id_t* svc) { +static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t* svc) { errno_t rc; category_id_t pcap_cat; size_t count; @@ -89,36 +89,39 @@ extern errno_t pcapctl_list(void) { rc = loc_category_get_id("pcap", &pcap_cat, 0); if (rc != EOK) { - printf("Error resolving category 'pcap'.\n"); + printf("Error resolving category pcap.\n"); return rc; } rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { printf("Error resolving list of pcap services.\n"); + free(pcap_svcs); return rc; } - assert((count > 0) && "TODO: not implemented when no services are available\n"); - - fprintf(stdout, "Drivers:\n"); + fprintf(stdout, "Services:\n"); for (unsigned i = 0; i < count; ++i) { char *name = NULL; loc_service_get_name(pcap_svcs[i], &name); - - fprintf(stdout, "driver: %s\n", name); + fprintf(stdout, "service: %s\n", name); } + free(pcap_svcs); return EOK; } -errno_t pcapctl_dump_init(pcapctl_sess_t *sess, const char *drv_name) + +errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess) { errno_t rc; service_id_t svc; - rc = pcapctl_cat_has_drv(drv_name, &svc); + pcapctl_sess_t *sess = calloc(1, sizeof(pcapctl_sess_t)); + if (sess == NULL) + return ENOMEM; + + rc = pcapctl_cat_get_svc(svcname, &svc); if (rc != EOK) { - fprintf(stderr, "No such driver was found.\n"); - return 1; + goto error; } async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { @@ -126,12 +129,21 @@ errno_t pcapctl_dump_init(pcapctl_sess_t *sess, const char *drv_name) rc = EREFUSED; goto error; } + sess->sess = new_session; - rc = EOK; + *rsess = sess; + return EOK; error: + pcapctl_dump_close(sess); return rc; } +errno_t pcapctl_dump_close(pcapctl_sess_t *sess) +{ + free(sess); + return EOK; +} + /** Starting a new session for pcapctl * * @param name Name of the file to dump packets to From 7924f82ec101a261376bacff95db36eaed3050fa Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Tue, 19 Mar 2024 16:15:50 +0100 Subject: [PATCH 08/39] choose nic: without --device|-d --- uspace/app/pcapctl/main.c | 61 +++++++++++++++------- uspace/lib/pcap/src/pcapctl_dump.c | 81 ++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 281dca2712..39814e5e95 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -40,14 +40,16 @@ #define NAME "pcapctl" -pcapctl_sess_t* sess; +//pcapctl_sess_t* sess = NULL; static errno_t start_dumping(const char *svc_name, const char *name) { + pcapctl_sess_t* sess = NULL; errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { return 1; } + pcapctl_dump_start(name, sess); pcapctl_dump_close(sess); return EOK; @@ -56,11 +58,11 @@ static errno_t start_dumping(const char *svc_name, const char *name) /** Session might */ static errno_t stop_dumping(const char *svc_name) { + pcapctl_sess_t* sess = NULL; errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { return 1; } - pcapctl_dump_stop(sess); pcapctl_dump_close(sess); return EOK; @@ -70,42 +72,65 @@ static void list_devs(void) { pcapctl_list(); } -static void usage(const char *progname) +static void usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s list: List of devices\n", progname); - fprintf(stderr, " %s start : Packets dumped from will be written to \n", progname); - fprintf(stderr, " %s stop : Dumping from stops\n", progname); + printf("Usage:\n" + NAME " list \n" + "\tList of devices\n" + NAME " start --device= | -d \n" + "\tPackets dumped from device will be written to \n" + NAME " stop --device= | -d \n" + "\tDumping from stops\n" + NAME " start \n" + "\tPackets dumped from the 1st device from the list will be written to \n" + NAME " --help | -h\n" + "\tShow this application help.\n"); } int main(int argc, char *argv[]) { if (argc < 2) { - usage(argv[0]); + usage(); return 1; } else { + /** help*/ if (str_cmp(argv[1], "--help") == 0 || str_cmp(argv[1], "-h") == 0) { - usage(argv[0]); + usage(); return 0; + /** list*/ } else if (str_cmp(argv[1], "list") == 0) { list_devs(); return 0; + /** start with/out devnum */ } else if (str_cmp(argv[1], "start") == 0) { - if (argc != 4) { - usage(argv[0]); + if (argc == 3) { + start_dumping((char *)"0", argv[2]); + return 0; + } + else if (argc == 4) { + start_dumping(argv[2], argv[3]); + return 0; + } else { + usage(); return 1; } - start_dumping(argv[2], argv[3]); + /** Stop with/out devnum */ } else if (str_cmp(argv[1], "stop") == 0) { - if (argc != 3) { - usage(argv[0]); + if (argc == 2) { + stop_dumping((char *)"0"); + fprintf(stdout, "Dumping was stopped\n"); + return 0; + } + else if (argc == 3) { + + stop_dumping(argv[2]); + fprintf(stdout, "Dumping was stopped\n"); + } else { + usage(); return 1; } - stop_dumping(argv[2]); - fprintf(stdout, "Dumping was stopped\n"); - return EOK; } else { - usage(argv[0]); + usage(); return 1; } } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index df524badfd..5f4f1c51e8 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -37,10 +37,27 @@ #include #include #include - +#include +#include #include "pcapctl_dump.h" #include "pcapdump_iface.h" +//static service_id_t *pcap_svcs = NULL; ?? + +static errno_t str2num(const char* str, size_t* number) { + size_t num = 0; + if (*str == 0) + return ELIMIT; + if (!isdigit(*str)) + return EINVAL; + while (isdigit(*str)) { + num = num * 10 + ((*str) - '0'); + str++; + } + + *number = num; + return EOK; +} /** Finish an async exchange on the pcapctl session * * @param exch Exchange to be finished @@ -104,14 +121,60 @@ extern errno_t pcapctl_list(void) { for (unsigned i = 0; i < count; ++i) { char *name = NULL; loc_service_get_name(pcap_svcs[i], &name); - fprintf(stdout, "service: %s\n", name); + fprintf(stdout, "%d. %s\n", i, name); } free(pcap_svcs); return EOK; } -errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess) +static errno_t pcapctl_get_name_from_number(const char* svcnum, const char** svcname) { + + 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) { + printf("Error resolving category pcap.\n"); + return rc; + } + size_t num; + rc = str2num(svcnum, &num); + if (rc != EOK) { + printf("Error converting char* to size_t.\n"); + free(pcap_svcs); + return rc; + } + + rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); + if (rc != EOK) { + printf("Error resolving list of pcap services.\n"); + free(pcap_svcs); + return rc; + } + + if (num >= count) { + printf("Error finding device: no device with such number\n"); + free(pcap_svcs); + return EINVAL; + } + char *name = NULL; + rc = loc_service_get_name(pcap_svcs[num], &name); + if (rc != EOK) { + printf("Error resolving name"); + } + + *svcname = name; + printf("%s\n", *svcname); + return EOK; +} + +/** + * + */ +errno_t pcapctl_dump_open(const char *svcnum, pcapctl_sess_t **rsess) { errno_t rc; service_id_t svc; @@ -119,6 +182,14 @@ errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; + + const char* svcname; + + rc = pcapctl_get_name_from_number(svcnum, &svcname); + if (rc != EOK) { + return rc; + } + rc = pcapctl_cat_get_svc(svcname, &svc); if (rc != EOK) { goto error; @@ -129,7 +200,6 @@ errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess) rc = EREFUSED; goto error; } - sess->sess = new_session; *rsess = sess; return EOK; @@ -138,6 +208,9 @@ errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess) return rc; } +/** + * + */ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) { free(sess); From 2ebbe9ba6bf8e1d1f1d39270fe8a4831f8dc9d9e Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Wed, 20 Mar 2024 18:06:29 +0100 Subject: [PATCH 09/39] nic, drvs, pcapctl --- uspace/app/pcapctl/main.c | 42 +++++++++++++------------- uspace/drv/nic/e1k/e1k.c | 24 +++++++++------ uspace/drv/nic/ne2k/ne2k.c | 7 +++++ uspace/drv/nic/rtl8139/driver.c | 7 +++++ uspace/lib/nic/include/nic.h | 2 ++ uspace/lib/nic/src/nic_impl.c | 19 ++++++++++++ uspace/lib/pcap/include/pcapctl_dump.h | 1 - uspace/lib/pcap/src/pcapctl_dump.c | 20 ++++++------ 8 files changed, 80 insertions(+), 42 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 39814e5e95..94b2e796f8 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -39,12 +39,13 @@ #include "pcapctl_dump.h" #define NAME "pcapctl" +#define DEFAULT_DEV_NUM 0 //pcapctl_sess_t* sess = NULL; static errno_t start_dumping(const char *svc_name, const char *name) { - pcapctl_sess_t* sess = NULL; + pcapctl_sess_t *sess = NULL; errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { return 1; @@ -58,7 +59,7 @@ static errno_t start_dumping(const char *svc_name, const char *name) /** Session might */ static errno_t stop_dumping(const char *svc_name) { - pcapctl_sess_t* sess = NULL; + pcapctl_sess_t *sess = NULL; errno_t rc = pcapctl_dump_open(svc_name, &sess); if (rc != EOK) { return 1; @@ -68,23 +69,24 @@ static errno_t stop_dumping(const char *svc_name) return EOK; } -static void list_devs(void) { +static void list_devs(void) +{ pcapctl_list(); } static void usage(void) { printf("Usage:\n" - NAME " list \n" - "\tList of devices\n" - NAME " start --device= | -d \n" - "\tPackets dumped from device will be written to \n" - NAME " stop --device= | -d \n" - "\tDumping from stops\n" - NAME " start \n" - "\tPackets dumped from the 1st device from the list will be written to \n" - NAME " --help | -h\n" - "\tShow this application help.\n"); + NAME " list \n" + "\tList of devices\n" + NAME " start --device= | -d \n" + "\tPackets dumped from device will be written to \n" + NAME " stop --device= | -d \n" + "\tDumping from stops\n" + NAME " start \n" + "\tPackets dumped from the 1st device from the list will be written to \n" + NAME " --help | -h\n" + "\tShow this application help.\n"); } int main(int argc, char *argv[]) @@ -93,35 +95,33 @@ int main(int argc, char *argv[]) usage(); return 1; } else { - /** help*/ + /** help */ if (str_cmp(argv[1], "--help") == 0 || str_cmp(argv[1], "-h") == 0) { usage(); return 0; - /** list*/ + /** list */ } else if (str_cmp(argv[1], "list") == 0) { list_devs(); return 0; - /** start with/out devnum */ + /** start with/out devnum */ } else if (str_cmp(argv[1], "start") == 0) { if (argc == 3) { start_dumping((char *)"0", argv[2]); return 0; - } - else if (argc == 4) { + } else if (argc == 4) { start_dumping(argv[2], argv[3]); return 0; } else { usage(); return 1; } - /** Stop with/out devnum */ + /** Stop with/out devnum */ } else if (str_cmp(argv[1], "stop") == 0) { if (argc == 2) { stop_dumping((char *)"0"); fprintf(stdout, "Dumping was stopped\n"); return 0; - } - else if (argc == 3) { + } else if (argc == 3) { stop_dumping(argv[2]); fprintf(stdout, "Dumping was stopped\n"); diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index 454819ede9..5a65bc63d3 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -2200,20 +2200,24 @@ errno_t e1000_dev_add(ddf_dev_t *dev) if (rc != EOK) goto err_fun_bind; - rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); - if (rc != EOK) - goto err_add_to_cat; - - rc = ddf_fun_add_to_category(fun, "pcap"); + // rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); + // if (rc != EOK) + // goto err_add_to_cat; + + // rc = ddf_fun_add_to_category(fun, "pcap"); + // if (rc != EOK) { + // ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); + // goto err_add_to_cat; + // } + rc = nic_fun_add_to_cats(fun); if (rc != EOK) { - ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - goto err_add_to_cat; + ddf_msg(LVL_ERROR, "Failed adding function to categories"); + return rc; } - return EOK; -err_add_to_cat: - ddf_fun_unbind(fun); + // err_add_to_cat: + // ddf_fun_unbind(fun); err_fun_bind: err_rx_structure: e1000_uninitialize_rx_structure(nic); diff --git a/uspace/drv/nic/ne2k/ne2k.c b/uspace/drv/nic/ne2k/ne2k.c index 7f7cec7b78..9d71476cc9 100644 --- a/uspace/drv/nic/ne2k/ne2k.c +++ b/uspace/drv/nic/ne2k/ne2k.c @@ -454,6 +454,13 @@ static errno_t ne2k_dev_add(ddf_dev_t *dev) ddf_fun_destroy(fun); return rc; } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) { + //ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); + ddf_fun_unbind(fun); + ddf_fun_destroy(fun); + return rc; + } return EOK; } diff --git a/uspace/drv/nic/rtl8139/driver.c b/uspace/drv/nic/rtl8139/driver.c index 659dcc8c38..4a2bc391f9 100644 --- a/uspace/drv/nic/rtl8139/driver.c +++ b/uspace/drv/nic/rtl8139/driver.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "defs.h" #include "driver.h" @@ -1310,6 +1311,12 @@ errno_t rtl8139_dev_add(ddf_dev_t *dev) goto err_fun_bind; } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) { + ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); + goto err_fun_bind; + } + ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", ddf_dev_get_name(dev)); diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index 470f9930f5..9fb0b5637f 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -281,6 +281,8 @@ extern void nic_sw_period_stop(nic_t *); /* pcapdump interface */ extern pcap_iface_t *nic_get_pcap_iface(nic_t *); +extern errno_t nic_fun_add_to_cats(ddf_fun_t *fun); + #endif // __NIC_H__ /** @} diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index e6285ab8bd..d894d63f69 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -843,5 +843,24 @@ void nic_close_impl(ddf_fun_t *fun) { } +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) + goto err_add_to_cat; + + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) { + //ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); + goto err_add_to_cat; + } + return EOK; + +err_add_to_cat: + ddf_fun_unbind(fun); + return rc; +} + /** @} */ diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h index e1241803f3..e3a7d5dce6 100644 --- a/uspace/lib/pcap/include/pcapctl_dump.h +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -54,7 +54,6 @@ extern errno_t pcapctl_dump_start(const char *, pcapctl_sess_t *); extern errno_t pcapctl_dump_stop(pcapctl_sess_t *); extern errno_t pcapctl_list(void); - #endif /** @} diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 5f4f1c51e8..5e117a0f5f 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -44,7 +44,8 @@ //static service_id_t *pcap_svcs = NULL; ?? -static errno_t str2num(const char* str, size_t* number) { +static errno_t str2num(const char *str, size_t *number) +{ size_t num = 0; if (*str == 0) return ELIMIT; @@ -67,7 +68,8 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t* svc) { +static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t *svc) +{ errno_t rc; category_id_t pcap_cat; size_t count; @@ -97,8 +99,8 @@ static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t* svc) { return 1; } -extern errno_t pcapctl_list(void) { - +errno_t pcapctl_list(void) +{ errno_t rc; category_id_t pcap_cat; size_t count; @@ -117,7 +119,7 @@ extern errno_t pcapctl_list(void) { return rc; } - fprintf(stdout, "Services:\n"); + fprintf(stdout, "Devices:\n"); for (unsigned i = 0; i < count; ++i) { char *name = NULL; loc_service_get_name(pcap_svcs[i], &name); @@ -127,9 +129,8 @@ extern errno_t pcapctl_list(void) { return EOK; } - -static errno_t pcapctl_get_name_from_number(const char* svcnum, const char** svcname) { - +static errno_t pcapctl_get_name_from_number(const char *svcnum, const char **svcname) +{ errno_t rc; category_id_t pcap_cat; size_t count; @@ -182,8 +183,7 @@ errno_t pcapctl_dump_open(const char *svcnum, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - - const char* svcname; + const char *svcname; rc = pcapctl_get_name_from_number(svcnum, &svcname); if (rc != EOK) { From 9e26790315ede55ef39bed61bf7491e61e392b37 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 7 Apr 2024 11:32:59 +0200 Subject: [PATCH 10/39] app: read options ok --- uspace/app/pcapctl/main.c | 111 +++++++++++++++---------- uspace/lib/pcap/include/pcapctl_dump.h | 3 +- uspace/lib/pcap/src/pcapctl_dump.c | 90 ++++++-------------- 3 files changed, 92 insertions(+), 112 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 94b2e796f8..c004caf420 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -35,18 +35,18 @@ #include #include #include +#include +#include #include "pcapctl_dump.h" #define NAME "pcapctl" #define DEFAULT_DEV_NUM 0 -//pcapctl_sess_t* sess = NULL; - -static errno_t start_dumping(const char *svc_name, const char *name) +static errno_t start_dumping(int *dev_number, const char *name) { pcapctl_sess_t *sess = NULL; - errno_t rc = pcapctl_dump_open(svc_name, &sess); + errno_t rc = pcapctl_dump_open(dev_number, &sess); if (rc != EOK) { return 1; } @@ -56,11 +56,10 @@ static errno_t start_dumping(const char *svc_name, const char *name) return EOK; } -/** Session might */ -static errno_t stop_dumping(const char *svc_name) +static errno_t stop_dumping(int *dev_number) { pcapctl_sess_t *sess = NULL; - errno_t rc = pcapctl_dump_open(svc_name, &sess); + errno_t rc = pcapctl_dump_open(dev_number, &sess); if (rc != EOK) { return 1; } @@ -74,12 +73,25 @@ static void list_devs(void) pcapctl_list(); } +/** + * Array of supported commandline options + */ +static const struct option opts[] = { + { "device", required_argument, 0, 'd' }, + { "list", no_argument, 0, 'l' }, + { "help", no_argument, 0, 'h' }, + { "outfile", required_argument, 0, 'f' }, + { "start", no_argument, 0, 'r' }, + { "stop", no_argument, 0, 't' }, + { 0, 0, 0, 0 } +}; + static void usage(void) { printf("Usage:\n" - NAME " list \n" + NAME " --list | -l \n" "\tList of devices\n" - NAME " start --device= | -d \n" + NAME " start --device= | -d --outfile | -f \n" "\tPackets dumped from device will be written to \n" NAME " stop --device= | -d \n" "\tDumping from stops\n" @@ -91,49 +103,56 @@ static void usage(void) int main(int argc, char *argv[]) { - if (argc < 2) { + bool start = false; + bool stop = false; + int dev_number = DEFAULT_DEV_NUM; + const char *output_file_name; + int idx = 0; + int ret = 0; + if (argc == 1) { usage(); - return 1; - } else { - /** help */ - if (str_cmp(argv[1], "--help") == 0 || str_cmp(argv[1], "-h") == 0) { - usage(); - return 0; - /** list */ - } else if (str_cmp(argv[1], "list") == 0) { - list_devs(); - return 0; - /** start with/out devnum */ - } else if (str_cmp(argv[1], "start") == 0) { - if (argc == 3) { - start_dumping((char *)"0", argv[2]); - return 0; - } else if (argc == 4) { - start_dumping(argv[2], argv[3]); - return 0; - } else { - usage(); - return 1; - } - /** Stop with/out devnum */ - } else if (str_cmp(argv[1], "stop") == 0) { - if (argc == 2) { - stop_dumping((char *)"0"); - fprintf(stdout, "Dumping was stopped\n"); - return 0; - } else if (argc == 3) { - - stop_dumping(argv[2]); - fprintf(stdout, "Dumping was stopped\n"); - } else { - usage(); + return 0; + } + while (ret != -1) { + ret = getopt_long(argc, argv, "d:lhf:rt", opts, &idx); + switch (ret) { + case 'd': + char *rest; + long result = strtol(optarg, &rest, 10); + dev_number = (int)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; } - } else { + break; + case 'l': + list_devs(); + return 0; + case 'h': usage(); - return 1; + return 0; + case 'f': + output_file_name = optarg; + break; + case 'r': + start = true; + break; + case 't': + stop = true; + break; } } + + printf("%s: HelenOS Packet Dumping utility: device - %d\n", NAME, dev_number); + + if (start) { + // start with dev number and optional..name + start_dumping(&dev_number, output_file_name); + } else if (stop) { + //stop with dev number + stop_dumping(&dev_number); + } return 0; } diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h index e3a7d5dce6..c15c3b66bc 100644 --- a/uspace/lib/pcap/include/pcapctl_dump.h +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -48,11 +48,12 @@ typedef struct { async_sess_t *sess; } pcapctl_sess_t; -extern errno_t pcapctl_dump_open(const char *svcname, pcapctl_sess_t **rsess); +extern errno_t pcapctl_dump_open(int *, pcapctl_sess_t **rsess); extern errno_t pcapctl_dump_close(pcapctl_sess_t *sess); extern errno_t pcapctl_dump_start(const char *, 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 *); #endif diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 5e117a0f5f..384a4e31ed 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -42,23 +42,6 @@ #include "pcapctl_dump.h" #include "pcapdump_iface.h" -//static service_id_t *pcap_svcs = NULL; ?? - -static errno_t str2num(const char *str, size_t *number) -{ - size_t num = 0; - if (*str == 0) - return ELIMIT; - if (!isdigit(*str)) - return EINVAL; - while (isdigit(*str)) { - num = num * 10 + ((*str) - '0'); - str++; - } - - *number = num; - return EOK; -} /** Finish an async exchange on the pcapctl session * * @param exch Exchange to be finished @@ -68,7 +51,7 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t *svc) +static errno_t pcapctl_cat_get_svc(int *index, service_id_t *svc) { errno_t rc; category_id_t pcap_cat; @@ -84,22 +67,19 @@ static errno_t pcapctl_cat_get_svc(const char *drv_name, service_id_t *svc) rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { printf("Error resolving list of pcap services.\n"); + free(pcap_svcs); return rc; } - - for (unsigned i = 0; i < count; ++i) { - char *name = NULL; - loc_service_get_name(pcap_svcs[i], &name); - if (!str_cmp(drv_name, name)) { - *svc = pcap_svcs[i]; - return EOK; - } + if (*index < (int)count) { + *svc = pcap_svcs[*index]; + free(pcap_svcs); + return EOK; } - free(pcap_svcs); - return 1; + + return ENOENT; } -errno_t pcapctl_list(void) +errno_t pcapctl_is_valid_device(int *index) { errno_t rc; category_id_t pcap_cat; @@ -118,18 +98,16 @@ errno_t pcapctl_list(void) 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); + if (*index + 1 > (int)count || *index < 0) { + return EINVAL; } - free(pcap_svcs); return EOK; } -static errno_t pcapctl_get_name_from_number(const char *svcnum, const char **svcname) +/** + * + */ +errno_t pcapctl_list(void) { errno_t rc; category_id_t pcap_cat; @@ -141,13 +119,6 @@ static errno_t pcapctl_get_name_from_number(const char *svcnum, const char **svc printf("Error resolving category pcap.\n"); return rc; } - size_t num; - rc = str2num(svcnum, &num); - if (rc != EOK) { - printf("Error converting char* to size_t.\n"); - free(pcap_svcs); - return rc; - } rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { @@ -156,26 +127,20 @@ static errno_t pcapctl_get_name_from_number(const char *svcnum, const char **svc return rc; } - if (num >= count) { - printf("Error finding device: no device with such number\n"); - free(pcap_svcs); - return EINVAL; - } - char *name = NULL; - rc = loc_service_get_name(pcap_svcs[num], &name); - if (rc != EOK) { - printf("Error resolving name"); + 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); } - - *svcname = name; - printf("%s\n", *svcname); + free(pcap_svcs); return EOK; } /** * */ -errno_t pcapctl_dump_open(const char *svcnum, pcapctl_sess_t **rsess) +errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) { errno_t rc; service_id_t svc; @@ -183,17 +148,12 @@ errno_t pcapctl_dump_open(const char *svcnum, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - const char *svcname; - - rc = pcapctl_get_name_from_number(svcnum, &svcname); - if (rc != EOK) { - return rc; - } - - rc = pcapctl_cat_get_svc(svcname, &svc); + rc = pcapctl_cat_get_svc(index, &svc); if (rc != EOK) { + printf("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"); From fd6845e92178621d1d191a0f1dafc90cac816ed3 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 7 Apr 2024 11:52:09 +0200 Subject: [PATCH 11/39] fix app help --- uspace/app/pcapctl/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index c004caf420..e81bb8c0bb 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -91,12 +91,12 @@ static void usage(void) printf("Usage:\n" NAME " --list | -l \n" "\tList of devices\n" - NAME " start --device= | -d --outfile | -f \n" + NAME " --start | -r --device= | -d --outfile= | -f \n" "\tPackets dumped from device will be written to \n" - NAME " stop --device= | -d \n" + NAME " --stop | -t --device= | -d \n" "\tDumping from stops\n" - NAME " start \n" - "\tPackets dumped from the 1st device from the list will be written to \n" + NAME " --start | -s --outfile= | -f \n" + "\tPackets dumped from the 0. device from the list will be written to \n" NAME " --help | -h\n" "\tShow this application help.\n"); } From 6baa611644e6fd8dc876a1e652282a7bd7dc577a Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 7 Apr 2024 14:53:23 +0200 Subject: [PATCH 12/39] add_to_cat func in lib --- uspace/drv/nic/e1k/e1k.c | 10 +--------- uspace/drv/nic/ne2k/ne2k.c | 13 ++++--------- uspace/drv/nic/rtl8139/driver.c | 16 ++++++---------- uspace/drv/nic/rtl8169/driver.c | 11 ++++++----- uspace/drv/nic/virtio-net/virtio-net.c | 17 ++++++----------- 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index 5a65bc63d3..97b80c8b15 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -2200,18 +2200,10 @@ errno_t e1000_dev_add(ddf_dev_t *dev) if (rc != EOK) goto err_fun_bind; - // rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); - // if (rc != EOK) - // goto err_add_to_cat; - - // rc = ddf_fun_add_to_category(fun, "pcap"); - // if (rc != EOK) { - // ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - // 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; diff --git a/uspace/drv/nic/ne2k/ne2k.c b/uspace/drv/nic/ne2k/ne2k.c index 9d71476cc9..d21231f86e 100644 --- a/uspace/drv/nic/ne2k/ne2k.c +++ b/uspace/drv/nic/ne2k/ne2k.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "dp8390.h" #define NAME "ne2k" @@ -448,17 +449,10 @@ static errno_t ne2k_dev_add(ddf_dev_t *dev) return rc; } - 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; - } - rc = ddf_fun_add_to_category(fun, "pcap"); - if (rc != EOK) { - //ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - ddf_fun_unbind(fun); - ddf_fun_destroy(fun); return rc; } @@ -488,6 +482,7 @@ int main(int argc, char *argv[]) nic_driver_init(NAME); nic_driver_implement(&ne2k_driver_ops, &ne2k_dev_ops, &ne2k_nic_iface); + ddf_log_init(NAME); return ddf_driver_main(&ne2k_driver); } diff --git a/uspace/drv/nic/rtl8139/driver.c b/uspace/drv/nic/rtl8139/driver.c index 4a2bc391f9..46b5960b12 100644 --- a/uspace/drv/nic/rtl8139/driver.c +++ b/uspace/drv/nic/rtl8139/driver.c @@ -1305,16 +1305,12 @@ errno_t rtl8139_dev_add(ddf_dev_t *dev) ddf_msg(LVL_ERROR, "Failed binding device function"); goto err_fun_create; } - rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); - if (rc != EOK) { - ddf_msg(LVL_ERROR, "Failed adding function to category"); - goto err_fun_bind; - } - rc = ddf_fun_add_to_category(fun, "pcap"); + rc = nic_fun_add_to_cats(fun); if (rc != EOK) { - ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - goto err_fun_bind; + ddf_msg(LVL_ERROR, "Failed adding function to categories"); + ddf_fun_unbind(fun); + return rc; } ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", @@ -1322,8 +1318,8 @@ errno_t rtl8139_dev_add(ddf_dev_t *dev) return EOK; -err_fun_bind: - ddf_fun_unbind(fun); + // err_fun_bind: + // ddf_fun_unbind(fun); err_fun_create: ddf_fun_destroy(fun); err_srv: diff --git a/uspace/drv/nic/rtl8169/driver.c b/uspace/drv/nic/rtl8169/driver.c index 28ddc10eed..e8d580107c 100644 --- a/uspace/drv/nic/rtl8169/driver.c +++ b/uspace/drv/nic/rtl8169/driver.c @@ -457,18 +457,19 @@ static errno_t rtl8169_dev_add(ddf_dev_t *dev) 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; } ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", ddf_dev_get_name(dev)); return EOK; -err_fun_bind: - ddf_fun_unbind(fun); + // err_fun_bind: + // ddf_fun_unbind(fun); err_fun_create: ddf_fun_destroy(fun); err_srv: diff --git a/uspace/drv/nic/virtio-net/virtio-net.c b/uspace/drv/nic/virtio-net/virtio-net.c index 010bf1fa8c..5f4051b75c 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.c +++ b/uspace/drv/nic/virtio-net/virtio-net.c @@ -428,25 +428,20 @@ static errno_t virtio_net_dev_add(ddf_dev_t *dev) goto destroy; } - 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; } ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.", ddf_dev_get_name(dev)); - rc = ddf_fun_add_to_category(fun, "pcap"); - if (rc != EOK) { - ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - goto unbind; - } - return EOK; -unbind: - ddf_fun_unbind(fun); + // unbind: + // ddf_fun_unbind(fun); destroy: ddf_fun_destroy(fun); uninitialize: From 1a59a89d7984e9dcbc55f35785b93f5a1491f2dd Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 7 Apr 2024 15:05:38 +0200 Subject: [PATCH 13/39] nic_device_added_impl decl delete --- uspace/lib/nic/include/nic_impl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/uspace/lib/nic/include/nic_impl.h b/uspace/lib/nic/include/nic_impl.h index d09de679c1..72a43e121c 100644 --- a/uspace/lib/nic/include/nic_impl.h +++ b/uspace/lib/nic/include/nic_impl.h @@ -86,8 +86,6 @@ extern void nic_default_handler_impl(ddf_fun_t *dev_fun, ipc_call_t *call); extern errno_t nic_open_impl(ddf_fun_t *fun); extern void nic_close_impl(ddf_fun_t *fun); -extern void nic_device_added_impl(ddf_dev_t *dev); - #endif /** @} From 6c60a7c0c97cb007c29f70f6b1ad4efc39d98c17 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Thu, 11 Apr 2024 11:36:03 +0200 Subject: [PATCH 14/39] inetsrv dumps --- uspace/lib/nic/src/nic_driver.c | 10 ++-- uspace/lib/nic/src/nic_impl.c | 17 ++---- uspace/lib/pcap/include/pcapdump_iface.h | 1 + uspace/lib/pcap/src/pcapctl_dump.c | 70 +++++++++++++----------- uspace/lib/pcap/src/pcapdump_iface.c | 4 +- uspace/srv/net/inetsrv/inetsrv.c | 22 +++++++- uspace/srv/net/inetsrv/meson.build | 3 +- 7 files changed, 73 insertions(+), 54 deletions(-) diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 1437b86a27..2151fed14f 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -522,7 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ - pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); fibril_rwlock_read_lock(&nic_data->rxc_lock); nic_frame_type_t frame_type; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -650,10 +650,10 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) nic_data->dev = device; - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); - if (pcap_rc != EOK) { - printf("Failed creating pcapdump port\n"); - } + // errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + // if (pcap_rc != EOK) { + // printf("Failed creating pcapdump port\n"); + // } return nic_data; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index d894d63f69..998ab3e600 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -179,7 +179,7 @@ errno_t nic_send_frame_impl(ddf_fun_t *fun, void *data, size_t size) fibril_rwlock_read_unlock(&nic_data->main_lock); return EBUSY; } - pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); + //pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); nic_data->send_frame(nic_data, data, size); fibril_rwlock_read_unlock(&nic_data->main_lock); return EOK; @@ -848,18 +848,13 @@ 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) - goto err_add_to_cat; + return rc; - rc = ddf_fun_add_to_category(fun, "pcap"); - if (rc != EOK) { - //ddf_msg(LVL_ERROR, "Failed adding function to category pcap"); - goto err_add_to_cat; - } + // rc = ddf_fun_add_to_category(fun, "pcap"); + // if (rc != EOK) { + // return rc; + // } return EOK; - -err_add_to_cat: - ddf_fun_unbind(fun); - return rc; } /** @} diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_iface.h index 8d64211652..6778cb6f2e 100644 --- a/uspace/lib/pcap/include/pcapdump_iface.h +++ b/uspace/lib/pcap/include/pcapdump_iface.h @@ -50,6 +50,7 @@ typedef enum { extern errno_t pcapdump_init(pcap_iface_t *); extern void pcapdump_packet(pcap_iface_t *, const void *, size_t); +extern void pcapdump_conn(ipc_call_t *, void *); #endif /** @} diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 384a4e31ed..3370b58f79 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -51,33 +51,33 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -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) { - printf("Error resolving category 'pcap'.\n"); - return rc; - } - - rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); - if (rc != EOK) { - printf("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; -} +// 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) { +// printf("Error resolving category 'pcap'.\n"); +// return rc; +// } + +// rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); +// if (rc != EOK) { +// printf("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; +// } errno_t pcapctl_is_valid_device(int *index) { @@ -148,11 +148,15 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - rc = pcapctl_cat_get_svc(index, &svc); - if (rc != EOK) { - printf("Error finding the device with index: %d\n", *index); - goto error; - } + // rc = pcapctl_cat_get_svc(index, &svc); + // if (rc != EOK) { + // printf("Error finding the device with index: %d\n", *index); + // goto error; + // } + + rc = loc_service_get_id("net/inet", &svc, 0); + if (rc != EOK) + return ENOENT; async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { @@ -160,6 +164,7 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) rc = EREFUSED; goto error; } + printf("got new session\n"); sess->sess = new_session; *rsess = sess; return EOK; @@ -185,6 +190,7 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) */ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) { + printf("pcapctl_dump_start\n"); errno_t rc; async_exch_t *exch = async_exchange_begin(sess->sess); diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_iface.c index 0696ad289e..e870a8831e 100644 --- a/uspace/lib/pcap/src/pcapdump_iface.c +++ b/uspace/lib/pcap/src/pcapdump_iface.c @@ -82,10 +82,10 @@ static void pcapdump_stop_srv(ipc_call_t *icall, pcap_iface_t *iface) async_answer_0(icall, EOK); } -static void pcapdump_conn(ipc_call_t *icall, void *arg) +void pcapdump_conn(ipc_call_t *icall, void *arg) { pcap_iface_t *iface = (pcap_iface_t *)arg; - + printf("pcapdump_conn\n"); assert((iface != NULL) && "pcapdump requires pcap interface\n"); /* Accept connection */ diff --git a/uspace/srv/net/inetsrv/inetsrv.c b/uspace/srv/net/inetsrv/inetsrv.c index 1f4b0245e0..2927dcef2d 100644 --- a/uspace/srv/net/inetsrv/inetsrv.c +++ b/uspace/srv/net/inetsrv/inetsrv.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "addrobj.h" #include "icmp.h" #include "icmp_std.h" @@ -62,6 +63,9 @@ #define NAME "inetsrv" +/** Interface for dumping packets */ +pcap_iface_t pcapdump; + static inet_naddr_t solicited_node_mask = { .version = ip_v6, .addr6 = { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0 }, @@ -116,7 +120,11 @@ static errno_t inet_init(void) inetping_conn, NULL, &port); if (rc != EOK) return rc; - + rc = async_create_port(INTERFACE_PCAP_CONTROL, + pcapdump_conn, &pcapdump, &port); + if (rc != EOK) { + return rc; + } rc = loc_server_register(NAME, &srv); if (rc != EOK) { log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc)); @@ -201,7 +209,8 @@ errno_t inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, return inet_link_send_dgram(ilink, dgram->src.addr, dgram->dest.addr, dgram, proto, ttl, df); } - + printf("SENDING: packet size is - %d\n", dgram->size); + pcapdump_packet(&pcapdump, dgram->data, dgram->size); log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed"); /* Route packet using source/destination addresses */ @@ -540,7 +549,8 @@ errno_t inet_recv_packet(inet_packet_t *packet) dgram.tos = packet->tos; dgram.data = packet->data; dgram.size = packet->size; - + printf("RECEIVING: packet size is - %d\n", packet->size); + pcapdump_packet(&pcapdump, packet->data, packet->size); return inet_recv_dgram_local(&dgram, packet->proto); } else { /* It is a fragment, queue it for reassembly */ @@ -561,11 +571,17 @@ int main(int argc, char *argv[]) printf(NAME ": Failed to initialize logging.\n"); return 1; } + rc = pcap_iface_init(&pcapdump); + if (rc != EOK) { + printf("Failed creating pcap interface: %s", str_error(rc)); + return rc; + } rc = inet_init(); if (rc != EOK) return 1; + printf(NAME ": Initialized dump iface from inetsrv.\n"); printf(NAME ": Accepting connections.\n"); task_retval(0); diff --git a/uspace/srv/net/inetsrv/meson.build b/uspace/srv/net/inetsrv/meson.build index 9b3600d426..c69af77187 100644 --- a/uspace/srv/net/inetsrv/meson.build +++ b/uspace/srv/net/inetsrv/meson.build @@ -26,7 +26,8 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -deps = [ 'inet', 'sif' ] +deps = [ 'inet', 'sif', 'pcap' ] + src = files( 'addrobj.c', 'icmp.c', From c7bd3f9e52905656ac433d57ce3adfecc230e0a4 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Tue, 16 Apr 2024 11:58:50 +0200 Subject: [PATCH 15/39] inetsrv: comments, linktype 101: ugly --- uspace/lib/pcap/include/pcap.h | 1 + uspace/lib/pcap/include/pcap_iface.h | 7 +++++++ uspace/lib/pcap/src/pcap.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 1e8089fbb8..964df227a9 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -52,6 +52,7 @@ #define PCAP_SNAP_LEN 0x00040000 #define PCAP_LINKTYPE_ETHERNET 1 /* IEEE 802.3 Ethernet*/ +#define PCAP_LINKTYPE_IP_RAW 101 /** Header of the .pcap file */ diff --git a/uspace/lib/pcap/include/pcap_iface.h b/uspace/lib/pcap/include/pcap_iface.h index ca660a3922..32db855c63 100644 --- a/uspace/lib/pcap/include/pcap_iface.h +++ b/uspace/lib/pcap/include/pcap_iface.h @@ -47,6 +47,13 @@ typedef struct pcap_iface { extern void pcap_close_file(void); extern errno_t pcap_iface_init(pcap_iface_t *); +//init to file +//init to serial +//add packet, dostane strukturu, data, velikost ... to to this pcap_iface_t +// v ramci init jeste linktype prg +//set snaplen taky lze pridavat prg +//create kam posila +// init extern errno_t pcap_init(const char *); extern void pcap_add_packet(const void *data, size_t size); diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index cf8c791c6f..06214fc802 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -58,7 +58,7 @@ void pcap_set_time(pcap_packet_header_t *header, bool nano) // maybe without boo void pcap_writer_add_header(pcap_writer_t *writer) { pcap_file_header_t file_header = { PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, - 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_ETHERNET }; + 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_IP_RAW }; writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); } From fc2d593b1195aadb5f9a5965a1bb2d0e8b682056 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Wed, 8 May 2024 15:47:52 +0200 Subject: [PATCH 16/39] ethip/drvs can dump, default ethip --- uspace/app/pcapctl/main.c | 2 +- uspace/lib/c/include/ipc/services.h | 1 - uspace/lib/nic/src/nic_driver.c | 12 ++--- uspace/lib/nic/src/nic_impl.c | 8 +-- uspace/lib/pcap/include/pcap.h | 6 ++- uspace/lib/pcap/src/pcap.c | 2 +- uspace/lib/pcap/src/pcap_iface.c | 1 - uspace/lib/pcap/src/pcapctl_dump.c | 82 ++++++++++++++++------------- uspace/srv/net/ethip/ethip.c | 12 ++++- uspace/srv/net/ethip/meson.build | 2 +- uspace/srv/net/inetsrv/inetsrv.c | 21 +------- 11 files changed, 75 insertions(+), 74 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index e81bb8c0bb..8265c4e9ad 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) { bool start = false; bool stop = false; - int dev_number = DEFAULT_DEV_NUM; + int dev_number = -1; const char *output_file_name; int idx = 0; int ret = 0; diff --git a/uspace/lib/c/include/ipc/services.h b/uspace/lib/c/include/ipc/services.h index e10b592090..0b3f591e18 100644 --- a/uspace/lib/c/include/ipc/services.h +++ b/uspace/lib/c/include/ipc/services.h @@ -66,7 +66,6 @@ typedef enum { #define SERVICE_NAME_TCP "net/tcp" #define SERVICE_NAME_VBD "vbd" #define SERVICE_NAME_VOLSRV "volsrv" -#define SERVICE_NAME_DUMPPCAP "dumppcap" #endif /** @} diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 2151fed14f..603850a133 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -522,7 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ - //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); fibril_rwlock_read_lock(&nic_data->rxc_lock); nic_frame_type_t frame_type; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -561,7 +561,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) } fibril_rwlock_write_unlock(&nic_data->stats_lock); } - //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); nic_release_frame(nic_data, frame); } @@ -650,10 +650,10 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) nic_data->dev = device; - // errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); - // if (pcap_rc != EOK) { - // printf("Failed creating pcapdump port\n"); - // } + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + if (pcap_rc != EOK) { + printf("Failed creating pcapdump port\n"); + } return nic_data; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index 998ab3e600..39fe80531b 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -850,10 +850,10 @@ errno_t nic_fun_add_to_cats(ddf_fun_t *fun) if (rc != EOK) return rc; - // rc = ddf_fun_add_to_category(fun, "pcap"); - // if (rc != EOK) { - // return rc; - // } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) { + return rc; + } return EOK; } diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 964df227a9..d98862e703 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -51,8 +51,10 @@ #define PCAP_MINOR_VERSION 0x0004 #define PCAP_SNAP_LEN 0x00040000 -#define PCAP_LINKTYPE_ETHERNET 1 /* IEEE 802.3 Ethernet*/ -#define PCAP_LINKTYPE_IP_RAW 101 +#define PCAP_LINKTYPE_ETHERNET 1 /* IEEE 802.3 Ethernet */ +#define PCAP_LINKTYPE_IP_RAW 101 /* Raw IP packet */ +#define WIRESHARK_EX 0xc +#define WIRESHARK_SNAPLEN 0xffff /** Header of the .pcap file */ diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 06214fc802..cf8c791c6f 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -58,7 +58,7 @@ void pcap_set_time(pcap_packet_header_t *header, bool nano) // maybe without boo void pcap_writer_add_header(pcap_writer_t *writer) { pcap_file_header_t file_header = { PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, - 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_IP_RAW }; + 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_ETHERNET }; writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); } diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c index 3618eaddbf..5c0c69a7e2 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -94,7 +94,6 @@ void pcap_close_file(void) */ errno_t pcap_iface_init(pcap_iface_t *iface) { - iface->to_dump = false; iface->add_packet = pcap_add_packet; iface->init = pcap_init; diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 3370b58f79..39e0629b19 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -51,33 +51,33 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -// 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) { -// printf("Error resolving category 'pcap'.\n"); -// return rc; -// } - -// rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); -// if (rc != EOK) { -// printf("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; -// } +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) { + printf("Error resolving category 'pcap'.\n"); + return rc; + } + + rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); + if (rc != EOK) { + printf("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; +} errno_t pcapctl_is_valid_device(int *index) { @@ -148,15 +148,24 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - // rc = pcapctl_cat_get_svc(index, &svc); - // if (rc != EOK) { - // printf("Error finding the device with index: %d\n", *index); - // goto error; - // } + printf("number: %d\n", *index); + if (*index == -1) { + + rc = loc_service_get_id("net/eth1", &svc, 0); + if (rc != EOK) + { + fprintf(stderr, "Error getting service id.\n"); + return ENOENT; + } + } + else { + rc = pcapctl_cat_get_svc(index, &svc); + if (rc != EOK) { + printf("Error finding the device with index: %d\n", *index); + goto error; + } + } - rc = loc_service_get_id("net/inet", &svc, 0); - if (rc != EOK) - return ENOENT; async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { @@ -164,7 +173,7 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) rc = EREFUSED; goto error; } - printf("got new session\n"); + sess->sess = new_session; *rsess = sess; return EOK; @@ -190,7 +199,6 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) */ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) { - printf("pcapctl_dump_start\n"); errno_t rc; async_exch_t *exch = async_exchange_begin(sess->sess); diff --git a/uspace/srv/net/ethip/ethip.c b/uspace/srv/net/ethip/ethip.c index 9143b4dbbc..597e922986 100644 --- a/uspace/srv/net/ethip/ethip.c +++ b/uspace/srv/net/ethip/ethip.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "arp.h" #include "ethip.h" #include "ethip_nic.h" @@ -52,6 +53,8 @@ #include "std.h" #define NAME "ethip" +/** Interface for dumping packets */ +pcap_iface_t pcapdump; static errno_t ethip_open(iplink_srv_t *srv); static errno_t ethip_close(iplink_srv_t *srv); @@ -89,6 +92,12 @@ static errno_t ethip_init(void) return rc; } + rc = pcapdump_init(&pcapdump); + if (rc != EOK) { + log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing dumping interface."); + return rc; + } + rc = ethip_nic_discovery_start(); if (rc != EOK) return rc; @@ -196,7 +205,7 @@ static errno_t ethip_send(iplink_srv_t *srv, iplink_sdu_t *sdu) rc = eth_pdu_encode(&frame, &data, &size); if (rc != EOK) return rc; - + pcapdump_packet(&pcapdump, data, size); rc = ethip_nic_send(nic, data, size); free(data); @@ -241,6 +250,7 @@ errno_t ethip_received(iplink_srv_t *srv, void *data, size_t size) log_msg(LOG_DEFAULT, LVL_DEBUG, " - eth_pdu_decode failed"); return rc; } + pcapdump_packet(&pcapdump, data, size); iplink_recv_sdu_t sdu; diff --git a/uspace/srv/net/ethip/meson.build b/uspace/srv/net/ethip/meson.build index d1577d8193..886f2e8b9b 100644 --- a/uspace/srv/net/ethip/meson.build +++ b/uspace/srv/net/ethip/meson.build @@ -26,7 +26,7 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -deps = [ 'drv' ] +deps = [ 'drv' , 'pcap' ] src = files( 'arp.c', 'atrans.c', diff --git a/uspace/srv/net/inetsrv/inetsrv.c b/uspace/srv/net/inetsrv/inetsrv.c index 2927dcef2d..002586ae6b 100644 --- a/uspace/srv/net/inetsrv/inetsrv.c +++ b/uspace/srv/net/inetsrv/inetsrv.c @@ -48,7 +48,6 @@ #include #include #include -#include #include "addrobj.h" #include "icmp.h" #include "icmp_std.h" @@ -63,8 +62,6 @@ #define NAME "inetsrv" -/** Interface for dumping packets */ -pcap_iface_t pcapdump; static inet_naddr_t solicited_node_mask = { .version = ip_v6, @@ -120,11 +117,7 @@ static errno_t inet_init(void) inetping_conn, NULL, &port); if (rc != EOK) return rc; - rc = async_create_port(INTERFACE_PCAP_CONTROL, - pcapdump_conn, &pcapdump, &port); - if (rc != EOK) { - return rc; - } + rc = loc_server_register(NAME, &srv); if (rc != EOK) { log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc)); @@ -209,12 +202,10 @@ errno_t inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, return inet_link_send_dgram(ilink, dgram->src.addr, dgram->dest.addr, dgram, proto, ttl, df); } - printf("SENDING: packet size is - %d\n", dgram->size); - pcapdump_packet(&pcapdump, dgram->data, dgram->size); + log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed"); /* Route packet using source/destination addresses */ - rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir); if (rc != EOK) return rc; @@ -549,8 +540,6 @@ errno_t inet_recv_packet(inet_packet_t *packet) dgram.tos = packet->tos; dgram.data = packet->data; dgram.size = packet->size; - printf("RECEIVING: packet size is - %d\n", packet->size); - pcapdump_packet(&pcapdump, packet->data, packet->size); return inet_recv_dgram_local(&dgram, packet->proto); } else { /* It is a fragment, queue it for reassembly */ @@ -571,17 +560,11 @@ int main(int argc, char *argv[]) printf(NAME ": Failed to initialize logging.\n"); return 1; } - rc = pcap_iface_init(&pcapdump); - if (rc != EOK) { - printf("Failed creating pcap interface: %s", str_error(rc)); - return rc; - } rc = inet_init(); if (rc != EOK) return 1; - printf(NAME ": Initialized dump iface from inetsrv.\n"); printf(NAME ": Accepting connections.\n"); task_retval(0); From 1333dfce89a42845e0aeeb66e3ee05c877f73f92 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Thu, 11 Apr 2024 11:36:03 +0200 Subject: [PATCH 17/39] inetsrv dumps --- uspace/lib/nic/src/nic_driver.c | 10 ++-- uspace/lib/nic/src/nic_impl.c | 9 ++-- uspace/lib/pcap/src/pcapctl_dump.c | 82 ++++++++++++++---------------- uspace/srv/net/inetsrv/inetsrv.c | 20 +++++++- 4 files changed, 65 insertions(+), 56 deletions(-) diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 603850a133..5515314feb 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -522,7 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ - pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); fibril_rwlock_read_lock(&nic_data->rxc_lock); nic_frame_type_t frame_type; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -650,10 +650,10 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) nic_data->dev = device; - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); - if (pcap_rc != EOK) { - printf("Failed creating pcapdump port\n"); - } + // errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + // if (pcap_rc != EOK) { + // printf("Failed creating pcapdump port\n"); + // } return nic_data; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index 39fe80531b..b3cd2dca13 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -849,11 +849,12 @@ errno_t nic_fun_add_to_cats(ddf_fun_t *fun) 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; - } + + // rc = ddf_fun_add_to_category(fun, "pcap"); + // if (rc != EOK) { + // return rc; + // } return EOK; } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 39e0629b19..3370b58f79 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -51,33 +51,33 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -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) { - printf("Error resolving category 'pcap'.\n"); - return rc; - } - - rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); - if (rc != EOK) { - printf("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; -} +// 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) { +// printf("Error resolving category 'pcap'.\n"); +// return rc; +// } + +// rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); +// if (rc != EOK) { +// printf("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; +// } errno_t pcapctl_is_valid_device(int *index) { @@ -148,24 +148,15 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - printf("number: %d\n", *index); - if (*index == -1) { - - rc = loc_service_get_id("net/eth1", &svc, 0); - if (rc != EOK) - { - fprintf(stderr, "Error getting service id.\n"); - return ENOENT; - } - } - else { - rc = pcapctl_cat_get_svc(index, &svc); - if (rc != EOK) { - printf("Error finding the device with index: %d\n", *index); - goto error; - } - } + // rc = pcapctl_cat_get_svc(index, &svc); + // if (rc != EOK) { + // printf("Error finding the device with index: %d\n", *index); + // goto error; + // } + rc = loc_service_get_id("net/inet", &svc, 0); + if (rc != EOK) + return ENOENT; async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { @@ -173,7 +164,7 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) rc = EREFUSED; goto error; } - + printf("got new session\n"); sess->sess = new_session; *rsess = sess; return EOK; @@ -199,6 +190,7 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) */ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) { + printf("pcapctl_dump_start\n"); errno_t rc; async_exch_t *exch = async_exchange_begin(sess->sess); diff --git a/uspace/srv/net/inetsrv/inetsrv.c b/uspace/srv/net/inetsrv/inetsrv.c index 002586ae6b..a06d0cd78d 100644 --- a/uspace/srv/net/inetsrv/inetsrv.c +++ b/uspace/srv/net/inetsrv/inetsrv.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "addrobj.h" #include "icmp.h" #include "icmp_std.h" @@ -62,6 +63,8 @@ #define NAME "inetsrv" +/** Interface for dumping packets */ +pcap_iface_t pcapdump; static inet_naddr_t solicited_node_mask = { .version = ip_v6, @@ -117,7 +120,11 @@ static errno_t inet_init(void) inetping_conn, NULL, &port); if (rc != EOK) return rc; - + rc = async_create_port(INTERFACE_PCAP_CONTROL, + pcapdump_conn, &pcapdump, &port); + if (rc != EOK) { + return rc; + } rc = loc_server_register(NAME, &srv); if (rc != EOK) { log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc)); @@ -202,7 +209,8 @@ errno_t inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, return inet_link_send_dgram(ilink, dgram->src.addr, dgram->dest.addr, dgram, proto, ttl, df); } - + printf("SENDING: packet size is - %d\n", dgram->size); + pcapdump_packet(&pcapdump, dgram->data, dgram->size); log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed"); /* Route packet using source/destination addresses */ @@ -540,6 +548,8 @@ errno_t inet_recv_packet(inet_packet_t *packet) dgram.tos = packet->tos; dgram.data = packet->data; dgram.size = packet->size; + printf("RECEIVING: packet size is - %d\n", packet->size); + pcapdump_packet(&pcapdump, packet->data, packet->size); return inet_recv_dgram_local(&dgram, packet->proto); } else { /* It is a fragment, queue it for reassembly */ @@ -560,11 +570,17 @@ int main(int argc, char *argv[]) printf(NAME ": Failed to initialize logging.\n"); return 1; } + rc = pcap_iface_init(&pcapdump); + if (rc != EOK) { + printf("Failed creating pcap interface: %s", str_error(rc)); + return rc; + } rc = inet_init(); if (rc != EOK) return 1; + printf(NAME ": Initialized dump iface from inetsrv.\n"); printf(NAME ": Accepting connections.\n"); task_retval(0); From 0210d42d7f545f5ab3378eafab9ca0abfa329891 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Wed, 8 May 2024 15:47:52 +0200 Subject: [PATCH 18/39] ethip/drvs can dump, default ethip --- uspace/lib/nic/src/nic_driver.c | 10 ++-- uspace/lib/nic/src/nic_impl.c | 8 +-- uspace/lib/pcap/src/pcapctl_dump.c | 82 ++++++++++++++++-------------- uspace/srv/net/inetsrv/inetsrv.c | 20 +------- 4 files changed, 56 insertions(+), 64 deletions(-) diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 5515314feb..603850a133 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -522,7 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ - //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); fibril_rwlock_read_lock(&nic_data->rxc_lock); nic_frame_type_t frame_type; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -650,10 +650,10 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) nic_data->dev = device; - // errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); - // if (pcap_rc != EOK) { - // printf("Failed creating pcapdump port\n"); - // } + errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + if (pcap_rc != EOK) { + printf("Failed creating pcapdump port\n"); + } return nic_data; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index b3cd2dca13..c7dcdb7cc3 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -851,10 +851,10 @@ errno_t nic_fun_add_to_cats(ddf_fun_t *fun) return rc; return rc; - // rc = ddf_fun_add_to_category(fun, "pcap"); - // if (rc != EOK) { - // return rc; - // } + rc = ddf_fun_add_to_category(fun, "pcap"); + if (rc != EOK) { + return rc; + } return EOK; } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 3370b58f79..39e0629b19 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -51,33 +51,33 @@ static void pcapctl_dump_exchange_end(async_exch_t *exch) async_exchange_end(exch); } -// 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) { -// printf("Error resolving category 'pcap'.\n"); -// return rc; -// } - -// rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); -// if (rc != EOK) { -// printf("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; -// } +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) { + printf("Error resolving category 'pcap'.\n"); + return rc; + } + + rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); + if (rc != EOK) { + printf("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; +} errno_t pcapctl_is_valid_device(int *index) { @@ -148,15 +148,24 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - // rc = pcapctl_cat_get_svc(index, &svc); - // if (rc != EOK) { - // printf("Error finding the device with index: %d\n", *index); - // goto error; - // } + printf("number: %d\n", *index); + if (*index == -1) { + + rc = loc_service_get_id("net/eth1", &svc, 0); + if (rc != EOK) + { + fprintf(stderr, "Error getting service id.\n"); + return ENOENT; + } + } + else { + rc = pcapctl_cat_get_svc(index, &svc); + if (rc != EOK) { + printf("Error finding the device with index: %d\n", *index); + goto error; + } + } - rc = loc_service_get_id("net/inet", &svc, 0); - if (rc != EOK) - return ENOENT; async_sess_t *new_session = loc_service_connect(svc, INTERFACE_PCAP_CONTROL, 0); if (new_session == NULL) { @@ -164,7 +173,7 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) rc = EREFUSED; goto error; } - printf("got new session\n"); + sess->sess = new_session; *rsess = sess; return EOK; @@ -190,7 +199,6 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) */ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) { - printf("pcapctl_dump_start\n"); errno_t rc; async_exch_t *exch = async_exchange_begin(sess->sess); diff --git a/uspace/srv/net/inetsrv/inetsrv.c b/uspace/srv/net/inetsrv/inetsrv.c index a06d0cd78d..002586ae6b 100644 --- a/uspace/srv/net/inetsrv/inetsrv.c +++ b/uspace/srv/net/inetsrv/inetsrv.c @@ -48,7 +48,6 @@ #include #include #include -#include #include "addrobj.h" #include "icmp.h" #include "icmp_std.h" @@ -63,8 +62,6 @@ #define NAME "inetsrv" -/** Interface for dumping packets */ -pcap_iface_t pcapdump; static inet_naddr_t solicited_node_mask = { .version = ip_v6, @@ -120,11 +117,7 @@ static errno_t inet_init(void) inetping_conn, NULL, &port); if (rc != EOK) return rc; - rc = async_create_port(INTERFACE_PCAP_CONTROL, - pcapdump_conn, &pcapdump, &port); - if (rc != EOK) { - return rc; - } + rc = loc_server_register(NAME, &srv); if (rc != EOK) { log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc)); @@ -209,8 +202,7 @@ errno_t inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, return inet_link_send_dgram(ilink, dgram->src.addr, dgram->dest.addr, dgram, proto, ttl, df); } - printf("SENDING: packet size is - %d\n", dgram->size); - pcapdump_packet(&pcapdump, dgram->data, dgram->size); + log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed"); /* Route packet using source/destination addresses */ @@ -548,8 +540,6 @@ errno_t inet_recv_packet(inet_packet_t *packet) dgram.tos = packet->tos; dgram.data = packet->data; dgram.size = packet->size; - printf("RECEIVING: packet size is - %d\n", packet->size); - pcapdump_packet(&pcapdump, packet->data, packet->size); return inet_recv_dgram_local(&dgram, packet->proto); } else { /* It is a fragment, queue it for reassembly */ @@ -570,17 +560,11 @@ int main(int argc, char *argv[]) printf(NAME ": Failed to initialize logging.\n"); return 1; } - rc = pcap_iface_init(&pcapdump); - if (rc != EOK) { - printf("Failed creating pcap interface: %s", str_error(rc)); - return rc; - } rc = inet_init(); if (rc != EOK) return 1; - printf(NAME ": Initialized dump iface from inetsrv.\n"); printf(NAME ": Accepting connections.\n"); task_retval(0); From 59fe16d48928236158c9d3c9e7e1180bdbfe21d8 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 13 Oct 2024 10:31:31 +0200 Subject: [PATCH 19/39] file name debugging --- uspace/lib/pcap/src/pcap.c | 1 + uspace/lib/pcap/src/pcapctl_dump.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index cf8c791c6f..6bf0bdf1e0 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -97,6 +97,7 @@ void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) { errno_t rc; + printf("File: %s\n", filename); writer->data = fopen(filename, "a"); if (writer->data == NULL) { rc = EINVAL; diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 39e0629b19..f58b7d6d7c 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -205,7 +205,7 @@ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) size_t size = str_size(name); aid_t req = async_send_0(exch, PCAP_CONTROL_SET_START, NULL); - rc = async_data_write_start(exch, (void *) name, size); + rc = async_data_write_start(exch, (const void *) name, size); pcapctl_dump_exchange_end(exch); From 03cd7a9eb6605c4b72ed6e4be5bc4822a6665043 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Mon, 28 Oct 2024 10:57:08 +0100 Subject: [PATCH 20/39] refactoring after 23.10 --- uspace/app/pcapctl/main.c | 67 +++++++++-------- uspace/drv/nic/e1k/e1k.c | 2 - uspace/lib/nic/include/nic.h | 2 +- uspace/lib/nic/include/nic_driver.h | 2 +- uspace/lib/nic/src/nic_driver.c | 2 +- uspace/lib/nic/src/nic_impl.c | 1 - uspace/lib/pcap/include/pcap.h | 3 +- uspace/lib/pcap/include/pcap_iface.h | 29 ++++---- uspace/lib/pcap/include/pcapdump_iface.h | 5 +- uspace/lib/pcap/src/pcap.c | 11 ++- uspace/lib/pcap/src/pcap_iface.c | 92 +++++++++++++++++++----- uspace/lib/pcap/src/pcapctl_dump.c | 21 ++---- uspace/lib/pcap/src/pcapdump_iface.c | 68 +++++++----------- uspace/srv/net/ethip/ethip.c | 8 --- 14 files changed, 172 insertions(+), 141 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 8265c4e9ad..f9b6e70901 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -106,7 +106,7 @@ int main(int argc, char *argv[]) bool start = false; bool stop = false; int dev_number = -1; - const char *output_file_name; + const char *output_file_name = ""; int idx = 0; int ret = 0; if (argc == 1) { @@ -116,41 +116,52 @@ int main(int argc, char *argv[]) while (ret != -1) { ret = getopt_long(argc, argv, "d:lhf:rt", opts, &idx); switch (ret) { - case 'd': - char *rest; - long result = strtol(optarg, &rest, 10); - dev_number = (int)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; + case 'd': + { + char *rest; + long result = strtol(optarg, &rest, 10); + dev_number = (int)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 'l': + { + list_devs(); + return 0; + } + case 'h': + { + usage(); + return 0; + } + case 'f': + { + output_file_name = optarg; + break; + } + case 'r': + { + start = true; + break; + } + case 't': + { stop = true; + break; } - break; - case 'l': - list_devs(); - return 0; - case 'h': - usage(); - return 0; - case 'f': - output_file_name = optarg; - break; - case 'r': - start = true; - break; - case 't': - stop = true; - break; } } - printf("%s: HelenOS Packet Dumping utility: device - %d\n", NAME, dev_number); + printf("%s: HelenOS Packet Dumping utility: device - %d.\n", NAME, dev_number); if (start) { - // start with dev number and optional..name + /* start with dev number and name*/ start_dumping(&dev_number, output_file_name); } else if (stop) { - //stop with dev number + /* stop with dev number*/ stop_dumping(&dev_number); } return 0; diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index 97b80c8b15..dc811a847b 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -2208,8 +2208,6 @@ errno_t e1000_dev_add(ddf_dev_t *dev) } return EOK; - // err_add_to_cat: - // ddf_fun_unbind(fun); err_fun_bind: err_rx_structure: e1000_uninitialize_rx_structure(nic); diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index 9fb0b5637f..0816f74437 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -279,7 +279,7 @@ extern void nic_sw_period_start(nic_t *); extern void nic_sw_period_stop(nic_t *); /* pcapdump interface */ -extern pcap_iface_t *nic_get_pcap_iface(nic_t *); +extern pcap_dumper_t *nic_get_pcap_iface(nic_t *); extern errno_t nic_fun_add_to_cats(ddf_fun_t *fun); diff --git a/uspace/lib/nic/include/nic_driver.h b/uspace/lib/nic/include/nic_driver.h index f99e5a0746..03d543e93b 100644 --- a/uspace/lib/nic/include/nic_driver.h +++ b/uspace/lib/nic/include/nic_driver.h @@ -197,7 +197,7 @@ struct nic { poll_request_handler on_poll_request; /** Interface for dumping packets */ - pcap_iface_t pcapdump; + pcap_dumper_t pcapdump; /** Data specific for particular driver */ void *specific; diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 603850a133..ffbb76feff 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -1140,7 +1140,7 @@ void nic_sw_period_stop(nic_t *nic_data) nic_data->sw_poll_info.running = 0; } -pcap_iface_t *nic_get_pcap_iface(nic_t *nic_data) +pcap_dumper_t *nic_get_pcap_iface(nic_t *nic_data) { return &nic_data->pcapdump; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index c7dcdb7cc3..39fe80531b 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -849,7 +849,6 @@ errno_t nic_fun_add_to_cats(ddf_fun_t *fun) rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); if (rc != EOK) return rc; - return rc; rc = ddf_fun_add_to_category(fun, "pcap"); if (rc != EOK) { diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index d98862e703..61297312a9 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -53,6 +53,7 @@ #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 WIRESHARK_EX 0xc #define WIRESHARK_SNAPLEN 0xffff @@ -98,7 +99,7 @@ extern void pcap_writer_add_header(pcap_writer_t *); 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, bool nano); +extern void pcap_set_time(pcap_packet_header_t *header); #endif diff --git a/uspace/lib/pcap/include/pcap_iface.h b/uspace/lib/pcap/include/pcap_iface.h index 32db855c63..94de16e699 100644 --- a/uspace/lib/pcap/include/pcap_iface.h +++ b/uspace/lib/pcap/include/pcap_iface.h @@ -36,26 +36,25 @@ #define PCAP_IFACE_H_ #include +#include #include "pcap.h" -typedef struct pcap_iface { +typedef struct pcap_dumper { + fibril_mutex_t mutex; bool to_dump; - errno_t (*init)(const char *); - void (*add_packet)(const void *data, size_t size); - void (*fini)(void); -} pcap_iface_t; - -extern void pcap_close_file(void); -extern errno_t pcap_iface_init(pcap_iface_t *); -//init to file -//init to serial -//add packet, dostane strukturu, data, velikost ... to to this pcap_iface_t + pcap_writer_t writer; +} pcap_dumper_t; + + +extern void pcap_dumper_stop(struct pcap_dumper *); + +extern errno_t pcap_dumper_init(pcap_dumper_t *); + // v ramci init jeste linktype prg //set snaplen taky lze pridavat prg -//create kam posila -// init -extern errno_t pcap_init(const char *); -extern void pcap_add_packet(const void *data, size_t size); + +extern errno_t pcap_dumper_start(struct pcap_dumper *, const char *); +extern void pcap_dumper_add_packet(struct pcap_dumper *, const void *data, size_t size); #endif /** @} diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_iface.h index 6778cb6f2e..ded1df85d6 100644 --- a/uspace/lib/pcap/include/pcapdump_iface.h +++ b/uspace/lib/pcap/include/pcapdump_iface.h @@ -47,9 +47,8 @@ typedef enum { PCAP_CONTROL_GET_NAME } pcap_request_t; -extern errno_t pcapdump_init(pcap_iface_t *); -extern void pcapdump_packet(pcap_iface_t *, const void *, size_t); - +extern errno_t pcapdump_init(pcap_dumper_t *); +extern void pcapdump_packet(pcap_dumper_t *, const void *, size_t); extern void pcapdump_conn(ipc_call_t *, void *); #endif diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 6bf0bdf1e0..b5ac2a4116 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -42,12 +42,12 @@ * @param header Header of the packet to be dumped. * */ -void pcap_set_time(pcap_packet_header_t *header, bool nano) // maybe without bool nano as nano is in pcapng +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_nsec / 1000; + header->magic_stamp = (uint32_t)ts.tv_nsec; } /** Add pcap file header to the new .pcap file. @@ -57,7 +57,7 @@ void pcap_set_time(pcap_packet_header_t *header, bool nano) // maybe without boo */ void pcap_writer_add_header(pcap_writer_t *writer) { - pcap_file_header_t file_header = { PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, + pcap_file_header_t file_header = { PCAP_MAGIC_NANO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_ETHERNET }; writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); } @@ -74,8 +74,8 @@ void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, if (!writer->data) return; pcap_packet_header_t pcap_packet; - pcap_set_time(&pcap_packet, false); - pcap_packet.original_length = (uint32_t)size; + pcap_set_time(&pcap_packet); + pcap_packet.original_length = size; if (PCAP_SNAP_LEN < size) { pcap_packet.captured_length = PCAP_SNAP_LEN; @@ -97,7 +97,6 @@ void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) { errno_t rc; - printf("File: %s\n", filename); writer->data = fopen(filename, "a"); if (writer->data == NULL) { rc = EINVAL; diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c index 5c0c69a7e2..f006694b6b 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -64,41 +64,97 @@ static pcap_writer_ops_t file_ops = { .close = &pcap_file_close }; -static pcap_writer_t pcap_writer = { - .ops = &file_ops, -}; +// static size_t pcap_short_file_w32(pcap_writer_t *writer, uint32_t data) +// { +// return fwrite(&data, 1, 4, (FILE *)writer->data); +// } + +// static size_t pcap_short_file_w16(pcap_writer_t *writer, uint16_t data) +// { +// return fwrite(&data, 1, 2, (FILE *)writer->data); +// } + +// static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) +// { +// return fwrite(data, 1, size<60?size:60, (FILE *)writer->data); +// } + +// static void pcap_short_file_close(pcap_writer_t *writer) +// { +// fclose((FILE *)writer->data); +// } + + +// static pcap_writer_ops_t short_file_ops = { +// .write_u32 = &pcap_short_file_w32, +// .write_u16 = &pcap_short_file_w16, +// .write_buffer = &pcap_short_file_wbuffer, +// .close = &pcap_short_file_close -errno_t pcap_init(const char *name) +// }; + +errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) { - errno_t rc = pcap_writer_to_file_init(&pcap_writer, name); + fibril_mutex_lock(&dumper->mutex); + + /** When try to start when already started, close current and starts new */ + if (dumper->to_dump == true) + { + pcap_dumper_stop(dumper); + } + errno_t rc = pcap_writer_to_file_init(&dumper->writer, name); + if (rc == EOK) + { + dumper->to_dump = true; + } + else + { + printf("Failed creating pcap dumper: %s", str_error(rc)); + } + fibril_mutex_unlock(&dumper->mutex); return rc; } -void pcap_add_packet(const void *data, size_t size) +//udelat globalni +void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t size) { - if (pcap_writer.data == NULL) + fibril_mutex_lock(&dumper->mutex); + + if (dumper->writer.data == NULL || !dumper->to_dump) + { + fibril_mutex_unlock(&dumper->mutex); return; - pcap_writer_add_packet(&pcap_writer, data, size); + } + pcap_writer_add_packet(&dumper->writer, data, size); + fibril_mutex_unlock(&dumper->mutex); } -void pcap_close_file(void) +//udelt globalni +void pcap_dumper_stop(struct pcap_dumper *dumper) { - pcap_writer.ops->close(&pcap_writer); - pcap_writer.data = NULL; + fibril_mutex_lock(&dumper->mutex); + + /** If want to stop, when already stopped, do nothing */ + if (dumper->to_dump == false) { + fibril_mutex_unlock(&dumper->mutex); + return; + } + dumper->to_dump = false; + dumper->writer.ops->close(&dumper->writer); + dumper->writer.data = NULL; + fibril_mutex_unlock(&dumper->mutex); } /** Initialize interface for dumping packets * - * @param iface Device dumping interface + * @param dumper Device dumping interface * */ -errno_t pcap_iface_init(pcap_iface_t *iface) +errno_t pcap_dumper_init(pcap_dumper_t *dumper) { - iface->to_dump = false; - iface->add_packet = pcap_add_packet; - iface->init = pcap_init; - iface->fini = pcap_close_file; - + fibril_mutex_initialize(&dumper->mutex); + dumper->to_dump = false; + dumper->writer.ops = &file_ops; return EOK; } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index f58b7d6d7c..3304698709 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -150,20 +150,13 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) printf("number: %d\n", *index); if (*index == -1) { - - rc = loc_service_get_id("net/eth1", &svc, 0); - if (rc != EOK) - { - fprintf(stderr, "Error getting service id.\n"); - return ENOENT; - } + *index = 0; } - else { - rc = pcapctl_cat_get_svc(index, &svc); - if (rc != EOK) { - printf("Error finding the device with index: %d\n", *index); - goto error; - } + + rc = pcapctl_cat_get_svc(index, &svc); + if (rc != EOK) { + printf("Error finding the device with index: %d\n", *index); + goto error; } @@ -205,7 +198,7 @@ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) size_t size = str_size(name); aid_t req = async_send_0(exch, PCAP_CONTROL_SET_START, NULL); - rc = async_data_write_start(exch, (const void *) name, size); + rc = async_data_write_start(exch, (const void *)name, size); pcapctl_dump_exchange_end(exch); diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_iface.c index e870a8831e..72c7669310 100644 --- a/uspace/lib/pcap/src/pcapdump_iface.c +++ b/uspace/lib/pcap/src/pcapdump_iface.c @@ -37,56 +37,44 @@ #include #include +#include #include +#include #include "pcapdump_iface.h" -FIBRIL_MUTEX_INITIALIZE(to_dump_mutex); - -static void pcapdump_start_srv(ipc_call_t *icall, pcap_iface_t *iface) +static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) { char *data; size_t size; - errno_t rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size); + errno_t rc = async_data_write_accept((void **) &data, true, 0, 0, 0, &size); if (rc != EOK) { async_answer_0(icall, rc); return; } - /** When try to start when already started, close current and starts new */ - if (iface->to_dump == true) { - iface->fini(); - } - iface->init((const char *)data); - - fibril_mutex_lock(&to_dump_mutex); - iface->to_dump = true; - fibril_mutex_unlock(&to_dump_mutex); + assert(str_length(data) == size && "Data were damaged during transmission.\n"); - async_answer_0(icall, rc); + rc = pcap_dumper_start(dumper, (const char *)data); + free(data); + if (rc != EOK) + { + //TODO what? + } + async_answer_0(icall, EOK); } -static void pcapdump_stop_srv(ipc_call_t *icall, pcap_iface_t *iface) +static void pcapdump_stop_srv(ipc_call_t *icall, pcap_dumper_t *dumper) { - /** If want to stop, when already stopped, do nothing */ - if (iface->to_dump == false) { - async_answer_0(icall, EOK); - return; - } - - fibril_mutex_lock(&to_dump_mutex); - iface->to_dump = false; - fibril_mutex_unlock(&to_dump_mutex); - - iface->fini(); + pcap_dumper_stop(dumper); async_answer_0(icall, EOK); } void pcapdump_conn(ipc_call_t *icall, void *arg) { - pcap_iface_t *iface = (pcap_iface_t *)arg; - printf("pcapdump_conn\n"); - assert((iface != NULL) && "pcapdump requires pcap interface\n"); + pcap_dumper_t *dumper = (pcap_dumper_t *)arg; + + assert((dumper != NULL) && "pcapdump requires pcap dumper\n"); /* Accept connection */ async_accept_0(icall); @@ -102,10 +90,10 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) } switch (method) { case PCAP_CONTROL_SET_START: - pcapdump_start_srv(&call, iface); + pcapdump_start_srv(&call, dumper); break; case PCAP_CONTROL_SET_STOP: - pcapdump_stop_srv(&call, iface); + pcapdump_stop_srv(&call, dumper); break; default: async_answer_0(&call, EINVAL); @@ -114,12 +102,12 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) } } -errno_t pcapdump_init(pcap_iface_t *iface) +errno_t pcapdump_init(pcap_dumper_t *dumper) { port_id_t port; errno_t rc; - rc = pcap_iface_init(iface); + rc = pcap_dumper_init(dumper); if (rc != EOK) { printf("Failed creating pcap interface: %s", str_error(rc)); @@ -127,7 +115,7 @@ errno_t pcapdump_init(pcap_iface_t *iface) } rc = async_create_port(INTERFACE_PCAP_CONTROL, - pcapdump_conn, iface, &port); + pcapdump_conn, dumper, &port); if (rc != EOK) { return rc; } @@ -138,23 +126,19 @@ errno_t pcapdump_init(pcap_iface_t *iface) * * Called every time, the packet is sent/recieved by the device * - * @param iface Dumping interface + * @param dumper Dumping interface * @param data The packet * @param size Size of the packet * */ -void pcapdump_packet(pcap_iface_t *iface, const void *data, size_t size) +void pcapdump_packet(pcap_dumper_t *dumper, const void *data, size_t size) { - if (iface == NULL) { - return; - } - - if (!iface->to_dump) { + if (dumper == NULL) { return; } - iface->add_packet(data, size); + pcap_dumper_add_packet(dumper, data, size); } /** @} diff --git a/uspace/srv/net/ethip/ethip.c b/uspace/srv/net/ethip/ethip.c index 597e922986..00a42e307f 100644 --- a/uspace/srv/net/ethip/ethip.c +++ b/uspace/srv/net/ethip/ethip.c @@ -54,7 +54,6 @@ #define NAME "ethip" /** Interface for dumping packets */ -pcap_iface_t pcapdump; static errno_t ethip_open(iplink_srv_t *srv); static errno_t ethip_close(iplink_srv_t *srv); @@ -92,11 +91,6 @@ static errno_t ethip_init(void) return rc; } - rc = pcapdump_init(&pcapdump); - if (rc != EOK) { - log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing dumping interface."); - return rc; - } rc = ethip_nic_discovery_start(); if (rc != EOK) @@ -205,7 +199,6 @@ static errno_t ethip_send(iplink_srv_t *srv, iplink_sdu_t *sdu) rc = eth_pdu_encode(&frame, &data, &size); if (rc != EOK) return rc; - pcapdump_packet(&pcapdump, data, size); rc = ethip_nic_send(nic, data, size); free(data); @@ -250,7 +243,6 @@ errno_t ethip_received(iplink_srv_t *srv, void *data, size_t size) log_msg(LOG_DEFAULT, LVL_DEBUG, " - eth_pdu_decode failed"); return rc; } - pcapdump_packet(&pcapdump, data, size); iplink_recv_sdu_t sdu; From f08447b8647b2eb26f43e7993e08f77113274783 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Mon, 28 Oct 2024 11:18:35 +0100 Subject: [PATCH 21/39] ccheck --- uspace/app/pcapctl/main.c | 63 ++++++++++++---------------- uspace/lib/pcap/include/pcap_iface.h | 2 - uspace/lib/pcap/src/pcap_iface.c | 14 ++----- uspace/lib/pcap/src/pcapctl_dump.c | 1 - uspace/lib/pcap/src/pcapdump_iface.c | 5 +-- uspace/srv/net/ethip/ethip.c | 1 - uspace/srv/net/inetsrv/inetsrv.c | 1 - 7 files changed, 31 insertions(+), 56 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index f9b6e70901..5c8d2b2d21 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -116,52 +116,41 @@ int main(int argc, char *argv[]) while (ret != -1) { ret = getopt_long(argc, argv, "d:lhf:rt", opts, &idx); switch (ret) { - case 'd': - { - char *rest; - long result = strtol(optarg, &rest, 10); - dev_number = (int)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 'l': - { - list_devs(); - return 0; - } - case 'h': - { - usage(); - return 0; - } - case 'f': - { - output_file_name = optarg; - break; - } - case 'r': - { - start = true; - break; - } - case 't': - { stop = true; - break; + case 'd': + char *rest; + long result = strtol(optarg, &rest, 10); + dev_number = (int)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 'l': + list_devs(); + return 0; + case 'h': + usage(); + return 0; + case 'f': + output_file_name = optarg; + break; + case 'r': + start = true; + break; + case 't': + stop = true; + break; } } printf("%s: HelenOS Packet Dumping utility: device - %d.\n", NAME, dev_number); if (start) { - /* start with dev number and name*/ + /* start with dev number and name */ start_dumping(&dev_number, output_file_name); } else if (stop) { - /* stop with dev number*/ + /* stop with dev number */ stop_dumping(&dev_number); } return 0; diff --git a/uspace/lib/pcap/include/pcap_iface.h b/uspace/lib/pcap/include/pcap_iface.h index 94de16e699..5fd095b2fd 100644 --- a/uspace/lib/pcap/include/pcap_iface.h +++ b/uspace/lib/pcap/include/pcap_iface.h @@ -45,9 +45,7 @@ typedef struct pcap_dumper { pcap_writer_t writer; } pcap_dumper_t; - extern void pcap_dumper_stop(struct pcap_dumper *); - extern errno_t pcap_dumper_init(pcap_dumper_t *); // v ramci init jeste linktype prg diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_iface.c index f006694b6b..d7710fe9c6 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_iface.c @@ -84,7 +84,6 @@ static pcap_writer_ops_t file_ops = { // fclose((FILE *)writer->data); // } - // static pcap_writer_ops_t short_file_ops = { // .write_u32 = &pcap_short_file_w32, // .write_u16 = &pcap_short_file_w16, @@ -98,17 +97,13 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) fibril_mutex_lock(&dumper->mutex); /** When try to start when already started, close current and starts new */ - if (dumper->to_dump == true) - { + if (dumper->to_dump == true) { pcap_dumper_stop(dumper); } errno_t rc = pcap_writer_to_file_init(&dumper->writer, name); - if (rc == EOK) - { + if (rc == EOK) { dumper->to_dump = true; - } - else - { + } else { printf("Failed creating pcap dumper: %s", str_error(rc)); } fibril_mutex_unlock(&dumper->mutex); @@ -120,8 +115,7 @@ void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t { fibril_mutex_lock(&dumper->mutex); - if (dumper->writer.data == NULL || !dumper->to_dump) - { + if (dumper->writer.data == NULL || !dumper->to_dump) { fibril_mutex_unlock(&dumper->mutex); return; } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 3304698709..2ca37e2a05 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -159,7 +159,6 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) 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"); diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_iface.c index 72c7669310..62c3a1bd09 100644 --- a/uspace/lib/pcap/src/pcapdump_iface.c +++ b/uspace/lib/pcap/src/pcapdump_iface.c @@ -57,8 +57,7 @@ static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) rc = pcap_dumper_start(dumper, (const char *)data); free(data); - if (rc != EOK) - { + if (rc != EOK) { //TODO what? } async_answer_0(icall, EOK); @@ -133,11 +132,9 @@ errno_t pcapdump_init(pcap_dumper_t *dumper) */ void pcapdump_packet(pcap_dumper_t *dumper, const void *data, size_t size) { - if (dumper == NULL) { return; } - pcap_dumper_add_packet(dumper, data, size); } diff --git a/uspace/srv/net/ethip/ethip.c b/uspace/srv/net/ethip/ethip.c index 00a42e307f..0ede4363bc 100644 --- a/uspace/srv/net/ethip/ethip.c +++ b/uspace/srv/net/ethip/ethip.c @@ -91,7 +91,6 @@ static errno_t ethip_init(void) return rc; } - rc = ethip_nic_discovery_start(); if (rc != EOK) return rc; diff --git a/uspace/srv/net/inetsrv/inetsrv.c b/uspace/srv/net/inetsrv/inetsrv.c index 002586ae6b..425a2b2070 100644 --- a/uspace/srv/net/inetsrv/inetsrv.c +++ b/uspace/srv/net/inetsrv/inetsrv.c @@ -62,7 +62,6 @@ #define NAME "inetsrv" - static inet_naddr_t solicited_node_mask = { .version = ip_v6, .addr6 = { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0 }, From 1d14090b705fa4005fba453cbb74488c510827cc Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Nov 2024 10:08:41 +0100 Subject: [PATCH 22/39] dumper ops can be set by user --- uspace/app/pcapctl/main.c | 41 +++++++++- uspace/lib/nic/include/nic.h | 2 +- uspace/lib/nic/src/nic_driver.c | 2 +- uspace/lib/nic/src/nic_impl.c | 2 +- .../include/{pcap_iface.h => pcap_dumper.h} | 5 +- uspace/lib/pcap/include/pcapctl_dump.h | 5 +- uspace/lib/pcap/include/pcapdump_iface.h | 5 +- uspace/lib/pcap/meson.build | 2 +- uspace/lib/pcap/src/pcap.c | 3 +- .../pcap/src/{pcap_iface.c => pcap_dumper.c} | 82 ++++++++++++------- uspace/lib/pcap/src/pcapctl_dump.c | 24 +++++- uspace/lib/pcap/src/pcapdump_iface.c | 24 ++++++ 12 files changed, 150 insertions(+), 47 deletions(-) rename uspace/lib/pcap/include/{pcap_iface.h => pcap_dumper.h} (96%) rename uspace/lib/pcap/src/{pcap_iface.c => pcap_dumper.c} (73%) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 5c8d2b2d21..fe114ea01f 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -51,7 +51,11 @@ static errno_t start_dumping(int *dev_number, const char *name) return 1; } - pcapctl_dump_start(name, sess); + rc = pcapctl_dump_start(name, sess); + if (rc != EOK) + { + printf("Starting the dumping was not successful.\n"); + } pcapctl_dump_close(sess); return EOK; } @@ -63,7 +67,29 @@ static errno_t stop_dumping(int *dev_number) if (rc != EOK) { return 1; } - pcapctl_dump_stop(sess); + rc = pcapctl_dump_stop(sess); + if (rc != EOK) + { + printf("Stoping the dumping was not successful.\n"); + } + pcapctl_dump_close(sess); + return EOK; +} + +static errno_t set_dumper_ops(int *dev_number, const char *name) +{ + pcapctl_sess_t *sess = NULL; + errno_t rc = pcapctl_dump_open(dev_number, &sess); + if (rc != EOK) + { + return rc; + } + + rc = pcapctl_dump_set_ops(name, sess); + if (rc != EOK) + { + printf("Setting dumper ops was not successful.\n"); + } pcapctl_dump_close(sess); return EOK; } @@ -83,6 +109,7 @@ static const struct option opts[] = { { "outfile", required_argument, 0, 'f' }, { "start", no_argument, 0, 'r' }, { "stop", no_argument, 0, 't' }, + { "ops", required_argument, 0, 'o' }, { 0, 0, 0, 0 } }; @@ -105,8 +132,10 @@ int main(int argc, char *argv[]) { bool start = false; bool stop = false; + bool set_ops = false; int dev_number = -1; const char *output_file_name = ""; + const char *ops_name = ""; int idx = 0; int ret = 0; if (argc == 1) { @@ -141,6 +170,10 @@ int main(int argc, char *argv[]) case 't': stop = true; break; + case 'o': + set_ops = true; + ops_name = optarg; + break; } } @@ -153,6 +186,10 @@ int main(int argc, char *argv[]) /* stop with dev number */ stop_dumping(&dev_number); } + else if (set_ops) + { + set_dumper_ops(&dev_number, ops_name); + } return 0; } diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index 0816f74437..e46362057a 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #define DEVICE_CATEGORY_NIC "nic" diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index ffbb76feff..cc567aa30a 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -561,7 +561,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) } fibril_rwlock_write_unlock(&nic_data->stats_lock); } - pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); nic_release_frame(nic_data, frame); } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index 39fe80531b..1ae2ed836e 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -179,7 +179,7 @@ errno_t nic_send_frame_impl(ddf_fun_t *fun, void *data, size_t size) fibril_rwlock_read_unlock(&nic_data->main_lock); return EBUSY; } - //pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); + pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); nic_data->send_frame(nic_data, data, size); fibril_rwlock_read_unlock(&nic_data->main_lock); return EOK; diff --git a/uspace/lib/pcap/include/pcap_iface.h b/uspace/lib/pcap/include/pcap_dumper.h similarity index 96% rename from uspace/lib/pcap/include/pcap_iface.h rename to uspace/lib/pcap/include/pcap_dumper.h index 5fd095b2fd..618caae7f5 100644 --- a/uspace/lib/pcap/include/pcap_iface.h +++ b/uspace/lib/pcap/include/pcap_dumper.h @@ -47,10 +47,7 @@ typedef struct pcap_dumper { extern void pcap_dumper_stop(struct pcap_dumper *); extern errno_t pcap_dumper_init(pcap_dumper_t *); - -// v ramci init jeste linktype prg -//set snaplen taky lze pridavat prg - +extern errno_t pcap_dumper_set_ops(struct pcap_dumper *, const char *); extern errno_t pcap_dumper_start(struct pcap_dumper *, const char *); extern void pcap_dumper_add_packet(struct pcap_dumper *, const void *data, size_t size); diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapctl_dump.h index c15c3b66bc..0d84848aeb 100644 --- a/uspace/lib/pcap/include/pcapctl_dump.h +++ b/uspace/lib/pcap/include/pcapctl_dump.h @@ -48,9 +48,10 @@ typedef struct { async_sess_t *sess; } pcapctl_sess_t; -extern errno_t pcapctl_dump_open(int *, pcapctl_sess_t **rsess); -extern errno_t pcapctl_dump_close(pcapctl_sess_t *sess); +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 *, pcapctl_sess_t *); +extern errno_t pcapctl_dump_set_ops(const char *, 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 *); diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_iface.h index ded1df85d6..5170a9d653 100644 --- a/uspace/lib/pcap/include/pcapdump_iface.h +++ b/uspace/lib/pcap/include/pcapdump_iface.h @@ -39,12 +39,13 @@ #define _PCAPDUMP_IFACE_H_ #include -#include "pcap_iface.h" +#include "pcap_dumper.h" typedef enum { PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, PCAP_CONTROL_SET_STOP, - PCAP_CONTROL_GET_NAME + PCAP_CONTROL_GET_NAME, + PCAP_CONTROL_SET_OPS, } pcap_request_t; extern errno_t pcapdump_init(pcap_dumper_t *); diff --git a/uspace/lib/pcap/meson.build b/uspace/lib/pcap/meson.build index bb70637845..1a0b6b4a4c 100644 --- a/uspace/lib/pcap/meson.build +++ b/uspace/lib/pcap/meson.build @@ -28,7 +28,7 @@ src = files( 'src/pcap.c', - 'src/pcap_iface.c', + 'src/pcap_dumper.c', 'src/pcapdump_iface.c', 'src/pcapctl_dump.c', ) diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index b5ac2a4116..87b672a147 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -71,8 +71,7 @@ void pcap_writer_add_header(pcap_writer_t *writer) */ void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size) { - if (!writer->data) - return; + pcap_packet_header_t pcap_packet; pcap_set_time(&pcap_packet); pcap_packet.original_length = size; diff --git a/uspace/lib/pcap/src/pcap_iface.c b/uspace/lib/pcap/src/pcap_dumper.c similarity index 73% rename from uspace/lib/pcap/src/pcap_iface.c rename to uspace/lib/pcap/src/pcap_dumper.c index d7710fe9c6..5c1a9f83fc 100644 --- a/uspace/lib/pcap/src/pcap_iface.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -34,7 +34,8 @@ */ #include -#include "pcap_iface.h" +#include +#include "pcap_dumper.h" static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data) { @@ -48,12 +49,14 @@ static size_t pcap_file_w16(pcap_writer_t *writer, uint16_t 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); } static void pcap_file_close(pcap_writer_t *writer) { fclose((FILE *)writer->data); + writer->data = NULL; } static pcap_writer_ops_t file_ops = { @@ -64,40 +67,40 @@ static pcap_writer_ops_t file_ops = { .close = &pcap_file_close }; -// static size_t pcap_short_file_w32(pcap_writer_t *writer, uint32_t data) -// { -// return fwrite(&data, 1, 4, (FILE *)writer->data); -// } +static size_t pcap_short_file_w32(pcap_writer_t *writer, uint32_t data) +{ + return fwrite(&data, 1, 4, (FILE *)writer->data); +} -// static size_t pcap_short_file_w16(pcap_writer_t *writer, uint16_t data) -// { -// return fwrite(&data, 1, 2, (FILE *)writer->data); -// } +static size_t pcap_short_file_w16(pcap_writer_t *writer, uint16_t data) +{ + return fwrite(&data, 1, 2, (FILE *)writer->data); +} -// static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) -// { -// return fwrite(data, 1, size<60?size:60, (FILE *)writer->data); -// } +static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) +{ + return fwrite(data, 1, size<60?size:60, (FILE *)writer->data); +} -// static void pcap_short_file_close(pcap_writer_t *writer) -// { -// fclose((FILE *)writer->data); -// } +static void pcap_short_file_close(pcap_writer_t *writer) +{ + fclose((FILE *)writer->data); +} -// static pcap_writer_ops_t short_file_ops = { -// .write_u32 = &pcap_short_file_w32, -// .write_u16 = &pcap_short_file_w16, -// .write_buffer = &pcap_short_file_wbuffer, -// .close = &pcap_short_file_close +static pcap_writer_ops_t short_file_ops = { + .write_u32 = &pcap_short_file_w32, + .write_u16 = &pcap_short_file_w16, + .write_buffer = &pcap_short_file_wbuffer, + .close = &pcap_short_file_close -// }; +}; errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) { fibril_mutex_lock(&dumper->mutex); /** When try to start when already started, close current and starts new */ - if (dumper->to_dump == true) { + if (dumper->to_dump) { pcap_dumper_stop(dumper); } errno_t rc = pcap_writer_to_file_init(&dumper->writer, name); @@ -110,32 +113,51 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) return rc; } -//udelat globalni +errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, const char *name) +{ + fibril_mutex_lock(&dumper->mutex); + errno_t rc = EOK; + if (!str_cmp(name, "short_file")) + { + dumper->writer.ops = &short_file_ops; + } + else if (!str_cmp(name, "full_file")) + { + dumper->writer.ops = &file_ops; + } + else + { + rc = EINVAL; + } + fibril_mutex_unlock(&dumper->mutex); + return rc; +} + + void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t size) { fibril_mutex_lock(&dumper->mutex); - if (dumper->writer.data == NULL || !dumper->to_dump) { + if (!dumper->to_dump) { fibril_mutex_unlock(&dumper->mutex); return; } + pcap_writer_add_packet(&dumper->writer, data, size); fibril_mutex_unlock(&dumper->mutex); } -//udelt globalni void pcap_dumper_stop(struct pcap_dumper *dumper) { fibril_mutex_lock(&dumper->mutex); /** If want to stop, when already stopped, do nothing */ - if (dumper->to_dump == false) { + if (!dumper->to_dump) { fibril_mutex_unlock(&dumper->mutex); return; } dumper->to_dump = false; dumper->writer.ops->close(&dumper->writer); - dumper->writer.data = NULL; fibril_mutex_unlock(&dumper->mutex); } @@ -148,7 +170,7 @@ errno_t pcap_dumper_init(pcap_dumper_t *dumper) { fibril_mutex_initialize(&dumper->mutex); dumper->to_dump = false; - dumper->writer.ops = &file_ops; + dumper->writer.ops = NULL; return EOK; } diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapctl_dump.c index 2ca37e2a05..8a5da57184 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapctl_dump.c @@ -197,7 +197,7 @@ errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) size_t size = str_size(name); aid_t req = async_send_0(exch, PCAP_CONTROL_SET_START, NULL); - rc = async_data_write_start(exch, (const void *)name, size); + rc = async_data_write_start(exch, name, size); pcapctl_dump_exchange_end(exch); @@ -226,5 +226,27 @@ errno_t pcapctl_dump_stop(pcapctl_sess_t *sess) return rc; } +errno_t pcapctl_dump_set_ops(const char *ops_name, pcapctl_sess_t *sess) +{ + errno_t rc; + async_exch_t *exch = async_exchange_begin(sess->sess); + + size_t size = str_size(ops_name); + aid_t req = async_send_0(exch, PCAP_CONTROL_SET_OPS, NULL); + + rc = async_data_write_start(exch, ops_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; +} + /** @} */ diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_iface.c index 62c3a1bd09..86a843d9d0 100644 --- a/uspace/lib/pcap/src/pcapdump_iface.c +++ b/uspace/lib/pcap/src/pcapdump_iface.c @@ -69,6 +69,27 @@ static void pcapdump_stop_srv(ipc_call_t *icall, pcap_dumper_t *dumper) async_answer_0(icall, EOK); } +static void pcapdump_set_ops_srv(ipc_call_t *icall, pcap_dumper_t *dumper) +{ + char *data; + size_t size; + 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"); + + rc = pcap_dumper_set_ops(dumper, (const char *)data); + free(data); + if (rc != EOK) { + //TODO what? + } + async_answer_0(icall, EOK); + +} + void pcapdump_conn(ipc_call_t *icall, void *arg) { pcap_dumper_t *dumper = (pcap_dumper_t *)arg; @@ -94,6 +115,9 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) case PCAP_CONTROL_SET_STOP: pcapdump_stop_srv(&call, dumper); break; + case PCAP_CONTROL_SET_OPS: + pcapdump_set_ops_srv(&call, dumper); + break; default: async_answer_0(&call, EINVAL); break; From 64ea52540d7ba538c1a62e625d2a88ba1521b400 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Nov 2024 10:31:01 +0100 Subject: [PATCH 23/39] init dumping destionation move to ops --- uspace/app/pcapctl/main.c | 16 ++++--------- uspace/lib/pcap/include/pcap.h | 7 ++---- uspace/lib/pcap/src/pcap.c | 21 ---------------- uspace/lib/pcap/src/pcap_dumper.c | 40 +++++++++++++++++++++---------- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index fe114ea01f..7ac7eed716 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -52,8 +52,7 @@ static errno_t start_dumping(int *dev_number, const char *name) } rc = pcapctl_dump_start(name, sess); - if (rc != EOK) - { + if (rc != EOK) { printf("Starting the dumping was not successful.\n"); } pcapctl_dump_close(sess); @@ -68,8 +67,7 @@ static errno_t stop_dumping(int *dev_number) return 1; } rc = pcapctl_dump_stop(sess); - if (rc != EOK) - { + if (rc != EOK) { printf("Stoping the dumping was not successful.\n"); } pcapctl_dump_close(sess); @@ -80,14 +78,12 @@ static errno_t set_dumper_ops(int *dev_number, const char *name) { pcapctl_sess_t *sess = NULL; errno_t rc = pcapctl_dump_open(dev_number, &sess); - if (rc != EOK) - { + if (rc != EOK) { return rc; } rc = pcapctl_dump_set_ops(name, sess); - if (rc != EOK) - { + if (rc != EOK) { printf("Setting dumper ops was not successful.\n"); } pcapctl_dump_close(sess); @@ -185,9 +181,7 @@ int main(int argc, char *argv[]) } else if (stop) { /* stop with dev number */ stop_dumping(&dev_number); - } - else if (set_ops) - { + } else if (set_ops) { set_dumper_ops(&dev_number, ops_name); } return 0; diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 61297312a9..84f75181d2 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -79,6 +79,7 @@ typedef struct pcap_packet_header { typedef struct pcap_writer pcap_writer_t; typedef struct { + errno_t (*open)(struct pcap_writer *, const char *); size_t (*write_u32)(struct pcap_writer *, uint32_t); size_t (*write_u16)(struct pcap_writer *, uint16_t); size_t (*write_buffer)(struct pcap_writer *, const void *, size_t); @@ -93,12 +94,8 @@ typedef struct pcap_writer { pcap_writer_ops_t *ops; } pcap_writer_t; -errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename); - extern void pcap_writer_add_header(pcap_writer_t *); -extern void pcap_writer_add_packet( - pcap_writer_t *writer, const void *captured_packet, size_t size); - +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 diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 87b672a147..5d185b6719 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -86,26 +86,5 @@ void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, } -/** Initialize writing to .pcap file. - * - * @param writer Interface for working with .pcap file - * @param filename Name of the file for dumping packets - * @return EOK on success or an error code - * - */ -errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) -{ - errno_t rc; - writer->data = fopen(filename, "a"); - if (writer->data == NULL) { - rc = EINVAL; - return rc; - } - pcap_writer_add_header(writer); - - rc = EOK; - return rc; -} - /** @} */ diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 5c1a9f83fc..7db303288f 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -37,6 +37,27 @@ #include #include "pcap_dumper.h" +/** Initialize writing to .pcap file. + * + * @param writer Interface for working with .pcap file + * @param filename Name of the file for dumping packets + * @return EOK on success or an error code + * + */ +static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) +{ + errno_t rc; + writer->data = fopen(filename, "a"); + if (writer->data == NULL) { + rc = EINVAL; + return rc; + } + pcap_writer_add_header(writer); + + rc = EOK; + return rc; +} + static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data) { return fwrite(&data, 1, 4, (FILE *)writer->data); @@ -60,7 +81,7 @@ static void pcap_file_close(pcap_writer_t *writer) } static 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, @@ -79,7 +100,7 @@ static size_t pcap_short_file_w16(pcap_writer_t *writer, uint16_t data) static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) { - return fwrite(data, 1, size<60?size:60, (FILE *)writer->data); + return fwrite(data, 1, size < 60 ? size : 60, (FILE *)writer->data); } static void pcap_short_file_close(pcap_writer_t *writer) @@ -88,6 +109,7 @@ static void pcap_short_file_close(pcap_writer_t *writer) } static pcap_writer_ops_t short_file_ops = { + .open = &pcap_writer_to_file_init, .write_u32 = &pcap_short_file_w32, .write_u16 = &pcap_short_file_w16, .write_buffer = &pcap_short_file_wbuffer, @@ -103,7 +125,7 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) if (dumper->to_dump) { pcap_dumper_stop(dumper); } - errno_t rc = pcap_writer_to_file_init(&dumper->writer, name); + errno_t rc = dumper->writer.ops->open(&dumper->writer, name); if (rc == EOK) { dumper->to_dump = true; } else { @@ -117,23 +139,17 @@ errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, const char *name) { fibril_mutex_lock(&dumper->mutex); errno_t rc = EOK; - if (!str_cmp(name, "short_file")) - { + if (!str_cmp(name, "short_file")) { dumper->writer.ops = &short_file_ops; - } - else if (!str_cmp(name, "full_file")) - { + } else if (!str_cmp(name, "full_file")) { dumper->writer.ops = &file_ops; - } - else - { + } else { rc = EINVAL; } fibril_mutex_unlock(&dumper->mutex); return rc; } - void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t size) { fibril_mutex_lock(&dumper->mutex); From f161ce1546b7bccc00c4d5db104db3aeb2c6216a Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Nov 2024 11:02:57 +0100 Subject: [PATCH 24/39] renaming and cleaning --- uspace/app/pcapctl/main.c | 2 +- uspace/drv/nic/e1k/e1k.c | 1 - uspace/drv/nic/rtl8139/driver.c | 1 - uspace/drv/nic/virtio-net/virtio-net.c | 1 - uspace/lib/nic/include/nic_driver.h | 2 +- uspace/lib/nic/src/nic_driver.c | 2 +- uspace/lib/nic/src/nic_impl.c | 2 +- uspace/lib/pcap/include/{pcapctl_dump.h => pcapdump_client.h} | 0 uspace/lib/pcap/include/{pcapdump_iface.h => pcapdump_srv.h} | 0 uspace/lib/pcap/meson.build | 4 ++-- uspace/lib/pcap/src/{pcapctl_dump.c => pcapdump_client.c} | 4 ++-- uspace/lib/pcap/src/{pcapdump_iface.c => pcapdump_srv.c} | 2 +- uspace/srv/net/ethip/ethip.c | 1 - 13 files changed, 9 insertions(+), 13 deletions(-) rename uspace/lib/pcap/include/{pcapctl_dump.h => pcapdump_client.h} (100%) rename uspace/lib/pcap/include/{pcapdump_iface.h => pcapdump_srv.h} (100%) rename uspace/lib/pcap/src/{pcapctl_dump.c => pcapdump_client.c} (99%) rename uspace/lib/pcap/src/{pcapdump_iface.c => pcapdump_srv.c} (99%) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 7ac7eed716..fcfb386621 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -38,7 +38,7 @@ #include #include -#include "pcapctl_dump.h" +#include "pcapdump_client.h" #define NAME "pcapctl" #define DEFAULT_DEV_NUM 0 diff --git a/uspace/drv/nic/e1k/e1k.c b/uspace/drv/nic/e1k/e1k.c index dc811a847b..02fd900546 100644 --- a/uspace/drv/nic/e1k/e1k.c +++ b/uspace/drv/nic/e1k/e1k.c @@ -48,7 +48,6 @@ #include #include #include -#include #include "e1k.h" #define NAME "e1k" diff --git a/uspace/drv/nic/rtl8139/driver.c b/uspace/drv/nic/rtl8139/driver.c index 46b5960b12..2177b456f4 100644 --- a/uspace/drv/nic/rtl8139/driver.c +++ b/uspace/drv/nic/rtl8139/driver.c @@ -41,7 +41,6 @@ #include #include #include -#include #include "defs.h" #include "driver.h" diff --git a/uspace/drv/nic/virtio-net/virtio-net.c b/uspace/drv/nic/virtio-net/virtio-net.c index 5f4051b75c..2be085532c 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.c +++ b/uspace/drv/nic/virtio-net/virtio-net.c @@ -42,7 +42,6 @@ #include #include -#include #define NAME "virtio-net" diff --git a/uspace/lib/nic/include/nic_driver.h b/uspace/lib/nic/include/nic_driver.h index 03d543e93b..e8dbf96417 100644 --- a/uspace/lib/nic/include/nic_driver.h +++ b/uspace/lib/nic/include/nic_driver.h @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include "nic.h" #include "nic_rx_control.h" diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index cc567aa30a..1fff7b125d 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include "nic_driver.h" #include "nic_ev.h" diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index 1ae2ed836e..74755fe28b 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include "nic_driver.h" #include "nic_ev.h" #include "nic_impl.h" diff --git a/uspace/lib/pcap/include/pcapctl_dump.h b/uspace/lib/pcap/include/pcapdump_client.h similarity index 100% rename from uspace/lib/pcap/include/pcapctl_dump.h rename to uspace/lib/pcap/include/pcapdump_client.h diff --git a/uspace/lib/pcap/include/pcapdump_iface.h b/uspace/lib/pcap/include/pcapdump_srv.h similarity index 100% rename from uspace/lib/pcap/include/pcapdump_iface.h rename to uspace/lib/pcap/include/pcapdump_srv.h diff --git a/uspace/lib/pcap/meson.build b/uspace/lib/pcap/meson.build index 1a0b6b4a4c..253e83c341 100644 --- a/uspace/lib/pcap/meson.build +++ b/uspace/lib/pcap/meson.build @@ -29,6 +29,6 @@ src = files( 'src/pcap.c', 'src/pcap_dumper.c', - 'src/pcapdump_iface.c', - 'src/pcapctl_dump.c', + 'src/pcapdump_srv.c', + 'src/pcapdump_client.c', ) diff --git a/uspace/lib/pcap/src/pcapctl_dump.c b/uspace/lib/pcap/src/pcapdump_client.c similarity index 99% rename from uspace/lib/pcap/src/pcapctl_dump.c rename to uspace/lib/pcap/src/pcapdump_client.c index 8a5da57184..dbb01ecbbd 100644 --- a/uspace/lib/pcap/src/pcapctl_dump.c +++ b/uspace/lib/pcap/src/pcapdump_client.c @@ -39,8 +39,8 @@ #include #include #include -#include "pcapctl_dump.h" -#include "pcapdump_iface.h" +#include "pcapdump_client.h" +#include "pcapdump_srv.h" /** Finish an async exchange on the pcapctl session * diff --git a/uspace/lib/pcap/src/pcapdump_iface.c b/uspace/lib/pcap/src/pcapdump_srv.c similarity index 99% rename from uspace/lib/pcap/src/pcapdump_iface.c rename to uspace/lib/pcap/src/pcapdump_srv.c index 86a843d9d0..fb05e2cc60 100644 --- a/uspace/lib/pcap/src/pcapdump_iface.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -41,7 +41,7 @@ #include #include -#include "pcapdump_iface.h" +#include "pcapdump_srv.h" static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) { diff --git a/uspace/srv/net/ethip/ethip.c b/uspace/srv/net/ethip/ethip.c index 0ede4363bc..3b1dbf3f62 100644 --- a/uspace/srv/net/ethip/ethip.c +++ b/uspace/srv/net/ethip/ethip.c @@ -45,7 +45,6 @@ #include #include #include -#include #include "arp.h" #include "ethip.h" #include "ethip_nic.h" From 467d2b98ec891dbd3a427c37d18d7e695350113a Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 10 Nov 2024 19:34:17 +0100 Subject: [PATCH 25/39] logger --- uspace/lib/pcap/include/pcap.h | 11 +++++------ uspace/lib/pcap/src/pcap.c | 2 +- uspace/lib/pcap/src/pcap_dumper.c | 17 ++++++++++++----- uspace/lib/pcap/src/pcapdump_srv.c | 15 +++++++++------ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 84f75181d2..81126110bb 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -57,8 +57,7 @@ #define WIRESHARK_EX 0xc #define WIRESHARK_SNAPLEN 0xffff -/** Header of the .pcap file - */ +/** Header of the .pcap file. */ typedef struct { uint32_t magic_number; uint16_t major_v; @@ -69,6 +68,7 @@ typedef struct { 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; @@ -78,23 +78,22 @@ typedef struct pcap_packet_header { typedef struct pcap_writer pcap_writer_t; +/** Operations for dumper. */ typedef struct { errno_t (*open)(struct pcap_writer *, const char *); size_t (*write_u32)(struct pcap_writer *, uint32_t); size_t (*write_u16)(struct pcap_writer *, uint16_t); size_t (*write_buffer)(struct pcap_writer *, const void *, size_t); void (*close)(struct pcap_writer *); - } pcap_writer_ops_t; -/** Interface for working with .pcap file - */ +/** Interface for working with .pcap file. */ typedef struct pcap_writer { void *data; pcap_writer_ops_t *ops; } pcap_writer_t; -extern void pcap_writer_add_header(pcap_writer_t *); +extern void pcap_writer_add_header(pcap_writer_t *writer); 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); diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 5d185b6719..e090c8ac94 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -52,7 +52,7 @@ void pcap_set_time(pcap_packet_header_t *header) /** Add pcap file header to the new .pcap file. * - * @param writer + * @param writer writer that has destination buffer and ops to write to destination buffer. * */ void pcap_writer_add_header(pcap_writer_t *writer) diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 7db303288f..2760df55dd 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -35,13 +35,14 @@ #include #include +#include #include "pcap_dumper.h" /** Initialize writing to .pcap file. * - * @param writer Interface for working with .pcap file - * @param filename Name of the file for dumping packets - * @return EOK on success or an error code + * @param writer Interface for working with .pcap file. + * @param filename Name of the file for dumping packets. + * @return EOK on success or an error code. * */ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) @@ -125,12 +126,12 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) if (dumper->to_dump) { pcap_dumper_stop(dumper); } + errno_t rc = dumper->writer.ops->open(&dumper->writer, name); if (rc == EOK) { dumper->to_dump = true; - } else { - printf("Failed creating pcap dumper: %s", str_error(rc)); } + fibril_mutex_unlock(&dumper->mutex); return rc; } @@ -187,6 +188,12 @@ errno_t pcap_dumper_init(pcap_dumper_t *dumper) fibril_mutex_initialize(&dumper->mutex); dumper->to_dump = false; dumper->writer.ops = NULL; + + errno_t rc = log_init("pcap"); + if (rc != EOK) { + printf("pcap : Failed to initialize log.\n"); + return 1; + } return EOK; } diff --git a/uspace/lib/pcap/src/pcapdump_srv.c b/uspace/lib/pcap/src/pcapdump_srv.c index fb05e2cc60..de083ba68b 100644 --- a/uspace/lib/pcap/src/pcapdump_srv.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "pcapdump_srv.h" @@ -58,7 +59,7 @@ static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) rc = pcap_dumper_start(dumper, (const char *)data); free(data); if (rc != EOK) { - //TODO what? + log_msg(LOG_DEFAULT, LVL_DEBUG, "Starting the dumping was not successful.\n"); } async_answer_0(icall, EOK); } @@ -84,10 +85,12 @@ static void pcapdump_set_ops_srv(ipc_call_t *icall, pcap_dumper_t *dumper) rc = pcap_dumper_set_ops(dumper, (const char *)data); free(data); if (rc != EOK) { - //TODO what? + log_msg(LOG_DEFAULT, LVL_DEBUG, "Setting ops for dumper was not successful.\n"); } - async_answer_0(icall, EOK); + log_msg(LOG_DEFAULT, LVL_NOTE, "Setting ops for dumper was successful.\n"); + + async_answer_0(icall, EOK); } void pcapdump_conn(ipc_call_t *icall, void *arg) @@ -133,13 +136,13 @@ errno_t pcapdump_init(pcap_dumper_t *dumper) rc = pcap_dumper_init(dumper); if (rc != EOK) { - printf("Failed creating pcap interface: %s", str_error(rc)); + log_msg(LOG_DEFAULT, LVL_DEBUG, "Failed creating pcap interface: %s", str_error(rc)); return rc; } - rc = async_create_port(INTERFACE_PCAP_CONTROL, - pcapdump_conn, dumper, &port); + rc = async_create_port(INTERFACE_PCAP_CONTROL, pcapdump_conn, dumper, &port); if (rc != EOK) { + log_msg(LOG_DEFAULT, LVL_DEBUG, "Failed creating port: %s", str_error(rc)); return rc; } return EOK; From e1e8f7a30634baf2e129e1afccd3b463b330bc55 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 16 Nov 2024 12:14:06 +0100 Subject: [PATCH 26/39] set ops as number and with start req --- uspace/app/pcapctl/main.c | 45 ++++++-------- uspace/lib/pcap/include/pcap.h | 6 +- uspace/lib/pcap/include/pcap_dumper.h | 5 +- uspace/lib/pcap/include/pcapdump_client.h | 6 +- uspace/lib/pcap/include/pcapdump_ipc.h | 52 ++++++++++++++++ uspace/lib/pcap/include/pcapdump_srv.h | 7 --- uspace/lib/pcap/src/pcap_dumper.c | 76 ++++++++++++----------- uspace/lib/pcap/src/pcapdump_client.c | 52 ++++++++-------- uspace/lib/pcap/src/pcapdump_srv.c | 38 ++++++------ 9 files changed, 165 insertions(+), 122 deletions(-) create mode 100644 uspace/lib/pcap/include/pcapdump_ipc.h diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index fcfb386621..86badbc4e2 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -42,8 +42,9 @@ #define NAME "pcapctl" #define DEFAULT_DEV_NUM 0 +#define DECIMAL_SYSTEM 10 -static errno_t start_dumping(int *dev_number, const char *name) +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); @@ -51,7 +52,15 @@ static errno_t start_dumping(int *dev_number, const char *name) return 1; } - rc = pcapctl_dump_start(name, sess); + 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) { printf("Starting the dumping was not successful.\n"); } @@ -74,22 +83,6 @@ static errno_t stop_dumping(int *dev_number) return EOK; } -static errno_t set_dumper_ops(int *dev_number, const char *name) -{ - pcapctl_sess_t *sess = NULL; - errno_t rc = pcapctl_dump_open(dev_number, &sess); - if (rc != EOK) { - return rc; - } - - rc = pcapctl_dump_set_ops(name, sess); - if (rc != EOK) { - printf("Setting dumper ops was not successful.\n"); - } - pcapctl_dump_close(sess); - return EOK; -} - static void list_devs(void) { pcapctl_list(); @@ -128,10 +121,9 @@ int main(int argc, char *argv[]) { bool start = false; bool stop = false; - bool set_ops = false; int dev_number = -1; + int ops_number = -1; const char *output_file_name = ""; - const char *ops_name = ""; int idx = 0; int ret = 0; if (argc == 1) { @@ -143,8 +135,8 @@ int main(int argc, char *argv[]) switch (ret) { case 'd': char *rest; - long result = strtol(optarg, &rest, 10); - dev_number = (int)result; + 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); @@ -167,8 +159,9 @@ int main(int argc, char *argv[]) stop = true; break; case 'o': - set_ops = true; - ops_name = optarg; + char* ops_inval; + long ops_result = strtol(optarg, &ops_inval, DECIMAL_SYSTEM); + ops_number = (int)ops_result; break; } } @@ -177,12 +170,10 @@ int main(int argc, char *argv[]) if (start) { /* start with dev number and name */ - start_dumping(&dev_number, output_file_name); + start_dumping(&dev_number, output_file_name, &ops_number); } else if (stop) { /* stop with dev number */ stop_dumping(&dev_number); - } else if (set_ops) { - set_dumper_ops(&dev_number, ops_name); } return 0; } diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 81126110bb..b7ba6e34fc 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -80,7 +80,7 @@ typedef struct pcap_writer pcap_writer_t; /** Operations for dumper. */ typedef struct { - errno_t (*open)(struct pcap_writer *, const char *); + errno_t (*open)(pcap_writer_t *, const char *); size_t (*write_u32)(struct pcap_writer *, uint32_t); size_t (*write_u16)(struct pcap_writer *, uint16_t); size_t (*write_buffer)(struct pcap_writer *, const void *, size_t); @@ -88,10 +88,10 @@ typedef struct { } pcap_writer_ops_t; /** Interface for working with .pcap file. */ -typedef struct pcap_writer { +struct pcap_writer { void *data; pcap_writer_ops_t *ops; -} pcap_writer_t; +}; extern void pcap_writer_add_header(pcap_writer_t *writer); extern void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size); diff --git a/uspace/lib/pcap/include/pcap_dumper.h b/uspace/lib/pcap/include/pcap_dumper.h index 618caae7f5..2c8f6683ef 100644 --- a/uspace/lib/pcap/include/pcap_dumper.h +++ b/uspace/lib/pcap/include/pcap_dumper.h @@ -46,8 +46,9 @@ typedef struct pcap_dumper { } pcap_dumper_t; extern void pcap_dumper_stop(struct pcap_dumper *); -extern errno_t pcap_dumper_init(pcap_dumper_t *); -extern errno_t pcap_dumper_set_ops(struct pcap_dumper *, const char *); +extern errno_t pcap_dumper_init(pcap_dumper_t *); ///tahle +extern int pcap_dumper_get_ops_number(void); +extern errno_t pcap_dumper_set_ops(struct pcap_dumper *, int); extern errno_t pcap_dumper_start(struct pcap_dumper *, const char *); extern void pcap_dumper_add_packet(struct pcap_dumper *, const void *data, size_t size); diff --git a/uspace/lib/pcap/include/pcapdump_client.h b/uspace/lib/pcap/include/pcapdump_client.h index 0d84848aeb..30e8cd3640 100644 --- a/uspace/lib/pcap/include/pcapdump_client.h +++ b/uspace/lib/pcap/include/pcapdump_client.h @@ -50,11 +50,13 @@ typedef struct { 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 *, pcapctl_sess_t *); -extern errno_t pcapctl_dump_set_ops(const char *, pcapctl_sess_t *); +extern errno_t pcapctl_dump_start(const char *, int *, pcapctl_sess_t *); +// extern errno_t pcapctl_dump_set_ops(const char *, 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 *index, pcapctl_sess_t* sess); + #endif diff --git a/uspace/lib/pcap/include/pcapdump_ipc.h b/uspace/lib/pcap/include/pcapdump_ipc.h new file mode 100644 index 0000000000..6ccd6d25c6 --- /dev/null +++ b/uspace/lib/pcap/include/pcapdump_ipc.h @@ -0,0 +1,52 @@ +/* + * 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 + +typedef enum { + PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, + PCAP_CONTROL_SET_STOP, + PCAP_CONTROL_GET_OPS_NUM, +} pcap_request_t; + +#endif + +/** @} + */ diff --git a/uspace/lib/pcap/include/pcapdump_srv.h b/uspace/lib/pcap/include/pcapdump_srv.h index 5170a9d653..ffa571d22d 100644 --- a/uspace/lib/pcap/include/pcapdump_srv.h +++ b/uspace/lib/pcap/include/pcapdump_srv.h @@ -41,13 +41,6 @@ #include #include "pcap_dumper.h" -typedef enum { - PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, - PCAP_CONTROL_SET_STOP, - PCAP_CONTROL_GET_NAME, - PCAP_CONTROL_SET_OPS, -} pcap_request_t; - extern errno_t pcapdump_init(pcap_dumper_t *); extern void pcapdump_packet(pcap_dumper_t *, const void *, size_t); extern void pcapdump_conn(ipc_call_t *, void *); diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 2760df55dd..b690721e31 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -38,6 +38,9 @@ #include #include "pcap_dumper.h" +#define SHORT_OPS_BYTE_COUNT 60 +#define NAME "pcap" + /** Initialize writing to .pcap file. * * @param writer Interface for working with .pcap file. @@ -47,16 +50,23 @@ */ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) { - errno_t rc; writer->data = fopen(filename, "a"); if (writer->data == NULL) { - rc = EINVAL; - return rc; + return EINVAL; } pcap_writer_add_header(writer); - rc = EOK; - return rc; + return EOK; +} + +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; } static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data) @@ -81,7 +91,7 @@ static void pcap_file_close(pcap_writer_t *writer) writer->data = NULL; } -static pcap_writer_ops_t file_ops = { +static const pcap_writer_ops_t file_ops = { .open = &pcap_writer_to_file_init, .write_u32 = &pcap_file_w32, .write_u16 = &pcap_file_w16, @@ -89,35 +99,35 @@ static pcap_writer_ops_t file_ops = { .close = &pcap_file_close }; -static size_t pcap_short_file_w32(pcap_writer_t *writer, uint32_t data) -{ - return fwrite(&data, 1, 4, (FILE *)writer->data); -} - -static size_t pcap_short_file_w16(pcap_writer_t *writer, uint16_t data) -{ - return fwrite(&data, 1, 2, (FILE *)writer->data); -} - static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) { - return fwrite(data, 1, size < 60 ? size : 60, (FILE *)writer->data); + return fwrite(data, 1, size < 60 ? size : 60, (FILE *)writer->data); //define } -static void pcap_short_file_close(pcap_writer_t *writer) -{ - fclose((FILE *)writer->data); -} - -static pcap_writer_ops_t short_file_ops = { +static const pcap_writer_ops_t short_file_ops = { .open = &pcap_writer_to_file_init, - .write_u32 = &pcap_short_file_w32, - .write_u16 = &pcap_short_file_w16, + .write_u32 = &pcap_file_w32, + .write_u16 = &pcap_file_w16, .write_buffer = &pcap_short_file_wbuffer, - .close = &pcap_short_file_close + .close = &pcap_file_close + +}; +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 }; +static pcap_writer_ops_t ops[3] = {file_ops, short_file_ops, append_file_ops}; + +int pcap_dumper_get_ops_number(void) +{ + return (int)(sizeof(ops) / sizeof(pcap_writer_ops_t)); +} + errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) { fibril_mutex_lock(&dumper->mutex); @@ -136,17 +146,11 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) return rc; } -errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, const char *name) +errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, int index) { fibril_mutex_lock(&dumper->mutex); errno_t rc = EOK; - if (!str_cmp(name, "short_file")) { - dumper->writer.ops = &short_file_ops; - } else if (!str_cmp(name, "full_file")) { - dumper->writer.ops = &file_ops; - } else { - rc = EINVAL; - } + dumper->writer.ops = &ops[index]; fibril_mutex_unlock(&dumper->mutex); return rc; } @@ -189,9 +193,9 @@ errno_t pcap_dumper_init(pcap_dumper_t *dumper) dumper->to_dump = false; dumper->writer.ops = NULL; - errno_t rc = log_init("pcap"); + errno_t rc = log_init(NAME); if (rc != EOK) { - printf("pcap : Failed to initialize log.\n"); + printf("%s : Failed to initialize log.\n", NAME); return 1; } return EOK; diff --git a/uspace/lib/pcap/src/pcapdump_client.c b/uspace/lib/pcap/src/pcapdump_client.c index dbb01ecbbd..3de562bcf4 100644 --- a/uspace/lib/pcap/src/pcapdump_client.c +++ b/uspace/lib/pcap/src/pcapdump_client.c @@ -40,7 +40,7 @@ #include #include #include "pcapdump_client.h" -#include "pcapdump_srv.h" +#include "pcapdump_ipc.h" /** Finish an async exchange on the pcapctl session * @@ -104,6 +104,30 @@ errno_t pcapctl_is_valid_device(int *index) return EOK; } + +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; +} + /** * */ @@ -148,7 +172,6 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) if (sess == NULL) return ENOMEM; - printf("number: %d\n", *index); if (*index == -1) { *index = 0; } @@ -189,13 +212,13 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) * @param sess session to start * @return EOK on success or an error code */ -errno_t pcapctl_dump_start(const char *name, pcapctl_sess_t *sess) +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_0(exch, PCAP_CONTROL_SET_START, NULL); + aid_t req = async_send_1(exch, PCAP_CONTROL_SET_START, *ops_index, NULL); rc = async_data_write_start(exch, name, size); @@ -226,27 +249,6 @@ errno_t pcapctl_dump_stop(pcapctl_sess_t *sess) return rc; } -errno_t pcapctl_dump_set_ops(const char *ops_name, pcapctl_sess_t *sess) -{ - errno_t rc; - async_exch_t *exch = async_exchange_begin(sess->sess); - - size_t size = str_size(ops_name); - aid_t req = async_send_0(exch, PCAP_CONTROL_SET_OPS, NULL); - - rc = async_data_write_start(exch, ops_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; -} /** @} */ diff --git a/uspace/lib/pcap/src/pcapdump_srv.c b/uspace/lib/pcap/src/pcapdump_srv.c index de083ba68b..bb87324b89 100644 --- a/uspace/lib/pcap/src/pcapdump_srv.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -43,11 +43,13 @@ #include #include "pcapdump_srv.h" +#include "pcapdump_ipc.h" 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); @@ -56,6 +58,15 @@ static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) assert(str_length(data) == size && "Data were damaged during transmission.\n"); + 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) { @@ -70,27 +81,14 @@ static void pcapdump_stop_srv(ipc_call_t *icall, pcap_dumper_t *dumper) async_answer_0(icall, EOK); } -static void pcapdump_set_ops_srv(ipc_call_t *icall, pcap_dumper_t *dumper) -{ - char *data; - size_t size; - 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"); - rc = pcap_dumper_set_ops(dumper, (const char *)data); - free(data); - if (rc != EOK) { - log_msg(LOG_DEFAULT, LVL_DEBUG, "Setting ops for dumper was not successful.\n"); - } +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, "Setting ops for dumper was successful.\n"); + log_msg(LOG_DEFAULT, LVL_NOTE, "Getting number of ops.\n"); - async_answer_0(icall, EOK); + async_answer_1(icall, EOK, count); } void pcapdump_conn(ipc_call_t *icall, void *arg) @@ -118,8 +116,8 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) case PCAP_CONTROL_SET_STOP: pcapdump_stop_srv(&call, dumper); break; - case PCAP_CONTROL_SET_OPS: - pcapdump_set_ops_srv(&call, dumper); + case PCAP_CONTROL_GET_OPS_NUM: + pcapdump_get_ops_num_srv(&call); break; default: async_answer_0(&call, EINVAL); From e5b277735c855b7daa14f648d67fca8deb0b7b92 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 17 Nov 2024 10:14:10 +0100 Subject: [PATCH 27/39] create drv iface for drivers --- uspace/lib/nic/include/nic.h | 2 +- uspace/lib/nic/src/nic_driver.c | 10 +- uspace/lib/nic/src/nic_impl.c | 4 +- uspace/lib/pcap/include/pcap.h | 3 +- uspace/lib/pcap/include/pcap_dumper.h | 9 +- uspace/lib/pcap/include/pcapdump_client.h | 6 +- uspace/lib/pcap/include/pcapdump_drv_iface.h | 50 +++++++++ uspace/lib/pcap/include/pcapdump_srv.h | 3 - uspace/lib/pcap/meson.build | 1 + uspace/lib/pcap/src/pcap.c | 11 +- uspace/lib/pcap/src/pcap_dumper.c | 49 ++++----- uspace/lib/pcap/src/pcapdump_client.c | 14 +-- uspace/lib/pcap/src/pcapdump_drv_iface.c | 103 +++++++++++++++++++ uspace/lib/pcap/src/pcapdump_srv.c | 36 +------ 14 files changed, 212 insertions(+), 89 deletions(-) create mode 100644 uspace/lib/pcap/include/pcapdump_drv_iface.h create mode 100644 uspace/lib/pcap/src/pcapdump_drv_iface.c diff --git a/uspace/lib/nic/include/nic.h b/uspace/lib/nic/include/nic.h index e46362057a..14367f4bc4 100644 --- a/uspace/lib/nic/include/nic.h +++ b/uspace/lib/nic/include/nic.h @@ -279,7 +279,7 @@ extern void nic_sw_period_start(nic_t *); extern void nic_sw_period_stop(nic_t *); /* pcapdump interface */ -extern pcap_dumper_t *nic_get_pcap_iface(nic_t *); +extern pcap_dumper_t *nic_get_pcap_dumper(nic_t *); extern errno_t nic_fun_add_to_cats(ddf_fun_t *fun); diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 1fff7b125d..2cc6422885 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include "nic_driver.h" #include "nic_ev.h" @@ -522,7 +522,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) * Note: this function must not lock main lock, because loopback driver * calls it inside send_frame handler (with locked main lock) */ - pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + 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; bool check = nic_rxc_check(&nic_data->rx_control, frame->data, @@ -561,7 +561,7 @@ void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) } fibril_rwlock_write_unlock(&nic_data->stats_lock); } - //pcapdump_packet(nic_get_pcap_iface(nic_data), frame->data, frame->size); + //pcapdump_packet(nic_get_pcap_dumper(nic_data), frame->data, frame->size); nic_release_frame(nic_data, frame); } @@ -650,7 +650,7 @@ nic_t *nic_create_and_bind(ddf_dev_t *device) nic_data->dev = device; - errno_t pcap_rc = pcapdump_init(nic_get_pcap_iface(nic_data)); + errno_t pcap_rc = pcapdump_init(nic_get_pcap_dumper(nic_data)); if (pcap_rc != EOK) { printf("Failed creating pcapdump port\n"); } @@ -1140,7 +1140,7 @@ void nic_sw_period_stop(nic_t *nic_data) nic_data->sw_poll_info.running = 0; } -pcap_dumper_t *nic_get_pcap_iface(nic_t *nic_data) +pcap_dumper_t *nic_get_pcap_dumper(nic_t *nic_data) { return &nic_data->pcapdump; } diff --git a/uspace/lib/nic/src/nic_impl.c b/uspace/lib/nic/src/nic_impl.c index 74755fe28b..5dac2d92dd 100644 --- a/uspace/lib/nic/src/nic_impl.c +++ b/uspace/lib/nic/src/nic_impl.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include "nic_driver.h" #include "nic_ev.h" #include "nic_impl.h" @@ -179,7 +179,7 @@ errno_t nic_send_frame_impl(ddf_fun_t *fun, void *data, size_t size) fibril_rwlock_read_unlock(&nic_data->main_lock); return EBUSY; } - pcapdump_packet(nic_get_pcap_iface(nic_data), data, size); + 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); return EOK; diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index b7ba6e34fc..1375ddeb04 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -54,6 +54,7 @@ #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 #define WIRESHARK_EX 0xc #define WIRESHARK_SNAPLEN 0xffff @@ -93,7 +94,7 @@ struct pcap_writer { pcap_writer_ops_t *ops; }; -extern void pcap_writer_add_header(pcap_writer_t *writer); +extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano); 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); diff --git a/uspace/lib/pcap/include/pcap_dumper.h b/uspace/lib/pcap/include/pcap_dumper.h index 2c8f6683ef..d811cd115e 100644 --- a/uspace/lib/pcap/include/pcap_dumper.h +++ b/uspace/lib/pcap/include/pcap_dumper.h @@ -45,12 +45,11 @@ typedef struct pcap_dumper { pcap_writer_t writer; } pcap_dumper_t; -extern void pcap_dumper_stop(struct pcap_dumper *); -extern errno_t pcap_dumper_init(pcap_dumper_t *); ///tahle +extern void pcap_dumper_stop(pcap_dumper_t *); extern int pcap_dumper_get_ops_number(void); -extern errno_t pcap_dumper_set_ops(struct pcap_dumper *, int); -extern errno_t pcap_dumper_start(struct pcap_dumper *, const char *); -extern void pcap_dumper_add_packet(struct pcap_dumper *, const void *data, size_t size); +extern errno_t pcap_dumper_set_ops(pcap_dumper_t *, int); +extern errno_t pcap_dumper_start(pcap_dumper_t *, const char *); +extern void pcap_dumper_add_packet(pcap_dumper_t *, const void *data, size_t size); #endif /** @} diff --git a/uspace/lib/pcap/include/pcapdump_client.h b/uspace/lib/pcap/include/pcapdump_client.h index 30e8cd3640..75ff6c4ac6 100644 --- a/uspace/lib/pcap/include/pcapdump_client.h +++ b/uspace/lib/pcap/include/pcapdump_client.h @@ -35,8 +35,8 @@ * */ -#ifndef _PCAPCTL_DUMP_H_ -#define _PCAPCTL_DUMP_H_ +#ifndef _PCAPDUMP_CLIENT_H_ +#define _PCAPDUMP_CLIENT_H_ #include #include @@ -50,8 +50,8 @@ typedef struct { 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_set_ops(const char *, 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 *); diff --git a/uspace/lib/pcap/include/pcapdump_drv_iface.h b/uspace/lib/pcap/include/pcapdump_drv_iface.h new file mode 100644 index 0000000000..4f7036094d --- /dev/null +++ b/uspace/lib/pcap/include/pcapdump_drv_iface.h @@ -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 + * + */ + +#ifndef _PCAPDUMP_DRV_IFACE_H_ +#define _PCAPDUMP_DRV_IFACE_H_ + +#include +#include "pcap_dumper.h" + +extern errno_t pcapdump_init(pcap_dumper_t *); +extern void pcapdump_packet(pcap_dumper_t *, const void *, size_t); + +#endif + +/** @} + */ diff --git a/uspace/lib/pcap/include/pcapdump_srv.h b/uspace/lib/pcap/include/pcapdump_srv.h index ffa571d22d..4dcc95f17d 100644 --- a/uspace/lib/pcap/include/pcapdump_srv.h +++ b/uspace/lib/pcap/include/pcapdump_srv.h @@ -39,10 +39,7 @@ #define _PCAPDUMP_IFACE_H_ #include -#include "pcap_dumper.h" -extern errno_t pcapdump_init(pcap_dumper_t *); -extern void pcapdump_packet(pcap_dumper_t *, const void *, size_t); extern void pcapdump_conn(ipc_call_t *, void *); #endif diff --git a/uspace/lib/pcap/meson.build b/uspace/lib/pcap/meson.build index 253e83c341..fb7c890a30 100644 --- a/uspace/lib/pcap/meson.build +++ b/uspace/lib/pcap/meson.build @@ -31,4 +31,5 @@ src = files( 'src/pcap_dumper.c', 'src/pcapdump_srv.c', 'src/pcapdump_client.c', + 'src/pcapdump_drv_iface.c', ) diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index e090c8ac94..e51af181e5 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -55,10 +55,15 @@ void pcap_set_time(pcap_packet_header_t *header) * @param writer writer that has destination buffer and ops to write to destination buffer. * */ -void pcap_writer_add_header(pcap_writer_t *writer) +void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano) { - pcap_file_header_t file_header = { PCAP_MAGIC_NANO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, - 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, (uint32_t)PCAP_LINKTYPE_ETHERNET }; + uint32_t magic_version = PCAP_MAGIC_MICRO; + if (nano) + { + magic_version = PCAP_MAGIC_NANO; + } + pcap_file_header_t file_header = { magic_version, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, + 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, linktype }; writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); } diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index b690721e31..80a917b763 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -39,7 +39,6 @@ #include "pcap_dumper.h" #define SHORT_OPS_BYTE_COUNT 60 -#define NAME "pcap" /** Initialize writing to .pcap file. * @@ -54,7 +53,7 @@ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filen if (writer->data == NULL) { return EINVAL; } - pcap_writer_add_header(writer); + pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET, false); return EOK; } @@ -69,6 +68,17 @@ static errno_t pcap_writer_to_file_init_append(pcap_writer_t *writer, const char return EOK; } +static errno_t pcap_writer_to_file_usb_init(pcap_writer_t *writer, const char *filename) +{ + writer->data = fopen(filename, "a"); + if (writer->data == NULL) { + return EINVAL; + } + pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED, false); + + return EOK; +} + static size_t pcap_file_w32(pcap_writer_t *writer, uint32_t data) { return fwrite(&data, 1, 4, (FILE *)writer->data); @@ -121,14 +131,22 @@ static const pcap_writer_ops_t append_file_ops = { .close = &pcap_file_close }; -static pcap_writer_ops_t ops[3] = {file_ops, short_file_ops, append_file_ops}; +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 +}; + +static pcap_writer_ops_t ops[4] = {file_ops, short_file_ops, append_file_ops, usb_file_ops}; int pcap_dumper_get_ops_number(void) { return (int)(sizeof(ops) / sizeof(pcap_writer_ops_t)); } -errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) +errno_t pcap_dumper_start(pcap_dumper_t *dumper, const char *name) { fibril_mutex_lock(&dumper->mutex); @@ -146,7 +164,7 @@ errno_t pcap_dumper_start(struct pcap_dumper *dumper, const char *name) return rc; } -errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, int index) +errno_t pcap_dumper_set_ops(pcap_dumper_t *dumper, int index) { fibril_mutex_lock(&dumper->mutex); errno_t rc = EOK; @@ -155,7 +173,7 @@ errno_t pcap_dumper_set_ops(struct pcap_dumper *dumper, int index) return rc; } -void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t size) +void pcap_dumper_add_packet(pcap_dumper_t *dumper, const void *data, size_t size) { fibril_mutex_lock(&dumper->mutex); @@ -168,7 +186,7 @@ void pcap_dumper_add_packet(struct pcap_dumper *dumper, const void *data, size_t fibril_mutex_unlock(&dumper->mutex); } -void pcap_dumper_stop(struct pcap_dumper *dumper) +void pcap_dumper_stop(pcap_dumper_t *dumper) { fibril_mutex_lock(&dumper->mutex); @@ -182,24 +200,7 @@ void pcap_dumper_stop(struct pcap_dumper *dumper) fibril_mutex_unlock(&dumper->mutex); } -/** Initialize interface for dumping packets - * - * @param dumper Device dumping interface - * - */ -errno_t pcap_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; -} /** @} */ diff --git a/uspace/lib/pcap/src/pcapdump_client.c b/uspace/lib/pcap/src/pcapdump_client.c index 3de562bcf4..65dbbabf0d 100644 --- a/uspace/lib/pcap/src/pcapdump_client.c +++ b/uspace/lib/pcap/src/pcapdump_client.c @@ -60,13 +60,13 @@ static errno_t pcapctl_cat_get_svc(int *index, service_id_t *svc) rc = loc_category_get_id("pcap", &pcap_cat, 0); if (rc != EOK) { - printf("Error resolving category 'pcap'.\n"); + fprintf(stderr, "Error resolving category 'pcap'.\n"); return rc; } rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { - printf("Error resolving list of pcap services.\n"); + fprintf(stderr, "Error resolving list of pcap services.\n"); free(pcap_svcs); return rc; } @@ -88,13 +88,13 @@ errno_t pcapctl_is_valid_device(int *index) rc = loc_category_get_id("pcap", &pcap_cat, 0); if (rc != EOK) { - printf("Error resolving category pcap.\n"); + fprintf(stderr, "Error resolving category pcap.\n"); return rc; } rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { - printf("Error resolving list of pcap services.\n"); + fprintf(stderr, "Error resolving list of pcap services.\n"); free(pcap_svcs); return rc; } @@ -140,13 +140,13 @@ errno_t pcapctl_list(void) rc = loc_category_get_id("pcap", &pcap_cat, 0); if (rc != EOK) { - printf("Error resolving category pcap.\n"); + fprintf(stderr, "Error resolving category pcap.\n"); return rc; } rc = loc_category_get_svcs(pcap_cat, &pcap_svcs, &count); if (rc != EOK) { - printf("Error resolving list of pcap services.\n"); + fprintf(stderr, "Error resolving list of pcap services.\n"); free(pcap_svcs); return rc; } @@ -178,7 +178,7 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) rc = pcapctl_cat_get_svc(index, &svc); if (rc != EOK) { - printf("Error finding the device with index: %d\n", *index); + fprintf(stderr, "Error finding the device with index: %d\n", *index); goto error; } diff --git a/uspace/lib/pcap/src/pcapdump_drv_iface.c b/uspace/lib/pcap/src/pcapdump_drv_iface.c new file mode 100644 index 0000000000..eb5129d4d3 --- /dev/null +++ b/uspace/lib/pcap/src/pcapdump_drv_iface.c @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "pcapdump_srv.h" +#include "pcapdump_drv_iface.h" + +#define NAME "pcap" + +/** Initialize interface for dumping packets + * + * @param dumper Device dumping interface + * + */ +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; +} + +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); +} \ No newline at end of file diff --git a/uspace/lib/pcap/src/pcapdump_srv.c b/uspace/lib/pcap/src/pcapdump_srv.c index bb87324b89..82ec5e1fa5 100644 --- a/uspace/lib/pcap/src/pcapdump_srv.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -42,6 +42,7 @@ #include #include +#include "pcap_dumper.h" #include "pcapdump_srv.h" #include "pcapdump_ipc.h" @@ -126,42 +127,7 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) } } -errno_t pcapdump_init(pcap_dumper_t *dumper) -{ - port_id_t port; - errno_t rc; - - rc = pcap_dumper_init(dumper); - - if (rc != EOK) { - log_msg(LOG_DEFAULT, LVL_DEBUG, "Failed creating pcap interface: %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: %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); -} /** @} */ From 31d2aeee10d6cd21b90def54db9987b00f3ea4b8 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 23 Nov 2024 09:40:45 +0100 Subject: [PATCH 28/39] Renaming --- uspace/lib/nic/include/nic_driver.h | 4 ++-- uspace/lib/nic/src/nic_driver.c | 2 +- uspace/lib/pcap/include/pcap.h | 8 ++++---- uspace/lib/pcap/src/pcap_dumper.c | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/uspace/lib/nic/include/nic_driver.h b/uspace/lib/nic/include/nic_driver.h index e8dbf96417..9abc3d6060 100644 --- a/uspace/lib/nic/include/nic_driver.h +++ b/uspace/lib/nic/include/nic_driver.h @@ -196,8 +196,8 @@ struct nic { */ poll_request_handler on_poll_request; - /** Interface for dumping packets */ - pcap_dumper_t pcapdump; + /** Packets dumper. */ + pcap_dumper_t dumper; /** Data specific for particular driver */ void *specific; diff --git a/uspace/lib/nic/src/nic_driver.c b/uspace/lib/nic/src/nic_driver.c index 2cc6422885..6f502a5112 100644 --- a/uspace/lib/nic/src/nic_driver.c +++ b/uspace/lib/nic/src/nic_driver.c @@ -1142,7 +1142,7 @@ void nic_sw_period_stop(nic_t *nic_data) pcap_dumper_t *nic_get_pcap_dumper(nic_t *nic_data) { - return &nic_data->pcapdump; + return &nic_data->dumper; } /** @} diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 1375ddeb04..fb15ec2136 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -82,10 +82,10 @@ typedef struct pcap_writer pcap_writer_t; /** Operations for dumper. */ typedef struct { errno_t (*open)(pcap_writer_t *, const char *); - size_t (*write_u32)(struct pcap_writer *, uint32_t); - size_t (*write_u16)(struct pcap_writer *, uint16_t); - size_t (*write_buffer)(struct pcap_writer *, const void *, size_t); - void (*close)(struct pcap_writer *); + 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; /** Interface for working with .pcap file. */ diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 80a917b763..284c359b07 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -101,6 +101,11 @@ static void pcap_file_close(pcap_writer_t *writer) writer->data = NULL; } +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); +} + static const pcap_writer_ops_t file_ops = { .open = &pcap_writer_to_file_init, .write_u32 = &pcap_file_w32, @@ -109,11 +114,6 @@ static const pcap_writer_ops_t file_ops = { .close = &pcap_file_close }; -static size_t pcap_short_file_wbuffer(pcap_writer_t *writer, const void *data, size_t size) -{ - return fwrite(data, 1, size < 60 ? size : 60, (FILE *)writer->data); //define -} - static const pcap_writer_ops_t short_file_ops = { .open = &pcap_writer_to_file_init, .write_u32 = &pcap_file_w32, From 28ed2d895c391b0a614fa176129126725c0fac4b Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 23 Nov 2024 09:41:19 +0100 Subject: [PATCH 29/39] add force option for existing files --- uspace/app/pcapctl/main.c | 40 ++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 86badbc4e2..51468b0497 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -37,11 +37,13 @@ #include #include #include +#include #include "pcapdump_client.h" #define NAME "pcapctl" #define DEFAULT_DEV_NUM 0 +#define DEFAULT_OPS_NUM 0 #define DECIMAL_SYSTEM 10 static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) @@ -95,13 +97,24 @@ static const struct option opts[] = { { "device", required_argument, 0, 'd' }, { "list", no_argument, 0, 'l' }, { "help", no_argument, 0, 'h' }, - { "outfile", required_argument, 0, 'f' }, + { "outfile", required_argument, 0, 'o' }, { "start", no_argument, 0, 'r' }, { "stop", no_argument, 0, 't' }, - { "ops", required_argument, 0, 'o' }, + { "ops", required_argument, 0, 'p' }, + { "force", no_argument, 0, 'f'}, { 0, 0, 0, 0 } }; +static bool file_exists(const char *path) +{ + vfs_stat_t stats; + + if (vfs_stat_path(path, &stats) != EOK) + return false; + + return true; +} + static void usage(void) { printf("Usage:\n" @@ -121,8 +134,9 @@ int main(int argc, char *argv[]) { bool start = false; bool stop = false; - int dev_number = -1; - int ops_number = -1; + int dev_number = DEFAULT_DEV_NUM; + int ops_number = DEFAULT_OPS_NUM; + bool forced = false; const char *output_file_name = ""; int idx = 0; int ret = 0; @@ -131,7 +145,7 @@ int main(int argc, char *argv[]) return 0; } while (ret != -1) { - ret = getopt_long(argc, argv, "d:lhf:rt", opts, &idx); + ret = getopt_long(argc, argv, "d:lho:rtp:f", opts, &idx); switch (ret) { case 'd': char *rest; @@ -149,7 +163,7 @@ int main(int argc, char *argv[]) case 'h': usage(); return 0; - case 'f': + case 'o': output_file_name = optarg; break; case 'r': @@ -158,22 +172,34 @@ int main(int argc, char *argv[]) case 't': stop = true; break; - case 'o': + 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; } } printf("%s: HelenOS Packet Dumping utility: device - %d.\n", NAME, dev_number); if (start) { + + if (file_exists(output_file_name) && !forced) + { + printf("File %s already exists. If you want to write to it, then use flag --force.\n", output_file_name); + return 0; + } + /* start with dev number and name */ start_dumping(&dev_number, output_file_name, &ops_number); } else if (stop) { /* stop with dev number */ stop_dumping(&dev_number); + } else { + usage(); } return 0; } From fb316822bc92404f7ec785477d173721f75b2232 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Fri, 29 Nov 2024 11:41:19 +0100 Subject: [PATCH 30/39] user friendly options, trying to start while dumping -> err msg --- uspace/app/pcapctl/main.c | 74 +++++++++++++++++------ uspace/lib/pcap/include/pcap_dumper.h | 2 +- uspace/lib/pcap/include/pcapdump_client.h | 3 +- uspace/lib/pcap/src/pcap.c | 3 +- uspace/lib/pcap/src/pcap_dumper.c | 25 +++++--- uspace/lib/pcap/src/pcapdump_client.c | 7 +-- uspace/lib/pcap/src/pcapdump_drv_iface.c | 2 +- uspace/lib/pcap/src/pcapdump_srv.c | 14 +++-- 8 files changed, 85 insertions(+), 45 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 51468b0497..18e0c4ab21 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -43,9 +43,13 @@ #define NAME "pcapctl" #define DEFAULT_DEV_NUM 0 -#define DEFAULT_OPS_NUM 0 #define DECIMAL_SYSTEM 10 +#define DEFAULT_FILE_OPS 0 +#define SHORT_FILE_OPS 1 +#define APPEND_FILE_OPS 2 +#define USB_FILE_OPS 3 + static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) { pcapctl_sess_t *sess = NULL; @@ -55,8 +59,7 @@ static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) } rc = pcapctl_is_valid_ops_number(ops_index, sess); - if (rc != EOK) - { + if (rc != EOK) { printf("Wrong number of ops: %d.\n", *ops_index); pcapctl_dump_close(sess); return rc; @@ -64,6 +67,9 @@ static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) rc = pcapctl_dump_start(name, ops_index, sess); if (rc != EOK) { + if (rc == EBUSY) { + printf("Dumping for device %d is in process, stop to start dumping to file %s.\n", *dev_number, name); + } printf("Starting the dumping was not successful.\n"); } pcapctl_dump_close(sess); @@ -94,6 +100,10 @@ static void list_devs(void) * 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' }, // truncated ops + { "usb", required_argument, 0, 'U' }, //?? { "device", required_argument, 0, 'd' }, { "list", no_argument, 0, 'l' }, { "help", no_argument, 0, 'h' }, @@ -101,18 +111,18 @@ static const struct option opts[] = { { "start", no_argument, 0, 'r' }, { "stop", no_argument, 0, 't' }, { "ops", required_argument, 0, 'p' }, - { "force", no_argument, 0, 'f'}, + { "force", no_argument, 0, 'f' }, { 0, 0, 0, 0 } }; static bool file_exists(const char *path) { vfs_stat_t stats; - - if (vfs_stat_path(path, &stats) != EOK) - return false; - - return true; + if (vfs_stat_path(path, &stats) != EOK) { + return false; + } else { + return true; + } } static void usage(void) @@ -120,14 +130,16 @@ static void usage(void) printf("Usage:\n" NAME " --list | -l \n" "\tList of devices\n" - NAME " --start | -r --device= | -d --outfile= | -f \n" + NAME " --start | -r --device= | -d --outfile= | -o --ops= | p \n" "\tPackets dumped from device will be written to \n" - NAME " --stop | -t --device= | -d \n" + NAME " --stop | -t --device= | -d \n" "\tDumping from stops\n" - NAME " --start | -s --outfile= | -f \n" + NAME " --start | -r --outfile= | -o \n" "\tPackets dumped from the 0. device from the list will be written to \n" NAME " --help | -h\n" - "\tShow this application help.\n"); + "\tShow this application help.\n" + NAME " --force | -f" + "\tTo open existing file and write to it.\n"); } int main(int argc, char *argv[]) @@ -135,7 +147,7 @@ int main(int argc, char *argv[]) bool start = false; bool stop = false; int dev_number = DEFAULT_DEV_NUM; - int ops_number = DEFAULT_OPS_NUM; + int ops_number = DEFAULT_FILE_OPS; bool forced = false; const char *output_file_name = ""; int idx = 0; @@ -145,7 +157,7 @@ int main(int argc, char *argv[]) return 0; } while (ret != -1) { - ret = getopt_long(argc, argv, "d:lho:rtp:f", opts, &idx); + ret = getopt_long(argc, argv, "A:N:T:U:d:lho:rtp:f", opts, &idx); switch (ret) { case 'd': char *rest; @@ -157,6 +169,23 @@ int main(int argc, char *argv[]) return 1; } break; + case 'A': + output_file_name = optarg; + if (file_exists(output_file_name)) { + ops_number = APPEND_FILE_OPS; + } + break; + case 'N': + output_file_name = optarg; + break; + case 'T': + output_file_name = optarg; + ops_number = SHORT_FILE_OPS; + break; + case 'U': + output_file_name = optarg; + ops_number = USB_FILE_OPS; + break; case 'l': list_devs(); return 0; @@ -173,7 +202,7 @@ int main(int argc, char *argv[]) stop = true; break; case 'p': - char* ops_inval; + char *ops_inval; long ops_result = strtol(optarg, &ops_inval, DECIMAL_SYSTEM); ops_number = (int)ops_result; break; @@ -183,13 +212,17 @@ int main(int argc, char *argv[]) } } - printf("%s: HelenOS Packet Dumping utility: device - %d.\n", NAME, dev_number); + if (!str_cmp(output_file_name, "") && start) { + printf("Dumping destination was not specified. Specify with --outfile | -o\n"); + return 1; + } + + printf("%s: HelenOS Packet Dumping utility: device - %d, ops - %d.\n", NAME, dev_number, ops_number); if (start) { - if (file_exists(output_file_name) && !forced) - { - printf("File %s already exists. If you want to write to it, then use flag --force.\n", output_file_name); + if (file_exists(output_file_name) && !forced && ops_number != 2) { + printf("File %s already exists. If you want to overwrite to it, then use flag --force.\n", output_file_name); return 0; } @@ -200,6 +233,7 @@ int main(int argc, char *argv[]) stop_dumping(&dev_number); } else { usage(); + return 1; } return 0; } diff --git a/uspace/lib/pcap/include/pcap_dumper.h b/uspace/lib/pcap/include/pcap_dumper.h index d811cd115e..d2623a4d85 100644 --- a/uspace/lib/pcap/include/pcap_dumper.h +++ b/uspace/lib/pcap/include/pcap_dumper.h @@ -45,10 +45,10 @@ typedef struct pcap_dumper { 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 errno_t pcap_dumper_start(pcap_dumper_t *, const char *); extern void pcap_dumper_add_packet(pcap_dumper_t *, const void *data, size_t size); #endif diff --git a/uspace/lib/pcap/include/pcapdump_client.h b/uspace/lib/pcap/include/pcapdump_client.h index 75ff6c4ac6..9a9ef5021e 100644 --- a/uspace/lib/pcap/include/pcapdump_client.h +++ b/uspace/lib/pcap/include/pcapdump_client.h @@ -55,8 +55,7 @@ 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 *index, pcapctl_sess_t* sess); - +extern errno_t pcapctl_is_valid_ops_number(int *, pcapctl_sess_t *); #endif diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index e51af181e5..726dd8c4d5 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -58,8 +58,7 @@ void pcap_set_time(pcap_packet_header_t *header) void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano) { uint32_t magic_version = PCAP_MAGIC_MICRO; - if (nano) - { + if (nano) { magic_version = PCAP_MAGIC_NANO; } pcap_file_header_t file_header = { magic_version, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 284c359b07..c9924d88d6 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -38,7 +38,7 @@ #include #include "pcap_dumper.h" -#define SHORT_OPS_BYTE_COUNT 60 +#define SHORT_OPS_BYTE_COUNT 0x3C /** Initialize writing to .pcap file. * @@ -49,6 +49,13 @@ */ 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; @@ -70,6 +77,13 @@ static errno_t pcap_writer_to_file_init_append(pcap_writer_t *writer, const char 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; @@ -139,7 +153,7 @@ static const pcap_writer_ops_t usb_file_ops = { .close = &pcap_file_close }; -static pcap_writer_ops_t ops[4] = {file_ops, short_file_ops, append_file_ops, usb_file_ops}; +static pcap_writer_ops_t ops[4] = { file_ops, short_file_ops, append_file_ops, usb_file_ops }; int pcap_dumper_get_ops_number(void) { @@ -150,11 +164,6 @@ errno_t pcap_dumper_start(pcap_dumper_t *dumper, const char *name) { fibril_mutex_lock(&dumper->mutex); - /** When try to start when already started, close current and starts new */ - if (dumper->to_dump) { - pcap_dumper_stop(dumper); - } - errno_t rc = dumper->writer.ops->open(&dumper->writer, name); if (rc == EOK) { dumper->to_dump = true; @@ -200,7 +209,5 @@ void pcap_dumper_stop(pcap_dumper_t *dumper) fibril_mutex_unlock(&dumper->mutex); } - - /** @} */ diff --git a/uspace/lib/pcap/src/pcapdump_client.c b/uspace/lib/pcap/src/pcapdump_client.c index 65dbbabf0d..601be5fa3b 100644 --- a/uspace/lib/pcap/src/pcapdump_client.c +++ b/uspace/lib/pcap/src/pcapdump_client.c @@ -104,8 +104,7 @@ errno_t pcapctl_is_valid_device(int *index) return EOK; } - -errno_t pcapctl_is_valid_ops_number(int *index, pcapctl_sess_t* sess) +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; @@ -121,8 +120,7 @@ errno_t pcapctl_is_valid_ops_number(int *index, pcapctl_sess_t* sess) } int ops_count = (int)ipc_get_arg1(&answer); - if (*index + 1 > ops_count || *index < 0) - { + if (*index + 1 > ops_count || *index < 0) { return EINVAL; } return EOK; @@ -249,6 +247,5 @@ errno_t pcapctl_dump_stop(pcapctl_sess_t *sess) return rc; } - /** @} */ diff --git a/uspace/lib/pcap/src/pcapdump_drv_iface.c b/uspace/lib/pcap/src/pcapdump_drv_iface.c index eb5129d4d3..76e370ca12 100644 --- a/uspace/lib/pcap/src/pcapdump_drv_iface.c +++ b/uspace/lib/pcap/src/pcapdump_drv_iface.c @@ -100,4 +100,4 @@ void pcapdump_packet(pcap_dumper_t *dumper, const void *data, size_t size) return; } pcap_dumper_add_packet(dumper, data, size); -} \ No newline at end of file +} diff --git a/uspace/lib/pcap/src/pcapdump_srv.c b/uspace/lib/pcap/src/pcapdump_srv.c index 82ec5e1fa5..9bdb449ce2 100644 --- a/uspace/lib/pcap/src/pcapdump_srv.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -59,9 +59,16 @@ static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) 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) - { + if (rc != EOK) { log_msg(LOG_DEFAULT, LVL_DEBUG, "Setting ops for dumper was not successful.\n"); free(data); async_answer_0(icall, EOK); @@ -82,7 +89,6 @@ static void pcapdump_stop_srv(ipc_call_t *icall, pcap_dumper_t *dumper) async_answer_0(icall, EOK); } - static void pcapdump_get_ops_num_srv(ipc_call_t *icall) { size_t count = pcap_dumper_get_ops_number(); @@ -127,7 +133,5 @@ void pcapdump_conn(ipc_call_t *icall, void *arg) } } - - /** @} */ From 87b490e3bd8415518545092c263ede6ab3da8532 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 30 Nov 2024 20:08:32 +0100 Subject: [PATCH 31/39] docs comments --- uspace/app/pcapctl/main.c | 44 +++++++++---- uspace/lib/pcap/include/pcap.h | 20 +++--- uspace/lib/pcap/include/pcap_dumper.h | 6 +- uspace/lib/pcap/include/pcapdump_client.h | 3 +- uspace/lib/pcap/include/pcapdump_drv_iface.h | 2 +- uspace/lib/pcap/include/pcapdump_ipc.h | 1 + uspace/lib/pcap/include/pcapdump_srv.h | 2 +- uspace/lib/pcap/src/pcap.c | 13 ++-- uspace/lib/pcap/src/pcap_dumper.c | 66 ++++++++++++++++++-- uspace/lib/pcap/src/pcapdump_client.c | 45 ++++++++----- uspace/lib/pcap/src/pcapdump_drv_iface.c | 21 ++++--- uspace/lib/pcap/src/pcapdump_srv.c | 15 +++++ 12 files changed, 176 insertions(+), 62 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 18e0c4ab21..91f30e6978 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -29,7 +29,7 @@ /** @addtogroup pcapctl * @{ */ -/** @file pcapctl app +/** @file pcapctl command-line utility. */ #include @@ -41,15 +41,22 @@ #include "pcapdump_client.h" -#define NAME "pcapctl" -#define DEFAULT_DEV_NUM 0 -#define DECIMAL_SYSTEM 10 +#define NAME "pcapctl" +#define DEFAULT_DEV_NUM 0 +#define DECIMAL_SYSTEM 10 -#define DEFAULT_FILE_OPS 0 -#define SHORT_FILE_OPS 1 -#define APPEND_FILE_OPS 2 -#define USB_FILE_OPS 3 +/* 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; @@ -76,6 +83,10 @@ static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) 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; @@ -91,6 +102,7 @@ static errno_t stop_dumping(int *dev_number) return EOK; } +/** Print devices that can dump packets. */ static void list_devs(void) { pcapctl_list(); @@ -100,8 +112,8 @@ static void list_devs(void) * 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 + { "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' }, // truncated ops { "usb", required_argument, 0, 'U' }, //?? { "device", required_argument, 0, 'd' }, @@ -115,6 +127,10 @@ static const struct option opts[] = { { 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; @@ -127,7 +143,8 @@ static bool file_exists(const char *path) static void usage(void) { - printf("Usage:\n" + printf("HelenOS Packet Dumping utility.\n" + "Usage:\n" NAME " --list | -l \n" "\tList of devices\n" NAME " --start | -r --device= | -d --outfile= | -o --ops= | p \n" @@ -217,8 +234,6 @@ int main(int argc, char *argv[]) return 1; } - printf("%s: HelenOS Packet Dumping utility: device - %d, ops - %d.\n", NAME, dev_number, ops_number); - if (start) { if (file_exists(output_file_name) && !forced && ops_number != 2) { @@ -226,10 +241,13 @@ int main(int argc, char *argv[]) return 0; } + printf("Sarting 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("Stopping dumping on device - %d, ops - %d.\n", dev_number, ops_number); stop_dumping(&dev_number); } else { usage(); diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index fb15ec2136..52536a5e6a 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -32,7 +32,7 @@ */ /** * @file - * @brief Headers and functions for .pcap file and packets to be dumped + * @brief Headers and functions for PCAP format and packets to be dumped. */ #ifndef PCAP_H_ @@ -45,18 +45,16 @@ #include #include -#define PCAP_MAGIC_MICRO 0xA1B2C3D4 -#define PCAP_MAGIC_NANO 0xA1B23C4D -#define PCAP_MAJOR_VERSION 0x0002 -#define PCAP_MINOR_VERSION 0x0004 -#define PCAP_SNAP_LEN 0x00040000 +#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 -#define WIRESHARK_EX 0xc -#define WIRESHARK_SNAPLEN 0xffff /** Header of the .pcap file. */ typedef struct { @@ -79,7 +77,7 @@ typedef struct pcap_packet_header { typedef struct pcap_writer pcap_writer_t; -/** Operations for dumper. */ +/** Writing operations for destination buffer. */ typedef struct { errno_t (*open)(pcap_writer_t *, const char *); size_t (*write_u32)(pcap_writer_t *, uint32_t); @@ -88,9 +86,11 @@ typedef struct { void (*close)(pcap_writer_t *); } pcap_writer_ops_t; -/** Interface for working with .pcap file. */ +/** 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; }; diff --git a/uspace/lib/pcap/include/pcap_dumper.h b/uspace/lib/pcap/include/pcap_dumper.h index d2623a4d85..ccc97c6087 100644 --- a/uspace/lib/pcap/include/pcap_dumper.h +++ b/uspace/lib/pcap/include/pcap_dumper.h @@ -29,7 +29,7 @@ /** @addtogroup libpcap * @{ */ -/** @file pcap interface +/** @file Pcap dumper. Structure is a part of every device that is in category PCAP and can dump packets. */ #ifndef PCAP_IFACE_H_ @@ -39,9 +39,12 @@ #include #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; @@ -52,5 +55,6 @@ 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 + /** @} */ diff --git a/uspace/lib/pcap/include/pcapdump_client.h b/uspace/lib/pcap/include/pcapdump_client.h index 9a9ef5021e..11569efff4 100644 --- a/uspace/lib/pcap/include/pcapdump_client.h +++ b/uspace/lib/pcap/include/pcapdump_client.h @@ -31,7 +31,7 @@ * @{ */ /** - * @file + * @file Client side of the IPC communication for pcapctl. * */ @@ -44,6 +44,7 @@ #include #include +/** IPC session structure for pcapctl utility. */ typedef struct { async_sess_t *sess; } pcapctl_sess_t; diff --git a/uspace/lib/pcap/include/pcapdump_drv_iface.h b/uspace/lib/pcap/include/pcapdump_drv_iface.h index 4f7036094d..768bf1ef5c 100644 --- a/uspace/lib/pcap/include/pcapdump_drv_iface.h +++ b/uspace/lib/pcap/include/pcapdump_drv_iface.h @@ -31,7 +31,7 @@ * @{ */ /** - * @file + * @file Driver interface. Functions that are used in drivers that can dump packets. * */ diff --git a/uspace/lib/pcap/include/pcapdump_ipc.h b/uspace/lib/pcap/include/pcapdump_ipc.h index 6ccd6d25c6..50d0030bfb 100644 --- a/uspace/lib/pcap/include/pcapdump_ipc.h +++ b/uspace/lib/pcap/include/pcapdump_ipc.h @@ -40,6 +40,7 @@ #include +/** IPC requests for INTERFACE_PCAP_CONTROL interface. */ typedef enum { PCAP_CONTROL_SET_START = IPC_FIRST_USER_METHOD, PCAP_CONTROL_SET_STOP, diff --git a/uspace/lib/pcap/include/pcapdump_srv.h b/uspace/lib/pcap/include/pcapdump_srv.h index 4dcc95f17d..168e2c9363 100644 --- a/uspace/lib/pcap/include/pcapdump_srv.h +++ b/uspace/lib/pcap/include/pcapdump_srv.h @@ -31,7 +31,7 @@ * @{ */ /** - * @file + * @file Server side of the IPC communication for dumping packets framework. * */ diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index 726dd8c4d5..a57dc64796 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Nataliia Korop + * Copyright (c) 2024 Nataliia Korop * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,8 +52,9 @@ void pcap_set_time(pcap_packet_header_t *header) /** Add pcap file header to the new .pcap file. * - * @param writer writer that has destination buffer and ops to write to destination buffer. - * + * @param writer Writer that has destination buffer and ops to write to destination buffer. + * @param linktype Linktype for the file header. + * @param nano True for nanoseconds, false for microseconds in timestamp. */ void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano) { @@ -68,9 +69,9 @@ void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano) /** Add packet to the .pcap file. * - * @param writer - * @param captured_packet Packet to be dumped - * @param size Size of the captured packet + * @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) diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index c9924d88d6..132aca4772 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -29,8 +29,7 @@ /** @addtogroup libpcap * @{ */ -/** @file - * @brief pcap inteface: Dumping interface for the device which packets we want to dump +/** @file Pcap dumper. Structure is a part of every device that is in category PCAP and can dump packets. */ #include @@ -42,9 +41,9 @@ /** Initialize writing to .pcap file. * - * @param writer Interface for working with .pcap file. + * @param writer Interface for writing data. * @param filename Name of the file for dumping packets. - * @return EOK on success or an error code. + * @return EOK on success, otherwise an error code. * */ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filename) @@ -65,6 +64,11 @@ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filen 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"); @@ -75,6 +79,11 @@ static errno_t pcap_writer_to_file_init_append(pcap_writer_t *writer, const char 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. */ @@ -93,33 +102,59 @@ static errno_t pcap_writer_to_file_usb_init(pcap_writer_t *writer, const char *f 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, @@ -128,6 +163,7 @@ static const pcap_writer_ops_t file_ops = { .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, @@ -137,6 +173,7 @@ static const pcap_writer_ops_t short_file_ops = { }; +/** 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, @@ -145,6 +182,7 @@ static const pcap_writer_ops_t append_file_ops = { .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, @@ -153,13 +191,20 @@ static const pcap_writer_ops_t usb_file_ops = { .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); @@ -173,6 +218,11 @@ errno_t pcap_dumper_start(pcap_dumper_t *dumper, const char *name) 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); @@ -182,6 +232,11 @@ errno_t pcap_dumper_set_ops(pcap_dumper_t *dumper, int index) return rc; } +/** 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); @@ -195,6 +250,9 @@ void pcap_dumper_add_packet(pcap_dumper_t *dumper, const void *data, size_t 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); diff --git a/uspace/lib/pcap/src/pcapdump_client.c b/uspace/lib/pcap/src/pcapdump_client.c index 601be5fa3b..8925d77597 100644 --- a/uspace/lib/pcap/src/pcapdump_client.c +++ b/uspace/lib/pcap/src/pcapdump_client.c @@ -29,8 +29,7 @@ /** @addtogroup libpcap * @{ */ -/** @file - * @brief Client side of the pcapctl. Functions are called from the app pcapctl +/** @file Client side of the pcapctl. Functions are called from the app pcapctl. */ #include @@ -51,6 +50,11 @@ 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; @@ -79,6 +83,10 @@ static errno_t pcapctl_cat_get_svc(int *index, service_id_t *svc) 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; @@ -104,6 +112,10 @@ errno_t pcapctl_is_valid_device(int *index) 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); @@ -126,9 +138,7 @@ errno_t pcapctl_is_valid_ops_number(int *index, pcapctl_sess_t *sess) return EOK; } -/** - * - */ +/** Get all devices that can dump packets. */ errno_t pcapctl_list(void) { errno_t rc; @@ -159,8 +169,10 @@ errno_t pcapctl_list(void) 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) { @@ -195,8 +207,9 @@ errno_t pcapctl_dump_open(int *index, pcapctl_sess_t **rsess) 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) { @@ -204,11 +217,11 @@ errno_t pcapctl_dump_close(pcapctl_sess_t *sess) return EOK; } -/** Starting a new session for pcapctl +/** Send start request via IPC to start dumping. * - * @param name Name of the file to dump packets to - * @param sess session to start - * @return EOK on success or an error code + * @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) { @@ -232,10 +245,10 @@ errno_t pcapctl_dump_start(const char *name, int *ops_index, pcapctl_sess_t *ses return retval; } -/** Finish current session for pcapctl +/** Send stop request via IPC to start dumping. * - * @param sess Session to finish - * @return EOK on success or an error code + * @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) { diff --git a/uspace/lib/pcap/src/pcapdump_drv_iface.c b/uspace/lib/pcap/src/pcapdump_drv_iface.c index 76e370ca12..eb2cd68928 100644 --- a/uspace/lib/pcap/src/pcapdump_drv_iface.c +++ b/uspace/lib/pcap/src/pcapdump_drv_iface.c @@ -47,10 +47,9 @@ #define NAME "pcap" -/** Initialize interface for dumping packets - * - * @param dumper Device dumping interface - * +/** 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) { @@ -66,6 +65,10 @@ static errno_t pcapdump_drv_dumper_init(pcap_dumper_t *dumper) 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; @@ -85,13 +88,13 @@ errno_t pcapdump_init(pcap_dumper_t *dumper) return EOK; } -/** Dumping function for driver +/** Dumping function for driver. * - * Called every time, the packet is sent/recieved by the device + * 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 + * @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) diff --git a/uspace/lib/pcap/src/pcapdump_srv.c b/uspace/lib/pcap/src/pcapdump_srv.c index 9bdb449ce2..c465463e6a 100644 --- a/uspace/lib/pcap/src/pcapdump_srv.c +++ b/uspace/lib/pcap/src/pcapdump_srv.c @@ -46,6 +46,10 @@ #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; @@ -83,12 +87,19 @@ static void pcapdump_start_srv(ipc_call_t *icall, pcap_dumper_t *dumper) 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(); @@ -98,6 +109,10 @@ static void pcapdump_get_ops_num_srv(ipc_call_t *icall) 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; From 420b13d52f0d0149b0ff50f4b60cc6690842d6f3 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Fri, 13 Dec 2024 09:13:11 +0100 Subject: [PATCH 32/39] app typos --- uspace/app/pcapctl/main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 91f30e6978..8c304582dd 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -75,7 +75,7 @@ static errno_t start_dumping(int *dev_number, const char *name, int *ops_index) rc = pcapctl_dump_start(name, ops_index, sess); if (rc != EOK) { if (rc == EBUSY) { - printf("Dumping for device %d is in process, stop to start dumping to file %s.\n", *dev_number, name); + 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"); } @@ -187,19 +187,23 @@ int main(int argc, char *argv[]) } 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; @@ -237,17 +241,17 @@ int main(int argc, char *argv[]) if (start) { if (file_exists(output_file_name) && !forced && ops_number != 2) { - printf("File %s already exists. If you want to overwrite to it, then use flag --force.\n", output_file_name); + printf("File %s already exists. If you want to overwrite it, then use flag --force.\n", output_file_name); return 0; } - printf("Sarting dumping on device - %d, ops - %d.\n", dev_number, ops_number); + 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("Stopping dumping on device - %d, ops - %d.\n", dev_number, ops_number); + printf("Stop dumping on device - %d.\n", dev_number); stop_dumping(&dev_number); } else { usage(); From 01ccd702904f808f69c7fdd11bbd100b08ea6478 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Mon, 16 Dec 2024 19:42:29 +0100 Subject: [PATCH 33/39] pcapcat dumps file hdr --- uspace/app/meson.build | 1 + uspace/app/pcapcat/main.c | 111 +++++++++++++++++++++++++++++++++ uspace/app/pcapcat/meson.build | 29 +++++++++ 3 files changed, 141 insertions(+) create mode 100644 uspace/app/pcapcat/main.c create mode 100644 uspace/app/pcapcat/meson.build diff --git a/uspace/app/meson.build b/uspace/app/meson.build index 71263d3955..25f9d14aa6 100644 --- a/uspace/app/meson.build +++ b/uspace/app/meson.build @@ -71,6 +71,7 @@ apps = [ 'nic', 'nterm', 'ofw', + 'pcapcat', 'pcapctl', 'pci', 'ping', diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c new file mode 100644 index 0000000000..57a5c4e150 --- /dev/null +++ b/uspace/app/pcapcat/main.c @@ -0,0 +1,111 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "pcap.h" + +#define NAME "pcapcat" + +typedef struct { + uint32_t linktype; + void (*parse)(const char *); +} linktype_parser_t; + + + +static void read_head(FILE *file) +{ + pcap_file_header_t data; + memset(&data, 0, sizeof(pcap_file_header_t)); + + size_t bytesRead = fread(&data, 1, sizeof(pcap_file_header_t), file); + if (bytesRead < sizeof(pcap_file_header_t)) { + printf("Error: Could not read enough bytes (read %zu bytes)\n", bytesRead); + fclose(file); + return; + } + + printf("LinkType: %d\n", data.additional); + printf("Magic number: 0x%x\n", data.magic_number); + return; +} + +static void eth_parse(const char *file_path) +{ + FILE *f = fopen(file_path, "rb"); + if (f == NULL){ + printf("File %s does not exist.\n", file_path); + return; + } + + read_head(f); + + pcap_packet_header_t hdr; + + memset(&hdr, 0, sizeof(pcap_packet_header_t)); + size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); + + 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("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); + + fread(NULL, 1, (size_t)hdr.captured_length, f); + printf("After\n"); + read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); + } + + fclose(f); +} + +static const linktype_parser_t eth_parser = { + .parse = ð_parse, + .linktype = PCAP_LINKTYPE_ETHERNET +}; + + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + return 1; + } + + eth_parser.parse(argv[1]); + + return 0; +} \ No newline at end of file diff --git a/uspace/app/pcapcat/meson.build b/uspace/app/pcapcat/meson.build new file mode 100644 index 0000000000..ccc06218dc --- /dev/null +++ b/uspace/app/pcapcat/meson.build @@ -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') \ No newline at end of file From 1ea856685a263d13e4b8e9e30d1e526578df1b3e Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Wed, 18 Dec 2024 17:47:06 +0100 Subject: [PATCH 34/39] parse sizes --- uspace/app/pcapcat/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c index 57a5c4e150..699b64d44f 100644 --- a/uspace/app/pcapcat/main.c +++ b/uspace/app/pcapcat/main.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -83,9 +84,9 @@ static void eth_parse(const char *file_path) return; } printf("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); - - fread(NULL, 1, (size_t)hdr.captured_length, f); - printf("After\n"); + void *data = malloc(hdr.captured_length); + fread(data, 1, (size_t)hdr.captured_length, f); + free(data); read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); } From fc632e86554b61d90f229c7364e1e524a356b0a6 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 21 Dec 2024 12:37:22 +0100 Subject: [PATCH 35/39] pcapcat: ugly ipv4 and arp --- uspace/app/pcapcat/main.c | 106 +++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c index 699b64d44f..c40928eb49 100644 --- a/uspace/app/pcapcat/main.c +++ b/uspace/app/pcapcat/main.c @@ -25,6 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +//qemu-system-x86_64 -m 256m -nic bridge,id=n1,mac=52:54:00:BE:EF:01,br=br0 -boot order=d -cdrom image.iso -serial stdio #include #include @@ -43,8 +44,106 @@ typedef struct { void (*parse)(const char *); } linktype_parser_t; +#define PRINT_IP(msg, ip_addr, spaces) printf("%s IP: %d.%d.%d.%d%s", msg, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces) +#define PRINT_MAC(msg, mac, spaces) printf("%s MAC: %x:%x:%x:%x:%x:%x%s", msg, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], spaces) + +static void parse_arp(unsigned char *byte_source, size_t size) +{ + uint8_t sender_mac[6]; + uint8_t sender_ip[4]; + uint8_t target_mac[6]; + uint8_t target_ip[4]; + + for (int i = 22; i < 28; ++i) { + sender_mac[i - 22] = byte_source[i]; + } + + for (int i = 28; i < 32; ++i) { + sender_ip[i - 28] = byte_source[i]; + } + + for (int i = 32; i < 38; ++i) { + target_mac[i - 32] = byte_source[i]; + } + + for (int i = 38; i < 42; ++i) { + target_ip[i - 38] = byte_source[i]; + } + + PRINT_MAC("Sender", sender_mac, ", "); + PRINT_IP("Sender", sender_ip, " "); + PRINT_MAC("Target", target_mac, ", "); + PRINT_IP("Target", target_ip, "\n"); + +} + +static void parse_tcp(unsigned char *byte_source, size_t size) +{ + uint16_t src_port = byte_source[34] << 8 | byte_source[35]; + uint16_t dst_port = byte_source[36] << 8 | byte_source[37]; + printf(" [TCP] source port: %d, destination port: %d\n", src_port, dst_port); +} + +static void parse_ip(unsigned char *byte_source, size_t size) +{ + uint16_t total_length; + uint8_t header_length; + uint16_t payload_length; + uint8_t protocol; + uint8_t src_ip[4]; + uint8_t dst_ip[4]; + + header_length = (byte_source[14] & 0xf) * 4; + total_length = byte_source[16] << 8 | byte_source[17]; + payload_length = total_length - header_length; + protocol = byte_source[23]; + + for (int i = 26; i < 30; ++i) { + src_ip[i - 26] = byte_source[i]; + } + for (int i = 30; i < 34; ++i) { + dst_ip[i - 30] = byte_source[i]; + } + printf("IP header: %dB, payload: %dB, protocol: 0x%x, ", header_length, payload_length, protocol); + PRINT_IP("Source", src_ip, ", "); + PRINT_IP("Destination", dst_ip, "\n"); + + if (protocol == 0x6) { + parse_tcp(byte_source, size); + } +} +static void parse_packet(void *data, size_t size) +{ + unsigned char* byte_source = (unsigned char*)data; + + // Read the 12th and 13th bytes (indices 11 and 12) + unsigned char high_byte = byte_source[12]; // MSB + unsigned char low_byte = byte_source[13]; // LSB + + // Combine bytes in big-endian order + uint16_t value = (high_byte << 8) | low_byte; + + switch (value){ + case 0x0806: + printf("[ARP] "); + parse_arp(byte_source, size); + break; + case 0x0800: + printf("[IPv4] "); + parse_ip(byte_source, size); + break; + case 0x86DD: + printf("IPv6\n"); + break; + default: + printf("0x%x\n", value); + break; + } + //printf("Ethernet Type of packet: 0x%x\n", hdr->etype_len); +} + static void read_head(FILE *file) { pcap_file_header_t data; @@ -76,16 +175,19 @@ static void eth_parse(const char *file_path) memset(&hdr, 0, sizeof(pcap_packet_header_t)); size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); - + int 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("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); + printf("%04d) ", index); + index++; + //printf("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); void *data = malloc(hdr.captured_length); fread(data, 1, (size_t)hdr.captured_length, f); + parse_packet(data, (size_t)hdr.captured_length); free(data); read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); } From 3197b504ea375d9e7acbe08d262277596c01660f Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 21 Dec 2024 20:18:04 +0100 Subject: [PATCH 36/39] pcapcat utility, without docs and with literals --- uspace/app/pcapcat/eth_parser.c | 189 ++++++++++++++++++++++ uspace/app/pcapcat/eth_parser.h | 40 +++++ uspace/app/pcapcat/linktype_parser.h | 44 ++++++ uspace/app/pcapcat/main.c | 224 ++++++++++----------------- uspace/app/pcapcat/meson.build | 2 +- 5 files changed, 354 insertions(+), 145 deletions(-) create mode 100644 uspace/app/pcapcat/eth_parser.c create mode 100644 uspace/app/pcapcat/eth_parser.h create mode 100644 uspace/app/pcapcat/linktype_parser.h diff --git a/uspace/app/pcapcat/eth_parser.c b/uspace/app/pcapcat/eth_parser.c new file mode 100644 index 0000000000..6bb33a8f03 --- /dev/null +++ b/uspace/app/pcapcat/eth_parser.c @@ -0,0 +1,189 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "pcap.h" +#include "eth_parser.h" + +#define ETH_ADDR_SIZE 6 +#define IPV4_ADDR_SIZE 4 + +#define ETHER_TYPE_ARP 0x0806 +#define ETHER_TYPE_IP4 0x0800 +#define ETHER_TYPE_IP6 0x86DD + +#define BYTE_SIZE 8 + +#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 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] + + +static void read_from_buffer(unsigned char *buffer, int start_idx, int count, uint8_t *dst) +{ + for (int i = start_idx; i < start_idx + count; ++i) { + dst[i - start_idx] = buffer[i]; + } +} + +static void parse_arp(unsigned char *byte_source, size_t size) +{ + 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(byte_source, 22, ETH_ADDR_SIZE, sender_mac); + read_from_buffer(byte_source, 28, IPV4_ADDR_SIZE, sender_ip); + read_from_buffer(byte_source, 32, ETH_ADDR_SIZE, target_mac); + read_from_buffer(byte_source, 36, 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"); + +} + +static void parse_tcp(unsigned char *byte_source, size_t size) +{ + uint16_t src_port = BIG_END_16(byte_source, 34); + uint16_t dst_port = BIG_END_16(byte_source, 36); + printf(" [%s] source port: %d, destination port: %d\n", TCP_TEXT, src_port, dst_port); +} + +static void parse_ip(unsigned char *byte_source, 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]; + + header_length = (byte_source[14] & 0xf) * 4; + total_length = BIG_END_16(byte_source, 16); + payload_length = total_length - header_length; + ip_protocol = byte_source[23]; + + read_from_buffer(byte_source, 26, IPV4_ADDR_SIZE, src_ip); + read_from_buffer(byte_source, 28, 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(byte_source, size); + } +} + +static void parse_eth_packet(void *data, size_t size, bool verbose_flag) +{ + unsigned char* byte_source = (unsigned char*)data; + + uint16_t protocol = BIG_END_16(byte_source, 12); + + switch (protocol){ + case ETHER_TYPE_ARP: + printf("[%s] ", ARP_TEXT); + parse_arp(byte_source, size); + break; + case ETHER_TYPE_IP4: + printf("[%s] ", IPV4_TEXT); + parse_ip(byte_source, size, verbose_flag); + break; + case ETHER_TYPE_IP6: + printf("[%s]\n", IPV6_TEXT); + break; + default: + printf("[0x%x]\n", protocol); + break; + } +} + +void eth_parse_header(pcap_file_header_t *hdr) +{ + printf("LinkType: %d\n", hdr->additional); + printf("Magic number: 0x%x\n", hdr->magic_number); +} + +void eth_parse_packets(FILE *f, int count, bool verbose_flag) +{ + pcap_packet_header_t hdr; + + size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); + 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, f); + if (read_bytes < (size_t)hdr.captured_length) { + printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes); + return; + } + parse_eth_packet(data, (size_t)hdr.captured_length, verbose_flag); + free(data); + + //Read first count packets + 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), f); + } + + fclose(f); +} \ No newline at end of file diff --git a/uspace/app/pcapcat/eth_parser.h b/uspace/app/pcapcat/eth_parser.h new file mode 100644 index 0000000000..98d9670517 --- /dev/null +++ b/uspace/app/pcapcat/eth_parser.h @@ -0,0 +1,40 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +extern void eth_parse_packets(FILE *, int, bool); +extern void eth_parse_header(pcap_file_header_t *); diff --git a/uspace/app/pcapcat/linktype_parser.h b/uspace/app/pcapcat/linktype_parser.h new file mode 100644 index 0000000000..f96c3b0592 --- /dev/null +++ b/uspace/app/pcapcat/linktype_parser.h @@ -0,0 +1,44 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct { + uint32_t linktype; + void (*parse_file_header)(pcap_file_header_t *); + void (*parse_packets)(FILE *, int, bool); +} linktype_parser_t; \ No newline at end of file diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c index c40928eb49..f18ef78413 100644 --- a/uspace/app/pcapcat/main.c +++ b/uspace/app/pcapcat/main.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//qemu-system-x86_64 -m 256m -nic bridge,id=n1,mac=52:54:00:BE:EF:01,br=br0 -boot order=d -cdrom image.iso -serial stdio + #include #include @@ -34,181 +34,117 @@ #include #include #include +#include #include -#include "pcap.h" +#include + +#include "linktype_parser.h" +#include "eth_parser.h" #define NAME "pcapcat" -typedef struct { - uint32_t linktype; - void (*parse)(const char *); -} linktype_parser_t; +static const linktype_parser_t eth_parser = { + .parse_packets = ð_parse_packets, + .parse_file_header = ð_parse_header, + .linktype = PCAP_LINKTYPE_ETHERNET +}; -#define PRINT_IP(msg, ip_addr, spaces) printf("%s IP: %d.%d.%d.%d%s", msg, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces) -#define PRINT_MAC(msg, mac, spaces) printf("%s MAC: %x:%x:%x:%x:%x:%x%s", msg, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], spaces) +static const linktype_parser_t parsers[1] = {eth_parser}; -static void parse_arp(unsigned char *byte_source, size_t size) +static int parse_file(const char *file_path, int packet_count, bool verbose_flag) { - uint8_t sender_mac[6]; - uint8_t sender_ip[4]; - uint8_t target_mac[6]; - uint8_t target_ip[4]; - - for (int i = 22; i < 28; ++i) { - sender_mac[i - 22] = byte_source[i]; + FILE *f = fopen(file_path, "rb"); + if (f == NULL){ + printf("File %s does not exist.\n", file_path); + return 1; } - for (int i = 28; i < 32; ++i) { - sender_ip[i - 28] = byte_source[i]; - } + pcap_file_header_t hdr; + memset(&hdr, 0, sizeof(pcap_file_header_t)); - for (int i = 32; i < 38; ++i) { - target_mac[i - 32] = byte_source[i]; + 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; } - for (int i = 38; i < 42; ++i) { - target_ip[i - 38] = byte_source[i]; + 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; + } } - PRINT_MAC("Sender", sender_mac, ", "); - PRINT_IP("Sender", sender_ip, " "); - PRINT_MAC("Target", target_mac, ", "); - PRINT_IP("Target", target_ip, "\n"); + 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); + return 0; } -static void parse_tcp(unsigned char *byte_source, size_t size) +static void usage() { - uint16_t src_port = byte_source[34] << 8 | byte_source[35]; - uint16_t dst_port = byte_source[36] << 8 | byte_source[37]; - printf(" [TCP] source port: %d, destination port: %d\n", src_port, dst_port); + printf("HelenOS cat utility for PCAP file format.\n" + "Can run during dumping process.\n" + "Usage:\n" + NAME " \n" + "\tPrint all packets from file .\n" + NAME " --count= | -c \n" + "\tPrint first packets from .\n" + NAME " --verbose | -v \n" + "\tPrint verbose description (with TCP ports) of packets.\n" + ); } -static void parse_ip(unsigned char *byte_source, size_t size) -{ - uint16_t total_length; - uint8_t header_length; - uint16_t payload_length; - uint8_t protocol; - uint8_t src_ip[4]; - uint8_t dst_ip[4]; - - header_length = (byte_source[14] & 0xf) * 4; - total_length = byte_source[16] << 8 | byte_source[17]; - payload_length = total_length - header_length; - protocol = byte_source[23]; - - for (int i = 26; i < 30; ++i) { - src_ip[i - 26] = byte_source[i]; - } - for (int i = 30; i < 34; ++i) { - dst_ip[i - 30] = byte_source[i]; - } - printf("IP header: %dB, payload: %dB, protocol: 0x%x, ", header_length, payload_length, protocol); - PRINT_IP("Source", src_ip, ", "); - PRINT_IP("Destination", dst_ip, "\n"); - - if (protocol == 0x6) { - parse_tcp(byte_source, size); - } -} +static struct option options[] = { + {"count", required_argument, 0, 'c'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; -static void parse_packet(void *data, size_t size) +int main(int argc, char *argv[]) { - unsigned char* byte_source = (unsigned char*)data; - - // Read the 12th and 13th bytes (indices 11 and 12) - unsigned char high_byte = byte_source[12]; // MSB - unsigned char low_byte = byte_source[13]; // LSB - - // Combine bytes in big-endian order - uint16_t value = (high_byte << 8) | low_byte; + int ret = 0; + int idx = 0; + int count = -1; + bool verbose = false; + const char *filename = ""; + if (argc == 1) + { + usage(); + return 0; + } - switch (value){ - case 0x0806: - printf("[ARP] "); - parse_arp(byte_source, size); - break; - case 0x0800: - printf("[IPv4] "); - parse_ip(byte_source, size); + while (ret != -1) { + ret = getopt_long(argc, argv, "c:v", options, &idx); + switch (ret) + { + case 'c': + count = atoi(optarg); break; - case 0x86DD: - printf("IPv6\n"); + case 'v': + verbose = true; break; + case '?': + printf("Unknown option or missing argument.\n"); + return 1; default: - printf("0x%x\n", value); break; - } - //printf("Ethernet Type of packet: 0x%x\n", hdr->etype_len); -} - -static void read_head(FILE *file) -{ - pcap_file_header_t data; - memset(&data, 0, sizeof(pcap_file_header_t)); - - size_t bytesRead = fread(&data, 1, sizeof(pcap_file_header_t), file); - if (bytesRead < sizeof(pcap_file_header_t)) { - printf("Error: Could not read enough bytes (read %zu bytes)\n", bytesRead); - fclose(file); - return; - } - - printf("LinkType: %d\n", data.additional); - printf("Magic number: 0x%x\n", data.magic_number); - return; -} - -static void eth_parse(const char *file_path) -{ - FILE *f = fopen(file_path, "rb"); - if (f == NULL){ - printf("File %s does not exist.\n", file_path); - return; - } - - read_head(f); - - pcap_packet_header_t hdr; - - memset(&hdr, 0, sizeof(pcap_packet_header_t)); - size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); - int 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) ", index); - index++; - //printf("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); - void *data = malloc(hdr.captured_length); - fread(data, 1, (size_t)hdr.captured_length, f); - parse_packet(data, (size_t)hdr.captured_length); - free(data); - read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); } - fclose(f); -} - -static const linktype_parser_t eth_parser = { - .parse = ð_parse, - .linktype = PCAP_LINKTYPE_ETHERNET -}; - - -int main(int argc, char *argv[]) -{ - if (argc != 2) - { - return 1; + if (optind < argc) { + filename = argv[optind]; } - eth_parser.parse(argv[1]); + int ret_val = parse_file(filename, count, verbose); - return 0; + return ret_val; } \ No newline at end of file diff --git a/uspace/app/pcapcat/meson.build b/uspace/app/pcapcat/meson.build index ccc06218dc..6de8726c41 100644 --- a/uspace/app/pcapcat/meson.build +++ b/uspace/app/pcapcat/meson.build @@ -26,4 +26,4 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # deps = ['pcap'] -src = files('main.c') \ No newline at end of file +src = files('main.c', 'eth_parser.c') \ No newline at end of file From 373dded90dc9bcf4b2a1a0f9262855a26421fe24 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 21 Dec 2024 20:19:09 +0100 Subject: [PATCH 37/39] pcapcat: fix includes --- uspace/app/pcapcat/eth_parser.h | 1 + 1 file changed, 1 insertion(+) diff --git a/uspace/app/pcapcat/eth_parser.h b/uspace/app/pcapcat/eth_parser.h index 98d9670517..6dc225a5ba 100644 --- a/uspace/app/pcapcat/eth_parser.h +++ b/uspace/app/pcapcat/eth_parser.h @@ -35,6 +35,7 @@ #include #include #include +#include extern void eth_parse_packets(FILE *, int, bool); extern void eth_parse_header(pcap_file_header_t *); From caac05282f39a0eb12a799cdc11f53fa8229f95d Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sun, 22 Dec 2024 17:47:50 +0100 Subject: [PATCH 38/39] pcapcat: docs, no literals, time fix in pcap lib --- uspace/app/pcapcat/doc/doxygroups.h | 4 + uspace/app/pcapcat/eth_parser.c | 140 ++++++++++++++++++++------- uspace/app/pcapcat/eth_parser.h | 11 ++- uspace/app/pcapcat/linktype_parser.h | 17 ++-- uspace/app/pcapcat/main.c | 2 +- uspace/app/pcapctl/doc/doxygroups.h | 2 +- uspace/lib/pcap/include/pcap.h | 2 +- uspace/lib/pcap/src/pcap.c | 11 +-- uspace/lib/pcap/src/pcap_dumper.c | 4 +- 9 files changed, 135 insertions(+), 58 deletions(-) create mode 100644 uspace/app/pcapcat/doc/doxygroups.h diff --git a/uspace/app/pcapcat/doc/doxygroups.h b/uspace/app/pcapcat/doc/doxygroups.h new file mode 100644 index 0000000000..1402226765 --- /dev/null +++ b/uspace/app/pcapcat/doc/doxygroups.h @@ -0,0 +1,4 @@ +/** @addtogroup pcapcat pcapcat + * @brief Command-line utility for printing files of PCAP format. + * @ingroup apps + */ diff --git a/uspace/app/pcapcat/eth_parser.c b/uspace/app/pcapcat/eth_parser.c index 6bb33a8f03..f19a0fff3f 100644 --- a/uspace/app/pcapcat/eth_parser.c +++ b/uspace/app/pcapcat/eth_parser.c @@ -26,26 +26,31 @@ * 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 #include #include -#include #include -#include #include -#include -#include "pcap.h" +#include #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 @@ -57,46 +62,81 @@ #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] - -static void read_from_buffer(unsigned char *buffer, int start_idx, int count, uint8_t *dst) +/** 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 (int i = start_idx; i < start_idx + count; ++i) { + for (size_t i = start_idx; i < start_idx + count; ++i) { dst[i - start_idx] = buffer[i]; } } -static void parse_arp(unsigned char *byte_source, size_t size) +/** 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) { + size_t sender_mac_offset = 22; + size_t sender_ip_offset = 28; + size_t target_mac_offset = 32; + size_t target_ip_offset = 38; + if (size < target_ip_offset + 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(byte_source, 22, ETH_ADDR_SIZE, sender_mac); - read_from_buffer(byte_source, 28, IPV4_ADDR_SIZE, sender_ip); - read_from_buffer(byte_source, 32, ETH_ADDR_SIZE, target_mac); - read_from_buffer(byte_source, 36, IPV4_ADDR_SIZE, target_ip); + read_from_buffer(buffer, sender_mac_offset, ETH_ADDR_SIZE, sender_mac); + read_from_buffer(buffer, sender_ip_offset, IPV4_ADDR_SIZE, sender_ip); + read_from_buffer(buffer, target_mac_offset, ETH_ADDR_SIZE, target_mac); + read_from_buffer(buffer, target_ip_offset, 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"); - } -static void parse_tcp(unsigned char *byte_source, size_t size) +/** Parce TCP and print ports. + * @param buffer TCP segment. + * @param size of the buffer. + */ +static void parse_tcp(unsigned char *buffer, size_t size) { - uint16_t src_port = BIG_END_16(byte_source, 34); - uint16_t dst_port = BIG_END_16(byte_source, 36); + size_t src_port_offset = 34; + size_t dst_port_offset = 36; + + if (size < dst_port_offset + TCP_PORT_SIZE) { + printf("%s %s\n", TCP_TEXT, MALFORMED_PACKET); + return; + } + + uint16_t src_port = BIG_END_16(buffer, src_port_offset); + uint16_t dst_port = BIG_END_16(buffer, dst_port_offset); printf(" [%s] source port: %d, destination port: %d\n", TCP_TEXT, src_port, dst_port); } -static void parse_ip(unsigned char *byte_source, size_t size, bool verbose) +/** 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; @@ -105,37 +145,54 @@ static void parse_ip(unsigned char *byte_source, size_t size, bool verbose) uint8_t src_ip[IPV4_ADDR_SIZE]; uint8_t dst_ip[IPV4_ADDR_SIZE]; - header_length = (byte_source[14] & 0xf) * 4; - total_length = BIG_END_16(byte_source, 16); + size_t hdr_length_offset = 14; + size_t total_len_offset = 16; + size_t protocol_offset = 23; + size_t src_ip_offset = 26; + size_t dst_ip_offset = 30; + + if (size < dst_ip_offset + IPV4_ADDR_SIZE) { + printf("%s %s", IP_TEXT, MALFORMED_PACKET); + return; + } + + header_length = (buffer[hdr_length_offset] & LOWER_4_BITS) * HDR_SIZE_COEF; + total_length = BIG_END_16(buffer, total_len_offset); payload_length = total_length - header_length; - ip_protocol = byte_source[23]; + ip_protocol = buffer[protocol_offset]; - read_from_buffer(byte_source, 26, IPV4_ADDR_SIZE, src_ip); - read_from_buffer(byte_source, 28, IPV4_ADDR_SIZE, dst_ip); + read_from_buffer(buffer, src_ip_offset, IPV4_ADDR_SIZE, src_ip); + read_from_buffer(buffer, dst_ip_offset, 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(byte_source, size); + parse_tcp(buffer, size); } } -static void parse_eth_packet(void *data, size_t size, bool verbose_flag) +/** 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* byte_source = (unsigned char*)data; + unsigned char* buffer = (unsigned char*)data; - uint16_t protocol = BIG_END_16(byte_source, 12); + 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(byte_source, size); + parse_arp(buffer, size); break; case ETHER_TYPE_IP4: printf("[%s] ", IPV4_TEXT); - parse_ip(byte_source, size, verbose_flag); + parse_ip(buffer, size, verbose_flag); break; case ETHER_TYPE_IP6: printf("[%s]\n", IPV6_TEXT); @@ -146,17 +203,25 @@ static void parse_eth_packet(void *data, size_t size, bool verbose_flag) } } +/** 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); } -void eth_parse_packets(FILE *f, int count, bool verbose_flag) +/** 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), f); + size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file); int packet_index = 1; while (read_bytes > 0) { @@ -168,22 +233,25 @@ void eth_parse_packets(FILE *f, int count, bool verbose_flag) printf("%04d) ", packet_index++); void *data = malloc(hdr.captured_length); - read_bytes = fread(data, 1, (size_t)hdr.captured_length, f); + 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_packet(data, (size_t)hdr.captured_length, verbose_flag); + parse_eth_frame(data, (size_t)hdr.captured_length, verbose_flag); free(data); - //Read first count packets + //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), f); + read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file); } - fclose(f); -} \ No newline at end of file + fclose(pcap_file); +} + +/** @} + */ \ No newline at end of file diff --git a/uspace/app/pcapcat/eth_parser.h b/uspace/app/pcapcat/eth_parser.h index 6dc225a5ba..0288a0bdf9 100644 --- a/uspace/app/pcapcat/eth_parser.h +++ b/uspace/app/pcapcat/eth_parser.h @@ -26,6 +26,11 @@ * 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 #include @@ -34,8 +39,10 @@ #include #include #include -#include #include -extern void eth_parse_packets(FILE *, int, bool); +extern void eth_parse_frames(FILE *, int, bool); extern void eth_parse_header(pcap_file_header_t *); + +/** @} + */ \ No newline at end of file diff --git a/uspace/app/pcapcat/linktype_parser.h b/uspace/app/pcapcat/linktype_parser.h index f96c3b0592..d361d27f09 100644 --- a/uspace/app/pcapcat/linktype_parser.h +++ b/uspace/app/pcapcat/linktype_parser.h @@ -26,19 +26,22 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +/** @addtogroup pcapcat + * @{ + */ +/** @file Structure for parsing PCAP file. + */ + #include -#include #include -#include #include -#include #include - typedef struct { uint32_t linktype; void (*parse_file_header)(pcap_file_header_t *); void (*parse_packets)(FILE *, int, bool); -} linktype_parser_t; \ No newline at end of file +} linktype_parser_t; + +/** @} + */ diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c index f18ef78413..f7762e0707 100644 --- a/uspace/app/pcapcat/main.c +++ b/uspace/app/pcapcat/main.c @@ -44,7 +44,7 @@ #define NAME "pcapcat" static const linktype_parser_t eth_parser = { - .parse_packets = ð_parse_packets, + .parse_packets = ð_parse_frames, .parse_file_header = ð_parse_header, .linktype = PCAP_LINKTYPE_ETHERNET }; diff --git a/uspace/app/pcapctl/doc/doxygroups.h b/uspace/app/pcapctl/doc/doxygroups.h index 64f848ec60..1fe7582026 100644 --- a/uspace/app/pcapctl/doc/doxygroups.h +++ b/uspace/app/pcapctl/doc/doxygroups.h @@ -1,4 +1,4 @@ /** @addtogroup pcapctl pcapctl - * @brief Dump network packets + * @brief Command-line utility for dumping packets. * @ingroup apps */ diff --git a/uspace/lib/pcap/include/pcap.h b/uspace/lib/pcap/include/pcap.h index 52536a5e6a..9a76b9e1b7 100644 --- a/uspace/lib/pcap/include/pcap.h +++ b/uspace/lib/pcap/include/pcap.h @@ -94,7 +94,7 @@ struct pcap_writer { pcap_writer_ops_t *ops; }; -extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano); +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); diff --git a/uspace/lib/pcap/src/pcap.c b/uspace/lib/pcap/src/pcap.c index a57dc64796..a8700a0695 100644 --- a/uspace/lib/pcap/src/pcap.c +++ b/uspace/lib/pcap/src/pcap.c @@ -47,22 +47,17 @@ 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_nsec; + 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. - * @param nano True for nanoseconds, false for microseconds in timestamp. */ -void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano) +void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype) { - uint32_t magic_version = PCAP_MAGIC_MICRO; - if (nano) { - magic_version = PCAP_MAGIC_NANO; - } - pcap_file_header_t file_header = { magic_version, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, + 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)); } diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 132aca4772..7d76f22bf6 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -59,7 +59,7 @@ static errno_t pcap_writer_to_file_init(pcap_writer_t *writer, const char *filen if (writer->data == NULL) { return EINVAL; } - pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET, false); + pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET); return EOK; } @@ -97,7 +97,7 @@ static errno_t pcap_writer_to_file_usb_init(pcap_writer_t *writer, const char *f if (writer->data == NULL) { return EINVAL; } - pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED, false); + pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED); return EOK; } From 46e215263cd3d16caa96273a6ab8a25278514d03 Mon Sep 17 00:00:00 2001 From: Nataliia Korop Date: Sat, 28 Dec 2024 19:44:18 +0100 Subject: [PATCH 39/39] pcapcat: typos, small fixes, pcapctl: comments, docs --- uspace/app/pcapcat/eth_parser.c | 59 ++++++++++++++++--------------- uspace/app/pcapcat/main.c | 2 ++ uspace/app/pcapctl/main.c | 10 ++++-- uspace/lib/pcap/src/pcap_dumper.c | 3 +- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/uspace/app/pcapcat/eth_parser.c b/uspace/app/pcapcat/eth_parser.c index f19a0fff3f..fb4a0b8f14 100644 --- a/uspace/app/pcapcat/eth_parser.c +++ b/uspace/app/pcapcat/eth_parser.c @@ -68,6 +68,22 @@ #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. @@ -87,11 +103,7 @@ static void read_from_buffer(unsigned char *buffer, size_t start_idx, size_t cou */ static void parse_arp(unsigned char *buffer, size_t size) { - size_t sender_mac_offset = 22; - size_t sender_ip_offset = 28; - size_t target_mac_offset = 32; - size_t target_ip_offset = 38; - if (size < target_ip_offset + IPV4_ADDR_SIZE) { + if (size < ARP_TARGET_IP + IPV4_ADDR_SIZE) { printf("%s %s", ARP_TEXT, MALFORMED_PACKET); return; } @@ -101,10 +113,10 @@ static void parse_arp(unsigned char *buffer, size_t size) uint8_t target_mac[ETH_ADDR_SIZE]; uint8_t target_ip[IPV4_ADDR_SIZE]; - read_from_buffer(buffer, sender_mac_offset, ETH_ADDR_SIZE, sender_mac); - read_from_buffer(buffer, sender_ip_offset, IPV4_ADDR_SIZE, sender_ip); - read_from_buffer(buffer, target_mac_offset, ETH_ADDR_SIZE, target_mac); - read_from_buffer(buffer, target_ip_offset, IPV4_ADDR_SIZE, target_ip); + 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, " "); @@ -118,16 +130,13 @@ static void parse_arp(unsigned char *buffer, size_t size) */ static void parse_tcp(unsigned char *buffer, size_t size) { - size_t src_port_offset = 34; - size_t dst_port_offset = 36; - - if (size < dst_port_offset + TCP_PORT_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, src_port_offset); - uint16_t dst_port = BIG_END_16(buffer, dst_port_offset); + 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); } @@ -145,24 +154,18 @@ static void parse_ip(unsigned char *buffer, size_t size, bool verbose) uint8_t src_ip[IPV4_ADDR_SIZE]; uint8_t dst_ip[IPV4_ADDR_SIZE]; - size_t hdr_length_offset = 14; - size_t total_len_offset = 16; - size_t protocol_offset = 23; - size_t src_ip_offset = 26; - size_t dst_ip_offset = 30; - - if (size < dst_ip_offset + IPV4_ADDR_SIZE) { + if (size < IP_DST_ADDR + IPV4_ADDR_SIZE) { printf("%s %s", IP_TEXT, MALFORMED_PACKET); return; } - header_length = (buffer[hdr_length_offset] & LOWER_4_BITS) * HDR_SIZE_COEF; - total_length = BIG_END_16(buffer, total_len_offset); + 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[protocol_offset]; + ip_protocol = buffer[IP_PROTOCOL]; - read_from_buffer(buffer, src_ip_offset, IPV4_ADDR_SIZE, src_ip); - read_from_buffer(buffer, dst_ip_offset, IPV4_ADDR_SIZE, dst_ip); + 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, ", "); @@ -249,8 +252,6 @@ void eth_parse_frames(FILE *pcap_file, int count, bool verbose_flag) memset(&hdr, 0, sizeof(pcap_packet_header_t)); read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file); } - - fclose(pcap_file); } /** @} diff --git a/uspace/app/pcapcat/main.c b/uspace/app/pcapcat/main.c index f7762e0707..8fad8f71a0 100644 --- a/uspace/app/pcapcat/main.c +++ b/uspace/app/pcapcat/main.c @@ -85,6 +85,8 @@ static int parse_file(const char *file_path, int packet_count, bool verbose_flag parsers[parser_index].parse_file_header(&hdr); parsers[parser_index].parse_packets(f, packet_count, verbose_flag); + + fclose(f); return 0; } diff --git a/uspace/app/pcapctl/main.c b/uspace/app/pcapctl/main.c index 8c304582dd..6d8be1d6e2 100644 --- a/uspace/app/pcapctl/main.c +++ b/uspace/app/pcapctl/main.c @@ -114,8 +114,8 @@ static void list_devs(void) 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' }, // truncated ops - { "usb", required_argument, 0, 'U' }, //?? + { "truncated", required_argument, 0, 'T' }, /* file as an argument with device 0 and dump truncated packets (for debugging purposes) */ + { "usb", required_argument, 0, 'U' }, /* todo: dump usb packets (not fully implemnted)*/ { "device", required_argument, 0, 'd' }, { "list", no_argument, 0, 'l' }, { "help", no_argument, 0, 'h' }, @@ -147,6 +147,12 @@ static void usage(void) "Usage:\n" NAME " --list | -l \n" "\tList of devices\n" + NAME " --new= | -N \n" + "\tStart dumping with ops - 0, on device - 0\n" + NAME " --append= | -A \n" + "\tContinue dumping on device - 0 to already existing file\n" + NAME " --truncated= | -T \n" + "\tStart dumping truncated packets to file on device - 0\n" NAME " --start | -r --device= | -d --outfile= | -o --ops= | p \n" "\tPackets dumped from device will be written to \n" NAME " --stop | -t --device= | -d \n" diff --git a/uspace/lib/pcap/src/pcap_dumper.c b/uspace/lib/pcap/src/pcap_dumper.c index 7d76f22bf6..560b809265 100644 --- a/uspace/lib/pcap/src/pcap_dumper.c +++ b/uspace/lib/pcap/src/pcap_dumper.c @@ -226,10 +226,9 @@ errno_t pcap_dumper_start(pcap_dumper_t *dumper, const char *name) errno_t pcap_dumper_set_ops(pcap_dumper_t *dumper, int index) { fibril_mutex_lock(&dumper->mutex); - errno_t rc = EOK; dumper->writer.ops = &ops[index]; fibril_mutex_unlock(&dumper->mutex); - return rc; + return EOK; } /** Write packet to destination buffer.