1
/*********************************************************
2
* Copyright (C) 2005 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
23
#include <sys/types.h>
24
#include <netinet/in.h>
32
#include "SLPv2Private.h"
35
*-----------------------------------------------------------------------------
37
* SLPv2MsgParserStringValid -
39
* Returns TRUE if the string at 'offset' bytes into 'packet'
40
* actually fits inside the packet, which is 'len' bytes.
43
* Returns TRUE upon success, FALSE upon memory error.
48
*-----------------------------------------------------------------------------
52
SLPv2MsgParserStringValid(char *packet, // IN
56
uint16 stringLength = Portable_ntohs(*((uint16 *) (packet + len)));
57
return (offset + stringLength > len) ? FALSE : TRUE;
61
*-----------------------------------------------------------------------------
63
* SLPv2MsgParserGetString -
65
* Returns a C string, given the (16 bit length) Pascal string at
74
*-----------------------------------------------------------------------------
78
SLPv2MsgParserGetString(char *packet, // IN
79
int packetLength, // IN
83
uint16 stringLength = Portable_ntohs(*((uint16 *) (packet + offset)));
87
/* make sure the string actually fits in the packet */
88
if (offset + stringLength > packetLength) {
95
string = Util_SafeMalloc(stringLength + 1);
98
* We use memcpy() because Str_Strcpy() doesn't handle non-NULL
101
memcpy(string, packet + offset + 2, stringLength);
102
string[stringLength] = '\0';
106
if (*ok == FALSE && myOk == TRUE) {
115
*-----------------------------------------------------------------------------
117
* SLPv2MsgParser_Init -
119
* Initializes a SLPv2_Parse structure.
122
* Returns a pointer to a SLPv2_Parse structure or NULL upon error.
127
*-----------------------------------------------------------------------------
131
SLPv2MsgParser_Init()
133
struct SLPv2_Parse *parse;
135
parse = (struct SLPv2_Parse *) Util_SafeMalloc(sizeof (struct SLPv2_Parse));
136
parse->header = NULL;
137
parse->languageTag = NULL;
139
parse->serviceRequest.prList = NULL;
140
parse->serviceRequest.serviceType = NULL;
141
parse->serviceRequest.scope = NULL;
142
parse->serviceRequest.predicate = NULL;
143
parse->serviceRequest.spi = NULL;
145
parse->serviceReply.error = 0;
146
parse->serviceReply.urlCount = 0;
147
parse->serviceReply.url = NULL;
149
parse->attributeRequest.prList = NULL;
150
parse->attributeRequest.url = NULL;
151
parse->attributeRequest.scope = NULL;
152
parse->attributeRequest.tagList = NULL;
153
parse->attributeRequest.spi = NULL;
155
parse->attributeReply.error = 0;
156
parse->attributeReply.attributeList = NULL;
162
*-----------------------------------------------------------------------------
164
* SLPv2MsgParserGetHeader -
166
* Populates the SLPv2_Parse structure with SLPv2 header data.
169
* Returns TRUE upon success, FALSE upon memory error.
174
*-----------------------------------------------------------------------------
178
SLPv2MsgParserGetHeader(char *packet, // IN
180
struct SLPv2_Parse *parse) // IN
182
uint16 languageTagOffset = sizeof(struct SLPv2_Header);
185
uint8 *lengthArrayTemp = (uint8 *) &lengthTemp;
187
parse->header = (struct SLPv2_Header *) packet;
189
if (len < sizeof(struct SLPv2_Header)) {
193
if (SLPV2_VERSION != parse->header->version) {
197
parse->languageTagLength = Portable_ntohs(*((uint16 *) (packet + languageTagOffset)));
199
parse->languageTag = SLPv2MsgParserGetString(packet,
208
lengthArrayTemp[0] = parse->header->length[0];
209
lengthArrayTemp[1] = parse->header->length[1];
210
lengthArrayTemp[2] = parse->header->length[2];
211
lengthTemp = Portable_ntohl(lengthTemp);
212
parse->header->length[0] = lengthArrayTemp[0];
213
parse->header->length[1] = lengthArrayTemp[1];
214
parse->header->length[2] = lengthArrayTemp[2];
216
parse->header->xid = Portable_ntohs(parse->header->xid);
222
*-----------------------------------------------------------------------------
224
* SLPv2MsgParserParseServiceRequest -
226
* Populates the SLPv2_Parse structure with SLPv2 Service Request data.
229
* Returns TRUE upon success, FALSE upon memory error.
234
*-----------------------------------------------------------------------------
238
SLPv2MsgParserParseServiceRequest(char *packet, // IN
240
struct SLPv2_Parse *parse) // IN
242
Bool parseOkay = TRUE;
244
/* previous responder list */
245
uint16 prOffset = sizeof(struct SLPv2_Header) + parse->languageTagLength + 2;
246
uint16 prLength = Portable_ntohs(*((uint16 *) (packet + prOffset)));
249
uint16 stOffset = prOffset + prLength + 2;
250
uint16 stLength = Portable_ntohs(*((uint16 *) (packet + stOffset)));
253
uint16 slOffset = stOffset + stLength + 2;
254
uint16 slLength = Portable_ntohs(*((uint16 *) (packet + slOffset)));
257
uint16 predicateOffset = slOffset + slLength + 2;
258
uint16 predicateLength = Portable_ntohs(*((uint16 *) (packet + predicateOffset)));
260
/* security parameter index */
261
uint16 spiOffset = predicateOffset + predicateLength + 2;
263
parse->serviceRequest.prList = SLPv2MsgParserGetString(packet, len,
264
prOffset, &parseOkay);
265
parse->serviceRequest.serviceType = SLPv2MsgParserGetString(packet, len,
266
stOffset, &parseOkay);
267
parse->serviceRequest.scope = SLPv2MsgParserGetString(packet, len,
268
slOffset, &parseOkay);
269
parse->serviceRequest.predicate = SLPv2MsgParserGetString(packet, len,
270
predicateOffset, &parseOkay);
271
parse->serviceRequest.spi = SLPv2MsgParserGetString(packet, len,
272
spiOffset, &parseOkay);
282
*-----------------------------------------------------------------------------
284
* SLPv2MsgParserParseServiceReply -
286
* Populates the SLPv2_Parse structure with SLPv2 Service Reply data.
289
* Returns TRUE upon success, FALSE upon memory error.
294
*-----------------------------------------------------------------------------
298
SLPv2MsgParserParseServiceReply(char *packet, // IN
300
struct SLPv2_Parse *parse) // IN
303
uint16 urlCountOffset;
309
errorOffset = sizeof(struct SLPv2_Header) + parse->languageTagLength + 2;
310
parse->serviceReply.error = Portable_ntohs(*((uint16 *) (packet + errorOffset)));
312
urlCountOffset = errorOffset + 2;
313
parse->serviceReply.urlCount = Portable_ntohs(*((uint16 *) (packet
315
parse->serviceReply.url = Util_SafeMalloc(sizeof(char *)
316
* parse->serviceReply.urlCount);
317
urlOffset = urlCountOffset + 2;
320
* Zero out the URL array so if we fail in the middle of
321
* populating it, * SLPv2MsgParser_Destroy will free a bunch
322
* of NULLs instead of dangling pointers.
324
for (i = 0; i < parse->serviceReply.urlCount; i++) {
325
parse->serviceReply.url[i] = NULL;
328
for (i = 0; i < parse->serviceReply.urlCount; i++) {
329
uint16 urlLength = Portable_ntohs(*((uint16 *) (packet + urlOffset)));
331
parse->serviceReply.url[i] = SLPv2MsgParserGetString(packet, len,
332
urlOffset, &parseOk);
336
urlOffset = urlOffset + urlLength + 2;
344
*-----------------------------------------------------------------------------
346
* SLPv2MsgParserParseAttributeRequest -
348
* Populates the SLPv2_Parse structure with SLPv2 Attribute Request data.
351
* Returns TRUE upon success, FALSE upon memory error.
356
*-----------------------------------------------------------------------------
360
SLPv2MsgParserParseAttributeRequest(char *packet, // IN
362
struct SLPv2_Parse *parse) // IN
364
Bool parseOkay = TRUE;
366
/* previous responder list */
367
uint16 prOffset = sizeof(struct SLPv2_Header) + parse->languageTagLength + 2;
368
uint16 prLength = Portable_ntohs(*((uint16 *) (packet + prOffset)));
371
uint16 urlOffset = prOffset + prLength + 2;
372
uint16 urlLength = Portable_ntohs(*((uint16 *) (packet + urlOffset)));
375
uint16 slOffset = urlOffset + urlLength + 2;
376
uint16 slLength = Portable_ntohs(*((uint16 *) (packet + slOffset)));
379
uint16 tagOffset = slOffset + slLength + 2;
380
uint16 tagLength = Portable_ntohs(*((uint16 *) (packet + tagOffset)));
382
/* security parameter index */
383
uint16 spiOffset = tagOffset + tagLength + 2;
386
parse->attributeRequest.prList = SLPv2MsgParserGetString(packet, len,
387
prOffset, &parseOkay);
388
parse->attributeRequest.url = SLPv2MsgParserGetString(packet, len,
389
urlOffset, &parseOkay);
390
parse->attributeRequest.scope = SLPv2MsgParserGetString(packet, len,
391
slOffset, &parseOkay);
392
parse->attributeRequest.tagList = SLPv2MsgParserGetString(packet, len,
393
tagOffset, &parseOkay);
394
parse->attributeRequest.spi = SLPv2MsgParserGetString(packet, len,
395
spiOffset, &parseOkay);
406
*-----------------------------------------------------------------------------
408
* SLPv2MsgParserParseAttributeReply -
410
* Populates the SLPv2_Parse structure with SLPv2 Attribute Reply data.
413
* Returns TRUE upon success, FALSE upon memory error.
418
*-----------------------------------------------------------------------------
422
SLPv2MsgParserParseAttributeReply(char *packet, // IN
424
struct SLPv2_Parse *parse) // IN
427
uint16 attributeOffset;
428
Bool parseOkay = TRUE;
430
errorOffset = sizeof(struct SLPv2_Header) + parse->languageTagLength + 2;
431
parse->attributeReply.error = Portable_ntohs(*((uint16 *) (packet + errorOffset)));
434
attributeOffset = errorOffset + 2;
435
parse->attributeReply.attributeList = SLPv2MsgParserGetString(packet, len,
436
attributeOffset, &parseOkay);
446
*-----------------------------------------------------------------------------
448
* SLPv2MsgParser_Parse -
450
* Returns TRUE if the packet parses as a SLPv2 message.
453
* Returns TRUE upon success, FALSE upon memory error.
458
*-----------------------------------------------------------------------------
462
SLPv2MsgParser_Parse(struct SLPv2_Parse *parse, // IN
467
ASSERT(NULL != parse);
469
parseOk = SLPv2MsgParserGetHeader(packet, len, parse);
472
switch (parse->header->functionId) {
473
case SLPV2_SERVICEREQUEST:
474
parseOk = SLPv2MsgParserParseServiceRequest(packet, len, parse);
476
case SLPV2_SERVICEREPLY:
477
parseOk = SLPv2MsgParserParseServiceReply(packet, len, parse);
479
case SLPV2_ATTRIBUTEREQUEST:
480
parseOk = SLPv2MsgParserParseAttributeRequest(packet, len, parse);
482
case SLPV2_ATTRIBUTEREPLY:
483
parseOk = SLPv2MsgParserParseAttributeReply(packet, len, parse);
495
*-----------------------------------------------------------------------------
497
* SLPv2MsgParser_Destroy -
499
* Returns TRUE if the
502
* Disposes of a SLPv2_Parse structure.
507
*-----------------------------------------------------------------------------
511
SLPv2MsgParser_Destroy(struct SLPv2_Parse *parse) // IN
515
ASSERT(NULL != parse);
518
* header. We don't free(parse->header) because that's up to the caller
519
* to manage, since the caller allocated the buffer that contains the
523
parse->header = NULL;
524
free(parse->languageTag);
525
parse->languageTag = NULL;
528
* service request strings.
530
free(parse->serviceRequest.prList);
531
free(parse->serviceRequest.serviceType);
532
free(parse->serviceRequest.scope);
533
free(parse->serviceRequest.predicate);
534
free(parse->serviceRequest.spi);
535
parse->serviceRequest.prList = NULL;
536
parse->serviceRequest.serviceType = NULL;
537
parse->serviceRequest.scope = NULL;
538
parse->serviceRequest.predicate = NULL;
539
parse->serviceRequest.spi = NULL;
544
for (i=0; i < parse->serviceReply.urlCount; i++) {
545
free(parse->serviceReply.url[i]);
546
parse->serviceReply.url[i] = NULL;
548
free(parse->serviceReply.url);
553
free(parse->attributeRequest.prList);
554
free(parse->attributeRequest.url);
555
free(parse->attributeRequest.scope);
556
free(parse->attributeRequest.tagList);
557
free(parse->attributeRequest.spi);
558
parse->attributeRequest.prList = NULL;
559
parse->attributeRequest.url = NULL;
560
parse->attributeRequest.scope = NULL;
561
parse->attributeRequest.tagList = NULL;
562
parse->attributeRequest.spi = NULL;
567
free(parse->attributeReply.attributeList);
568
parse->attributeReply.attributeList = NULL;
571
} // SLPv2MsgParser_Destroy