mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
sniffer: capture packets to host via JTAG
Based on app-trace component, it's able to send sniffer packets to host via JTAG interface.
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
/* pcap encoder.
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -15,19 +21,19 @@
|
||||
#include "esp_log.h"
|
||||
#include "pcap.h"
|
||||
|
||||
static const char *TAG = "pcap";
|
||||
#define PCAP_CHECK(a, str, ret_val, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
return (ret_val); \
|
||||
} \
|
||||
static const char *PCAP_TAG = "pcap";
|
||||
#define PCAP_CHECK(a, str, goto_tag, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(PCAP_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Pcap File Header Type Definition
|
||||
* @brief Pcap File Header
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
@@ -41,23 +47,29 @@ typedef struct {
|
||||
} pcap_file_header_t;
|
||||
|
||||
/**
|
||||
* @brief Pcap Packet Header Type Definition
|
||||
* @brief Pcap Packet Header
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t seconds; /*!< Number of seconds since January 1st, 1970, 00:00:00 GMT */
|
||||
uint32_t microseconds; /*!< Number of microseconds when the packet was captured(offset from seconds) */
|
||||
uint32_t capture_length; /*!< Number of bytes of captured data, not longer than packet_length */
|
||||
uint32_t microseconds; /*!< Number of microseconds when the packet was captured (offset from seconds) */
|
||||
uint32_t capture_length; /*!< Number of bytes of captured data, no longer than packet_length */
|
||||
uint32_t packet_length; /*!< Actual length of current packet */
|
||||
} pcap_packet_header_t;
|
||||
|
||||
static FILE *file = NULL;
|
||||
/**
|
||||
* @brief Pcap Runtime Handle
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
FILE *file; /*!< File handle */
|
||||
} pcap_runtime_t;
|
||||
|
||||
esp_err_t pcap_capture_packet(void *payload, uint32_t length, uint32_t seconds, uint32_t microseconds)
|
||||
esp_err_t pcap_capture_packet(pcap_handle_t handle, void *payload, uint32_t length, uint32_t seconds, uint32_t microseconds)
|
||||
{
|
||||
if (!file) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
PCAP_CHECK(handle, "pcap handle is NULL", err);
|
||||
pcap_runtime_t *pcap_rt = (pcap_runtime_t *)handle;
|
||||
PCAP_CHECK(pcap_rt->file, "pcap file is NULL", err);
|
||||
size_t real_write = 0;
|
||||
pcap_packet_header_t header = {
|
||||
.seconds = seconds,
|
||||
@@ -65,33 +77,39 @@ esp_err_t pcap_capture_packet(void *payload, uint32_t length, uint32_t seconds,
|
||||
.capture_length = length,
|
||||
.packet_length = length
|
||||
};
|
||||
real_write = fwrite(&header, sizeof(header), 1, file);
|
||||
PCAP_CHECK(real_write == 1, "Write packet header error", ESP_FAIL);
|
||||
real_write = fwrite(payload, sizeof(uint8_t), length, file);
|
||||
PCAP_CHECK(real_write == length, "Write packet payload error", ESP_FAIL);
|
||||
real_write = fwrite(&header, sizeof(header), 1, pcap_rt->file);
|
||||
PCAP_CHECK(real_write == 1, "write packet header error", err);
|
||||
real_write = fwrite(payload, sizeof(uint8_t), length, pcap_rt->file);
|
||||
PCAP_CHECK(real_write == length, "write packet payload error", err);
|
||||
/* Flush content in the buffer into device */
|
||||
fflush(file);
|
||||
fflush(pcap_rt->file);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t pcap_close(void)
|
||||
esp_err_t pcap_deinit(pcap_handle_t handle)
|
||||
{
|
||||
if (!file) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (fclose(file)) {
|
||||
ESP_LOGE(TAG, "Close pcap file failed");
|
||||
file = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Close Pcap file OK");
|
||||
file = NULL;
|
||||
PCAP_CHECK(handle, "pcap handle is NULL", err);
|
||||
pcap_runtime_t *pcap_rt = (pcap_runtime_t *)handle;
|
||||
PCAP_CHECK(pcap_rt->file, "pcap file is NULL", err);
|
||||
PCAP_CHECK(fclose(pcap_rt->file) == 0, "close pcap file failed", err);
|
||||
pcap_rt->file = NULL;
|
||||
free(pcap_rt);
|
||||
ESP_LOGD(PCAP_TAG, "pcap deinit OK");
|
||||
return ESP_OK;
|
||||
err:
|
||||
ESP_LOGW(PCAP_TAG, "pcap deinit failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t pcap_new(pcap_config_t *config)
|
||||
esp_err_t pcap_init(pcap_config_t *config, pcap_handle_t *handle)
|
||||
{
|
||||
file = config->fp;
|
||||
PCAP_CHECK(config, "config is NULL", err);
|
||||
PCAP_CHECK(handle, "pcap handle is NULL", err);
|
||||
pcap_runtime_t *pcap_rt = calloc(sizeof(pcap_runtime_t), 1);
|
||||
PCAP_CHECK(pcap_rt, "calloc pcap runtime failed", err);
|
||||
pcap_rt->file = config->fp;
|
||||
/* Write Pcap File header */
|
||||
pcap_file_header_t header = {
|
||||
.magic = PCAP_MAGIC_BIG_ENDIAN,
|
||||
@@ -102,17 +120,19 @@ esp_err_t pcap_new(pcap_config_t *config)
|
||||
.snaplen = 0x40000,
|
||||
.link_type = config->link_type
|
||||
};
|
||||
size_t real_write = fwrite(&header, sizeof(header), 1, file);
|
||||
if (real_write != 1) {
|
||||
ESP_LOGE(TAG, "Write Pcap file header error");
|
||||
goto err_write;
|
||||
}
|
||||
size_t real_write = fwrite(&header, sizeof(header), 1, pcap_rt->file);
|
||||
PCAP_CHECK(real_write == 1, "write pcap file header failed", err_write);
|
||||
/* Flush content in the buffer into device */
|
||||
fflush(file);
|
||||
fflush(pcap_rt->file);
|
||||
*handle = (pcap_handle_t)pcap_rt;
|
||||
ESP_LOGD(PCAP_TAG, "pcap init OK");
|
||||
return ESP_OK;
|
||||
|
||||
/* Error Handling */
|
||||
err_write:
|
||||
fclose(file);
|
||||
fclose(pcap_rt->file);
|
||||
pcap_rt->file = NULL;
|
||||
free(pcap_rt);
|
||||
err:
|
||||
ESP_LOGW(PCAP_TAG, "pcap init failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user