#include "slp.hpp" #include "slp_meta.hpp" #include /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version | Function-ID | Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length, contd.|O|F|R| reserved |Next Ext Offset| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Extension Offset, contd.| XID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Language Tag Length | Language Tag \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ TEST(parseHeaderTest, BasicGoodPath) { // Basic buffer with valid Function-ID slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); } TEST(parseHeaderTest, InvalidBufferSize) { // 1 byte too small slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_NE(rc, 0); } TEST(parseHeaderTest, ValidLangTagLength) { // Language Tag Length that is valid slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); } TEST(parseHeaderTest, InvalidLangTagLength) { // Language Tag Length that is too big slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_NE(rc, 0); } /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Service Location header (function = SrvTypeRqst = 9) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of PRList | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of Naming Authority | \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ TEST(parseSrvTypeRqst, BasicGoodPath) { // Basic buffer with 0 for all lengths slp::buffer testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_EQ(rc, 0); } TEST(parseSrvTypeRqst, GoodPathWithData) { // Basic buffer with some valid lengths and data slp::buffer testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */ 'L', 'A', 'N', 'G', 0x00, 0x04, /* PRlist length*/ 'P', 'R', 'L', 'T', 0x00, 0x08, /* Naming auth length */ 'N', 'A', 'M', 'E', 'A', 'U', 'T', 'H', 0x00, 0x05, /* Scope length*/ 'S', 'C', 'O', 'P', 'E'}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "LANG"); EXPECT_EQ(req.header.langtagLen, 4); rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_EQ(rc, 0); EXPECT_EQ(req.body.srvtyperqst.prList, "PRLT"); EXPECT_EQ(req.body.srvtyperqst.namingAuth, "NAMEAUTH"); EXPECT_EQ(req.body.srvtyperqst.scopeList, "SCOPE"); } TEST(parseSrvTypeRqst, GoodPathMatchSlptoolFindSrvTypes) { // This matches what "slptool -u findsrvtypes" sends slp::buffer testData{0x02, 0x09, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xe2, 0x00, 0x02, /* Lang Length */ 'e', 'n', 0x00, 0x00, /* PRlist length*/ 0xff, 0xff, /* Naming auth length */ 0x00, 0x07, /* Scope length*/ 'D', 'E', 'F', 'A', 'U', 'L', 'T'}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "en"); EXPECT_EQ(req.header.langtagLen, 2); rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_EQ(rc, 0); EXPECT_EQ(req.body.srvtyperqst.namingAuth, ""); EXPECT_EQ(req.body.srvtyperqst.scopeList, "DEFAULT"); } TEST(parseSrvTypeRqst, BadPathSizes) { // Basic buffer with some valid lengths and data slp::buffer testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */ 'L', 'A', 'N', 'G', 0x00, 0x05, /* PRlist length*/ 'P', 'R', 'L', 'T', 0x00, 0x08, /* Naming auth length */ 'N', 'A', 'M', 'E', 'A', 'U', 'T', 'H', 0x00, 0x05, /* Scope length*/ 'S', 'C', 'O', 'P', 'E'}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "LANG"); EXPECT_EQ(req.header.langtagLen, 4); rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_NE(rc, 0); // Fix PR, make Name invalid testData[19] = 4; testData[25] = 5; rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_NE(rc, 0); // Fix Name, make Scope invalid testData[25] = 8; testData[35] = 10; rc = slp::parser::internal::parseSrvTypeRqst(testData, req); EXPECT_NE(rc, 0); } /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of predicate string | Service Request \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of string | String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ TEST(parseSrvRqst, BasicGoodPath) { // Basic buffer with 0 for all lengths slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* start of SrvRqst*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; slp::Message req; int rc = slp::SUCCESS; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_EQ(rc, 0); } TEST(parseSrvRqst, GoodPathWithData) { // Basic buffer with some valid lengths and data slp::buffer testData{ 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */ 'L', 'A', 'N', 'G', 0x00, 0x04, /* PRlist length*/ 'P', 'R', 'L', 'T', 0x00, 0xB, /* Service type length */ 'S', 'E', 'R', 'V', 'I', 'C', 'E', 'T', 'Y', 'P', 'E', 0x00, 0x05, /* Scope length*/ 'S', 'C', 'O', 'P', 'E', 0x00, 0x02, /* predicate length */ 'P', 'D', 0x00, 0x01, /* SLP SPI length */ 'S'}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "LANG"); EXPECT_EQ(req.header.langtagLen, 4); rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_EQ(rc, 0); EXPECT_EQ(req.body.srvrqst.prList, "PRLT"); EXPECT_EQ(req.body.srvrqst.srvType, "SERVICETYPE"); EXPECT_EQ(req.body.srvrqst.scopeList, "SCOPE"); EXPECT_EQ(req.body.srvrqst.predicate, "PD"); EXPECT_EQ(req.body.srvrqst.spistr, "S"); } TEST(parseSrvRqst, GoodPathMatchSlptoolFindSrvs) { // This matches what "slptool -u findsrvs service:obmc_console" // sends slp::buffer testData{0x02, 0x01, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0xc2, 0x00, 0x02, /* Lang Length */ 'e', 'n', 0x00, 0x00, /* PR list length*/ 0x00, 0x14, /* Service length */ 's', 'e', 'r', 'v', 'i', 'c', 'e', ':', 'o', 'b', 'm', 'c', '_', 'c', 'o', 'n', 's', 'o', 'l', 'e', 0x00, 0x07, /* Scope length*/ 'D', 'E', 'F', 'A', 'U', 'L', 'T', 0x00, 0x00, /* Predicate length */ 0x00, 0x00}; /* SLP SPI length*/ slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "en"); EXPECT_EQ(req.header.langtagLen, 2); rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_EQ(rc, 0); EXPECT_EQ(req.body.srvrqst.srvType, "service:obmc_console"); EXPECT_EQ(req.body.srvrqst.scopeList, "DEFAULT"); } TEST(parseSrvRqst, BadPathSizes) { // Basic buffer with invalid PRlist size slp::buffer testData{ 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */ 'L', 'A', 'N', 'G', 0x00, 0x05, /* PRlist length*/ 'P', 'R', 'L', 'T', 0x00, 0xB, /* Service type length */ 'S', 'E', 'R', 'V', 'I', 'C', 'E', 'T', 'Y', 'P', 'E', 0x00, 0x05, /* Scope length*/ 'S', 'C', 'O', 'P', 'E', 0x00, 0x02, /* predicate length */ 'P', 'D', 0x00, 0x01, /* SLP SPI length */ 'S'}; slp::Message req; int rc = slp::SUCCESS; std::tie(rc, req) = slp::parser::internal::parseHeader(testData); EXPECT_EQ(rc, 0); EXPECT_EQ(req.header.langtag, "LANG"); EXPECT_EQ(req.header.langtagLen, 4); rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_NE(rc, 0); // Fix PR, make Service type invalid testData[19] = 4; testData[25] = 5; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_NE(rc, 0); // Fix Service type, make Scope invalid testData[25] = 0xB; testData[38] = 10; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_NE(rc, 0); // Fix Scope, make Predicate invalid testData[38] = 5; testData[45] = 100; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_NE(rc, 0); // Fix Predicate, make SLP SPI invalid testData[45] = 2; testData[49] = 5; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_NE(rc, 0); // Now fix SLP SPI and make sure we pass testData[49] = 1; rc = slp::parser::internal::parseSrvRqst(testData, req); EXPECT_EQ(rc, 0); }