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