On Thu, Jul 18, 2019 at 1:44 PM Ramon Fried <[email protected]> wrote: > > Add support for capturing ethernet packets and storing > them in memory in PCAP(2.4) format, later to be analyzed by > any PCAP viewer software (IE. Wireshark) > > This feature greatly assist debugging network issues such > as detecting dropped packets, packet corruption etc. > > Signed-off-by: Ramon Fried <[email protected]> > Reviewed-by: Alex Marginean <[email protected]> > Tested-by: Alex Marginean <[email protected]> > > --- > > Changes in v4: > * Move implementation to pcap.c/pcap.h > * Display error message when memory is exhausted. > * Populate $pcapsize environment variable with actual capture > size. > * move outgoing pcap_post to eth_send() > > Changes in v3: > * Change to implementation to command based. > * Added counters for incoming/outgoing packets. > * Support clearing the capture for multiple captures. > * Added documentation (separate patch). > > Changes in v2: > Fix type assignmnet to header.ts_sec
[ ... ] > diff --git a/net/pcap.c b/net/pcap.c > new file mode 100644 > index 0000000000..4036d8a3fa > --- /dev/null > +++ b/net/pcap.c > @@ -0,0 +1,156 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright 2019 Ramon Fried <[email protected]> > + */ > + > +#include <common.h> > +#include <net.h> > +#include <net/pcap.h> > +#include <time.h> > +#include <asm/io.h> > + > +#define LINKTYPE_ETHERNET 1 > + > +static bool initialized; > +static bool running; > +static bool buffer_full; > +static void *buf; > +static unsigned int max_size; > +static unsigned int pos; > + > +static unsigned long incoming_count; > +static unsigned long outgoing_count; > + > +struct pcap_header { > + u32 magic; > + u16 version_major; > + u16 version_minor; > + s32 thiszone; > + u32 sigfigs; > + u32 snaplen; > + u32 network; > +}; > + > +struct pcap_packet_header { > + u32 ts_sec; > + u32 ts_usec; > + u32 incl_len; > + u32 orig_len; > +}; > + > +static struct pcap_header file_header = { > + .magic = 0xa1b2c3d4, > + .version_major = 2, > + .version_minor = 4, > + .snaplen = 65535, > + .network = LINKTYPE_ETHERNET, > +}; > + > +int pcap_init(phys_addr_t paddr, unsigned long size) > +{ > + buf = map_physmem(paddr, size, 0); Since this is mapping to physmem, and apparently from your documentation, you need to use the physical memory when writing to a file or tftp send, how is the mapping typically handled? Maybe we should be writing to a variable like "pcapaddr" so it can be used in the write as part of a script. > + if (!buf) { > + printf("Failed mapping PCAP memory\n"); > + return -ENOMEM; > + } > + > + printf("PCAP capture initialized: addr: 0x%lx max length: %lu\n", > + (unsigned long)buf, size); > + > + memcpy(buf, &file_header, sizeof(file_header)); > + pos = sizeof(file_header); > + max_size = size; > + initialized = true; > + running = false; > + buffer_full = false; > + incoming_count = 0; > + outgoing_count = 0; > + return 0; > +} > + > +int pcap_start_stop(bool start) > +{ > + if (!initialized) { > + printf("error: pcap was not initialized\n"); > + return -ENODEV; > + } > + > + running = start; > + > + return 0; > +} > + > +int pcap_clear(void) > +{ > + if (!initialized) { > + printf("error: pcap was not initialized\n"); > + return -ENODEV; > + } > + > + pos = sizeof(file_header); > + incoming_count = 0; > + outgoing_count = 0; > + buffer_full = false; > + > + printf("pcap capture cleared\n"); > + return 0; > +} > + > +int pcap_post(const void *packet, size_t len, bool outgoing) > +{ > + struct pcap_packet_header header; > + u64 cur_time = timer_get_us(); > + > + if (!initialized || !running || !buf) > + return -ENODEV; > + > + if (buffer_full) > + return -ENOMEM; > + > + if ((pos + len + sizeof(header)) >= max_size) { > + buffer_full = true; > + printf("\n!!! Buffer is full, consider increasing buffer size > !!!\n"); > + return -ENOMEM; > + } > + > + header.ts_sec = cur_time / 1000000; > + header.ts_usec = cur_time % 1000000; > + header.incl_len = len; > + header.orig_len = len; > + > + memcpy(buf + pos, &header, sizeof(header)); > + pos += sizeof(header); > + memcpy(buf + pos, packet, len); > + pos += len; > + > + if (outgoing) > + outgoing_count++; > + else > + incoming_count++; > + > + env_set_hex("pcapsize", pos); > + > + return 0; > +} > + > +int pcap_print_status(void) > +{ > + if (!initialized) { > + printf("pcap was not initialized\n"); > + return -ENODEV; > + } > + printf("PCAP status:\n"); > + printf("\tInitialized addr: 0x%lx\tmax length: %u\n", > + (unsigned long)buf, max_size); > + printf("\tStatus: %s.\t file size: %u\n", running ? "Active" : "Idle", > + pos); > + printf("\tIncoming packets: %lu Outgoing packets: %lu\n", > + incoming_count, outgoing_count); > + > + return 0; > +} > + > +bool pcap_active(void) > +{ > + return running; > +} > -- > 2.22.0 > > _______________________________________________ > U-Boot mailing list > [email protected] > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

