xref: /openbmc/slpd-lite/slp_parser.cpp (revision 20bab74865ba955921eb0e4e427c84e37e1c8916)
1537ff140SPatrick Venture #include "endian.hpp"
207c462acSRatan Gupta #include "slp.hpp"
3537ff140SPatrick Venture #include "slp_meta.hpp"
407c462acSRatan Gupta 
507c462acSRatan Gupta #include <string.h>
607c462acSRatan Gupta 
707c462acSRatan Gupta #include <algorithm>
8537ff140SPatrick Venture #include <string>
907c462acSRatan Gupta 
1007c462acSRatan Gupta namespace slp
1107c462acSRatan Gupta {
1207c462acSRatan Gupta 
1307c462acSRatan Gupta namespace parser
1407c462acSRatan Gupta {
1507c462acSRatan Gupta 
1607c462acSRatan Gupta namespace internal
1707c462acSRatan Gupta {
1807c462acSRatan Gupta 
parseHeader(const buffer & buff)1907c462acSRatan Gupta std::tuple<int, Message> parseHeader(const buffer& buff)
2007c462acSRatan Gupta {
2107c462acSRatan Gupta     /*  0                   1                   2                   3
2207c462acSRatan Gupta         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
2307c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2407c462acSRatan Gupta        |    Version    |  Function-ID  |            Length             |
2507c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2607c462acSRatan Gupta        | Length, contd.|O|F|R|       reserved          |Next Ext Offset|
2707c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2807c462acSRatan Gupta        |  Next Extension Offset, contd.|              XID              |
2907c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3007c462acSRatan Gupta        |      Language Tag Length      |         Language Tag          \
3107c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
3207c462acSRatan Gupta 
33f191bd8fSPatrick Williams     Message req{};
3407c462acSRatan Gupta     int rc = slp::SUCCESS;
3507c462acSRatan Gupta 
360e948dcaSAndrew Geissler     if (buff.size() < slp::header::MIN_LEN)
370e948dcaSAndrew Geissler     {
380e948dcaSAndrew Geissler         std::cerr << "Invalid msg size: " << buff.size() << std::endl;
390e948dcaSAndrew Geissler         rc = static_cast<int>(slp::Error::PARSE_ERROR);
400e948dcaSAndrew Geissler     }
410e948dcaSAndrew Geissler     else
420e948dcaSAndrew Geissler     {
430e948dcaSAndrew Geissler         std::copy_n(buff.data(), slp::header::SIZE_VERSION,
440e948dcaSAndrew Geissler                     &req.header.version);
4507c462acSRatan Gupta 
4607c462acSRatan Gupta         std::copy_n(buff.data() + slp::header::OFFSET_FUNCTION,
47537ff140SPatrick Venture                     slp::header::SIZE_VERSION, &req.header.functionID);
4807c462acSRatan Gupta 
4907c462acSRatan Gupta         std::copy_n(buff.data() + slp::header::OFFSET_LENGTH,
50537ff140SPatrick Venture                     slp::header::SIZE_LENGTH, req.header.length.data());
5107c462acSRatan Gupta 
5207c462acSRatan Gupta         std::copy_n(buff.data() + slp::header::OFFSET_FLAGS,
53537ff140SPatrick Venture                     slp::header::SIZE_FLAGS, (uint8_t*)&req.header.flags);
5407c462acSRatan Gupta 
5507c462acSRatan Gupta         req.header.flags = endian::from_network(req.header.flags);
560e948dcaSAndrew Geissler         std::copy_n(buff.data() + slp::header::OFFSET_EXT,
570e948dcaSAndrew Geissler                     slp::header::SIZE_EXT, req.header.extOffset.data());
5807c462acSRatan Gupta 
590e948dcaSAndrew Geissler         std::copy_n(buff.data() + slp::header::OFFSET_XID,
600e948dcaSAndrew Geissler                     slp::header::SIZE_XID, (uint8_t*)&req.header.xid);
6107c462acSRatan Gupta 
6207c462acSRatan Gupta         req.header.xid = endian::from_network(req.header.xid);
6307c462acSRatan Gupta 
6407c462acSRatan Gupta         uint16_t langtagLen;
6507c462acSRatan Gupta 
6607c462acSRatan Gupta         std::copy_n(buff.data() + slp::header::OFFSET_LANG_LEN,
67537ff140SPatrick Venture                     slp::header::SIZE_LANG, (uint8_t*)&langtagLen);
6807c462acSRatan Gupta 
6907c462acSRatan Gupta         langtagLen = endian::from_network(langtagLen);
7007c462acSRatan Gupta 
71c668313eSAndrew Geissler         // Enforce language tag size limits
72c668313eSAndrew Geissler         if ((slp::header::OFFSET_LANG + langtagLen) > buff.size())
73c668313eSAndrew Geissler         {
74c668313eSAndrew Geissler             std::cerr << "Invalid Language Tag Length: " << langtagLen
75c668313eSAndrew Geissler                       << std::endl;
76c668313eSAndrew Geissler             rc = static_cast<int>(slp::Error::PARSE_ERROR);
77c668313eSAndrew Geissler         }
78c668313eSAndrew Geissler         else
79c668313eSAndrew Geissler         {
80f60e7108SAndrew Geissler             req.header.langtagLen = langtagLen;
81537ff140SPatrick Venture             req.header.langtag.insert(
82c668313eSAndrew Geissler                 0, (const char*)buff.data() + slp::header::OFFSET_LANG,
83c668313eSAndrew Geissler                 langtagLen);
8407c462acSRatan Gupta 
8507c462acSRatan Gupta             /* check for the validity of the function */
86537ff140SPatrick Venture             if (req.header.functionID <
87537ff140SPatrick Venture                     static_cast<uint8_t>(slp::FunctionType::SRVRQST) ||
880e948dcaSAndrew Geissler                 req.header.functionID >
890e948dcaSAndrew Geissler                     static_cast<uint8_t>(slp::FunctionType::SAADV))
9007c462acSRatan Gupta             {
910e948dcaSAndrew Geissler                 std::cerr << "Invalid function ID: " << req.header.functionID
920e948dcaSAndrew Geissler                           << std::endl;
9307c462acSRatan Gupta                 rc = static_cast<int>(slp::Error::PARSE_ERROR);
9407c462acSRatan Gupta             }
950e948dcaSAndrew Geissler         }
96c668313eSAndrew Geissler     }
9707c462acSRatan Gupta 
9807c462acSRatan Gupta     return std::make_tuple(rc, std::move(req));
9907c462acSRatan Gupta }
10007c462acSRatan Gupta 
parseSrvTypeRqst(const buffer & buff,Message & req)10107c462acSRatan Gupta int parseSrvTypeRqst(const buffer& buff, Message& req)
10207c462acSRatan Gupta {
10307c462acSRatan Gupta     /*  0                   1                   2                   3
10407c462acSRatan Gupta         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
10507c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10607c462acSRatan Gupta        |        length of PRList       |        <PRList> String        \
10707c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10807c462acSRatan Gupta        |   length of Naming Authority  |   <Naming Authority String>   \
10907c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11007c462acSRatan Gupta        |     length of <scope-list>    |      <scope-list> String      \
11107c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
11207c462acSRatan Gupta 
11307c462acSRatan Gupta     /* Enforce SLPv2 service type request size limits. */
11407c462acSRatan Gupta     if (buff.size() < slp::request::MIN_SRVTYPE_LEN)
11507c462acSRatan Gupta     {
11607c462acSRatan Gupta         return (int)slp::Error::PARSE_ERROR;
11707c462acSRatan Gupta     }
11807c462acSRatan Gupta 
11907c462acSRatan Gupta     /* Parse the PRList. */
12007c462acSRatan Gupta     uint16_t prListLen;
121f60e7108SAndrew Geissler     uint32_t pos = slp::header::MIN_LEN + req.header.langtagLen;
122f60e7108SAndrew Geissler     if ((pos + slp::request::SIZE_PRLIST) > buff.size())
123f60e7108SAndrew Geissler     {
124f60e7108SAndrew Geissler         std::cerr << "PRList length field is greater than input buffer: "
125f60e7108SAndrew Geissler                   << (pos + slp::request::SIZE_PRLIST) << " / " << buff.size()
126f60e7108SAndrew Geissler                   << std::endl;
127f60e7108SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
128f60e7108SAndrew Geissler     }
129f60e7108SAndrew Geissler     std::copy_n(buff.data() + pos, slp::request::SIZE_PRLIST,
130f60e7108SAndrew Geissler                 (uint8_t*)&prListLen);
13107c462acSRatan Gupta 
132f60e7108SAndrew Geissler     pos += slp::request::SIZE_PRLIST;
13307c462acSRatan Gupta     prListLen = endian::from_network(prListLen);
13407c462acSRatan Gupta 
135f60e7108SAndrew Geissler     if ((pos + prListLen) > buff.size())
136f60e7108SAndrew Geissler     {
137f60e7108SAndrew Geissler         std::cerr << "Length of PRList is greater than input buffer: "
138f60e7108SAndrew Geissler                   << (slp::request::OFFSET_PR + prListLen) << " / "
139f60e7108SAndrew Geissler                   << buff.size() << std::endl;
140f60e7108SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
141f60e7108SAndrew Geissler     }
14207c462acSRatan Gupta 
143f60e7108SAndrew Geissler     req.body.srvtyperqst.prList.insert(0, (const char*)buff.data() + pos,
144f60e7108SAndrew Geissler                                        prListLen);
145f60e7108SAndrew Geissler 
146f60e7108SAndrew Geissler     pos += prListLen;
14707c462acSRatan Gupta 
14807c462acSRatan Gupta     /* Parse the Naming Authority. */
14907c462acSRatan Gupta     uint16_t namingAuthLen;
150f60e7108SAndrew Geissler     if ((pos + slp::request::SIZE_NAMING) > buff.size())
151f60e7108SAndrew Geissler     {
152f60e7108SAndrew Geissler         std::cerr << "Naming auth length field is greater than input buffer: "
153f60e7108SAndrew Geissler                   << (pos + slp::request::SIZE_NAMING) << " / " << buff.size()
154f60e7108SAndrew Geissler                   << std::endl;
155f60e7108SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
156f60e7108SAndrew Geissler     }
157537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_NAMING,
15807c462acSRatan Gupta                 (uint8_t*)&namingAuthLen);
15907c462acSRatan Gupta 
16007c462acSRatan Gupta     pos += slp::request::SIZE_NAMING;
16107c462acSRatan Gupta 
16207c462acSRatan Gupta     namingAuthLen = endian::from_network(namingAuthLen);
16307c462acSRatan Gupta     if (namingAuthLen == 0 || namingAuthLen == 0xffff)
16407c462acSRatan Gupta     {
16507c462acSRatan Gupta         req.body.srvtyperqst.namingAuth = "";
166f60e7108SAndrew Geissler         // If it's the special 0xffff, treat like 0 size
167f60e7108SAndrew Geissler         namingAuthLen = 0;
16807c462acSRatan Gupta     }
16907c462acSRatan Gupta     else
17007c462acSRatan Gupta     {
171f60e7108SAndrew Geissler         if ((pos + namingAuthLen) > buff.size())
172f60e7108SAndrew Geissler         {
173f60e7108SAndrew Geissler             std::cerr << "Length of Naming Size is greater than input buffer: "
174f60e7108SAndrew Geissler                       << (pos + namingAuthLen) << " / " << buff.size()
175f60e7108SAndrew Geissler                       << std::endl;
176f60e7108SAndrew Geissler             return (int)slp::Error::PARSE_ERROR;
177f60e7108SAndrew Geissler         }
178537ff140SPatrick Venture         req.body.srvtyperqst.namingAuth.insert(
179537ff140SPatrick Venture             0, (const char*)buff.data() + pos, namingAuthLen);
18007c462acSRatan Gupta     }
18107c462acSRatan Gupta 
18207c462acSRatan Gupta     pos += namingAuthLen;
18307c462acSRatan Gupta 
18407c462acSRatan Gupta     /* Parse the <scope-list>. */
18507c462acSRatan Gupta     uint16_t scopeListLen;
186f60e7108SAndrew Geissler     if ((pos + slp::request::SIZE_SCOPE) > buff.size())
187f60e7108SAndrew Geissler     {
188f60e7108SAndrew Geissler         std::cerr << "Length of Scope size is greater than input buffer: "
189f60e7108SAndrew Geissler                   << (pos + slp::request::SIZE_SCOPE) << " / " << buff.size()
190f60e7108SAndrew Geissler                   << std::endl;
191f60e7108SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
192f60e7108SAndrew Geissler     }
193537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_SCOPE,
19407c462acSRatan Gupta                 (uint8_t*)&scopeListLen);
19507c462acSRatan Gupta 
19607c462acSRatan Gupta     pos += slp::request::SIZE_SCOPE;
19707c462acSRatan Gupta 
19807c462acSRatan Gupta     scopeListLen = endian::from_network(scopeListLen);
199f60e7108SAndrew Geissler     if ((pos + scopeListLen) > buff.size())
200f60e7108SAndrew Geissler     {
201f60e7108SAndrew Geissler         std::cerr << "Length of Scope List is greater than input buffer: "
202f60e7108SAndrew Geissler                   << (pos + scopeListLen) << " / " << buff.size() << std::endl;
203f60e7108SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
204f60e7108SAndrew Geissler     }
20507c462acSRatan Gupta 
20607c462acSRatan Gupta     req.body.srvtyperqst.scopeList.insert(0, (const char*)buff.data() + pos,
20707c462acSRatan Gupta                                           scopeListLen);
20807c462acSRatan Gupta 
20907c462acSRatan Gupta     return slp::SUCCESS;
21007c462acSRatan Gupta }
21107c462acSRatan Gupta 
parseSrvRqst(const buffer & buff,Message & req)21207c462acSRatan Gupta int parseSrvRqst(const buffer& buff, Message& req)
21307c462acSRatan Gupta {
21407c462acSRatan Gupta     /*  0                   1                   2                   3
21507c462acSRatan Gupta         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
21607c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21707c462acSRatan Gupta        |      length of <PRList>       |        <PRList> String        \
21807c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21907c462acSRatan Gupta        |   length of <service-type>    |    <service-type> String      \
22007c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22107c462acSRatan Gupta        |    length of <scope-list>     |     <scope-list> String       \
22207c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22307c462acSRatan Gupta        |  length of predicate string   |  Service Request <predicate>  \
22407c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22507c462acSRatan Gupta        |  length of <SLP SPI> string   |       <SLP SPI> String        \
22607c462acSRatan Gupta        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
22707c462acSRatan Gupta 
22807c462acSRatan Gupta     /* Enforce v2 service request size limits. */
22907c462acSRatan Gupta     if (buff.size() < slp::request::MIN_SRV_LEN)
23007c462acSRatan Gupta     {
23107c462acSRatan Gupta         return (int)slp::Error::PARSE_ERROR;
23207c462acSRatan Gupta     }
23307c462acSRatan Gupta 
23407c462acSRatan Gupta     /* 1) Parse the PRList. */
23507c462acSRatan Gupta     uint16_t prListLen;
236*20bab748SAndrew Geissler     uint32_t pos = slp::header::MIN_LEN + req.header.langtagLen;
237*20bab748SAndrew Geissler     if ((pos + slp::request::SIZE_PRLIST) > buff.size())
238*20bab748SAndrew Geissler     {
239*20bab748SAndrew Geissler         std::cerr << "PRList length field is greater then input buffer: "
240*20bab748SAndrew Geissler                   << (pos + slp::request::SIZE_PRLIST) << " / " << buff.size()
241*20bab748SAndrew Geissler                   << std::endl;
242*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
243*20bab748SAndrew Geissler     }
244*20bab748SAndrew Geissler     std::copy_n(buff.data() + pos, slp::request::SIZE_PRLIST,
245*20bab748SAndrew Geissler                 (uint8_t*)&prListLen);
24607c462acSRatan Gupta 
247*20bab748SAndrew Geissler     pos += slp::request::SIZE_PRLIST;
24807c462acSRatan Gupta 
24907c462acSRatan Gupta     prListLen = endian::from_network(prListLen);
250*20bab748SAndrew Geissler     if ((pos + prListLen) > buff.size())
251*20bab748SAndrew Geissler     {
252*20bab748SAndrew Geissler         std::cerr << "Length of PRList is greater then input buffer: "
253*20bab748SAndrew Geissler                   << (slp::request::OFFSET_PR + prListLen) << " / "
254*20bab748SAndrew Geissler                   << buff.size() << std::endl;
255*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
256*20bab748SAndrew Geissler     }
25707c462acSRatan Gupta     req.body.srvrqst.prList.insert(0, (const char*)buff.data() + pos,
25807c462acSRatan Gupta                                    prListLen);
25907c462acSRatan Gupta 
26007c462acSRatan Gupta     pos += prListLen;
26107c462acSRatan Gupta 
26207c462acSRatan Gupta     /* 2) Parse the <service-type> string. */
26307c462acSRatan Gupta     uint16_t srvTypeLen;
264*20bab748SAndrew Geissler     if ((pos + slp::request::SIZE_SERVICE_TYPE) > buff.size())
265*20bab748SAndrew Geissler     {
266*20bab748SAndrew Geissler         std::cerr << "SrvType length field is greater then input buffer: "
267*20bab748SAndrew Geissler                   << (pos + slp::request::SIZE_SERVICE_TYPE) << " / "
268*20bab748SAndrew Geissler                   << buff.size() << std::endl;
269*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
270*20bab748SAndrew Geissler     }
271537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_SERVICE_TYPE,
27207c462acSRatan Gupta                 (uint8_t*)&srvTypeLen);
27307c462acSRatan Gupta 
27407c462acSRatan Gupta     srvTypeLen = endian::from_network(srvTypeLen);
27507c462acSRatan Gupta 
27607c462acSRatan Gupta     pos += slp::request::SIZE_SERVICE_TYPE;
27707c462acSRatan Gupta 
278*20bab748SAndrew Geissler     if ((pos + srvTypeLen) > buff.size())
279*20bab748SAndrew Geissler     {
280*20bab748SAndrew Geissler         std::cerr << "Length of SrvType is greater then input buffer: "
281*20bab748SAndrew Geissler                   << (pos + srvTypeLen) << " / " << buff.size() << std::endl;
282*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
283*20bab748SAndrew Geissler     }
28407c462acSRatan Gupta     req.body.srvrqst.srvType.insert(0, (const char*)buff.data() + pos,
28507c462acSRatan Gupta                                     srvTypeLen);
28607c462acSRatan Gupta 
28707c462acSRatan Gupta     pos += srvTypeLen;
28807c462acSRatan Gupta 
28907c462acSRatan Gupta     /* 3) Parse the <scope-list> string. */
29007c462acSRatan Gupta     uint16_t scopeListLen;
291*20bab748SAndrew Geissler     if ((pos + slp::request::SIZE_SCOPE) > buff.size())
292*20bab748SAndrew Geissler     {
293*20bab748SAndrew Geissler         std::cerr << "Scope List length field is greater then input buffer: "
294*20bab748SAndrew Geissler                   << (pos + slp::request::SIZE_SCOPE) << " / " << buff.size()
295*20bab748SAndrew Geissler                   << std::endl;
296*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
297*20bab748SAndrew Geissler     }
298537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_SCOPE,
29907c462acSRatan Gupta                 (uint8_t*)&scopeListLen);
30007c462acSRatan Gupta 
30107c462acSRatan Gupta     scopeListLen = endian::from_network(scopeListLen);
30207c462acSRatan Gupta 
30307c462acSRatan Gupta     pos += slp::request::SIZE_SCOPE;
30407c462acSRatan Gupta 
305*20bab748SAndrew Geissler     if ((pos + scopeListLen) > buff.size())
306*20bab748SAndrew Geissler     {
307*20bab748SAndrew Geissler         std::cerr << "Length of Scope List is greater then input buffer: "
308*20bab748SAndrew Geissler                   << (pos + scopeListLen) << " / " << buff.size() << std::endl;
309*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
310*20bab748SAndrew Geissler     }
31107c462acSRatan Gupta     req.body.srvrqst.scopeList.insert(0, (const char*)buff.data() + pos,
31207c462acSRatan Gupta                                       scopeListLen);
31307c462acSRatan Gupta 
31407c462acSRatan Gupta     pos += scopeListLen;
31507c462acSRatan Gupta 
31607c462acSRatan Gupta     /* 4) Parse the <predicate> string. */
31707c462acSRatan Gupta     uint16_t predicateLen;
318*20bab748SAndrew Geissler     if ((pos + slp::request::SIZE_PREDICATE) > buff.size())
319*20bab748SAndrew Geissler     {
320*20bab748SAndrew Geissler         std::cerr << "Predicate length field is greater then input buffer: "
321*20bab748SAndrew Geissler                   << (pos + slp::request::SIZE_PREDICATE) << " / "
322*20bab748SAndrew Geissler                   << buff.size() << std::endl;
323*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
324*20bab748SAndrew Geissler     }
325537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_PREDICATE,
32607c462acSRatan Gupta                 (uint8_t*)&predicateLen);
32707c462acSRatan Gupta 
32807c462acSRatan Gupta     predicateLen = endian::from_network(predicateLen);
32907c462acSRatan Gupta     pos += slp::request::SIZE_PREDICATE;
33007c462acSRatan Gupta 
331*20bab748SAndrew Geissler     if ((pos + predicateLen) > buff.size())
332*20bab748SAndrew Geissler     {
333*20bab748SAndrew Geissler         std::cerr << "Length of Predicate is greater then input buffer: "
334*20bab748SAndrew Geissler                   << (pos + predicateLen) << " / " << buff.size() << std::endl;
335*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
336*20bab748SAndrew Geissler     }
33707c462acSRatan Gupta     req.body.srvrqst.predicate.insert(0, (const char*)buff.data() + pos,
33807c462acSRatan Gupta                                       predicateLen);
33907c462acSRatan Gupta 
34007c462acSRatan Gupta     pos += predicateLen;
34107c462acSRatan Gupta 
34207c462acSRatan Gupta     /* 5) Parse the <SLP SPI> string. */
34307c462acSRatan Gupta     uint16_t spistrLen;
344*20bab748SAndrew Geissler     if ((pos + slp::request::SIZE_SLPI) > buff.size())
345*20bab748SAndrew Geissler     {
346*20bab748SAndrew Geissler         std::cerr << "SLP SPI length field is greater then input buffer: "
347*20bab748SAndrew Geissler                   << (pos + slp::request::SIZE_SLPI) << " / " << buff.size()
348*20bab748SAndrew Geissler                   << std::endl;
349*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
350*20bab748SAndrew Geissler     }
351537ff140SPatrick Venture     std::copy_n(buff.data() + pos, slp::request::SIZE_SLPI,
35207c462acSRatan Gupta                 (uint8_t*)&spistrLen);
35307c462acSRatan Gupta 
35407c462acSRatan Gupta     spistrLen = endian::from_network(spistrLen);
35507c462acSRatan Gupta     pos += slp::request::SIZE_SLPI;
35607c462acSRatan Gupta 
357*20bab748SAndrew Geissler     if ((pos + spistrLen) > buff.size())
358*20bab748SAndrew Geissler     {
359*20bab748SAndrew Geissler         std::cerr << "Length of SLP SPI is greater then input buffer: "
360*20bab748SAndrew Geissler                   << (pos + spistrLen) << " / " << buff.size() << std::endl;
361*20bab748SAndrew Geissler         return (int)slp::Error::PARSE_ERROR;
362*20bab748SAndrew Geissler     }
36307c462acSRatan Gupta     req.body.srvrqst.spistr.insert(0, (const char*)buff.data() + pos,
36407c462acSRatan Gupta                                    spistrLen);
36507c462acSRatan Gupta 
36607c462acSRatan Gupta     return slp::SUCCESS;
36707c462acSRatan Gupta }
36807c462acSRatan Gupta } // namespace internal
36907c462acSRatan Gupta 
parseBuffer(const buffer & buff)37007c462acSRatan Gupta std::tuple<int, Message> parseBuffer(const buffer& buff)
37107c462acSRatan Gupta {
37207c462acSRatan Gupta     Message req;
37307c462acSRatan Gupta     int rc = slp::SUCCESS;
37407c462acSRatan Gupta     /* parse the header first */
37507c462acSRatan Gupta     std::tie(rc, req) = internal::parseHeader(buff);
37607c462acSRatan Gupta     if (!rc)
37707c462acSRatan Gupta     {
37807c462acSRatan Gupta         /* switch on the function id to parse the body */
37907c462acSRatan Gupta         switch (req.header.functionID)
38007c462acSRatan Gupta         {
38107c462acSRatan Gupta             case (uint8_t)slp::FunctionType::SRVTYPERQST:
38207c462acSRatan Gupta                 rc = internal::parseSrvTypeRqst(buff, req);
38307c462acSRatan Gupta                 break;
38407c462acSRatan Gupta             case (uint8_t)slp::FunctionType::SRVRQST:
38507c462acSRatan Gupta                 rc = internal::parseSrvRqst(buff, req);
38607c462acSRatan Gupta                 break;
38707c462acSRatan Gupta             default:
38807c462acSRatan Gupta                 rc = (int)slp::Error::MSG_NOT_SUPPORTED;
38907c462acSRatan Gupta         }
39007c462acSRatan Gupta     }
39107c462acSRatan Gupta     return std::make_tuple(rc, std::move(req));
39207c462acSRatan Gupta }
39307c462acSRatan Gupta } // namespace parser
39407c462acSRatan Gupta } // namespace slp
395