1 #include "slp.hpp"
2 #include "slp_meta.hpp"
3
4 #include <gtest/gtest.h>
5
6 /* 0 1 2 3
7 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
8 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
9 | Version | Function-ID | Length |
10 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11 | Length, contd.|O|F|R| reserved |Next Ext Offset|
12 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13 | Next Extension Offset, contd.| XID |
14 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15 | Language Tag Length | Language Tag \
16 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
17
TEST(parseHeaderTest,BasicGoodPath)18 TEST(parseHeaderTest, BasicGoodPath)
19 {
20 // Basic buffer with valid Function-ID
21 slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
23
24 slp::Message req;
25 int rc = slp::SUCCESS;
26 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
27
28 EXPECT_EQ(rc, 0);
29 }
30
TEST(parseHeaderTest,InvalidBufferSize)31 TEST(parseHeaderTest, InvalidBufferSize)
32 {
33 // 1 byte too small
34 slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
36
37 slp::Message req;
38 int rc = slp::SUCCESS;
39 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
40
41 EXPECT_NE(rc, 0);
42 }
43
TEST(parseHeaderTest,ValidLangTagLength)44 TEST(parseHeaderTest, ValidLangTagLength)
45 {
46 // Language Tag Length that is valid
47 slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
49
50 slp::Message req;
51 int rc = slp::SUCCESS;
52 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
53
54 EXPECT_EQ(rc, 0);
55 }
56
TEST(parseHeaderTest,InvalidLangTagLength)57 TEST(parseHeaderTest, InvalidLangTagLength)
58 {
59 // Language Tag Length that is too big
60 slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00};
62
63 slp::Message req;
64 int rc = slp::SUCCESS;
65 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
66
67 EXPECT_NE(rc, 0);
68 }
69
70 /* 0 1 2 3
71 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
72 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 | Service Location header (function = SrvTypeRqst = 9) |
74 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 | length of PRList | <PRList> String \
76 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 | length of Naming Authority | <Naming Authority String> \
78 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 | length of <scope-list> | <scope-list> String \
80 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/
TEST(parseSrvTypeRqst,BasicGoodPath)81 TEST(parseSrvTypeRqst, BasicGoodPath)
82 {
83 // Basic buffer with 0 for all lengths
84 slp::buffer testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
87 slp::Message req;
88 int rc = slp::SUCCESS;
89 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
90
91 EXPECT_EQ(rc, 0);
92 }
93
TEST(parseSrvTypeRqst,GoodPathWithData)94 TEST(parseSrvTypeRqst, GoodPathWithData)
95 {
96 // Basic buffer with some valid lengths and data
97 slp::buffer
98 testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */
100 'L', 'A', 'N', 'G', 0x00, 0x04, /* PRlist length*/
101 'P', 'R', 'L', 'T', 0x00, 0x08, /* Naming auth length */
102 'N', 'A', 'M', 'E', 'A', 'U', 'T',
103 'H', 0x00, 0x05, /* Scope length*/
104 'S', 'C', 'O', 'P', 'E'};
105 slp::Message req;
106 int rc = slp::SUCCESS;
107 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
108 EXPECT_EQ(rc, 0);
109 EXPECT_EQ(req.header.langtag, "LANG");
110 EXPECT_EQ(req.header.langtagLen, 4);
111
112 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
113 EXPECT_EQ(rc, 0);
114 EXPECT_EQ(req.body.srvtyperqst.prList, "PRLT");
115 EXPECT_EQ(req.body.srvtyperqst.namingAuth, "NAMEAUTH");
116 EXPECT_EQ(req.body.srvtyperqst.scopeList, "SCOPE");
117 }
118
TEST(parseSrvTypeRqst,GoodPathMatchSlptoolFindSrvTypes)119 TEST(parseSrvTypeRqst, GoodPathMatchSlptoolFindSrvTypes)
120 {
121 // This matches what "slptool -u <server> findsrvtypes" sends
122 slp::buffer testData{0x02, 0x09, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x74, 0xe2, 0x00, 0x02, /* Lang Length */
124 'e', 'n', 0x00, 0x00, /* PRlist length*/
125 0xff, 0xff, /* Naming auth length */
126 0x00, 0x07, /* Scope length*/
127 'D', 'E', 'F', 'A', 'U', 'L', 'T'};
128 slp::Message req;
129 int rc = slp::SUCCESS;
130 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
131 EXPECT_EQ(rc, 0);
132 EXPECT_EQ(req.header.langtag, "en");
133 EXPECT_EQ(req.header.langtagLen, 2);
134
135 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
136 EXPECT_EQ(rc, 0);
137 EXPECT_EQ(req.body.srvtyperqst.namingAuth, "");
138 EXPECT_EQ(req.body.srvtyperqst.scopeList, "DEFAULT");
139 }
140
TEST(parseSrvTypeRqst,BadPathSizes)141 TEST(parseSrvTypeRqst, BadPathSizes)
142 {
143 // Basic buffer with some valid lengths and data
144 slp::buffer
145 testData{0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */
147 'L', 'A', 'N', 'G', 0x00, 0x05, /* PRlist length*/
148 'P', 'R', 'L', 'T', 0x00, 0x08, /* Naming auth length */
149 'N', 'A', 'M', 'E', 'A', 'U', 'T',
150 'H', 0x00, 0x05, /* Scope length*/
151 'S', 'C', 'O', 'P', 'E'};
152 slp::Message req;
153 int rc = slp::SUCCESS;
154 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
155 EXPECT_EQ(rc, 0);
156 EXPECT_EQ(req.header.langtag, "LANG");
157 EXPECT_EQ(req.header.langtagLen, 4);
158
159 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
160 EXPECT_NE(rc, 0);
161
162 // Fix PR, make Name invalid
163 testData[19] = 4;
164 testData[25] = 5;
165 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
166 EXPECT_NE(rc, 0);
167
168 // Fix Name, make Scope invalid
169 testData[25] = 8;
170 testData[35] = 10;
171 rc = slp::parser::internal::parseSrvTypeRqst(testData, req);
172 EXPECT_NE(rc, 0);
173 }
174
175 /* 0 1 2 3
176 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
177 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178 | length of <PRList> | <PRList> String \
179 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
180 | length of <service-type> | <service-type> String \
181 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182 | length of <scope-list> | <scope-list> String \
183 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184 | length of predicate string | Service Request <predicate> \
185 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
186 | length of <SLP SPI> string | <SLP SPI> String \
187 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
188
TEST(parseSrvRqst,BasicGoodPath)189 TEST(parseSrvRqst, BasicGoodPath)
190 {
191 // Basic buffer with 0 for all lengths
192 slp::buffer testData{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, /* start of SrvRqst*/
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
196 slp::Message req;
197 int rc = slp::SUCCESS;
198 rc = slp::parser::internal::parseSrvRqst(testData, req);
199
200 EXPECT_EQ(rc, 0);
201 }
202
TEST(parseSrvRqst,GoodPathWithData)203 TEST(parseSrvRqst, GoodPathWithData)
204 {
205 // Basic buffer with some valid lengths and data
206 slp::buffer testData{
207 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */
209 'L', 'A', 'N', 'G', 0x00, 0x04, /* PRlist length*/
210 'P', 'R', 'L', 'T', 0x00, 0xB, /* Service type length */
211 'S', 'E', 'R', 'V', 'I', 'C', 'E',
212 'T', 'Y', 'P', 'E', 0x00, 0x05, /* Scope length*/
213 'S', 'C', 'O', 'P', 'E', 0x00, 0x02, /* predicate length */
214 'P', 'D', 0x00, 0x01, /* SLP SPI length */
215 'S'};
216 slp::Message req;
217 int rc = slp::SUCCESS;
218 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
219 EXPECT_EQ(rc, 0);
220 EXPECT_EQ(req.header.langtag, "LANG");
221 EXPECT_EQ(req.header.langtagLen, 4);
222
223 rc = slp::parser::internal::parseSrvRqst(testData, req);
224 EXPECT_EQ(rc, 0);
225 EXPECT_EQ(req.body.srvrqst.prList, "PRLT");
226 EXPECT_EQ(req.body.srvrqst.srvType, "SERVICETYPE");
227 EXPECT_EQ(req.body.srvrqst.scopeList, "SCOPE");
228 EXPECT_EQ(req.body.srvrqst.predicate, "PD");
229 EXPECT_EQ(req.body.srvrqst.spistr, "S");
230 }
231
TEST(parseSrvRqst,GoodPathMatchSlptoolFindSrvs)232 TEST(parseSrvRqst, GoodPathMatchSlptoolFindSrvs)
233 {
234 // This matches what "slptool -u <server> findsrvs service:obmc_console"
235 // sends
236 slp::buffer testData{0x02, 0x01, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0xe5, 0xc2, 0x00, 0x02, /* Lang Length */
238 'e', 'n', 0x00, 0x00, /* PR list length*/
239 0x00, 0x14, /* Service length */
240 's', 'e', 'r', 'v', 'i', 'c', 'e', ':',
241 'o', 'b', 'm', 'c', '_', 'c', 'o', 'n',
242 's', 'o', 'l', 'e', 0x00, 0x07, /* Scope length*/
243 'D', 'E', 'F', 'A', 'U', 'L', 'T', 0x00,
244 0x00, /* Predicate length */
245 0x00, 0x00}; /* SLP SPI length*/
246 slp::Message req;
247 int rc = slp::SUCCESS;
248 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
249 EXPECT_EQ(rc, 0);
250 EXPECT_EQ(req.header.langtag, "en");
251 EXPECT_EQ(req.header.langtagLen, 2);
252
253 rc = slp::parser::internal::parseSrvRqst(testData, req);
254 EXPECT_EQ(rc, 0);
255 EXPECT_EQ(req.body.srvrqst.srvType, "service:obmc_console");
256 EXPECT_EQ(req.body.srvrqst.scopeList, "DEFAULT");
257 }
258
TEST(parseSrvRqst,BadPathSizes)259 TEST(parseSrvRqst, BadPathSizes)
260 {
261 // Basic buffer with invalid PRlist size
262 slp::buffer testData{
263 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* Lang Length */
265 'L', 'A', 'N', 'G', 0x00, 0x05, /* PRlist length*/
266 'P', 'R', 'L', 'T', 0x00, 0xB, /* Service type length */
267 'S', 'E', 'R', 'V', 'I', 'C', 'E',
268 'T', 'Y', 'P', 'E', 0x00, 0x05, /* Scope length*/
269 'S', 'C', 'O', 'P', 'E', 0x00, 0x02, /* predicate length */
270 'P', 'D', 0x00, 0x01, /* SLP SPI length */
271 'S'};
272 slp::Message req;
273 int rc = slp::SUCCESS;
274 std::tie(rc, req) = slp::parser::internal::parseHeader(testData);
275 EXPECT_EQ(rc, 0);
276 EXPECT_EQ(req.header.langtag, "LANG");
277 EXPECT_EQ(req.header.langtagLen, 4);
278
279 rc = slp::parser::internal::parseSrvRqst(testData, req);
280 EXPECT_NE(rc, 0);
281
282 // Fix PR, make Service type invalid
283 testData[19] = 4;
284 testData[25] = 5;
285 rc = slp::parser::internal::parseSrvRqst(testData, req);
286 EXPECT_NE(rc, 0);
287
288 // Fix Service type, make Scope invalid
289 testData[25] = 0xB;
290 testData[38] = 10;
291 rc = slp::parser::internal::parseSrvRqst(testData, req);
292 EXPECT_NE(rc, 0);
293
294 // Fix Scope, make Predicate invalid
295 testData[38] = 5;
296 testData[45] = 100;
297 rc = slp::parser::internal::parseSrvRqst(testData, req);
298 EXPECT_NE(rc, 0);
299
300 // Fix Predicate, make SLP SPI invalid
301 testData[45] = 2;
302 testData[49] = 5;
303 rc = slp::parser::internal::parseSrvRqst(testData, req);
304 EXPECT_NE(rc, 0);
305
306 // Now fix SLP SPI and make sure we pass
307 testData[49] = 1;
308 rc = slp::parser::internal::parseSrvRqst(testData, req);
309 EXPECT_EQ(rc, 0);
310 }
311