From 2579437b57a84c6fbc2611697ad9f849d1dda7fa Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 3 Apr 2021 20:02:20 +0100 Subject: [PATCH] Allow generating pcap files of Daynaport traffic If rasctl is given a file to "attach" to a daynaport interface, rascsi will generate a pcap file at that path containing all sent/received packets. --- easyinstall.sh | 2 +- src/raspberrypi/Makefile | 2 +- src/raspberrypi/devices/ctapdriver.cpp | 46 ++++++++++++++++++++++ src/raspberrypi/devices/ctapdriver.h | 10 ++++- src/raspberrypi/devices/scsi_daynaport.cpp | 6 +++ src/raspberrypi/devices/scsi_daynaport.h | 2 + src/raspberrypi/rascsi.cpp | 2 +- 7 files changed, 66 insertions(+), 4 deletions(-) diff --git a/easyinstall.sh b/easyinstall.sh index b3e0244f..669ae862 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -41,7 +41,7 @@ function initialChecks() { } function installPackages() { - sudo apt-get update && sudo apt install git libspdlog-dev genisoimage python3 python3-venv nginx -y + sudo apt-get update && sudo apt install git libspdlog-dev genisoimage python3 python3-venv nginx libpcap-dev -y } # install all dependency packages for RaSCSI Service diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 9a9984be..0b7d09b5 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -152,7 +152,7 @@ ALL: all docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(BINDIR)/$(RASCSI): $(OBJ_RASCSI) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz -lpcap $(BINDIR)/$(RASCTL): $(OBJ_RASCTL) | $(BINDIR) $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) diff --git a/src/raspberrypi/devices/ctapdriver.cpp b/src/raspberrypi/devices/ctapdriver.cpp index 96b87eb2..e9332d95 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -37,6 +37,8 @@ CTapDriver::CTapDriver() // Initialization m_hTAP = -1; memset(&m_MacAddr, 0, sizeof(m_MacAddr)); + m_pcap = NULL; + m_pcap_dumper = NULL; } //--------------------------------------------------------------------------- @@ -248,6 +250,22 @@ BOOL FASTCALL CTapDriver::Init() } #endif // __NetBSD__ +BOOL FASTCALL CTapDriver::OpenDump(const Filepath& path) { + if (m_pcap == NULL) { + m_pcap = pcap_open_dead(DLT_EN10MB, 65535); + } + if (m_pcap_dumper != NULL) { + pcap_dump_close(m_pcap_dumper); + } + m_pcap_dumper = pcap_dump_open(m_pcap, path.GetPath()); + if (m_pcap_dumper == NULL) { + LOGERROR("Error: can't open pcap file: %s", pcap_geterr(m_pcap)); + return FALSE; + } + LOGTRACE("%s Opened %s for dumping", __PRETTY_FUNCTION__, path.GetPath()) + return TRUE; +} + //--------------------------------------------------------------------------- // // Cleanup @@ -274,6 +292,14 @@ void FASTCALL CTapDriver::Cleanup() close(m_hTAP); m_hTAP = -1; } + + if (m_pcap_dumper != NULL) { + pcap_dump_close(m_pcap_dumper); + m_pcap_dumper = NULL; + } + if (m_pcap != NULL) { + pcap_close(m_pcap); + } } //--------------------------------------------------------------------------- @@ -400,6 +426,16 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) dwReceived += 4; } + if (m_pcap_dumper != NULL) { + struct pcap_pkthdr h = { + .caplen = dwReceived, + .len = dwReceived, + }; + gettimeofday(&h.ts, NULL); + pcap_dump((u_char*)m_pcap_dumper, &h, buf); + LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)dwReceived, buf[0], buf[dwReceived-1]); + } + // Return the number of bytes return dwReceived; } @@ -414,6 +450,16 @@ int FASTCALL CTapDriver::Tx(const BYTE *buf, int len) ASSERT(this); ASSERT(m_hTAP != -1); + if (m_pcap_dumper != NULL) { + struct pcap_pkthdr h = { + .caplen = (bpf_u_int32)len, + .len = (bpf_u_int32)len, + }; + gettimeofday(&h.ts, NULL); + pcap_dump((u_char*)m_pcap_dumper, &h, buf); + LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)h.len, buf[0], buf[h.len-1]); + } + // Start sending return write(m_hTAP, buf, len); } diff --git a/src/raspberrypi/devices/ctapdriver.h b/src/raspberrypi/devices/ctapdriver.h index 02fb5695..c52866f0 100644 --- a/src/raspberrypi/devices/ctapdriver.h +++ b/src/raspberrypi/devices/ctapdriver.h @@ -16,6 +16,9 @@ #if !defined(ctapdriver_h) #define ctapdriver_h +#include +#include "filepath.h" + #ifndef ETH_FRAME_LEN #define ETH_FRAME_LEN 1514 #endif @@ -32,7 +35,9 @@ public: CTapDriver(); // Constructor BOOL FASTCALL Init(); - // Initilization + // Initialization + BOOL FASTCALL OpenDump(const Filepath& path); + // Capture packets void FASTCALL Cleanup(); // Cleanup void FASTCALL GetMacAddr(BYTE *mac); @@ -58,6 +63,9 @@ private: int m_hTAP; // File handle BYTE m_garbage_buffer[ETH_FRAME_LEN]; + + pcap_t *m_pcap; + pcap_dumper_t *m_pcap_dumper; }; #endif // ctapdriver_h diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index 95181acc..44a58026 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -106,6 +106,12 @@ SCSIDaynaPort::~SCSIDaynaPort() } } +BOOL FASTCALL SCSIDaynaPort::Open(const Filepath& path, BOOL attn) +{ + LOGTRACE("SCSIDaynaPort Open"); + return m_tap->OpenDump(path); +} + //--------------------------------------------------------------------------- // // INQUIRY diff --git a/src/raspberrypi/devices/scsi_daynaport.h b/src/raspberrypi/devices/scsi_daynaport.h index b38a8a4b..a28e5863 100644 --- a/src/raspberrypi/devices/scsi_daynaport.h +++ b/src/raspberrypi/devices/scsi_daynaport.h @@ -46,6 +46,8 @@ public: // Constructor virtual ~SCSIDaynaPort(); // Destructor + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); + // Capture packets // commands int FASTCALL Inquiry(const DWORD *cdb, BYTE *buffer, DWORD major, DWORD minor); diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 56bc304f..a91c5bb6 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -557,7 +557,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) } // drive checks files - if (type <= rasctl_dev_scsi_hd || (type <= rasctl_dev_cd && xstrcasecmp(file, "-") != 0)) { + if (type <= rasctl_dev_scsi_hd || ((type <= rasctl_dev_cd || type == rasctl_dev_daynaport) && xstrcasecmp(file, "-") != 0)) { // Set the Path filepath.SetPath(file);