Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> --- commands/Kconfig | 8 +++++ commands/Makefile | 1 + commands/ethlog.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ include/net.h | 11 +++++++ net/eth.c | 4 +-- net/net.c | 3 ++ 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 commands/ethlog.c diff --git a/commands/Kconfig b/commands/Kconfig index caef1e8fb5..c5505321cf 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -1272,6 +1272,14 @@ config CMD_IP_ROUTE_GET be shown on the command line or alternatively a variable is set to the result. +config CMD_ETHLOG + tristate + prompt "ethlog" + help + log ethernet traffic. + + Usage: ethlog [-r] [DEVICENAME] + # end Network commands endmenu diff --git a/commands/Makefile b/commands/Makefile index fffb6d979e..b3b7bafe6b 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_CMD_MEMCMP) += memcmp.o obj-$(CONFIG_CMD_MEMCPY) += memcpy.o obj-$(CONFIG_CMD_MEMSET) += memset.o obj-$(CONFIG_CMD_EDIT) += edit.o +obj-$(CONFIG_CMD_ETHLOG) += ethlog.o obj-$(CONFIG_CMD_EXEC) += exec.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_SMC) += smc.o diff --git a/commands/ethlog.c b/commands/ethlog.c new file mode 100644 index 0000000000..138650bae0 --- /dev/null +++ b/commands/ethlog.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: (c) 2022 Pengutronix, Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> + +#include <common.h> +#include <command.h> +#include <complete.h> +#include <environment.h> +#include <getopt.h> +#include <net.h> + +static void ethlog_rx_monitor(struct eth_device *edev, void *packet, + int length) +{ + print_hex_dump(KERN_DEBUG, "rx data <: ", DUMP_PREFIX_OFFSET, + 16, 1, packet, length, true); +} + +static void ethlog_tx_monitor(struct eth_device *edev, void *packet, + int length) +{ + print_hex_dump(KERN_DEBUG, "tx data >: ", DUMP_PREFIX_OFFSET, + 16, 1, packet, length, true); +} + +static int do_ethlog(int argc, char *argv[]) +{ + struct eth_device *edev; + const char *edevname; + bool remove = false; + int opt; + + while ((opt = getopt(argc, argv, "r")) > 0) { + switch (opt) { + case 'r': + remove = true; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (optind == argc) + edevname = "eth0"; + else + edevname = argv[optind]; + + edev = eth_get_byname(edevname); + if (!edev) { + printf("No such network device: %s\n", edevname); + return 1; + } + + if (remove) { + edev->tx_monitor = NULL; + edev->rx_monitor = NULL; + + return 0; + } + + if (edev->tx_monitor || edev->rx_monitor) { + printf("TX/RX monitor is already registered on %s\n", edevname); + return 1; + } + + edev->tx_monitor = ethlog_tx_monitor; + edev->rx_monitor = ethlog_rx_monitor; + + return 0; +} + +BAREBOX_CMD_HELP_START(ethlog) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-r", "remove log handler from Ethernet interface") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(ethlog) + .cmd = do_ethlog, + BAREBOX_CMD_DESC("ETHLOG - tool to get dump of Ethernet packets") + BAREBOX_CMD_OPTS("[-r] [device]") + BAREBOX_CMD_GROUP(CMD_GRP_NET) + BAREBOX_CMD_COMPLETE(eth_complete) +BAREBOX_CMD_END diff --git a/include/net.h b/include/net.h index 8013f79c2e..b50b6e76c8 100644 --- a/include/net.h +++ b/include/net.h @@ -46,6 +46,8 @@ struct eth_device { int (*set_ethaddr) (struct eth_device*, const unsigned char *adr); int (*rx_preprocessor) (struct eth_device*, unsigned char **packet, int *length); + void (*rx_monitor) (struct eth_device*, void *packet, int length); + void (*tx_monitor) (struct eth_device*, void *packet, int length); struct eth_device *next; void *priv; @@ -90,6 +92,15 @@ static inline const char *eth_name(struct eth_device *edev) return edev->devname; } +static inline int eth_send_raw(struct eth_device *edev, void *packet, + int length) +{ + if (edev->tx_monitor) + edev->tx_monitor(edev, packet, length); + + return edev->send(edev, packet, length); +} + int eth_register(struct eth_device* dev); /* Register network device */ void eth_unregister(struct eth_device* dev); /* Unregister network device */ int eth_set_ethaddr(struct eth_device *edev, const char *ethaddr); diff --git a/net/eth.c b/net/eth.c index 06bf5fbe65..ac4dd7ab42 100644 --- a/net/eth.c +++ b/net/eth.c @@ -245,7 +245,7 @@ int eth_send(struct eth_device *edev, void *packet, int length) led_trigger_network(LED_TRIGGER_NET_TX); - ret = edev->send(edev, packet, length); + ret = eth_send_raw(edev, packet, length); slice_release(eth_device_slice(edev)); @@ -272,7 +272,7 @@ static void eth_do_work(struct eth_device *edev) list_for_each_entry_safe(q, tmp, &edev->send_queue, list) { led_trigger_network(LED_TRIGGER_NET_TX); - edev->send(edev, q->data, q->length); + eth_send_raw(edev, q->data, q->length); list_del(&q->list); free(q->data); free(q); diff --git a/net/net.c b/net/net.c index dd2ceb396d..2b0dcb6574 100644 --- a/net/net.c +++ b/net/net.c @@ -708,6 +708,9 @@ int net_receive(struct eth_device *edev, unsigned char *pkt, int len) goto out; } + if (edev->rx_monitor) + edev->rx_monitor(edev, pkt, len); + if (edev->rx_preprocessor) { ret = edev->rx_preprocessor(edev, &pkt, &len); if (ret == -ENOMSG) -- 2.30.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox