📄 slp_message.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol *//* *//* File: slp_message.h *//* *//* Abstract: Header file that defines structures and constants that are *//* specific to the SLP wire protocol messages. *//* *//*-------------------------------------------------------------------------*//* *//* Please submit patches to http://www.openslp.org *//* *//*-------------------------------------------------------------------------*//* *//* Copyright (C) 2000 Caldera Systems, Inc *//* All rights reserved. *//* *//* Redistribution and use in source and binary forms, with or without *//* modification, are permitted provided that the following conditions are *//* met: */ /* *//* Redistributions of source code must retain the above copyright *//* notice, this list of conditions and the following disclaimer. *//* *//* Redistributions in binary form must reproduce the above copyright *//* notice, this list of conditions and the following disclaimer in *//* the documentation and/or other materials provided with the *//* distribution. *//* *//* Neither the name of Caldera Systems nor the names of its *//* contributors may be used to endorse or promote products derived *//* from this software without specific prior written permission. *//* *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* *//***************************************************************************/#include "slp_message.h"#include "slp_xmalloc.h"#ifndef _WIN32#include <sys/types.h>#include <netinet/in.h>#endif#if defined(ENABLE_SLPv1)#include <slp_v1message.h>#endif/*=========================================================================*/int SLPMessageParseHeader(SLPBuffer buffer, SLPHeader* header)/* Fill out a header structure with what ever is in the buffer *//* *//* buffer (IN) the buffer to be parsed *//* *//* header (IN/OUT) pointer to the header structure to fill out *//*=========================================================================*/{ if (buffer->end - buffer->start < 2) { return SLP_ERROR_PARSE_ERROR; } header->version = *(buffer->curpos); header->functionid = *(buffer->curpos + 1); if(header->version != 2) { return SLP_ERROR_VER_NOT_SUPPORTED; } /* check for invalid length 18 bytes is the smallest v2 message*/ if (buffer->end - buffer->start < 18) { return SLP_ERROR_PARSE_ERROR; } header->length = AsUINT24(buffer->curpos + 2); header->flags = AsUINT16(buffer->curpos + 5); header->encoding = 0; /* not used for SLPv2 */ header->extoffset = AsUINT24(buffer->curpos + 7); header->xid = AsUINT16(buffer->curpos + 10); header->langtaglen = AsUINT16(buffer->curpos + 12); header->langtag = buffer->curpos + 14; /* check for invalid function id */ if(header->functionid > SLP_FUNCT_SAADVERT) { return SLP_ERROR_PARSE_ERROR; } if(header->length != buffer->end - buffer->start) { return SLP_ERROR_PARSE_ERROR; } /* check for invalid flags */ if(header->flags & 0x1fff) { return SLP_ERROR_PARSE_ERROR; } buffer->curpos = buffer->curpos + header->langtaglen + 14; /* check for invalid langtaglen */ if((void*)(header->langtag + header->langtaglen) > (void*)buffer->end) { return SLP_ERROR_PARSE_ERROR; } /* check for invalid ext offset */ if(buffer->start + header->extoffset > buffer->end) { return SLP_ERROR_PARSE_ERROR; } return 0;}/*--------------------------------------------------------------------------*/int ParseAuthBlock(SLPBuffer buffer, SLPAuthBlock* authblock)/* Returns - Zero on success, SLP_ERROR_INTERNAL_ERROR (out of memory) or *//* SLP_ERROR_PARSE_ERROR. *//*--------------------------------------------------------------------------*/{ /* make sure that min size is met */ if(buffer->end - buffer->curpos < 10) { return SLP_ERROR_PARSE_ERROR; } authblock->opaque = buffer->curpos; authblock->bsd = AsUINT16(buffer->curpos); authblock->length = AsUINT16(buffer->curpos + 2); if(authblock->length > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } authblock->timestamp = AsUINT32(buffer->curpos + 4); authblock->spistrlen = AsUINT16(buffer->curpos + 8); authblock->spistr = buffer->curpos + 10; if(authblock->spistrlen > buffer->end - buffer->curpos + 10) { return SLP_ERROR_PARSE_ERROR; } authblock->authstruct = buffer->curpos + authblock->spistrlen + 10; authblock->opaquelen = authblock->length; buffer->curpos = buffer->curpos + authblock->length; return 0;}/*--------------------------------------------------------------------------*/int ParseUrlEntry(SLPBuffer buffer, SLPUrlEntry* urlentry)/* *//* Returns - Zero on success, SLP_ERROR_INTERNAL_ERROR (out of memory) or *//* SLP_ERROR_PARSE_ERROR. *//*--------------------------------------------------------------------------*/{ int result; int i; /* make sure that min size is met */ if(buffer->end - buffer->curpos < 6) { return SLP_ERROR_PARSE_ERROR; } urlentry->opaque = buffer->curpos; /* parse out reserved */ urlentry->reserved = *(buffer->curpos); buffer->curpos = buffer->curpos + 1; /* parse out lifetime */ urlentry->lifetime = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; /* parse out url */ urlentry->urllen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(urlentry->urllen + 1 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } urlentry->url = buffer->curpos; buffer->curpos = buffer->curpos + urlentry->urllen; /* parse out auth block count */ urlentry->authcount = *(buffer->curpos); buffer->curpos = buffer->curpos + 1; /* parse out the auth block (if any) */ if(urlentry->authcount) { urlentry->autharray = (SLPAuthBlock*)xmalloc(sizeof(SLPAuthBlock) * urlentry->authcount); if(urlentry->autharray == 0) { return SLP_ERROR_INTERNAL_ERROR; } memset(urlentry->autharray,0,sizeof(SLPAuthBlock) * urlentry->authcount); for(i=0;i<urlentry->authcount;i++) { result = ParseAuthBlock(buffer,&(urlentry->autharray[i])); if(result) return result; } } urlentry->opaquelen = (char*)buffer->curpos - urlentry->opaque; return 0;}/*--------------------------------------------------------------------------*/int ParseSrvRqst(SLPBuffer buffer, SLPSrvRqst* srvrqst)/*--------------------------------------------------------------------------*/{ /* make sure that min size is met */ if(buffer->end - buffer->curpos < 10) { return SLP_ERROR_PARSE_ERROR; } /* parse the prlist */ srvrqst->prlistlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->prlistlen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->prlist = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->prlistlen; /* parse the service type */ srvrqst->srvtypelen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->srvtypelen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->srvtype = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->srvtypelen; /* parse the scope list */ srvrqst->scopelistlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->scopelistlen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->scopelist = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->scopelistlen; /* parse the predicate string */ srvrqst->predicatever = 2; /* SLPv2 predicate (LDAPv3) */ srvrqst->predicatelen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->predicatelen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->predicate = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->predicatelen; /* parse the slpspi string */ srvrqst->spistrlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->spistrlen > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->spistr = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->spistrlen; return 0;}/*--------------------------------------------------------------------------*/int ParseSrvRply(SLPBuffer buffer, SLPSrvRply* srvrply)/*--------------------------------------------------------------------------*/{ int result; int i; /* make sure that min size is met */ if(buffer->end - buffer->curpos < 4) { return SLP_ERROR_PARSE_ERROR; } /* parse out the error code */ srvrply->errorcode = AsUINT16(buffer->curpos); if(srvrply->errorcode) { /* We better not trust the rest of the packet */ memset( srvrply, 0, sizeof(SLPSrvRply)); srvrply->errorcode = AsUINT16(buffer->curpos); return 0; } buffer->curpos = buffer->curpos + 2; /* parse out the url entry count */ srvrply->urlcount = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; /* parse out the url entries (if any) */ if(srvrply->urlcount) { srvrply->urlarray = (SLPUrlEntry*)xmalloc(sizeof(SLPUrlEntry) * srvrply->urlcount); if(srvrply->urlarray == 0) { return SLP_ERROR_INTERNAL_ERROR; } memset(srvrply->urlarray,0,sizeof(SLPUrlEntry) * srvrply->urlcount); for(i=0;i<srvrply->urlcount;i++) { result = ParseUrlEntry(buffer,&(srvrply->urlarray[i])); if(result) return result; } } else { srvrply->urlarray = 0; } return 0;}/*--------------------------------------------------------------------------*/int ParseSrvReg(SLPBuffer buffer, SLPSrvReg* srvreg)/*--------------------------------------------------------------------------*/{ int result; int i; /* Parse out the url entry */ result = ParseUrlEntry(buffer,&(srvreg->urlentry)); if(result) { return result; } if(buffer->end - buffer->curpos < 2) { return SLP_ERROR_PARSE_ERROR; } /* parse the service type */ srvreg->srvtypelen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvreg->srvtypelen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvreg->srvtype = buffer->curpos; buffer->curpos = buffer->curpos + srvreg->srvtypelen; /* parse the scope list */ srvreg->scopelistlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvreg->scopelistlen + 2 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvreg->scopelist = buffer->curpos; buffer->curpos = buffer->curpos + srvreg->scopelistlen; /* parse the attribute list*/ srvreg->attrlistlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvreg->attrlistlen + 1 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvreg->attrlist = buffer->curpos; buffer->curpos = buffer->curpos + srvreg->attrlistlen; /* parse out attribute auth block count */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -