uboot/net/pcap.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2019 Ramon Fried <rfried.dev@gmail.com>
   4 */
   5
   6#include <common.h>
   7#include <net.h>
   8#include <net/pcap.h>
   9#include <time.h>
  10#include <asm/io.h>
  11
  12#define LINKTYPE_ETHERNET       1
  13
  14static bool initialized;
  15static bool running;
  16static bool buffer_full;
  17static void *buf;
  18static unsigned int max_size;
  19static unsigned int pos;
  20
  21static unsigned long incoming_count;
  22static unsigned long outgoing_count;
  23
  24struct pcap_header {
  25        u32 magic;
  26        u16 version_major;
  27        u16 version_minor;
  28        s32 thiszone;
  29        u32 sigfigs;
  30        u32 snaplen;
  31        u32 network;
  32};
  33
  34struct pcap_packet_header {
  35        u32 ts_sec;
  36        u32 ts_usec;
  37        u32 incl_len;
  38        u32 orig_len;
  39};
  40
  41static struct pcap_header file_header = {
  42        .magic = 0xa1b2c3d4,
  43        .version_major = 2,
  44        .version_minor = 4,
  45        .snaplen = 65535,
  46        .network = LINKTYPE_ETHERNET,
  47};
  48
  49int pcap_init(phys_addr_t paddr, unsigned long size)
  50{
  51        buf = map_physmem(paddr, size, 0);
  52        if (!buf) {
  53                printf("Failed mapping PCAP memory\n");
  54                return -ENOMEM;
  55        }
  56
  57        printf("PCAP capture initialized: addr: 0x%lx max length: %lu\n",
  58               (unsigned long)buf, size);
  59
  60        memcpy(buf, &file_header, sizeof(file_header));
  61        pos = sizeof(file_header);
  62        max_size = size;
  63        initialized = true;
  64        running = false;
  65        buffer_full = false;
  66        incoming_count = 0;
  67        outgoing_count = 0;
  68        return 0;
  69}
  70
  71int pcap_start_stop(bool start)
  72{
  73        if (!initialized) {
  74                printf("error: pcap was not initialized\n");
  75                return -ENODEV;
  76        }
  77
  78        running = start;
  79
  80        return 0;
  81}
  82
  83int pcap_clear(void)
  84{
  85        if (!initialized) {
  86                printf("error: pcap was not initialized\n");
  87                return -ENODEV;
  88        }
  89
  90        pos = sizeof(file_header);
  91        incoming_count = 0;
  92        outgoing_count = 0;
  93        buffer_full = false;
  94
  95        printf("pcap capture cleared\n");
  96        return 0;
  97}
  98
  99int pcap_post(const void *packet, size_t len, bool outgoing)
 100{
 101        struct pcap_packet_header header;
 102        u64 cur_time = timer_get_us();
 103
 104        if (!initialized || !running || !buf)
 105                return -ENODEV;
 106
 107        if (buffer_full)
 108                return -ENOMEM;
 109
 110        if ((pos + len + sizeof(header)) >= max_size) {
 111                buffer_full = true;
 112                printf("\n!!! Buffer is full, consider increasing buffer size !!!\n");
 113                return -ENOMEM;
 114        }
 115
 116        header.ts_sec = cur_time / 1000000;
 117        header.ts_usec = cur_time % 1000000;
 118        header.incl_len = len;
 119        header.orig_len = len;
 120
 121        memcpy(buf + pos, &header, sizeof(header));
 122        pos += sizeof(header);
 123        memcpy(buf + pos, packet, len);
 124        pos += len;
 125
 126        if (outgoing)
 127                outgoing_count++;
 128        else
 129                incoming_count++;
 130
 131        env_set_hex("pcapsize", pos);
 132
 133        return 0;
 134}
 135
 136int pcap_print_status(void)
 137{
 138        if (!initialized) {
 139                printf("pcap was not initialized\n");
 140                return -ENODEV;
 141        }
 142        printf("PCAP status:\n");
 143        printf("\tInitialized addr: 0x%lx\tmax length: %u\n",
 144               (unsigned long)buf, max_size);
 145        printf("\tStatus: %s.\t file size: %u\n", running ? "Active" : "Idle",
 146               pos);
 147        printf("\tIncoming packets: %lu Outgoing packets: %lu\n",
 148               incoming_count, outgoing_count);
 149
 150        return 0;
 151}
 152
 153bool pcap_active(void)
 154{
 155        return running;
 156}
 157