FruDevice: Move verifyOffset to util
Moving verifyOffset module to fruUtils.cpp
Signed-off-by: Vijay Khemka <vijaykhemkalinux@gmail.com>
Change-Id: I8d8450783d421c1db384ca1332fa5aee90a41ced
diff --git a/src/FruUtils.cpp b/src/FruUtils.cpp
index 4d8354c..9bfcf30 100644
--- a/src/FruUtils.cpp
+++ b/src/FruUtils.cpp
@@ -33,6 +33,21 @@
static constexpr bool DEBUG = false;
constexpr size_t fruVersion = 1; // Current FRU spec version number is 1
+static constexpr std::array<const char*, 5> FRU_AREAS_NAMES = {
+ "INTERNAL", "CHASSIS", "BOARD", "PRODUCT", "MULTIRECORD"};
+
+std::string getFruAreaName(fruAreas area)
+{
+ // Check range of passed area value
+ if (static_cast<unsigned int>(area) >= FRU_AREAS_NAMES.size())
+ {
+ std::cerr << "Error: Fru area is out of range\n";
+ return "";
+ }
+
+ return std::string(FRU_AREAS_NAMES[static_cast<unsigned int>(area)]);
+}
+
bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData)
{
// ipmi spec format version number is currently at 1, verify it
@@ -94,6 +109,81 @@
return true;
}
+/* This function verifies for other offsets to check if they are not
+ * falling under other field area
+ *
+ * fruBytes: Start of Fru data
+ * currentArea: Index of current area offset to be compared against all area
+ * offset and it is a multiple of 8 bytes as per specification
+ * len: Length of current area space and it is a multiple of 8 bytes
+ * as per specification
+ */
+bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
+ uint8_t len)
+{
+
+ unsigned int fruBytesSize = fruBytes.size();
+
+ // check if Fru data has at least 8 byte header
+ if (fruBytesSize <= fruBlockSize)
+ {
+ std::cerr << "Error: trying to parse empty FRU\n";
+ return false;
+ }
+
+ // Check range of passed currentArea value
+ if (currentArea > fruAreas::fruAreaMultirecord)
+ {
+ std::cerr << "Error: Fru area is out of range\n";
+ return false;
+ }
+
+ unsigned int currentAreaIndex = getHeaderAreaFieldOffset(currentArea);
+ if (currentAreaIndex > fruBytesSize)
+ {
+ std::cerr << "Error: Fru area index is out of range\n";
+ return false;
+ }
+
+ unsigned int start = fruBytes[currentAreaIndex];
+ unsigned int end = start + len;
+
+ /* Verify each offset within the range of start and end */
+ for (fruAreas area = fruAreas::fruAreaInternal;
+ area <= fruAreas::fruAreaMultirecord; ++area)
+ {
+ // skip the current offset
+ if (area == currentArea)
+ {
+ continue;
+ }
+
+ unsigned int areaIndex = getHeaderAreaFieldOffset(area);
+ if (areaIndex > fruBytesSize)
+ {
+ std::cerr << "Error: Fru area index is out of range\n";
+ return false;
+ }
+
+ unsigned int areaOffset = fruBytes[areaIndex];
+ // if areaOffset is 0 means this area is not available so skip
+ if (areaOffset == 0)
+ {
+ continue;
+ }
+
+ // check for overlapping of current offset with given areaoffset
+ if (areaOffset == start || (areaOffset > start && areaOffset < end))
+ {
+ std::cerr << getFruAreaName(currentArea)
+ << " offset is overlapping with " << getFruAreaName(area)
+ << " offset\n";
+ return false;
+ }
+ }
+ return true;
+}
+
std::vector<uint8_t> readFRUContents(int flag, int file, uint16_t address,
ReadBlockFunc readBlock,
const std::string& errorHelp)