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:
morris
2019-01-25 17:03:01 +08:00
parent a8b2e982e1
commit ae6d19b4fb
10 changed files with 399 additions and 269 deletions

View File

@@ -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;
}