#include <stdio.h>
#include <string.h>
#include "mslp_sd.h"
#include "slp.h"
#include "mslp.h"
#include "mslp_dat.h"
#include "mslpd_store.h"
#include "mslpd.h"
#include "mslpd_mask.h"
#include "mslpd_parse.h"
SLPInternalError srvrqst_in(Slphdr *pslphdr, const char *pcInBuf, int iInSz,
char **ppcPRList, char **ppcSrvType, char **ppcScopes,
char **ppcPredicate) {
SLPInternalError err;
int offset = HDRLEN + strlen(pslphdr->h_pcLangTag);
*ppcPRList = NULL;
*ppcSrvType = NULL;
*ppcScopes = NULL;
if ((err = get_string(pcInBuf, iInSz, &offset, ppcPRList)) < 0)
goto srvrqst_in_fail;
if ((err = get_string(pcInBuf, iInSz, &offset, ppcSrvType)) < 0)
goto srvrqst_in_fail;
if ((err = get_string(pcInBuf, iInSz, &offset, ppcScopes)) < 0)
goto srvrqst_in_fail;
if ((err = get_string(pcInBuf, iInSz, &offset, ppcPredicate)) < 0)
goto srvrqst_in_fail;
return SLP_OK;
srvrqst_in_fail:
if (*ppcPRList) SLPFree((void*)ppcPRList); *ppcPRList = NULL;
if (*ppcSrvType) SLPFree((void*)ppcSrvType); *ppcSrvType = NULL;
if (*ppcScopes) SLPFree((void*)ppcScopes); *ppcScopes = NULL;
return err;
}
SLPInternalError srvrply_out(SAStore *ps, SLPInternalError err, Mask *pm,
Slphdr *pslphdr, char **ppcOutBuf, int *piOutSz,
int *piGot) {
char* endPtr = NULL;
int iMTU = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10):1400;
int iOverflow = 0;
int iIsMcast = (pslphdr->h_usFlags & MCASTFLAG)?1:0;
int hdrsz = HDRLEN + strlen(pslphdr->h_pcLangTag);
int offset = 0;
int count = 0;
*piOutSz = hdrsz + 4;
*piGot = 0;
if (err == SLP_OK) {
int item;
mask_reset(pm);
while((item = mask_next(pm,1)) >= 0) {
count++;
*piOutSz += 6 + strlen(ps->url[item]);
}
}
if (iIsMcast && *piOutSz >= iMTU) {
*piOutSz = hdrsz + 4;
iOverflow = 1;
}
*piGot = count;
*ppcOutBuf = safe_malloc(*piOutSz, 0, 0);
if( !*ppcOutBuf ) return SLP_PARSE_ERROR;
SETVER(*ppcOutBuf,2);
SETFUN(*ppcOutBuf,SRVRPLY);
SETLEN(*ppcOutBuf,*piOutSz);
SETLANG(*ppcOutBuf,pslphdr->h_pcLangTag);
SETXID(*ppcOutBuf,pslphdr->h_usXID);
if (iOverflow) {
SETFLAGS(*ppcOutBuf,OVERFLOWFLAG);
return SLP_OK;
}
offset = hdrsz;
SETSHT(*ppcOutBuf,api2slp(err),offset); offset += 2;
if (err == SLP_OK) {
SETSHT(*ppcOutBuf,count,offset); offset += 2;
mask_reset(pm);
while (count--) {
int item = mask_next(pm,1);
offset++;
if ((err = add_sht(*ppcOutBuf,*piOutSz,
(0xFFFF & ps->life[item]),&offset)) < 0 ||
(err = add_string(*ppcOutBuf,*piOutSz,ps->url[item],&offset)) < 0) {
return err;
}
offset++;
}
}
return SLP_OK;
}
#ifdef EXTRA_MSGS
int saadvert_out(SAState *ps, Slphdr *pslph, char **ppc, int *piOutSz){
int offset = 0;
const char *pcLang = (pslph->h_pcLangTag)?pslph->h_pcLangTag:"en";
const char *pcScopeList = SLPGetProperty("net.slp.useScopes");
const char *pcSrvTypeList = SLPGetProperty("com.sun.slp.saSrvTypes");
char *pcSAAttrs;
if (!pcScopeList) pcScopeList = "";
if (!pcSrvTypeList) pcSrvTypeList = "";
pcSAAttrs = safe_malloc(strlen(pcSrvTypeList)+strlen("(service-types=")+2,
"(service-types=",strlen("(service-types="));
if( !pcSAAttrs ) return SLP_MEMORY_ALLOC_FAILED;
strcat(pcSAAttrs,pcSrvTypeList);
strcat(pcSAAttrs,")");
*piOutSz = strlen(ps->pcSAURL) + 2 + strlen(pcScopeList) + 2 + HDRLEN +
strlen(pcLang) + strlen(pcSAAttrs) + 1;
*ppc = safe_malloc(*piOutSz,0,0);
if( !*ppc ) return SLP_MEMORY_ALLOC_FAILED;
SETVER(*ppc,2);
SETFUN(*ppc,SAADVERT);
SETLEN(*ppc,*piOutSz);
SETLANG(*ppc,pslph->h_pcLangTag);
SETXID(*ppc,pslph->h_usXID);
offset = HDRLEN + strlen(pcLang);
add_string(*ppc,*piOutSz,ps->pcSAURL, &offset);
add_string(*ppc,*piOutSz,pcScopeList, &offset);
add_string(*ppc,*piOutSz,pcSAAttrs, &offset);
(*ppc)[offset] = '\0';
SLPFree(pcSAAttrs);
return SLP_OK;
}
#endif
#ifdef MAC_OS_X
int daadvert_out(SAState *ps, SLPBoolean viaTCP, Slphdr *pslph, char **ppc, int *piOutSz)
{
const char * pcAttributeList = "";
char* advertMessage = NULL;
char* scopeListToAdvertise = (char*)malloc( strlen(SLPGetProperty("com.apple.slp.daScopeList")) + 1 ); SLPBoolean needToSetOverflow = SLP_FALSE;
SLP_LOG( SLP_LOG_DEBUG, "daadvert_out called");
if ( SLPGetProperty("com.apple.slp.daAttributeList") )
pcAttributeList = SLPGetProperty("com.apple.slp.daAttributeList");
if ( !viaTCP && SLPGetProperty("com.apple.slp.daPrunedScopeList") && SLPGetProperty("com.apple.slp.daPrunedScopeList") != "" )
{
strcpy( scopeListToAdvertise, SLPGetProperty("com.apple.slp.daPrunedScopeList") );
needToSetOverflow = SLP_TRUE;
}
else if ( SLPGetProperty("com.apple.slp.daScopeList") )
strcpy( scopeListToAdvertise, SLPGetProperty("com.apple.slp.daScopeList") );
else
return -1;
advertMessage = MakeDAAdvertisementMessage( pslph, ps->pcDAURL, scopeListToAdvertise, pcAttributeList, GetStatelessBootTime(), piOutSz );
if ( needToSetOverflow )
SETFLAGS(advertMessage,(unsigned char) OVERFLOWFLAG);
*ppc = advertMessage;
if ( strlen(scopeListToAdvertise) < strlen(SLPGetProperty("com.apple.slp.daScopeList")) )
{
SLP_LOG( SLP_LOG_DEBUG, "daadvert_out, advertising scopelist of size:%d out of original size:%d", strlen(scopeListToAdvertise), strlen(SLPGetProperty("com.apple.slp.daScopeList")) );
}
if ( scopeListToAdvertise )
free( scopeListToAdvertise );
return SLP_OK;
}
char* MakeDAAdvertisementMessage( Slphdr* pslph,
char* url,
const char* scopeList,
const char* attributeList,
long timeStamp,
int* outSize )
{
short urlLength =strlen( url );
short scopeListLength = strlen(scopeList);
short attributeListLength = strlen(attributeList);
const char* pcLang = (pslph && pslph->h_pcLangTag)?pslph->h_pcLangTag:"en";
char* newRequest = NULL;
char* curPtr;
short sizeofNewMessage = HDRLEN + strlen(pcLang)
+ 2 + 4 + urlLength + sizeof(urlLength)
+ scopeListLength + sizeof(scopeListLength)
+ attributeListLength + sizeof(attributeListLength)
+ 2 + 1;
if ( ServerScopeSponsoringEnabled() )
{
sizeofNewMessage += 2 + SizeOfServerScopeSponsorData(); }
newRequest = (char*)safe_malloc( sizeofNewMessage, 0, 0 );
if( newRequest )
{
SETVER(newRequest,2);
SETFUN(newRequest, DAADVERT);
SETLEN(newRequest, sizeofNewMessage);
SETLANG(newRequest,pcLang);
SETXID(newRequest, (pslph)?pslph->h_usXID:0);
curPtr = newRequest+GETHEADERLEN(newRequest);
*((short*)curPtr) = SLP_OK; curPtr += 2;
*(long*)curPtr = timeStamp; curPtr += 4;
*(short*)curPtr = urlLength;
curPtr += sizeof(urlLength); strcpy( curPtr, url ); curPtr += urlLength;
*((short*)curPtr) = scopeListLength; curPtr += sizeof(scopeListLength);
if ( scopeListLength > 0 )
strcpy( curPtr, scopeList );
curPtr += scopeListLength;
*((short*)curPtr) = attributeListLength; curPtr += sizeof(attributeListLength);
if ( attributeListLength > 0 )
strcpy( curPtr, attributeList );
curPtr += attributeListLength;
*((short*)curPtr) = 0;
curPtr += 2;
*((char*)curPtr) = 0;
curPtr += 2;
if ( ServerScopeSponsoringEnabled() )
{
memcpy( curPtr, GetServerScopeSponsorData(), SizeOfServerScopeSponsorData() ); curPtr += SizeOfServerScopeSponsorData();
}
*outSize = sizeofNewMessage;
}
else
*outSize = 0;
return newRequest;
}
#endif
unsigned char api2slp(SLPInternalError se) {
switch(se) {
case SLP_OK: return 0;
case SLP_LANGUAGE_NOT_SUPPORTED:
return LANGUAGE_NOT_SUPPORTED;
case SLP_PARSE_ERROR:
return PARSE_ERROR;
case SLP_SCOPE_NOT_SUPPORTED:
return SCOPE_NOT_SUPPORTED;
default: return INTERNAL_ERROR;
}
}