#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "mslp_sd.h"
#include "slp.h"
#include "mslp_dat.h"
#include "mslp.h"
#include "mslplib.h"
SLPInternalError active_da_discovery(SLPHandle hSLP, time_t tWait, SOCKET sd, int iMTU,
struct sockaddr_in sin,
const char *pcScopeList,
void *pvUser, void *pvCallback, CBType cbt)
{
SLPInternalError err;
int iNoSA = 0;
char *pcSendBuf = safe_malloc(iMTU,0,0);
char *pcRecvBuf = safe_malloc(RECVMTU,0,0);
const char *pcNOSA = SLPGetProperty("com.sun.slp.noSA");
char* endPtr = NULL;
if (!(err = generate_srvrqst(pcSendBuf,&iMTU,"en",pcScopeList, "service:directory-agent","")))
{
if (pcNOSA && !SDstrcasecmp(SLPGetProperty("com.sun.slp.noSA"),"true"))
{
iNoSA = 1;
SLPSetProperty("com.sun.slp.noSA",NULL);
}
SETFLAGS(pcSendBuf,(unsigned char) MCASTFLAG);
const char* multicastTTL = SLPGetProperty("net.slp.multicastTTL");
err = get_converge_result(tWait,sd,pcSendBuf,iMTU,pcRecvBuf,RECVMTU,sin, (multicastTTL)?(unsigned char) strtol(multicastTTL, &endPtr, 10):255, pvUser,hSLP,pvCallback,cbt);
if (iNoSA)
{
SLPSetProperty("com.sun.slp.noSA","true");
}
}
SLPFree(pcSendBuf);
SLPFree(pcRecvBuf);
#ifdef ENABLE_SLP_LOGGING
if (err != SLP_OK)
SLP_LOG(SLP_LOG_DEBUG,"active_da_discovery failed",err);
#endif
return err;
}
SLPInternalError handle_daadvert_in(const char *pcSendBuf,
const char *pcRecvBuf, int iRecvSz,
void *pvUser, SLPHandle hSLP,
void *pvCallback, CBType cbCallbackType)
{
int offset = 0;
int iTemp = 0;
int iErrorCode = 0;
char *pcURL = NULL, *pcScopes = NULL;
DATable *pdat = GetGlobalDATable();
SLPInternalError err = SLP_OK;
struct sockaddr_in sinDA;
long lBootTime;
Slphdr slph;
char *pcDAAttrs;
if ( !pdat )
return SLP_OK;
if(!pdat || !pcRecvBuf || !pvCallback || !(cbCallbackType == SLPDAADVERT_CALLBACK)) return SLP_PARSE_ERROR;
if ((err= get_header(pcSendBuf, pcRecvBuf, iRecvSz, &slph, &offset)) !=SLP_OK)
{
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_header failed",err);
}
if ( slph.h_iOffset > 0 )
{
int extOffset = slph.h_iOffset, extID = 0;
if ((err = get_sht(pcRecvBuf,iRecvSz,&extOffset,&extID)) != SLP_OK)
{
SLP_LOG( SLP_LOG_ERR, "handle_daadvert_in, get_sht extension id failed: %s", slperror(err) );
}
else
{
if ( extID == SCOPE_SPONSER_EXTENSION_ID )
{
long extLength;
char* scopeToUse = NULL;
if ( extOffset )
extLength = extOffset - slph.h_iOffset;
else
extLength = slph.h_ulLen - slph.h_iOffset;
extLength -= 2;
scopeToUse = safe_malloc( extLength+1, pcRecvBuf+extOffset, extLength );
if( !scopeToUse ) return SLP_PARSE_ERROR;
#ifdef ENABLE_SLP_LOGGING
SLP_LOG( SLP_LOG_DA, "Received manditory scope to use for registration: %s", scopeToUse );
#endif
}
}
}
if ((err = get_sht(pcRecvBuf,iRecvSz,&offset,&iErrorCode)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_sht errcode",err);
}
if ((err = get_sht(pcRecvBuf,iRecvSz,&offset,&iTemp)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_long boot time, sht 1",err);
}
lBootTime = (0xffff & iTemp)<<16;
if ((err = get_sht(pcRecvBuf,iRecvSz,&offset,&iTemp)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_long boot time, sht 1",err);
}
lBootTime += (0xffff & iTemp);
if ((err = get_string(pcRecvBuf,iRecvSz,&offset,&pcURL)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_string sa url",err);
}
else if ((err = get_string(pcRecvBuf,iRecvSz, &offset,&pcScopes)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
SLPFree(pcURL);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_string scopes",err);
}
if ((err = get_string(pcRecvBuf,iRecvSz,&offset,&pcDAAttrs)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
SLPFree(pcURL);
SLPFree(pcScopes);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in: get_string da attributes",err);
}
if ((err = get_sin_from_url(pcURL,strlen(pcURL),&sinDA)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
SLPFree(pcURL);
SLPFree(pcScopes);
SLPFree(pcDAAttrs);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_daadvert_in get_sin da",err);
}
if (pvCallback != NULL)
{
SLPDAAdvertCallback *psdaac = (SLPDAAdvertCallback *) pvCallback;
#ifdef ENABLE_SLP_LOGGING
SLP_LOG( SLP_LOG_DEBUG,"handle_daadvert_in calling callback");
#endif
psdaac(hSLP,iErrorCode,sinDA,pcScopes,pcDAAttrs,lBootTime,(void*)pdat);
}
else
err = (SLPInternalError) iTemp;
SLPFree(slph.h_pcLangTag);
SLPFree(pcURL);
SLPFree(pcScopes);
SLPFree(pcDAAttrs);
return SLP_OK;
}
#ifdef EXTRA_MSGS
SLPInternalError active_sa_discovery(SLPHandle hSLP, const char *pcTypeHint)
{
int iErr;
SLPInternalError err;
int iNoSA = 0;
char* endPtr = NULL;
int iWait = strtol(SLPGetProperty("net.slp.multicastMaximumWait"), &endPtr, 10);
int iMTU = strtol(SLPGetProperty("net.slp.MTU"), &endPtr, 10);
char *pcSendBuf = safe_malloc(iMTU,0,0);
char *pcRecvBuf = safe_malloc(RECVMTU,0,0);
char pcRqst[120];
struct sockaddr_in sin;
DATable *pdat = GetGlobalDATable();
SOCKET sd = socket(AF_INET, SOCK_DGRAM, 0);
const char *pcIsBCast = SLPGetProperty("net.slp.isBroadcastOnly");
const char *pcIsNoSA = SLPGetProperty("com.sun.slp.noSA");
if (sd < 0 || sd == SOCKET_ERROR)
{
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"active_sa_discovery: socket",SLP_NETWORK_INIT_FAILED); }
memset(&sin,0,sizeof sin);
sin.sin_family = AF_INET;
sin.sin_port = htons(SLP_PORT);
if (pcIsBCast && !(SDstrcasecmp(pcIsBCast,"true")))
{
int f = 1;
iErr = setsockopt(sd,SOL_SOCKET,SO_BROADCAST,(char*)&f,sizeof(f));
if (iErr)
{
CLOSESOCKET(sd);
mslplog(SLP_LOG_FAIL, "mslpd_init_network: set broadcast option",strerror(errno));
}
sin.sin_addr.s_addr = BROADCAST;
}
else
{
sin.sin_addr.s_addr = SLP_MCAST;
if ((err = set_multicast_sender_interf(sd)) != SLP_OK)
{
CLOSESOCKET(sd);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_FAIL,"mslpd_init_network: set_multicast_sender_interf",err);
}
}
if ((pcRqst != NULL) && (strlen(pcRqst) > 0))
{
sprintf(pcRqst,"(service-type=%s)",pcTypeHint);
}
else
{
pcRqst[0] = '\0';
}
if (!(err = generate_srvrqst(pcSendBuf,&iMTU,"en","", "service:service-agent",pcRqst)))
{
if (pcIsNoSA && !SDstrcasecmp(pcIsNoSA,"true"))
{
iNoSA = 1;
SLPSetProperty("com.sun.slp.noSA",NULL);
}
SETFLAGS(pcSendBuf,(unsigned char) MCASTFLAG);
err = get_converge_result(iWait, sd, pcSendBuf, iMTU, pcRecvBuf, RECVMTU, sin, (unsigned char) strtol(SLPGetProperty("net.slp.multicastTTL"), &endPtr, 10), (void*)pdat, hSLP, (void*) handle_saadvert_in, SLPSAADVERT_CALLBACK);
if (iNoSA)
{
SLPSetProperty("com.sun.slp.noSA","true");
}
}
SLPFree(pcSendBuf);
SLPFree(pcRecvBuf);
CLOSESOCKET(sd);
if (err != SLP_OK)
{
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"active_sa_discovery failed",err);
}
return err;
}
#ifdef MAC_OS_X
#ifdef EXTRA_MSGS
SLPInternalError active_sa_async_discovery(SLPHandle hSLP, SLPScopeCallback callback, void *pvUser, const char *pcTypeHint)
{
int iErr;
SLPInternalError err = SLP_OK;
int iNoSA = 0;
char* endPtr = NULL;
int iWait = (SLPGetProperty("net.slp.multicastMaximumWait"))?strtol(SLPGetProperty("net.slp.multicastMaximumWait"), &endPtr, 10):15000;
int iMTU = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"), &endPtr, 10):1400;
char *pcSendBuf = safe_malloc(iMTU,0,0);
char *pcRecvBuf = safe_malloc(RECVMTU,0,0);
char pcRqst[120];
struct sockaddr_in sin;
SOCKET sd = socket(AF_INET, SOCK_DGRAM, 0);
const char *pcIsBCast = SLPGetProperty("net.slp.isBroadcastOnly");
const char *pcIsNoSA = SLPGetProperty("com.sun.slp.noSA");
if (sd < 0 || sd == SOCKET_ERROR)
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"active_sa_async_discovery: socket",SLP_NETWORK_INIT_FAILED);
memset(&sin,0,sizeof sin);
sin.sin_family = AF_INET;
sin.sin_port = htons(SLP_PORT);
if (pcIsBCast && !(SDstrcasecmp(pcIsBCast,"true")))
{
int f = 1;
iErr = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, (char*)&f, sizeof(f));
if (iErr)
{
mslplog(SLP_LOG_FAIL, "active_sa_async_discovery: set broadcast option",strerror(errno));
err = SLP_NETWORK_INIT_FAILED;
}
sin.sin_addr.s_addr = BROADCAST;
}
else
{
sin.sin_addr.s_addr = SLP_MCAST;
if ((err = set_multicast_sender_interf(sd)) != SLP_OK)
{
mslplog(SLP_LOG_ERR,"active_sa_async_discovery: set_multicast_sender_interf",strerror(errno));
}
}
if ( !err )
{
if ((pcRqst != NULL) && (strlen(pcRqst) > 0))
{
sprintf(pcRqst,"(service-type=%s)",pcTypeHint);
}
else
{
pcRqst[0] = '\0';
}
if (!(err = generate_srvrqst(pcSendBuf, &iMTU, "en", "", "service:service-agent", pcRqst)))
{
if (pcIsNoSA && !SDstrcasecmp(pcIsNoSA,"true"))
{
iNoSA = 1;
SLPSetProperty("com.sun.slp.noSA",NULL);
}
SETFLAGS(pcSendBuf,(unsigned char) MCASTFLAG);
err = get_converge_result(iWait,sd,pcSendBuf,iMTU,pcRecvBuf,RECVMTU,sin, (unsigned char) strtol(SLPGetProperty("net.slp.multicastTTL"), &endPtr, 10),
(void*) pvUser,hSLP,(void*) callback,
SLPSAADVERT_ASYNC_CALLBACK);
if (iNoSA)
{
SLPSetProperty("com.sun.slp.noSA","true");
}
}
}
SLPFree(pcSendBuf);
SLPFree(pcRecvBuf);
CLOSESOCKET(sd);
#ifdef ENABLE_SLP_LOGGING
if (err != SLP_OK)
SLP_LOG(SLP_LOG_DEBUG,"active_sa_async_discovery failed",err);
#endif
return err;
}
#endif
#endif
SLPInternalError handle_saadvert_in(const char *pcSendBuf,
const char *pcRecvBuf, int iRecvSz,
void *pvUser, SLPHandle hSLP,
void *pvCallback, CBType cbCallbackType)
{
int offset = 0;
char *pcURL = NULL;
char *pcScopes = NULL;
char *pcAttrs = NULL;
DATable *pdat = (DATable *) pvUser;
Slphdr slph;
SLPInternalError err;
hSLP = hSLP;
#ifdef MAC_OS_X
if(!pdat || !pcRecvBuf || !pcSendBuf || !pvCallback ||
!(cbCallbackType == SLPSAADVERT_CALLBACK || cbCallbackType == SLPSAADVERT_ASYNC_CALLBACK ) ) return SLP_PARSE_ERROR;
#else
assert(pdat && pcRecvBuf && pcSendBuf && pvCallback &&
cbCallbackType == SLPSAADVERT_CALLBACK);
#endif
if ((err = get_header(pcSendBuf,pcRecvBuf,iRecvSz,&slph,&offset))!=SLP_OK)
{
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_saadvert_in get_header failed",err);
}
if ((err = get_string(pcRecvBuf,iRecvSz,&offset,&pcURL)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_saadvert_in get_string sa url",err);
}
if ((err = get_string(pcRecvBuf,iRecvSz,&offset,&pcScopes)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_saadvert_in get_string scopes",err);
}
if ((err = get_string(pcRecvBuf,iRecvSz,&offset,&pcAttrs)) != SLP_OK)
{
SLPFree(slph.h_pcLangTag);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DROP,"handle_saadvert_in get_string attrs",err);
}
dat_saadvert_in(pdat,pcScopes,pcAttrs);
SLPFree(slph.h_pcLangTag);
SLPFree(pcURL);
SLPFree(pcScopes);
SLPFree(pcAttrs);
return SLP_OK;
}
#endif