/** Formats and sends an SLPFindSrvs wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPFindSrvs. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvRqst(SLPHandleInfo * handle) { uint8_t * buf; uint8_t * curpos; SLPError serr; size_t spistrlen = 0; char * spistr = 0; struct sockaddr_storage peeraddr; struct sockaddr_in* destaddrs = 0; sockfd_t sock = SLP_INVALID_SOCKET; /* Is this a special attempt to locate DAs? */ if (strncasecmp(handle->params.findsrvs.srvtype, SLP_DA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) == 0) { KnownDAProcessSrvRqst(handle); return 0; } #ifdef ENABLE_SLPv2_SECURITY if (SLPPropertyAsBoolean("net.slp.securityEnabled")) SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); #endif /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <service-type> | <service-type> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of predicate string | Service Request <predicate> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <SLP SPI> string | <SLP SPI> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ buf = curpos = xmalloc( + 2 + handle->params.findsrvs.srvtypelen + 2 + handle->params.findsrvs.scopelistlen + 2 + handle->params.findsrvs.predicatelen + 2 + spistrlen); if (buf == 0) { xfree(spistr); return SLP_MEMORY_ALLOC_FAILED; } /* <service-type> */ PutL16String(&curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); /* <scope-list> */ PutL16String(&curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); /* predicate string */ PutL16String(&curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); /* <SLP SPI> */ PutL16String(&curpos, (char *)spistr, spistrlen); /* Call the RqstRply engine. */ do { #ifndef UNICAST_NOT_SUPPORTED if (handle->dounicast == 1) { serr = NetworkUcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); break; } if (SLPNetIsIPV4()) { if (KnownDASpanningListFromCache(handle, (int)handle->params.findsrvs.scopelistlen, handle->params.findsrvs.scopelist, &destaddrs) > 0) { serr = NetworkMultiUcastRqstRply(destaddrs, handle->langtag, (char*)buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); xfree(destaddrs); break; } } #endif if (strncasecmp(handle->params.findsrvs.srvtype, SLP_SA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) != 0) sock = NetworkConnectToDA(handle, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); if (sock == SLP_INVALID_SOCKET) { /* Use multicast as a last resort. */ serr = NetworkMcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, 0, false); break; } serr = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); if (serr) NetworkDisconnectDA(handle); } while (serr == SLP_NETWORK_ERROR); xfree(buf); xfree(spistr); return serr; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = -1; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int spistrlen = 0; char* spistr = 0; #endif /*------------------------------------------*/ /* Is this a special attempt to locate DAs? */ /*------------------------------------------*/ if(strncasecmp(handle->params.findsrvs.srvtype, SLP_DA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) == 0) { KnownDAProcessSrvRqst(handle); goto FINISHED; } #ifdef ENABLE_SLPv2_SECURITY if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvs.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.predicatelen + 2; /* 2 bytes for len field */ bufsize += 2; /* 2 bytes for spistr len*/ #ifdef ENABLE_SLPv2_SECURITY bufsize += spistrlen; #endif buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,handle->params.findsrvs.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); curpos = curpos + handle->params.findsrvs.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.findsrvs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); curpos = curpos + handle->params.findsrvs.scopelistlen; /* predicate */ ToUINT16(curpos,handle->params.findsrvs.predicatelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); curpos = curpos + handle->params.findsrvs.predicatelen; #ifdef ENABLE_SLPv2_SECURITY ToUINT16(curpos,spistrlen); curpos = curpos + 2; memcpy(curpos,spistr,spistrlen); curpos = curpos + spistrlen; #else ToUINT16(curpos,0); #endif /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { #ifndef UNICAST_NOT_SUPPORTED if ( handle->dounicast == 1 ) { void *cookie = (PSLPHandleInfo) handle; result = NetworkUcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, cookie); break; } else #endif if(strncasecmp(handle->params.findsrvs.srvtype, SLP_SA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen)) { sock = NetworkConnectToDA(handle, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); } if(sock == -1) { /* use multicast as a last resort */ #ifndef MI_NOT_SUPPORTED result = NetworkMcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, NULL); #else result = NetworkMcastRqstRply(handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); #endif /* MI_NOT_SUPPORTED */ break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(spistr) xfree(spistr); #endif return result; }
/** Formats and sends an SLPFindSrvTypes wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPFindSrvTypes. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvTypeRqst(SLPHandleInfo * handle) { sockfd_t sock; uint8_t * buf; uint8_t * curpos; SLPError serr = SLP_OK; struct sockaddr_storage peeraddr; /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of Naming Authority | <Naming Authority String> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ /** @todo Ensure that we don't exceed the MTU. */ buf = curpos = xmalloc( + 2 + handle->params.findsrvtypes.namingauthlen + 2 + handle->params.findsrvtypes.scopelistlen); if (buf == 0) return SLP_MEMORY_ALLOC_FAILED; /* Naming Authority */ if (strcmp(handle->params.findsrvtypes.namingauth, "*") == 0) PutUINT16(&curpos, 0xffff); /* 0xffff is wildcard */ else PutL16String(&curpos, handle->params.findsrvtypes.namingauth, handle->params.findsrvtypes.namingauthlen); /* <scope-list> */ PutL16String(&curpos, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen); /* Send request, receive reply. */ do { #ifndef UNICAST_NOT_SUPPORTED if (handle->dounicast == 1) { serr = NetworkUcastRqstRply(handle, buf, SLP_FUNCT_SRVTYPERQST, curpos - buf, ProcessSrvTypeRplyCallback, handle); break; } #endif sock = NetworkConnectToDA(handle, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen, &peeraddr); if (sock == SLP_INVALID_SOCKET) { serr = NetworkMcastRqstRply(handle, buf, SLP_FUNCT_SRVTYPERQST, curpos - buf, ProcessSrvTypeRplyCallback, 0); break; } serr = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVTYPERQST, curpos - buf, ProcessSrvTypeRplyCallback, handle); if (serr) NetworkDisconnectDA(handle); } while (serr == SLP_NETWORK_ERROR); xfree(buf); return serr; }