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