mirror of
https://github.com/akuker/RASCSI.git
synced 2025-08-07 15:25:54 +00:00
Daynaport device can be configured with interface list (issue #202)
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
#include "ctapdriver.h"
|
#include "ctapdriver.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include <string>
|
#include <sstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -35,9 +35,14 @@ using namespace std;
|
|||||||
// Constructor
|
// Constructor
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
CTapDriver::CTapDriver()
|
CTapDriver::CTapDriver(const string& interfaces)
|
||||||
{
|
{
|
||||||
LOGTRACE("%s",__PRETTY_FUNCTION__);
|
stringstream s(interfaces);
|
||||||
|
string interface;
|
||||||
|
while (getline(s, interface, ',')) {
|
||||||
|
this->interfaces.push_back(interface);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
m_bTxValid = FALSE;
|
m_bTxValid = FALSE;
|
||||||
m_hTAP = -1;
|
m_hTAP = -1;
|
||||||
@@ -88,7 +93,7 @@ static BOOL ip_link(int fd, const char* ifname, BOOL up) {
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_interface_up(const char *interface) {
|
static bool is_interface_up(const string& interface) {
|
||||||
string file = "/sys/class/net/";
|
string file = "/sys/class/net/";
|
||||||
file += interface;
|
file += interface;
|
||||||
file += "/carrier";
|
file += "/carrier";
|
||||||
@@ -150,24 +155,31 @@ BOOL CTapDriver::Init()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the bridge is already created
|
// Check if the bridge has already been created
|
||||||
if (access("/sys/class/net/rascsi_bridge", F_OK) != 0) {
|
if (access("/sys/class/net/rascsi_bridge", F_OK) != 0) {
|
||||||
LOGINFO("rascsi_bridge is not yet available");
|
LOGINFO("rascsi_bridge is not yet available");
|
||||||
|
|
||||||
LOGINFO("Checking whether to create bridge for interface eth0 or wlan0");
|
LOGTRACE("Checking which interface is available for creating the bridge");
|
||||||
const char *interface = NULL;
|
string interface;
|
||||||
if (is_interface_up("eth0")) {
|
for (auto it = interfaces.begin(); it != interfaces.end(); ++it) {
|
||||||
interface = "eth0";
|
if (is_interface_up(*it)) {
|
||||||
|
LOGTRACE(string("Interface " + (*it) + " is up").c_str());
|
||||||
|
|
||||||
|
interface = *it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOGTRACE(string("Interface " + (*it) + " is not up").c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (is_interface_up("wlan0")) {
|
|
||||||
interface = "wlan0";
|
if (interface.empty()) {
|
||||||
}
|
LOGERROR("No interface is up, not creating bridge");
|
||||||
if (!interface) {
|
|
||||||
LOGERROR("Neither interface eth0 nor wlan0 is up, not creating bridge");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGINFO("Creating rascsi_bridge for interface %s...", interface);
|
LOGINFO("Creating rascsi_bridge for interface %s", interface.c_str());
|
||||||
|
|
||||||
LOGDEBUG("brctl addbr rascsi_bridge");
|
LOGDEBUG("brctl addbr rascsi_bridge");
|
||||||
if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, "rascsi_bridge")) < 0) {
|
if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, "rascsi_bridge")) < 0) {
|
||||||
LOGERROR("Error: can't ioctl SIOCBRADDBR. Errno: %d %s", errno, strerror(errno));
|
LOGERROR("Error: can't ioctl SIOCBRADDBR. Errno: %d %s", errno, strerror(errno));
|
||||||
@@ -176,16 +188,17 @@ BOOL CTapDriver::Init()
|
|||||||
close(br_socket_fd);
|
close(br_socket_fd);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (strcmp(interface, "wlan0")) {
|
|
||||||
LOGDEBUG("brctl addif rascsi_bridge %s", interface);
|
if (interface == "eth0") {
|
||||||
if (!br_setif(br_socket_fd, "rascsi_bridge", interface, TRUE)) {
|
LOGDEBUG("brctl addif rascsi_bridge %s", interface.c_str());
|
||||||
|
if (!br_setif(br_socket_fd, "rascsi_bridge", interface.c_str(), TRUE)) {
|
||||||
close(m_hTAP);
|
close(m_hTAP);
|
||||||
close(ip_fd);
|
close(ip_fd);
|
||||||
close(br_socket_fd);
|
close(br_socket_fd);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!strcmp(interface, "wlan0")) {
|
else {
|
||||||
LOGDEBUG("ip address add 10.10.20.1/24 dev rascsi_bridge");
|
LOGDEBUG("ip address add 10.10.20.1/24 dev rascsi_bridge");
|
||||||
struct ifreq ifr_a;
|
struct ifreq ifr_a;
|
||||||
ifr_a.ifr_addr.sa_family = AF_INET;
|
ifr_a.ifr_addr.sa_family = AF_INET;
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include <pcap/pcap.h>
|
#include <pcap/pcap.h>
|
||||||
#include "filepath.h"
|
#include "filepath.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifndef ETH_FRAME_LEN
|
#ifndef ETH_FRAME_LEN
|
||||||
#define ETH_FRAME_LEN 1514
|
#define ETH_FRAME_LEN 1514
|
||||||
@@ -32,8 +34,8 @@ class CTapDriver
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Basic Functionality
|
// Basic Functionality
|
||||||
CTapDriver(); // Constructor
|
CTapDriver(const std::string&); // Constructor
|
||||||
BOOL Init(); // Initilization
|
BOOL Init(); // Initialization
|
||||||
void OpenDump(const Filepath& path);
|
void OpenDump(const Filepath& path);
|
||||||
// Capture packets
|
// Capture packets
|
||||||
void Cleanup(); // Cleanup
|
void Cleanup(); // Cleanup
|
||||||
@@ -55,6 +57,8 @@ private:
|
|||||||
pcap_t *m_pcap;
|
pcap_t *m_pcap;
|
||||||
pcap_dumper_t *m_pcap_dumper;
|
pcap_dumper_t *m_pcap_dumper;
|
||||||
|
|
||||||
|
// Prioritized comma-separated list of interfaces to create the bridge for
|
||||||
|
std::vector<std::string> interfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ctapdriver_h
|
#endif // ctapdriver_h
|
||||||
|
@@ -92,7 +92,7 @@ public:
|
|||||||
virtual ~Device() {};
|
virtual ~Device() {};
|
||||||
|
|
||||||
// Override for device specific initializations, to be called after all device properties have been set
|
// Override for device specific initializations, to be called after all device properties have been set
|
||||||
virtual void Init() {};
|
virtual void Init(const string&) {};
|
||||||
|
|
||||||
virtual bool Dispatch(SCSIDEV *) = 0;
|
virtual bool Dispatch(SCSIDEV *) = 0;
|
||||||
|
|
||||||
|
@@ -77,11 +77,11 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSIDaynaPort::Init()
|
void SCSIDaynaPort::Init(const string& interfaces)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// TAP Driver Generation
|
// TAP Driver Generation
|
||||||
m_tap = new CTapDriver();
|
m_tap = new CTapDriver(!interfaces.empty() ? interfaces : "eth0,wlan0");
|
||||||
m_bTapEnable = m_tap->Init();
|
m_bTapEnable = m_tap->Init();
|
||||||
if(!m_bTapEnable){
|
if(!m_bTapEnable){
|
||||||
LOGERROR("Unable to open the TAP interface");
|
LOGERROR("Unable to open the TAP interface");
|
||||||
@@ -115,8 +115,6 @@ void SCSIDaynaPort::Init()
|
|||||||
|
|
||||||
void SCSIDaynaPort::Open(const Filepath& path)
|
void SCSIDaynaPort::Open(const Filepath& path)
|
||||||
{
|
{
|
||||||
LOGTRACE("SCSIDaynaPort Open");
|
|
||||||
|
|
||||||
m_tap->OpenDump(path);
|
m_tap->OpenDump(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "ctapdriver.h"
|
#include "ctapdriver.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
SCSIDaynaPort();
|
SCSIDaynaPort();
|
||||||
~SCSIDaynaPort();
|
~SCSIDaynaPort();
|
||||||
|
|
||||||
void Init() override;
|
void Init(const string&) override;
|
||||||
|
|
||||||
void Open(const Filepath& path);
|
void Open(const Filepath& path);
|
||||||
// Capture packets
|
// Capture packets
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#include "ctapdriver.h"
|
#include "ctapdriver.h"
|
||||||
#include "cfilesystem.h"
|
#include "cfilesystem.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// SCSI Host Bridge
|
// SCSI Host Bridge
|
||||||
@@ -76,11 +78,11 @@ SCSIBR::~SCSIBR()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSIBR::Init()
|
void SCSIBR::Init(const string&)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// TAP Driver Generation
|
// TAP Driver Generation
|
||||||
tap = new CTapDriver();
|
tap = new CTapDriver("");
|
||||||
m_bTapEnable = tap->Init();
|
m_bTapEnable = tap->Init();
|
||||||
|
|
||||||
// Generate MAC Address
|
// Generate MAC Address
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "xm6.h"
|
#include "xm6.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
@@ -49,7 +50,7 @@ public:
|
|||||||
SCSIBR();
|
SCSIBR();
|
||||||
~SCSIBR();
|
~SCSIBR();
|
||||||
|
|
||||||
void Init() override;
|
void Init(const string&) override;
|
||||||
|
|
||||||
bool Dispatch(SCSIDEV *) override;
|
bool Dispatch(SCSIDEV *) override;
|
||||||
|
|
||||||
|
@@ -592,14 +592,13 @@ bool ProcessCmd(int fd, const PbDeviceDefinition& pbDevice, const PbOperation cm
|
|||||||
|
|
||||||
const int id = pbDevice.id();
|
const int id = pbDevice.id();
|
||||||
const int unit = pbDevice.unit();
|
const int unit = pbDevice.unit();
|
||||||
const string filename = pbDevice.file();
|
|
||||||
PbDeviceType type = pbDevice.type();
|
PbDeviceType type = pbDevice.type();
|
||||||
bool all = params == "all";
|
bool all = params == "all";
|
||||||
|
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
s << (dryRun ? "Validating: " : "Executing: ");
|
s << (dryRun ? "Validating: " : "Executing: ");
|
||||||
s << "cmd=" << PbOperation_Name(cmd) << ", id=" << id << ", unit=" << unit << ", type=" << PbDeviceType_Name(type)
|
s << "cmd=" << PbOperation_Name(cmd) << ", id=" << id << ", unit=" << unit << ", type=" << PbDeviceType_Name(type)
|
||||||
<< ", filename='" << filename << "', vendor='" << pbDevice.vendor()
|
<< ", params='" << pbDevice.params() << "', vendor='" << pbDevice.vendor()
|
||||||
<< ", product='" << pbDevice.product() << "', revision='" << pbDevice.revision() << "'"
|
<< ", product='" << pbDevice.product() << "', revision='" << pbDevice.revision() << "'"
|
||||||
<< "', block size=" << pbDevice.block_size() << ", params='" << params << "'";
|
<< "', block size=" << pbDevice.block_size() << ", params='" << params << "'";
|
||||||
LOGINFO("%s", s.str().c_str());
|
LOGINFO("%s", s.str().c_str());
|
||||||
@@ -628,6 +627,7 @@ bool ProcessCmd(int fd, const PbDeviceDefinition& pbDevice, const PbOperation cm
|
|||||||
return ReturnStatus(fd, false, error);
|
return ReturnStatus(fd, false, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string filename = pbDevice.params();
|
||||||
string ext;
|
string ext;
|
||||||
int len = filename.length();
|
int len = filename.length();
|
||||||
if (len > 4 && filename[len - 4] == '.') {
|
if (len > 4 && filename[len - 4] == '.') {
|
||||||
@@ -736,7 +736,7 @@ bool ProcessCmd(int fd, const PbDeviceDefinition& pbDevice, const PbOperation cm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize everything that would have caused issues when being initialized during the dry run
|
// Initialize everything that would have caused issues when being initialized during the dry run
|
||||||
device->Init();
|
device->Init(pbDevice.params());
|
||||||
|
|
||||||
// Replace with the newly created unit
|
// Replace with the newly created unit
|
||||||
map[id * UnitNum + unit] = device;
|
map[id * UnitNum + unit] = device;
|
||||||
@@ -819,39 +819,42 @@ bool ProcessCmd(int fd, const PbDeviceDefinition& pbDevice, const PbOperation cm
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case INSERT:
|
case INSERT: {
|
||||||
if (!pbDevice.vendor().empty() || !pbDevice.product().empty() || !pbDevice.revision().empty()) {
|
if (!pbDevice.vendor().empty() || !pbDevice.product().empty() || !pbDevice.revision().empty()) {
|
||||||
return ReturnStatus(fd, false, "Device name cannot be changed");
|
return ReturnStatus(fd, false, "Device name cannot be changed");
|
||||||
}
|
|
||||||
|
|
||||||
if (filename.empty()) {
|
|
||||||
return ReturnStatus(fd, false, "Missing filename");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dryRun) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
filepath.SetPath(filename.c_str());
|
|
||||||
LOGINFO("Insert file '%s' requested into %s ID: %d unit: %d", filename.c_str(), device->GetType().c_str(), id, unit);
|
|
||||||
|
|
||||||
try {
|
|
||||||
fileSupport->Open(filepath);
|
|
||||||
}
|
|
||||||
catch(const io_exception& e) {
|
|
||||||
if (!default_image_folder.empty()) {
|
|
||||||
// If the file does not exist search for it in the default image folder
|
|
||||||
string default_file = default_image_folder + "/" + filename;
|
|
||||||
filepath.SetPath(default_file.c_str());
|
|
||||||
try {
|
|
||||||
fileSupport->Open(filepath);
|
|
||||||
}
|
|
||||||
catch(const io_exception&) {
|
|
||||||
return ReturnStatus(fd, false, "Tried to open an invalid file '" + filename + "': " + e.getmsg());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return ReturnStatus(fd, false, "No default image folder");
|
string filename = pbDevice.params();
|
||||||
|
|
||||||
|
if (filename.empty()) {
|
||||||
|
return ReturnStatus(fd, false, "Missing filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dryRun) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
filepath.SetPath(filename.c_str());
|
||||||
|
LOGINFO("Insert file '%s' requested into %s ID: %d unit: %d", filename.c_str(), device->GetType().c_str(), id, unit);
|
||||||
|
|
||||||
|
try {
|
||||||
|
fileSupport->Open(filepath);
|
||||||
|
}
|
||||||
|
catch(const io_exception& e) {
|
||||||
|
if (!default_image_folder.empty()) {
|
||||||
|
// If the file does not exist search for it in the default image folder
|
||||||
|
string default_file = default_image_folder + "/" + filename;
|
||||||
|
filepath.SetPath(default_file.c_str());
|
||||||
|
try {
|
||||||
|
fileSupport->Open(filepath);
|
||||||
|
}
|
||||||
|
catch(const io_exception&) {
|
||||||
|
return ReturnStatus(fd, false, "Tried to open an invalid file '" + filename + "': " + e.getmsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ReturnStatus(fd, false, "No default image folder");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1030,7 +1033,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
device->set_unit(unit);
|
device->set_unit(unit);
|
||||||
device->set_type(type);
|
device->set_type(type);
|
||||||
device->set_block_size(block_size);
|
device->set_block_size(block_size);
|
||||||
device->set_file(optarg);
|
device->set_params(optarg);
|
||||||
|
|
||||||
size_t separatorPos = name.find(':');
|
size_t separatorPos = name.find(':');
|
||||||
if (separatorPos != string::npos) {
|
if (separatorPos != string::npos) {
|
||||||
|
@@ -61,10 +61,10 @@ message PbDeviceDefinition {
|
|||||||
int32 id = 1;
|
int32 id = 1;
|
||||||
int32 unit = 2;
|
int32 unit = 2;
|
||||||
PbDeviceType type = 3;
|
PbDeviceType type = 3;
|
||||||
|
// Optional device specific parameter, e.g. the name of an image file
|
||||||
|
string params = 4;
|
||||||
// The optional SCSI hard disk drive block size in bytes per sector, must be 512, 1024, 2048 or 4096
|
// The optional SCSI hard disk drive block size in bytes per sector, must be 512, 1024, 2048 or 4096
|
||||||
int32 block_size = 4;
|
int32 block_size = 5;
|
||||||
// The optional name of the image file
|
|
||||||
string file = 5;
|
|
||||||
// The device name components
|
// The device name components
|
||||||
string vendor = 6;
|
string vendor = 6;
|
||||||
string product = 7;
|
string product = 7;
|
||||||
|
@@ -360,7 +360,7 @@ int main(int argc, char* argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
device->set_file(optarg);
|
device->set_params(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
Reference in New Issue
Block a user