Files
RASCSI/cpp/test/ctapdriver_test.cpp
T
Daniel Markstedt 485298ffe5 restore X68000 Host Bridge support
Restore the SCBR device as an X68000 Host Bridge, including the Human68k-compatible host file-system service and the bridge-specific SCSI message handlers. Back its Ethernet path with the TAP driver, derive a stable locally administered MAC address, preserve the driver minimum-frame/FCS expectations, and restrict received traffic to its own unicast frames and broadcasts.

Match the RASCTL/RASETHER/RASDRV bridge protocol that originated in the parent RaSCSI project: dispatch its non-standard message format on READ(10)/WRITE(10) (0x28/0x2a), with type, function, phase, and a three-byte byte count carried in the CDB. Advertise the legacy control channel required by RASCTL, translate its list and device-management commands to PiSCSI operations, and defer stop or system-shutdown requests until after the response is sent, while gating this insecure interface behind a new '-c disabled|media|full' runtime option. Preserve the type-1 Ethernet exchange used by RASETHER and the type-2, phased filesystem exchange used by RASDRV.

Register the device in the factory, protobuf API, controller transfer path, command-line tooling, device listings, and web UI. Share the explicit bridge and proxy-ARP topology workflow with DaynaPort so both adapters validate and use the same mode/interface pair.

Add build support for iconv where needed, extend unit coverage for device creation, RAS* protocol handling, CLI parsing, web attachment, and topology selection, and update the man pages and network-profile documentation for Host Bridge operation and its networking limits.
2026-09-01 00:52:00 +02:00

89 lines
3.0 KiB
C++

//---------------------------------------------------------------------------
//
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Copyright (C) 2022-2023 Uwe Seimet
//
//---------------------------------------------------------------------------
#include "mocks.h"
#include <net/ethernet.h>
#include "devices/ctapdriver.h"
using namespace network_util;
TEST(CTapDriverTest, GetDefaultParams)
{
CTapDriver driver;
const auto params = driver.GetDefaultParams();
EXPECT_EQ(2, params.size());
EXPECT_EQ("piscsi_bridge", params.at("interface"));
EXPECT_EQ("bridge", params.at("mode"));
EXPECT_FALSE(params.contains("inet"));
}
TEST(CTapDriverTest, ValidateProfiles)
{
const network_interface_map interfaces = {
{ "piscsi_bridge", { "piscsi_bridge", NetworkInterfaceType::BRIDGE, true } },
{ "wlan0", { "wlan0", NetworkInterfaceType::WIFI, true } },
{ "eth0", { "eth0", NetworkInterfaceType::ETHERNET, true } },
{ "wlan1", { "wlan1", NetworkInterfaceType::WIFI, false } },
};
EXPECT_TRUE(CTapDriver::GetProfileValidationError("bridge", "piscsi_bridge", interfaces).empty());
EXPECT_TRUE(CTapDriver::GetProfileValidationError("proxyarp", "wlan0", interfaces).empty());
EXPECT_THAT(CTapDriver::GetProfileValidationError("", "piscsi_bridge", interfaces), HasSubstr("Unsupported"));
EXPECT_THAT(CTapDriver::GetProfileValidationError("bridge", "eth0", interfaces), HasSubstr("requires"));
EXPECT_THAT(CTapDriver::GetProfileValidationError("proxyarp", "eth0", interfaces), HasSubstr("Wi-Fi"));
EXPECT_THAT(CTapDriver::GetProfileValidationError("proxyarp", "wlan1", interfaces), HasSubstr("down"));
EXPECT_THAT(CTapDriver::GetProfileValidationError("proxyarp", "wlan0,eth0", interfaces), HasSubstr("Invalid"));
auto conflicting_interfaces = interfaces;
conflicting_interfaces.emplace("piscsi0", NetworkInterfaceInfo { "piscsi0", NetworkInterfaceType::TAP, true });
EXPECT_THAT(CTapDriver::GetProfileValidationError("proxyarp", "wlan0", conflicting_interfaces), HasSubstr("in use"));
}
TEST(CTapDriverTest, CleanupAndMacAreSafeWithoutATap)
{
CTapDriver driver;
array<uint8_t, 6> mac;
mac.fill(0xff);
driver.GetUplinkMacAddr(mac.data());
EXPECT_THAT(mac, Each(0));
driver.CleanUp();
driver.CleanUp();
}
TEST(CTapDriverTest, Crc32)
{
array<uint8_t, ETH_FRAME_LEN> buf;
buf.fill(0x00);
EXPECT_EQ(0xe3d887bb, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
buf.fill(0xff);
EXPECT_EQ(0x814765f4, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
buf.fill(0x10);
EXPECT_EQ(0xb7288Cd3, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
buf.fill(0x7f);
EXPECT_EQ(0x4b543477, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
buf.fill(0x80);
EXPECT_EQ(0x29cbd638, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
for (size_t i = 0; i < buf.size(); i++) {
buf[i] = (uint8_t)i;
}
EXPECT_EQ(0xe7870705, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
for (size_t i = buf.size() - 1; i > 0; i--) {
buf[i] = (uint8_t)i;
}
EXPECT_EQ(0xe7870705, CTapDriver::Crc32(span(buf.data(), ETH_FRAME_LEN)));
}