diff --git a/easyinstall.sh b/easyinstall.sh index 811adda9..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 bridge-utils -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..434d0d1c 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -75,7 +75,6 @@ SRC_RASCSI = \ gpiobus.cpp \ filepath.cpp \ fileio.cpp\ - os.cpp\ rascsi_version.cpp # os.cpp # rasctl_command.cpp @@ -152,7 +151,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 d4f0a247..e9332d95 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -13,13 +13,18 @@ // //--------------------------------------------------------------------------- +#include +#ifdef __linux__ +#include +#include +#include +#endif #include // For crc32() #include "os.h" #include "xm6.h" #include "ctapdriver.h" #include "log.h" -const char rascsi_bridge_string[] = "rascsi_bridge"; //--------------------------------------------------------------------------- // @@ -32,6 +37,8 @@ CTapDriver::CTapDriver() // Initialization m_hTAP = -1; memset(&m_MacAddr, 0, sizeof(m_MacAddr)); + m_pcap = NULL; + m_pcap_dumper = NULL; } //--------------------------------------------------------------------------- @@ -40,12 +47,48 @@ CTapDriver::CTapDriver() // //--------------------------------------------------------------------------- #ifdef __linux__ + +static BOOL br_setif(int br_socket_fd, const char* bridgename, const char* ifname, BOOL add) { + struct ifreq ifr; + ifr.ifr_ifindex = if_nametoindex(ifname); + if (ifr.ifr_ifindex == 0) { + LOGERROR("Error: can't if_nametoindex. Errno: %d %s", errno, strerror(errno)); + return FALSE; + } + strncpy(ifr.ifr_name, bridgename, IFNAMSIZ); + if (ioctl(br_socket_fd, add ? SIOCBRADDIF : SIOCBRDELIF, &ifr) < 0) { + LOGERROR("Error: can't ioctl %s. Errno: %d %s", add ? "SIOCBRADDIF" : "SIOCBRDELIF", errno, strerror(errno)); + return FALSE; + } + return TRUE; +} + +static BOOL ip_link(int fd, const char* ifname, BOOL up) { + struct ifreq ifr; + int err; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + err = ioctl(fd, SIOCGIFFLAGS, &ifr); + if (err) { + LOGERROR("Error: can't ioctl SIOCGIFFLAGS. Errno: %d %s", errno, strerror(errno)); + return FALSE; + } + ifr.ifr_flags &= ~IFF_UP; + if (up) { + ifr.ifr_flags |= IFF_UP; + } + err = ioctl(fd, SIOCSIFFLAGS, &ifr); + if (err) { + LOGERROR("Error: can't ioctl SIOCSIFFLAGS. Errno: %d %s", errno, strerror(errno)); + return FALSE; + } + return TRUE; +} + BOOL FASTCALL CTapDriver::Init() { LOGTRACE("%s",__PRETTY_FUNCTION__); char dev[IFNAMSIZ] = "ras0"; - char cmd_output[256] = ""; struct ifreq ifr; int ret; @@ -72,23 +115,48 @@ BOOL FASTCALL CTapDriver::Init() } LOGTRACE("return code from ioctl was %d", ret); + int ip_fd; + if ((ip_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + LOGERROR("Error: can't open ip socket. Errno: %d %s", errno, strerror(errno)); + close(m_hTAP); + return FALSE; + } + + int br_socket_fd = -1; + if ((br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { + LOGERROR("Error: can't open bridge socket. Errno: %d %s", errno, strerror(errno)); + close(m_hTAP); + close(ip_fd); + return FALSE; + } + LOGTRACE("Going to see if the bridge is created"); - ret = run_system_cmd_with_output("brctl show | grep rascsi_bridge", cmd_output, sizeof(cmd_output)); - if(ret != EXIT_SUCCESS){ - LOGTRACE("Unable to run brctl show command"); - } - LOGTRACE("%s brctl show returned %s", __PRETTY_FUNCTION__, cmd_output); - // Check if the bridge is already created - if(strncmp(rascsi_bridge_string, cmd_output, strlen(rascsi_bridge_string)) != 0){ + if (access("/sys/class/net/rascsi_bridge", F_OK) != 0) { LOGINFO("Creating the rascsi_bridge..."); LOGDEBUG("brctl addbr rascsi_bridge"); - ret = run_system_cmd("brctl addbr rascsi_bridge"); + if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, "rascsi_bridge")) < 0) { + LOGERROR("Error: can't ioctl SIOCBRADDBR. Errno: %d %s", errno, strerror(errno)); + close(m_hTAP); + close(ip_fd); + close(br_socket_fd); + return FALSE; + } LOGDEBUG("brctl addif rascsi_bridge eth0"); - ret = run_system_cmd("brctl addif rascsi_bridge eth0"); + if (!br_setif(br_socket_fd, "rascsi_bridge", "eth0", TRUE)) { + close(m_hTAP); + close(ip_fd); + close(br_socket_fd); + return FALSE; + } LOGDEBUG("ip link set dev rascsi_bridge up"); - ret = run_system_cmd("ip link set dev rascsi_bridge up"); + if (!ip_link(ip_fd, "rascsi_bridge", TRUE)) { + close(m_hTAP); + close(ip_fd); + close(br_socket_fd); + return FALSE; + } } else { @@ -96,19 +164,29 @@ BOOL FASTCALL CTapDriver::Init() } LOGDEBUG("ip link set ras0 up"); - ret = run_system_cmd("ip link set ras0 up"); - LOGTRACE("return code from ip link set ras0 up was %d", ret); - + if (!ip_link(ip_fd, "ras0", TRUE)) { + close(m_hTAP); + close(ip_fd); + close(br_socket_fd); + return FALSE; + } + LOGDEBUG("brctl addif rascsi_bridge ras0"); - ret = run_system_cmd("brctl addif rascsi_bridge ras0"); - LOGTRACE("return code from brctl addif rascsi_bridge ras0 was %d", ret); - + if (!br_setif(br_socket_fd, "rascsi_bridge", "ras0", TRUE)) { + close(m_hTAP); + close(ip_fd); + close(br_socket_fd); + return FALSE; + } + // Get MAC address LOGTRACE("Getting the MAC address"); ifr.ifr_addr.sa_family = AF_INET; if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) { LOGERROR("Error: can't ioctl SIOCGIFHWADDR. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); + close(ip_fd); + close(br_socket_fd); return FALSE; } LOGTRACE("got the mac"); @@ -116,6 +194,10 @@ BOOL FASTCALL CTapDriver::Init() // Save MAC address memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr)); LOGINFO("Tap device %s created", ifr.ifr_name); + + close(ip_fd); + close(br_socket_fd); + return TRUE; } #endif // __linux__ @@ -168,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 @@ -176,13 +274,17 @@ BOOL FASTCALL CTapDriver::Init() void FASTCALL CTapDriver::Cleanup() { ASSERT(this); - int result; - LOGDEBUG("brctl delif rascsi_bridge ras0"); - result = run_system_cmd("brctl delif rascsi_bridge ras0"); - if(result != EXIT_SUCCESS){ - LOGWARN("Warning: The brctl delif command failed."); - LOGWARN("You may need to manually remove the ras0 tap device from the bridge"); + int br_socket_fd = -1; + if ((br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { + LOGERROR("Error: can't open bridge socket. Errno: %d %s", errno, strerror(errno)); + } else { + LOGDEBUG("brctl delif rascsi_bridge ras0"); + if (!br_setif(br_socket_fd, "rascsi_bridge", "ras0", FALSE)) { + LOGWARN("Warning: Removing ras0 from the bridge failed."); + LOGWARN("You may need to manually remove the ras0 tap device from the bridge"); + } + close(br_socket_fd); } // Release TAP defice @@ -190,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); + } } //--------------------------------------------------------------------------- @@ -198,10 +308,11 @@ void FASTCALL CTapDriver::Cleanup() // //--------------------------------------------------------------------------- BOOL FASTCALL CTapDriver::Enable(){ - int result; + int fd = socket(PF_INET, SOCK_DGRAM, 0); LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__); - result = run_system_cmd("ip link set ras0 up"); - return (result == EXIT_SUCCESS); + BOOL result = ip_link(fd, "ras0", TRUE); + close(fd); + return result; } //--------------------------------------------------------------------------- @@ -210,10 +321,11 @@ BOOL FASTCALL CTapDriver::Enable(){ // //--------------------------------------------------------------------------- BOOL FASTCALL CTapDriver::Disable(){ - int result; + int fd = socket(PF_INET, SOCK_DGRAM, 0); LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__); - result = run_system_cmd("ip link set ras0 down"); - return (result == EXIT_SUCCESS); + BOOL result = ip_link(fd, "ras0", FALSE); + close(fd); + return result; } //--------------------------------------------------------------------------- @@ -314,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; } @@ -328,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/os.cpp b/src/raspberrypi/os.cpp deleted file mode 100644 index 0b26424f..00000000 --- a/src/raspberrypi/os.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2020 GIMONS -// Copyright (C) 2020-2021 akuker -// -// [ OS related definitions ] -// -//--------------------------------------------------------------------------- - -#include "os.h" -#include "log.h" -#include - - -//--------------------------------------------------------------------------- -// -// Run system command and wait for it to finish -// -//--------------------------------------------------------------------------- -int run_system_cmd(const char* command) -{ - pid_t pid; - int result; - int status = 0; - pid=fork(); - if(pid == 0){ - result = system(command); - exit(result); - } - waitpid(pid, &status, 0); - return status; -} - - -//--------------------------------------------------------------------------- -// -// Run system command and save the output to a string -// -//--------------------------------------------------------------------------- -int run_system_cmd_with_output(const char* command, char* output_str, size_t max_size) -{ - FILE *fp; - char str_buff[1024]; - - fp = popen(command,"r"); - if(fp == NULL) - { - LOGWARN("%s Unable to run command %s", __PRETTY_FUNCTION__, command); - return EXIT_FAILURE; - } - - while((fgets(str_buff, sizeof(str_buff), fp) != NULL) && (strlen(output_str) < max_size)) - { - strncat(output_str, str_buff, max_size); - } - - pclose(fp); - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index b526cd57..cb145f7e 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -155,11 +155,4 @@ typedef const char *LPCSTR; #define xstrcasecmp strcasecmp #define xstrncasecmp strncasecmp -// Run system command and wait for it to finish -extern int run_system_cmd(const char* command); - -// Run system command and wait for it to finish and keep the output -extern int run_system_cmd_with_output(const char* command, char* output_str, size_t max_size); - - #endif // os_h 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);