diff --git a/doc/ide_test_ini.md b/doc/ide_test_ini.md index 0d8b076..4a5eadc 100644 --- a/doc/ide_test_ini.md +++ b/doc/ide_test_ini.md @@ -35,6 +35,7 @@ EntryName=EntryValue | pci_log|0/1 |0 | O | enable pci log if 1| | libspdm_log|0/1 |0 | O | enable libspdm log if 1| | debug_level | verbose/info/warn/error | warn | O | debug level| +| pcap_enable | 0/1 | 0 | O | enable pcap capture if 1| [Ports] |Entry|Value|Default|Mandatory|Comment| diff --git a/teeio-validator/include/ide_test.h b/teeio-validator/include/ide_test.h index 85517f0..467ad35 100644 --- a/teeio-validator/include/ide_test.h +++ b/teeio-validator/include/ide_test.h @@ -155,6 +155,7 @@ typedef struct uint32_t debug_level; bool libspdm_log; bool wo_tdisp; + bool pcap_enable; } IDE_TEST_MAIN_CONFIG; typedef struct { @@ -486,4 +487,4 @@ struct _ide_run_test_suite { ide_run_test_config_t *test_config; }; -#endif \ No newline at end of file +#endif diff --git a/teeio-validator/include/teeio_validator.h b/teeio-validator/include/teeio_validator.h index a45a456..e09e802 100644 --- a/teeio-validator/include/teeio_validator.h +++ b/teeio-validator/include/teeio_validator.h @@ -27,5 +27,6 @@ #define TEEIO_VALIDATOR_VERSION "0.2.0" #define LOGFILE "./teeio_log" +#define PCAPFILE "./teeio_pcap" #endif diff --git a/teeio-validator/library/helperlib/CMakeLists.txt b/teeio-validator/library/helperlib/CMakeLists.txt index 93e7059..ddfbaae 100644 --- a/teeio-validator/library/helperlib/CMakeLists.txt +++ b/teeio-validator/library/helperlib/CMakeLists.txt @@ -12,14 +12,17 @@ SET(CMAKE_EXE_LINKER_FLAGS "-static") INCLUDE_DIRECTORIES( ${LIBSPDM_DIR}/include ${LIBSPDM_DIR}/include/hal + ${LIBSPDM_DIR}/os_stub/include/ ${PROJECT_SOURCE_DIR}/include ${TEEIO_VALIDATOR_LIB_DIR}/helperlib/include + ${SPDM_EMU_DIR}/spdm_emu/spdm_emu_common ) SET(src_helperlib ide_ini_helper.c pcie_helper.c utils.c + pcap.c ) SET(helperlib_LIBRARY diff --git a/teeio-validator/library/helperlib/include/pcap.h b/teeio-validator/library/helperlib/include/pcap.h new file mode 100644 index 0000000..dc0b174 --- /dev/null +++ b/teeio-validator/library/helperlib/include/pcap.h @@ -0,0 +1,18 @@ +/** + * Copyright Notice: + * Copyright 2021-2022 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#ifndef __SPDM_PCAP_H__ +#define __SPDM_PCAP_H__ + +bool open_pcap_packet_file(const char *pcap_file_name, uint32_t transport_layer); + +void close_pcap_packet_file(void); + +void append_pcap_packet_data(const void *header, size_t header_size, + const void *data, size_t size); + + +#endif diff --git a/teeio-validator/library/helperlib/pcap.c b/teeio-validator/library/helperlib/pcap.c new file mode 100644 index 0000000..1082c94 --- /dev/null +++ b/teeio-validator/library/helperlib/pcap.c @@ -0,0 +1,116 @@ +/** + * Copyright Notice: + * Copyright 2021-2022 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include +#include +#include +#include +#include +#include +#include "pcap.h" +#include "command.h" +#include "teeio_debug.h" + +#define PCAP_PACKET_MAX_SIZE 0x00010000 + +static FILE *m_pcap_file; + +bool open_pcap_packet_file(const char *pcap_file_name, uint32_t transport_layer) +{ + pcap_global_header_t pcap_global_header; + + if (pcap_file_name == NULL) { + return false; + } + + pcap_global_header.magic_number = PCAP_GLOBAL_HEADER_MAGIC; + pcap_global_header.version_major = PCAP_GLOBAL_HEADER_VERSION_MAJOR; + pcap_global_header.version_minor = PCAP_GLOBAL_HEADER_VERSION_MINOR; + pcap_global_header.this_zone = 0; + pcap_global_header.sig_figs = 0; + pcap_global_header.snap_len = PCAP_PACKET_MAX_SIZE; + if (transport_layer == SOCKET_TRANSPORT_TYPE_MCTP) { + pcap_global_header.network = LINKTYPE_MCTP; + } else if (transport_layer == SOCKET_TRANSPORT_TYPE_PCI_DOE) { + pcap_global_header.network = LINKTYPE_PCI_DOE; + } else { + return false; + } + + if ((m_pcap_file = fopen(pcap_file_name, "wb")) == NULL) { + TEEIO_DEBUG ((TEEIO_DEBUG_ERROR, "!!!Unable to open pcap file %s!!!\n!!!", pcap_file_name)); + return false; + } + + if ((fwrite(&pcap_global_header, 1, sizeof(pcap_global_header), + m_pcap_file)) != sizeof(pcap_global_header)) { + TEEIO_DEBUG ((TEEIO_DEBUG_ERROR, "!!!Write pcap file error!!!\n")); + close_pcap_packet_file(); + return false; + } + + fflush(m_pcap_file); + return true; +} + +void close_pcap_packet_file(void) +{ + if (m_pcap_file != NULL) { + fclose(m_pcap_file); + m_pcap_file = NULL; + } +} + +void append_pcap_packet_data(const void *header, size_t header_size, + const void *data, size_t size) +{ + pcap_packet_header_t pcap_packet_header; + size_t total_size; + + total_size = header_size + size; + + if (m_pcap_file != NULL) { + time_t rawtime; + time(&rawtime); + + pcap_packet_header.ts_sec = (uint32_t)rawtime; + pcap_packet_header.ts_usec = 0; + + pcap_packet_header.incl_len = + (uint32_t)((total_size > PCAP_PACKET_MAX_SIZE) ? + PCAP_PACKET_MAX_SIZE : + total_size); + pcap_packet_header.orig_len = (uint32_t)total_size; + + if ((fwrite(&pcap_packet_header, 1, sizeof(pcap_packet_header), + m_pcap_file)) != sizeof(pcap_packet_header)) { + TEEIO_DEBUG ((TEEIO_DEBUG_ERROR, "!!!Write pcap file error!!!\n")); + close_pcap_packet_file(); + return; + } + + if (total_size > PCAP_PACKET_MAX_SIZE) { + total_size = PCAP_PACKET_MAX_SIZE; + } + + if (header_size != 0) { + if ((fwrite(header, 1, header_size, m_pcap_file)) != + header_size) { + TEEIO_DEBUG ((TEEIO_DEBUG_ERROR, "!!!Write pcap file error!!!\n")); + close_pcap_packet_file(); + return; + } + } + + if ((fwrite(data, 1, size, m_pcap_file)) != size) { + TEEIO_DEBUG ((TEEIO_DEBUG_ERROR, "!!!Write pcap file error!!!\n")); + close_pcap_packet_file(); + return; + } + + fflush(m_pcap_file); + } +} diff --git a/teeio-validator/library/helperlib/utils.c b/teeio-validator/library/helperlib/utils.c index 553d651..a6f77d8 100644 --- a/teeio-validator/library/helperlib/utils.c +++ b/teeio-validator/library/helperlib/utils.c @@ -14,6 +14,7 @@ #include "teeio_debug.h" #include "helperlib.h" #include "helper_internal.h" +#include "pcap.h" extern FILE* m_logfile; @@ -375,3 +376,33 @@ void log_file_close(){ fclose(m_logfile); } } + +bool pcap_file_init(const char* pcap_file, uint32_t transport_layer) +{ + bool ret; + + char full_pcap_file[MAX_FILE_NAME] = {0}; + char current_time_stamp[MAX_TIME_STAMP_LENGTH] = {0}; + struct timeval currentTime; + gettimeofday(¤tTime, NULL); + + // Convert to local time + time_t rawtime = currentTime.tv_sec; + struct tm *localTime = localtime(&rawtime); + + strftime(current_time_stamp, MAX_TIME_STAMP_LENGTH, "%Y-%m-%d_%H-%M-%S", localTime); + + snprintf(full_pcap_file, MAX_FILE_NAME, "%s_%s.pcap", pcap_file, current_time_stamp); + ret = open_pcap_packet_file(full_pcap_file, transport_layer); + if(!ret){ + TEEIO_DEBUG((TEEIO_DEBUG_ERROR, "Failed to open pcap file [%s]\n", full_pcap_file)); + return false; + } + + return true; +} + +void pcap_file_close() +{ + close_pcap_packet_file(); +} diff --git a/teeio-validator/library/spdmlib/CMakeLists.txt b/teeio-validator/library/spdmlib/CMakeLists.txt index 69799bb..2cba2cc 100644 --- a/teeio-validator/library/spdmlib/CMakeLists.txt +++ b/teeio-validator/library/spdmlib/CMakeLists.txt @@ -14,6 +14,7 @@ INCLUDE_DIRECTORIES( ${LIBSPDM_DIR}/include/hal ${SPDM_EMU_DIR}/include ${PROJECT_SOURCE_DIR}/include + ${TEEIO_VALIDATOR_LIB_DIR}/helperlib/include ) SET(src_spdmlib diff --git a/teeio-validator/library/spdmlib/pci_doe.c b/teeio-validator/library/spdmlib/pci_doe.c index 2373649..205da76 100644 --- a/teeio-validator/library/spdmlib/pci_doe.c +++ b/teeio-validator/library/spdmlib/pci_doe.c @@ -6,6 +6,7 @@ #include "teeio_validator.h" #include "teeio_spdmlib.h" +#include "pcap.h" /* PCI Express - begin */ #define PCI_EXPRESS_EXTENDED_CAPABILITY_DOE_ID 0x002E @@ -208,6 +209,7 @@ libspdm_return_t device_doe_send_message( /* Write 1b to the DOE Abort bit. */ trigger_doe_abort(); } else { + append_pcap_packet_data(NULL, 0, (const void *)request, request_size); status = LIBSPDM_STATUS_SUCCESS; } } @@ -336,6 +338,7 @@ libspdm_return_t device_doe_receive_message( /* Write 1b to the DOE Abort bit. */ trigger_doe_abort(); } else { + append_pcap_packet_data(NULL, 0, (const void *)*response, *response_size); status = LIBSPDM_STATUS_SUCCESS; } } @@ -446,4 +449,4 @@ bool pcie_doe_init_request() } return found; -} \ No newline at end of file +} diff --git a/teeio-validator/teeio_validator/CMakeLists.txt b/teeio-validator/teeio_validator/CMakeLists.txt index 3974a8f..d8e702d 100644 --- a/teeio-validator/teeio_validator/CMakeLists.txt +++ b/teeio-validator/teeio_validator/CMakeLists.txt @@ -15,6 +15,7 @@ INCLUDE_DIRECTORIES(${SPDM_DEVICE_DIR}/include ${LIBSPDM_DIR}/os_stub/include ${LIBSPDM_DIR}/os_stub ${SPDM_EMU_DIR}/include + ${SPDM_EMU_DIR}/spdm_emu/spdm_emu_common ) SET(src_teeio_validator diff --git a/teeio-validator/teeio_validator/ide_test_ini.c b/teeio-validator/teeio_validator/ide_test_ini.c index e235a07..11c7000 100644 --- a/teeio-validator/teeio_validator/ide_test_ini.c +++ b/teeio-validator/teeio_validator/ide_test_ini.c @@ -2333,6 +2333,12 @@ void ParseMainSection(void *context, IDE_TEST_CONFIG *test_config) { test_config->main_config.debug_level = get_ide_log_level_from_string((const char*)entry_value); } + + sprintf(entry_name, "pcap_enable"); + if (GetDecimalUint32FromDataFile(context, (uint8_t *)section_name, (uint8_t *)entry_name, &data32)) + { + test_config->main_config.pcap_enable = data32 == 1; + } } void ParsePortsSection(void *context, IDE_TEST_CONFIG *test_config, IDE_PORT_TYPE port_type) diff --git a/teeio-validator/teeio_validator/teeio_validator.c b/teeio-validator/teeio_validator/teeio_validator.c index 8f5cd5b..eba5d28 100644 --- a/teeio-validator/teeio_validator/teeio_validator.c +++ b/teeio-validator/teeio_validator/teeio_validator.c @@ -9,6 +9,7 @@ #include #include #include "ide_test.h" +#include "command.h" char g_bdf[] = {'2','a',':','0','0','.','0','\0'}; char g_rp_bdf[] = {'2','9',':','0','2','.','0','\0'}; @@ -30,7 +31,9 @@ uint8_t g_scan_bus = INVALID_SCAN_BUS; FILE* m_logfile = NULL; bool log_file_init(const char* filepath); +bool pcap_file_init(const char* filepath, uint32_t transport_layer); void log_file_close(); +void pcap_file_close(); extern const char *IDE_TEST_IDE_TYPE_NAMES[]; @@ -94,12 +97,25 @@ int main(int argc, char *argv[]) } } + // Open pcap file + if (ide_test_config.main_config.pcap_enable) { + if (!pcap_file_init(PCAPFILE, SOCKET_TRANSPORT_TYPE_PCI_DOE)) { + TEEIO_PRINT(("Failed to open pcap file!\n")); + goto MainDone; + } + } + srand((unsigned int)time(NULL)); run(&ide_test_config); ret = 0; + // Close pcap file + if (ide_test_config.main_config.pcap_enable) { + pcap_file_close(); + } + MainDone: log_file_close();