📄 slp_v1message.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol *//* *//* File: slp_v1message.c *//* *//* Abstract: Source file specific to the SLPv1 wire protocol messages. *//* *//*-------------------------------------------------------------------------*//* *//* This program is free software; you can redistribute it and/or modify it *//* under the terms of the GNU Lesser General Public License as published *//* by the Free Software Foundation; either version 2.1 of the License, or *//* (at your option) any later version. *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU Lesser General Public License for more details. *//* *//* You should have received a copy of the GNU Lesser General Public *//* License along with this program; see the file COPYING. If not, *//* please obtain a copy from http://www.gnu.org/copyleft/lesser.html *//* *//*-------------------------------------------------------------------------*//* *//* Please submit patches to http://www.openslp.org *//* *//***************************************************************************/#include <string.h>#include <ctype.h>#ifndef _WIN32#include <stdlib.h>#include <sys/types.h>#include <netinet/in.h>#endif#include "slp_v1message.h"#include "slp_utf8.h"#include "slp_compare.h"/* Implementation Note: * * This file duplicates the parsing routines in slp_message.c. Even * though the format of the messages are mostly identical, handling of * the character encoding makes it enough of a problem to keep this * code independent. * * Unicode handling is currently a hack. We assume that we have enough * space the UTF-8 string in place instead of the unicode string. This * assumption is not always correct 16-bit unicode encoding. *//*=========================================================================*/int SLPv1MessageParseHeader(SLPBuffer buffer, SLPHeader* header)/* *//* Returns - Zero on success, SLP_ERROR_VER_NOT_SUPPORTED, or *//* SLP_ERROR_PARSE_ERROR. *//*=========================================================================*/{ if (buffer->end - buffer->start < 12) { /* invalid length 12 bytes is the smallest v1 message*/ return SLP_ERROR_PARSE_ERROR; } header->version = *(buffer->curpos); header->functionid = *(buffer->curpos + 1); header->length = AsUINT16(buffer->curpos + 2); header->flags = *(buffer->curpos + 4); header->encoding = AsUINT16(buffer->curpos + 8); header->extoffset = 0; /* not used for SLPv1 */ header->xid = AsUINT16(buffer->curpos + 10); header->langtaglen = 2; header->langtag = buffer->curpos + 6; if(header->functionid > SLP_FUNCT_SRVTYPERQST) { /* invalid function id */ return SLP_ERROR_PARSE_ERROR; } if(header->encoding != SLP_CHAR_ASCII && header->encoding != SLP_CHAR_UTF8 && header->encoding != SLP_CHAR_UNICODE16 && header->encoding != SLP_CHAR_UNICODE32) { return SLP_ERROR_CHARSET_NOT_UNDERSTOOD; } if(header->length != buffer->end - buffer->start) { return SLP_ERROR_PARSE_ERROR; } /* TODO - do something about the other flags */ if(header->flags & 0x07) { /* invalid flags */ return SLP_ERROR_PARSE_ERROR; } buffer->curpos += 12; return 0;}/*--------------------------------------------------------------------------*/int v1ParseUrlEntry(SLPBuffer buffer, SLPHeader* header, SLPUrlEntry* urlentry)/* *//* Returns - Zero on success, SLP_ERROR_INTERNAL_ERROR (out of memory) or *//* SLP_ERROR_PARSE_ERROR. *//*--------------------------------------------------------------------------*/{ int result; /* make sure that min size is met */ if(buffer->end - buffer->curpos < 4) { return SLP_ERROR_PARSE_ERROR; } /* no reserved stuff for SLPv1 */ urlentry->reserved = 0; /* 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 > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } urlentry->url = buffer->curpos; buffer->curpos = buffer->curpos + urlentry->urllen; result = SLPv1AsUTF8(header->encoding, (char *) urlentry->url, &urlentry->urllen); if(result) { return result; } /* we don't support auth blocks for SLPv1 - no one uses them anyway */ urlentry->authcount = 0; urlentry->autharray = 0; return 0;}/*--------------------------------------------------------------------------*/int v1ParseSrvRqst(SLPBuffer buffer, SLPHeader* header, SLPSrvRqst* srvrqst)/*--------------------------------------------------------------------------*/{ char *tmp; int result; /* make sure that min size is met */ if(buffer->end - buffer->curpos < 4) { 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; result = SLPv1AsUTF8(header->encoding, (char *) srvrqst->prlist, &srvrqst->prlistlen); if(result) return result; /* parse the predicate string */ srvrqst->predicatelen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvrqst->predicatelen > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvrqst->predicate = buffer->curpos; buffer->curpos = buffer->curpos + srvrqst->predicatelen; result = SLPv1AsUTF8(header->encoding, (char *) srvrqst->predicate, &srvrqst->predicatelen); if(result) { return result; } /* null terminate the predicate */ * (char *) (srvrqst->predicate + srvrqst->predicatelen) = '\0'; /* Now split out the service type */ srvrqst->srvtype = srvrqst->predicate; tmp = strchr(srvrqst->srvtype, '/'); if(!tmp) return SLP_ERROR_PARSE_ERROR; *tmp = 0; /* null terminate service type */ srvrqst->srvtypelen = tmp - srvrqst->srvtype; /* Parse out the predicate */ srvrqst->predicatever = 1; /* SLPv1 predicate (a bit messy) */ srvrqst->predicatelen -= srvrqst->srvtypelen + 1; srvrqst->predicate += srvrqst->srvtypelen + 1; /* Now split out the scope (if any) */ /* Special case DA discovery, empty scope is allowed here */ if(*srvrqst->predicate == '/' && SLPCompareString(srvrqst->srvtypelen, srvrqst->srvtype, 15, "directory-agent") != 0) { /* no scope - so set default scope */ srvrqst->scopelist = "default"; srvrqst->scopelistlen = 7; srvrqst->predicate++; srvrqst->predicatelen--; } else { srvrqst->scopelist = srvrqst->predicate; tmp = strchr(srvrqst->scopelist, '/'); if(!tmp) return SLP_ERROR_PARSE_ERROR; /* null terminate scope list */ *tmp = 0; srvrqst->scopelistlen = tmp - srvrqst->scopelist; srvrqst->predicate += srvrqst->scopelistlen + 1; srvrqst->predicatelen -= srvrqst->scopelistlen + 1; } srvrqst->predicatelen--; tmp = (char*)(srvrqst->predicate + srvrqst->predicatelen); /* null term. pred */ *tmp = 0; /* SLPv1 service requests don't have SPI strings */ srvrqst->spistrlen = 0; srvrqst->spistr = 0; return 0;}/*--------------------------------------------------------------------------*/int v1ParseSrvReg(SLPBuffer buffer, SLPHeader* header, SLPSrvReg* srvreg)/*--------------------------------------------------------------------------*/{ char *tmp; int result; /* Parse out the url entry */ result = v1ParseUrlEntry(buffer, header, &(srvreg->urlentry)); if(result) { return result; } /* SLPv1 registration requests don't have a separate service type. They must be parsed from the url */ srvreg->srvtype = srvreg->urlentry.url; tmp = strstr(srvreg->srvtype, ":/"); if(!tmp) return SLP_ERROR_PARSE_ERROR; srvreg->srvtypelen = tmp - srvreg->srvtype; /* parse the attribute list */ if(buffer->end - buffer->curpos < 2) { return SLP_ERROR_PARSE_ERROR; } srvreg->attrlistlen = AsUINT16(buffer->curpos); buffer->curpos = buffer->curpos + 2; if(srvreg->attrlistlen > buffer->end - buffer->curpos) { return SLP_ERROR_PARSE_ERROR; } srvreg->attrlist = buffer->curpos; buffer->curpos = buffer->curpos + srvreg->attrlistlen; result = SLPv1AsUTF8(header->encoding, (char *) srvreg->attrlist, &srvreg->attrlistlen); if(result) { return result; } /* SLPv1 registration requests don't include a scope either. The scope is included in the attribute list */ if((tmp = strstr(srvreg->attrlist, "SCOPE")) || (tmp = strstr(srvreg->attrlist, "scope"))) { tmp += 5; /* go past the scope */ while(*tmp && (isspace((unsigned char)*tmp) || *tmp == '=')) tmp++; /* go past = and white space */ srvreg->scopelist = tmp; while(*tmp && !isspace((unsigned char)*tmp) && *tmp != ')') tmp++; /* find end of scope */ srvreg->scopelistlen = tmp - srvreg->scopelist; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -