mirror of
https://github.com/akuker/RASCSI.git
synced 2025-01-11 09:29:53 +00:00
Daynaport device can be configured with interface list (issue #202)
This commit is contained in:
parent
e336e726cb
commit
106d2d50d1
@ -26,7 +26,7 @@
|
||||
#include "ctapdriver.h"
|
||||
#include "log.h"
|
||||
#include "exceptions.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -35,9 +35,14 @@ using namespace std;
|
||||
// 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
|
||||
m_bTxValid = FALSE;
|
||||
m_hTAP = -1;
|
||||
@ -88,7 +93,7 @@ static BOOL ip_link(int fd, const char* ifname, BOOL up) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool is_interface_up(const char *interface) {
|
||||
static bool is_interface_up(const string& interface) {
|
||||
string file = "/sys/class/net/";
|
||||
file += interface;
|
||||
file += "/carrier";
|
||||
@ -150,24 +155,31 @@ BOOL CTapDriver::Init()
|
||||
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) {
|
||||
LOGINFO("rascsi_bridge is not yet available");
|
||||
|
||||
LOGINFO("Checking whether to create bridge for interface eth0 or wlan0");
|
||||
const char *interface = NULL;
|
||||
if (is_interface_up("eth0")) {
|
||||
interface = "eth0";
|
||||
LOGTRACE("Checking which interface is available for creating the bridge");
|
||||
string interface;
|
||||
for (auto it = interfaces.begin(); it != interfaces.end(); ++it) {
|
||||
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) {
|
||||
LOGERROR("Neither interface eth0 nor wlan0 is up, not creating bridge");
|
||||
|
||||
if (interface.empty()) {
|
||||
LOGERROR("No interface is up, not creating bridge");
|
||||
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");
|
||||
if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, "rascsi_bridge")) < 0) {
|
||||
LOGERROR("Error: can't ioctl SIOCBRADDBR. Errno: %d %s", errno, strerror(errno));
|
||||
@ -176,16 +188,17 @@ BOOL CTapDriver::Init()
|
||||
close(br_socket_fd);
|
||||
return FALSE;
|
||||
}
|
||||
if (strcmp(interface, "wlan0")) {
|
||||
LOGDEBUG("brctl addif rascsi_bridge %s", interface);
|
||||
if (!br_setif(br_socket_fd, "rascsi_bridge", interface, TRUE)) {
|
||||
|
||||
if (interface == "eth0") {
|
||||
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(ip_fd);
|
||||
close(br_socket_fd);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!strcmp(interface, "wlan0")) {
|
||||
else {
|
||||
LOGDEBUG("ip address add 10.10.20.1/24 dev rascsi_bridge");
|
||||
struct ifreq ifr_a;
|
||||
ifr_a.ifr_addr.sa_family = AF_INET;
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
#include "filepath.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifndef ETH_FRAME_LEN
|
||||
#define ETH_FRAME_LEN 1514
|
||||
@ -32,8 +34,8 @@ class CTapDriver
|
||||
{
|
||||
public:
|
||||
// Basic Functionality
|
||||
CTapDriver(); // Constructor
|
||||
BOOL Init(); // Initilization
|
||||
CTapDriver(const std::string&); // Constructor
|
||||
BOOL Init(); // Initialization
|
||||
void OpenDump(const Filepath& path);
|
||||
// Capture packets
|
||||
void Cleanup(); // Cleanup
|
||||
@ -55,6 +57,8 @@ private:
|
||||
pcap_t *m_pcap;
|
||||
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
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
virtual ~Device() {};
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -77,11 +77,11 @@ SCSIDaynaPort::~SCSIDaynaPort()
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIDaynaPort::Init()
|
||||
void SCSIDaynaPort::Init(const string& interfaces)
|
||||
{
|
||||
#ifdef __linux__
|
||||
// TAP Driver Generation
|
||||
m_tap = new CTapDriver();
|
||||
m_tap = new CTapDriver(!interfaces.empty() ? interfaces : "eth0,wlan0");
|
||||
m_bTapEnable = m_tap->Init();
|
||||
if(!m_bTapEnable){
|
||||
LOGERROR("Unable to open the TAP interface");
|
||||
@ -115,8 +115,6 @@ void SCSIDaynaPort::Init()
|
||||
|
||||
void SCSIDaynaPort::Open(const Filepath& path)
|
||||
{
|
||||
LOGTRACE("SCSIDaynaPort Open");
|
||||
|
||||
m_tap->OpenDump(path);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "disk.h"
|
||||
#include "ctapdriver.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -60,7 +61,7 @@ public:
|
||||
SCSIDaynaPort();
|
||||
~SCSIDaynaPort();
|
||||
|
||||
void Init() override;
|
||||
void Init(const string&) override;
|
||||
|
||||
void Open(const Filepath& path);
|
||||
// Capture packets
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "ctapdriver.h"
|
||||
#include "cfilesystem.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Host Bridge
|
||||
@ -76,11 +78,11 @@ SCSIBR::~SCSIBR()
|
||||
}
|
||||
}
|
||||
|
||||
void SCSIBR::Init()
|
||||
void SCSIBR::Init(const string&)
|
||||
{
|
||||
#ifdef __linux__
|
||||
// TAP Driver Generation
|
||||
tap = new CTapDriver();
|
||||
tap = new CTapDriver("");
|
||||
m_bTapEnable = tap->Init();
|
||||
|
||||
// Generate MAC Address
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "xm6.h"
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include <string>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
@ -49,7 +50,7 @@ public:
|
||||
SCSIBR();
|
||||
~SCSIBR();
|
||||
|
||||
void Init() override;
|
||||
void Init(const string&) 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 unit = pbDevice.unit();
|
||||
const string filename = pbDevice.file();
|
||||
PbDeviceType type = pbDevice.type();
|
||||
bool all = params == "all";
|
||||
|
||||
ostringstream s;
|
||||
s << (dryRun ? "Validating: " : "Executing: ");
|
||||
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() << "'"
|
||||
<< "', block size=" << pbDevice.block_size() << ", params='" << params << "'";
|
||||
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);
|
||||
}
|
||||
|
||||
string filename = pbDevice.params();
|
||||
string ext;
|
||||
int len = filename.length();
|
||||
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
|
||||
device->Init();
|
||||
device->Init(pbDevice.params());
|
||||
|
||||
// Replace with the newly created unit
|
||||
map[id * UnitNum + unit] = device;
|
||||
@ -819,39 +819,42 @@ bool ProcessCmd(int fd, const PbDeviceDefinition& pbDevice, const PbOperation cm
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case INSERT:
|
||||
if (!pbDevice.vendor().empty() || !pbDevice.product().empty() || !pbDevice.revision().empty()) {
|
||||
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());
|
||||
}
|
||||
case INSERT: {
|
||||
if (!pbDevice.vendor().empty() || !pbDevice.product().empty() || !pbDevice.revision().empty()) {
|
||||
return ReturnStatus(fd, false, "Device name cannot be changed");
|
||||
}
|
||||
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;
|
||||
@ -1030,7 +1033,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
||||
device->set_unit(unit);
|
||||
device->set_type(type);
|
||||
device->set_block_size(block_size);
|
||||
device->set_file(optarg);
|
||||
device->set_params(optarg);
|
||||
|
||||
size_t separatorPos = name.find(':');
|
||||
if (separatorPos != string::npos) {
|
||||
|
@ -61,10 +61,10 @@ message PbDeviceDefinition {
|
||||
int32 id = 1;
|
||||
int32 unit = 2;
|
||||
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
|
||||
int32 block_size = 4;
|
||||
// The optional name of the image file
|
||||
string file = 5;
|
||||
int32 block_size = 5;
|
||||
// The device name components
|
||||
string vendor = 6;
|
||||
string product = 7;
|
||||
|
@ -360,7 +360,7 @@ int main(int argc, char* argv[])
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
device->set_file(optarg);
|
||||
device->set_params(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
|
Loading…
x
Reference in New Issue
Block a user