Initial commit: project docs and ignore rules
This commit is contained in:
145
ESP32-C5-Toolkit/main/pcap_serializer.c
Normal file
145
ESP32-C5-Toolkit/main/pcap_serializer.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file pcap_serializer.c
|
||||
* @brief PCAP file serializer implementation
|
||||
*
|
||||
* Generates PCAP format files compatible with Wireshark and other tools
|
||||
*/
|
||||
#include "pcap_serializer.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "pcap_serializer";
|
||||
|
||||
// PCAP Constants
|
||||
#define PCAP_MAGIC_NUMBER 0xa1b2c3d4
|
||||
#define SNAPLEN 65535
|
||||
#define LINKTYPE_IEEE802_11 105 // 802.11 wireless
|
||||
#define MAX_PCAP_SIZE (512 * 1024) // 512KB limit to prevent memory exhaustion
|
||||
|
||||
// Buffer management
|
||||
static uint8_t *pcap_buffer = NULL;
|
||||
static unsigned pcap_size = 0;
|
||||
static unsigned packet_count = 0;
|
||||
|
||||
uint8_t* pcap_serializer_init(void) {
|
||||
// Free any existing buffer
|
||||
if (pcap_buffer) {
|
||||
free(pcap_buffer);
|
||||
}
|
||||
|
||||
// Create global header
|
||||
pcap_global_header_t header = {
|
||||
.magic_number = PCAP_MAGIC_NUMBER,
|
||||
.version_major = 2,
|
||||
.version_minor = 4,
|
||||
.thiszone = 0,
|
||||
.sigfigs = 0,
|
||||
.snaplen = SNAPLEN,
|
||||
.network = LINKTYPE_IEEE802_11
|
||||
};
|
||||
|
||||
// Allocate buffer for header
|
||||
pcap_buffer = malloc(sizeof(pcap_global_header_t));
|
||||
if (!pcap_buffer) {
|
||||
ESP_LOGE(TAG, "Failed to allocate PCAP buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(pcap_buffer, &header, sizeof(pcap_global_header_t));
|
||||
pcap_size = sizeof(pcap_global_header_t);
|
||||
packet_count = 0;
|
||||
|
||||
ESP_LOGI(TAG, "PCAP serializer initialized");
|
||||
return pcap_buffer;
|
||||
}
|
||||
|
||||
void pcap_serializer_append_frame(const uint8_t *buffer, unsigned size, unsigned ts_usec) {
|
||||
if (!buffer || size == 0) {
|
||||
ESP_LOGD(TAG, "Empty frame, not appending");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pcap_buffer) {
|
||||
ESP_LOGW(TAG, "PCAP not initialized, initializing now");
|
||||
pcap_serializer_init();
|
||||
if (!pcap_buffer) return;
|
||||
}
|
||||
|
||||
// Create record header
|
||||
pcap_record_header_t record = {
|
||||
.ts_sec = ts_usec / 1000000,
|
||||
.ts_usec = ts_usec % 1000000,
|
||||
.incl_len = size,
|
||||
.orig_len = size
|
||||
};
|
||||
|
||||
// Limit to SNAPLEN
|
||||
if (size > SNAPLEN) {
|
||||
size = SNAPLEN;
|
||||
record.incl_len = SNAPLEN;
|
||||
}
|
||||
|
||||
// Reallocate buffer
|
||||
unsigned new_size = pcap_size + sizeof(pcap_record_header_t) + size;
|
||||
|
||||
// Check if new size exceeds maximum limit
|
||||
if (new_size > MAX_PCAP_SIZE) {
|
||||
ESP_LOGW(TAG, "PCAP buffer limit reached (%u bytes), dropping frame", MAX_PCAP_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *new_buffer = realloc(pcap_buffer, new_size);
|
||||
if (!new_buffer) {
|
||||
ESP_LOGE(TAG, "Failed to reallocate PCAP buffer (size: %u bytes)! PCAP may be incomplete.", new_size);
|
||||
// Optionally: Could implement packet dropping strategy here (FIFO)
|
||||
return;
|
||||
}
|
||||
|
||||
// Append record header and data
|
||||
memcpy(new_buffer + pcap_size, &record, sizeof(pcap_record_header_t));
|
||||
memcpy(new_buffer + pcap_size + sizeof(pcap_record_header_t), buffer, size);
|
||||
|
||||
pcap_buffer = new_buffer;
|
||||
pcap_size = new_size;
|
||||
packet_count++;
|
||||
|
||||
ESP_LOGD(TAG, "Appended frame: %u bytes (total: %u bytes, %u packets)",
|
||||
size, pcap_size, packet_count);
|
||||
}
|
||||
|
||||
void pcap_serializer_deinit(void) {
|
||||
if (pcap_buffer) {
|
||||
free(pcap_buffer);
|
||||
pcap_buffer = NULL;
|
||||
}
|
||||
pcap_size = 0;
|
||||
packet_count = 0;
|
||||
ESP_LOGI(TAG, "PCAP serializer deinitialized");
|
||||
}
|
||||
|
||||
unsigned pcap_serializer_get_size(void) {
|
||||
return pcap_size;
|
||||
}
|
||||
|
||||
uint8_t* pcap_serializer_get_buffer(void) {
|
||||
return pcap_buffer;
|
||||
}
|
||||
|
||||
void pcap_serializer_reset(void) {
|
||||
// Keep just the global header
|
||||
if (pcap_buffer && pcap_size > sizeof(pcap_global_header_t)) {
|
||||
uint8_t *new_buffer = realloc(pcap_buffer, sizeof(pcap_global_header_t));
|
||||
if (new_buffer) {
|
||||
pcap_buffer = new_buffer;
|
||||
}
|
||||
}
|
||||
pcap_size = sizeof(pcap_global_header_t);
|
||||
packet_count = 0;
|
||||
ESP_LOGI(TAG, "PCAP buffer reset");
|
||||
}
|
||||
|
||||
unsigned pcap_serializer_get_packet_count(void) {
|
||||
return packet_count;
|
||||
}
|
||||
Reference in New Issue
Block a user