2 Commits
Author SHA1 Message Date
David RebbeandKyle Schwarz 77a886bbe0 C2: Validate MAC network IDs 2026-07-21 13:30:21 -04:00
David RebbeandKyle Schwarz aff547b738 C2: Report copied buffer lengths 2026-07-21 13:07:06 -04:00
4 changed files with 70 additions and 13 deletions
+18 -9
View File
@@ -5,6 +5,7 @@
#include "icsneo/device/devicefinder.h" #include "icsneo/device/devicefinder.h"
#include "icsneo/icsneocpp.h" #include "icsneo/icsneocpp.h"
#include "icsneo/communication/io.h" #include "icsneo/communication/io.h"
#include "icsneo/communication/network.h"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -465,11 +466,13 @@ icsneoc2_error_t icsneoc2_device_pcb_serial_get(const icsneoc2_device_t* device,
return icsneoc2_error_invalid_type; return icsneoc2_error_invalid_type;
} }
const auto& data = *pcbSerial; const auto& data = *pcbSerial;
if(value) { if(!value) {
*value_length = data.size();
return icsneoc2_error_success;
}
size_t copyLen = std::min(*value_length, data.size()); size_t copyLen = std::min(*value_length, data.size());
std::copy(data.begin(), data.begin() + copyLen, value); std::copy(data.begin(), data.begin() + copyLen, value);
} *value_length = copyLen;
*value_length = data.size();
return icsneoc2_error_success; return icsneoc2_error_success;
} }
@@ -503,26 +506,32 @@ icsneoc2_error_t icsneoc2_device_mac_addresses_enumerate(const icsneoc2_device_t
} }
tail = node; tail = node;
} }
*mac_entries = head;
return icsneoc2_error_success; return icsneoc2_error_success;
} }
icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, _icsneoc2_netid_t* network_id) { icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, icsneoc2_netid_t* network_id) {
if(!mac_address || !network_id) { if(!mac_address || !network_id) {
return icsneoc2_error_invalid_parameters; return icsneoc2_error_invalid_parameters;
} }
*network_id = static_cast<_icsneoc2_netid_t>(mac_address->network_id); const auto netid = static_cast<Network::NetID>(mac_address->network_id);
*network_id = Network::GetCoreMiniNetworkFromNetID(netid).has_value()
? mac_address->network_id
: static_cast<icsneoc2_netid_t>(icsneoc2_netid_invalid);
return icsneoc2_error_success; return icsneoc2_error_success;
} }
icsneoc2_error_t icsneoc2_mac_address_get(const icsneoc2_mac_addr_entry_t* mac_address, uint8_t* value, size_t* value_length) { icsneoc2_error_t icsneoc2_mac_address_get(const icsneoc2_mac_addr_entry_t* mac_address, uint8_t* value, size_t* value_length) {
if(!mac_address || !value || !value_length) { if(!mac_address || !value_length) {
return icsneoc2_error_invalid_parameters; return icsneoc2_error_invalid_parameters;
} }
if(value) { if(!value) {
*value_length = static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN);
return icsneoc2_error_success;
}
size_t copyLen = std::min(*value_length, static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN)); size_t copyLen = std::min(*value_length, static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN));
std::copy(mac_address->address, mac_address->address + copyLen, value); std::copy(mac_address->address, mac_address->address + copyLen, value);
} *value_length = copyLen;
*value_length = static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN);
return icsneoc2_error_success; return icsneoc2_error_success;
} }
+1 -1
View File
@@ -112,7 +112,7 @@ int main() {
} }
printf("MACs: %u entr%s\n", mac_count, mac_count == 1 ? "y" : "ies"); printf("MACs: %u entr%s\n", mac_count, mac_count == 1 ? "y" : "ies");
for(icsneoc2_mac_addr_entry_t* cur = macs; cur; cur = icsneoc2_mac_addresses_next(cur)) { for(icsneoc2_mac_addr_entry_t* cur = macs; cur; cur = icsneoc2_mac_addresses_next(cur)) {
_icsneoc2_netid_t network_id; icsneoc2_netid_t network_id;
icsneoc2_mac_network_id_get(cur, &network_id); icsneoc2_mac_network_id_get(cur, &network_id);
printf(" Network %-5u ", (unsigned)network_id); printf(" Network %-5u ", (unsigned)network_id);
uint8_t address[6]; uint8_t address[6];
+2 -1
View File
@@ -372,10 +372,11 @@ icsneoc2_error_t icsneoc2_device_mac_addresses_enumerate(const icsneoc2_device_t
* *
* @param[in] mac_address The MAC address object to get the network ID of. * @param[in] mac_address The MAC address object to get the network ID of.
* @param[out] network_id Pointer to an icsneoc2_netid_t to copy the network ID into. * @param[out] network_id Pointer to an icsneoc2_netid_t to copy the network ID into.
* Unrecognized values are normalized to icsneoc2_netid_invalid.
* *
* @return icsneoc2_error_t icsneoc2_error success if successful, icsneoc2_error_invalid_parameters on failure. * @return icsneoc2_error_t icsneoc2_error success if successful, icsneoc2_error_invalid_parameters on failure.
*/ */
icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, _icsneoc2_netid_t* network_id); icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, icsneoc2_netid_t* network_id);
/** /**
* Get the MAC Address bytes of a MAC address. * Get the MAC Address bytes of a MAC address.
+47
View File
@@ -127,6 +127,28 @@ TEST(icsneoc2, test_icsneoc2_device_is_valid)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL));
} }
TEST(icsneoc2, test_icsneoc2_mac_address_get_query_length)
{
icsneoc2_mac_addr_entry_t mac_address = {};
size_t value_length = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_mac_address_get(&mac_address, NULL, &value_length));
ASSERT_EQ(ICSNEO_MAC_ADDRESS_LEN, value_length);
}
TEST(icsneoc2, test_icsneoc2_mac_address_get_truncated_length)
{
icsneoc2_mac_addr_entry_t mac_address = {};
const uint8_t expected[ICSNEO_MAC_ADDRESS_LEN] = {0x00, 0xFC, 0x70, 0x1E, 0x18, 0x70};
std::copy(std::begin(expected), std::end(expected), mac_address.address);
uint8_t value[3] = {};
size_t value_length = sizeof(value);
ASSERT_EQ(icsneoc2_error_success, icsneoc2_mac_address_get(&mac_address, value, &value_length));
ASSERT_EQ(sizeof(value), value_length);
ASSERT_EQ(0, memcmp(expected, value, sizeof(value)));
}
TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device) TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
{ {
bool placeholderBool = false; bool placeholderBool = false;
@@ -2131,3 +2153,28 @@ TEST(icsneoc2, test_gptp_enum_alignment)
ASSERT_EQ(sizeof(RADGPTPRole), sizeof(icsneoc2_gptp_role_t)); ASSERT_EQ(sizeof(RADGPTPRole), sizeof(icsneoc2_gptp_role_t));
} }
TEST(icsneoc2, test_mac_network_id_get)
{
icsneoc2_mac_addr_entry_t entry {};
icsneoc2_netid_t network_id = 0;
entry.network_id = icsneoc2_netid_ethernet_01;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_mac_network_id_get(&entry, &network_id));
ASSERT_EQ(icsneoc2_netid_ethernet_01, network_id);
entry.network_id = 43;
network_id = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_mac_network_id_get(&entry, &network_id));
ASSERT_EQ(icsneoc2_netid_invalid, network_id);
entry.network_id = icsneoc2_netid_invalid;
network_id = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_mac_network_id_get(&entry, &network_id));
ASSERT_EQ(icsneoc2_netid_invalid, network_id);
ASSERT_EQ(icsneoc2_error_invalid_parameters,
icsneoc2_mac_network_id_get(nullptr, &network_id));
ASSERT_EQ(icsneoc2_error_invalid_parameters,
icsneoc2_mac_network_id_get(&entry, nullptr));
}