mirror of
https://github.com/akuker/RASCSI.git
synced 2025-02-16 19:31:09 +00:00
Merge pull request #93 from quentinmit/daynaport-pcap
Daynaport improvements
This commit is contained in:
commit
877a7a129c
@ -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
|
||||
|
@ -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)
|
||||
|
@ -13,13 +13,18 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <unistd.h>
|
||||
#ifdef __linux__
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
#include <zlib.h> // 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);
|
||||
}
|
||||
|
@ -16,6 +16,9 @@
|
||||
#if !defined(ctapdriver_h)
|
||||
#define ctapdriver_h
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
#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
|
||||
|
@ -106,6 +106,12 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
||||
}
|
||||
}
|
||||
|
||||
BOOL FASTCALL SCSIDaynaPort::Open(const Filepath& path, BOOL attn)
|
||||
{
|
||||
LOGTRACE("SCSIDaynaPort Open");
|
||||
return m_tap->OpenDump(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
|
@ -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);
|
||||
|
@ -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 <sys/wait.h>
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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;
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user