/** 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; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = 0; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; /*-------------------------------------------------------------------*/ /* 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*/ /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)malloc(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; /* TODO: add spi list stuff here later*/ ToUINT16(curpos,0); /*---------------------------------------*/ /* Connect to DA, multicast or broadcast */ /*---------------------------------------*/ sock = NetworkConnectToDA(handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); if(sock < 0) { sock = NetworkConnectToMulticast(&peeraddr); if(sock < 0) { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, CallbackSrvRqst, handle); FINISHED: if(buf) free(buf); return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvTypeRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVTYPERQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvtypes.namingauthlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvtypes.scopelistlen + 2; /* 2 bytes for len field */ /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*----------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVTYPERQST */ /*----------------------------------------------------------------*/ /* naming authority */ if(strcmp(handle->params.findsrvtypes.namingauth, "*") == 0) { ToUINT16(curpos,0xffff); /* 0xffff indicates all service types */ curpos += 2; bufsize--; /* '*' is not put on the wire */ } else { ToUINT16(curpos,handle->params.findsrvtypes.namingauthlen); curpos += 2; memcpy(curpos, handle->params.findsrvtypes.namingauth, handle->params.findsrvtypes.namingauthlen); curpos += handle->params.findsrvtypes.namingauthlen; } /* scope list */ ToUINT16(curpos,handle->params.findsrvtypes.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen); curpos = curpos + handle->params.findsrvtypes.scopelistlen; /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToDA(handle, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen, &peeraddr); if(sock == -1) { /* use multicast as a last resort */ result = NetworkMcastRqstRply(handle->langtag, buf, SLP_FUNCT_SRVTYPERQST, bufsize, ProcessSrvTypeRplyCallback, handle); break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVTYPERQST, bufsize, ProcessSrvTypeRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessAttrRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int spistrlen = 0; char* spistr = 0; 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 ATTRRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findattrs.urllen + 2; /* 2 bytes for len field */ bufsize += handle->params.findattrs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findattrs.taglistlen + 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 ATTRRQST*/ /*------------------------------------------------------------*/ /* url */ ToUINT16(curpos,handle->params.findattrs.urllen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.url, handle->params.findattrs.urllen); curpos = curpos + handle->params.findattrs.urllen; /* scope list */ ToUINT16(curpos,handle->params.findattrs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.scopelist, handle->params.findattrs.scopelistlen); curpos = curpos + handle->params.findattrs.scopelistlen; /* taglist */ ToUINT16(curpos,handle->params.findattrs.taglistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.taglist, handle->params.findattrs.taglistlen); curpos = curpos + handle->params.findattrs.taglistlen; #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 { sock = NetworkConnectToDA(handle, handle->params.findattrs.scopelist, handle->params.findattrs.scopelistlen, &peeraddr); if(sock == -1) { /* use multicast as a last resort */ result = NetworkMcastRqstRply(handle->langtag, buf, SLP_FUNCT_ATTRRQST, bufsize, ProcessAttrRplyCallback, handle); break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_ATTRRQST, bufsize, ProcessAttrRplyCallback, 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; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvDeReg(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = 0; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVREG */ /*-------------------------------------------------------------------*/ bufsize += handle->params.dereg.scopelistlen + 2; /* 2 bytes for len field*/ bufsize += handle->params.dereg.urllen + 8; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += 2; /* 2 bytes for taglistlen*/ /* TODO: Fix this for authentication */ buf = curpos = (char*)malloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVDEREG*/ /*------------------------------------------------------------*/ /* scope list */ ToUINT16(curpos,handle->params.dereg.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.dereg.scopelist, handle->params.dereg.scopelistlen); curpos = curpos + handle->params.dereg.scopelistlen; /* url-entry reserved */ *curpos = 0; curpos = curpos + 1; /* url-entry lifetime */ ToUINT16(curpos, 0); curpos = curpos + 2; /* url-entry urllen */ ToUINT16(curpos,handle->params.dereg.urllen); curpos = curpos + 2; /* url-entry url */ memcpy(curpos, handle->params.dereg.url, handle->params.dereg.urllen); curpos = curpos + handle->params.dereg.urllen; /* url-entry authcount */ *curpos = 0; curpos = curpos + 1; /* TODO: put in urlentry authentication stuff */ /* tag list */ /* TODO: put in taglist stuff */ ToUINT16(curpos,0); /*---------------------------------------*/ /* Connect to slpd or a DA */ /*---------------------------------------*/ sock = NetworkConnectToSlpd(&peeraddr); if(sock < 0) { sock = NetworkConnectToDA(handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVDEREG, bufsize, CallbackSrvDeReg, handle); FINISHED: if(buf) free(buf); 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; }