/*-------------------------------------------------------------------------*/ int KnownDADiscoveryRqstRply(int sock, struct sockaddr_in* peeraddr, int scopelistlen, const char* scopelist) /* Returns: number of *new* DAEntries found */ /*-------------------------------------------------------------------------*/ { char* buf; char* curpos; int bufsize; int result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = 31; /* 2 bytes for the srvtype length */ /* 23 bytes for "service:directory-agent" srvtype */ /* 2 bytes for scopelistlen */ /* 2 bytes for predicatelen */ /* 2 bytes for sprstrlen */ bufsize += scopelistlen; /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { return 0; } memset(buf,0,bufsize); /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,23); curpos = curpos + 2; /* 23 is the length of SLP_DA_SERVICE_TYPE */ memcpy(curpos,SLP_DA_SERVICE_TYPE,23); curpos += 23; /* scope list */ ToUINT16(curpos,scopelistlen); curpos = curpos + 2; memcpy(curpos,scopelist,scopelistlen); /* predicate zero length */ /* spi list zero length */ NetworkRqstRply(sock, peeraddr, "en", buf, SLP_FUNCT_DASRVRQST, bufsize, KnownDADiscoveryCallback, &result); xfree(buf); return result; }
/*-------------------------------------------------------------------------*/ int KnownDADiscoveryRqstRply(int sock, struct sockaddr_in* peeraddr) /*-------------------------------------------------------------------------*/ { int result = 0; char* buf; char* curpos; int bufsize; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = 31; /* 2 bytes for the srvtype length */ /* 23 bytes for "service:directory-agent" srvtype */ /* 2 bytes for scopelistlen */ /* 2 bytes for predicatelen */ /* 2 bytes for sprstrlen */ /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)malloc(bufsize); if(buf == 0) { return 0; } memset(buf,0,bufsize); /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,23); curpos = curpos + 2; memcpy(curpos,"service:directory-agent",23); /* scope list zero length */ /* predicate zero length */ /* spi list zero length */ NetworkRqstRply(sock, peeraddr, "en", buf, SLP_FUNCT_DASRVRQST, bufsize, KnownDADiscoveryCallback, &result); free(buf); return result; }
/*-------------------------------------------------------------------------*/ 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 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 ProcessSrvReg(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SECURITY int urlauthlen = 0; unsigned char* urlauth = 0; int attrauthlen = 0; unsigned char* attrauth = 0; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { result = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen, handle->params.reg.url, &urlauthlen, &urlauth); if(result == 0) { result = SLPAuthSignString(handle->hspi, 0, 0, handle->params.reg.attrlistlen, handle->params.reg.attrlist, &attrauthlen, &attrauth); } bufsize += urlauthlen; bufsize += attrauthlen; } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVREG */ /*-------------------------------------------------------------------*/ bufsize += handle->params.reg.urllen + 6; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += handle->params.reg.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.attrlistlen + 2; /* 2 bytes for len field */ bufsize += 1; /* 1 byte for authcount */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVREG */ /*------------------------------------------------------------*/ /* url-entry reserved */ *curpos= 0; curpos = curpos + 1; /* url-entry lifetime */ ToUINT16(curpos,handle->params.reg.lifetime); curpos = curpos + 2; /* url-entry urllen */ ToUINT16(curpos,handle->params.reg.urllen); curpos = curpos + 2; /* url-entry url */ memcpy(curpos, handle->params.reg.url, handle->params.reg.urllen); curpos = curpos + handle->params.reg.urllen; /* url-entry authblock */ #ifdef ENABLE_SECURITY if(urlauth) { /* authcount */ *curpos = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,urlauth,urlauthlen); curpos = curpos + urlauthlen; } else #endif { /* authcount */ *curpos = 0; curpos = curpos + 1; } /* service type */ ToUINT16(curpos,handle->params.reg.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); curpos = curpos + handle->params.reg.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.reg.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); curpos = curpos + handle->params.reg.scopelistlen; /* attr list */ ToUINT16(curpos,handle->params.reg.attrlistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); curpos = curpos + handle->params.reg.attrlistlen; /* attribute auth block */ #ifdef ENABLE_SECURITY if(attrauth) { /* authcount */ *curpos = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,attrauth,attrauthlen); curpos = curpos + attrauthlen; } else #endif { /* authcount */ *curpos = 0; curpos = curpos + 1; } /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &peeraddr); if(sock == -1) { result = SLP_NETWORK_INIT_FAILED; break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVREG, bufsize, CallbackSrvReg, handle); if(result) { NetworkDisconnectSA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SECURITY if(urlauth) xfree(urlauth); if(attrauth) xfree(attrauth); #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; }
/** Formats and sends an SLPReg wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPReg. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvReg(SLPHandleInfo * handle) { sockfd_t sock; uint8_t * buf; uint8_t * curpos; SLPError serr; size_t extoffset = 0; int urlauthlen = 0; uint8_t * urlauth = 0; int attrauthlen = 0; uint8_t * attrauth = 0; SLPBoolean watchRegPID; struct sockaddr_storage saaddr; #ifdef ENABLE_SLPv2_SECURITY if (SLPPropertyAsBoolean("net.slp.securityEnabled")) { int err = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen, handle->params.reg.url, &urlauthlen, &urlauth); if (err == 0) err = SLPAuthSignString(handle->hspi, 0, 0, handle->params.reg.attrlistlen, handle->params.reg.attrlist, &attrauthlen, &attrauth); if (err != 0) return SLP_AUTHENTICATION_ABSENT; } #endif /* Should we send the "Watch Registration PID" extension? */ watchRegPID = SLPPropertyAsBoolean("net.slp.watchRegistrationPID"); /* 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | <URL-Entry> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of service type string | <service-type> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of attr-list string | <attr-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |# of AttrAuths |(if present) Attribute Authentication Blocks...\ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WATCH-PID extension ID | next extension offset \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nxo (cont) | process identifier to be monitored \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | PID (cont) | +-+-+-+-+-+-+-+-+ */ buf = curpos = xmalloc( + SizeofURLEntry(handle->params.reg.urllen, urlauthlen) + 2 + handle->params.reg.srvtypelen + 2 + handle->params.reg.scopelistlen + 2 + handle->params.reg.attrlistlen + 1 + attrauthlen + (watchRegPID? (2 + 3 + 4): 0)); if (buf == 0) { xfree(urlauth); xfree(attrauth); return SLP_MEMORY_ALLOC_FAILED; } /* URL entry */ PutURLEntry(&curpos, handle->params.reg.lifetime, handle->params.reg.url, handle->params.reg.urllen, urlauth, urlauthlen); /* <service-type> */ PutL16String(&curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); /* <scope-list> */ PutL16String(&curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); /* <attr-list> */ PutL16String(&curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); /** @todo Handle multiple attribute authentication blocks. */ /* Attribute Authentication Blocks */ *curpos++ = attrauth? 1: 0; memcpy(curpos, attrauth, attrauthlen); curpos += attrauthlen; /* SLP_EXTENSION_ID_REG_PID */ if (watchRegPID) { extoffset = curpos - buf; /** @todo In some future code base, this should be changed to use the * non-deprecated official version, SLP_EXTENSION_ID_REG_PID. For now * we need to use the EXPerimental version in order to interoperate * properly with OpenSLP 1.x SA's. */ PutUINT16(&curpos, SLP_EXTENSION_ID_REG_PID_EXP); PutUINT24(&curpos, 0); PutUINT32(&curpos, SLPPidGet()); } /* Call the Request-Reply engine. */ sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &saaddr); if (sock != SLP_INVALID_SOCKET) { serr = NetworkRqstRply(sock, &saaddr, handle->langtag, extoffset, buf, SLP_FUNCT_SRVREG, curpos - buf, CallbackSrvReg, handle); if (serr) NetworkDisconnectSA(handle); } else serr = SLP_NETWORK_INIT_FAILED; xfree(buf); xfree(urlauth); xfree(attrauth); return serr; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvDeReg(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 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); /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToSA(handle, handle->params.dereg.scopelist, handle->params.dereg.scopelistlen, &peeraddr); if(sock == -1) { result = SLP_NETWORK_INIT_FAILED; break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVDEREG, bufsize, CallbackSrvDeReg, handle); if(result) { NetworkDisconnectSA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) free(buf); return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvDeReg(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_storage peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int urlauthlen = 0; unsigned char* urlauth = 0; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { result = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.dereg.urllen, handle->params.dereg.url, &urlauthlen, &urlauth); bufsize += urlauthlen; } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVDEREG */ /*-------------------------------------------------------------------*/ bufsize += handle->params.dereg.scopelistlen + 2; /* 2 bytes for len field*/ bufsize += handle->params.dereg.urllen + 6; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += 2; /* 2 bytes for taglistlen*/ /*--------------------------------------------*/ /* Allocate a buffer for the SRVDEREG message */ /*--------------------------------------------*/ buf = curpos = (char*)xmalloc(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 */ #ifdef ENABLE_SLPv2_SECURITY if(urlauth) { /* authcount */ *(curpos) = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,urlauth,urlauthlen); curpos = curpos + urlauthlen; } else #endif { /* authcount */ *(curpos) = 0; curpos = curpos + 1; } /* tag list */ /* TODO: No tag list for now put in taglist stuff */ ToUINT16(curpos,0); /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &peeraddr); if(sock >= 0) { result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVDEREG, bufsize, CallbackSrvDeReg, handle); if (result) { NetworkDisconnectSA(handle); } } else { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(urlauth) xfree(urlauth); #endif 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; }
/** 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; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvReg(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.reg.urllen + 6; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += handle->params.reg.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.attrlistlen + 2; /* 2 bytes for len field */ bufsize += 1; /* 1 byte for authcount */ /* 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 SRVREG */ /*------------------------------------------------------------*/ /* url-entry reserved */ *curpos= 0; curpos = curpos + 1; /* url-entry lifetime */ ToUINT16(curpos,handle->params.reg.lifetime); curpos = curpos + 2; /* url-entry urllen */ ToUINT16(curpos,handle->params.reg.urllen); curpos = curpos + 2; /* url-entry url */ memcpy(curpos, handle->params.reg.url, handle->params.reg.urllen); curpos = curpos + handle->params.reg.urllen; /* url-entry authcount */ *curpos = 0; curpos = curpos + 1; /* TODO: put in urlentry authentication stuff too */ /* service type */ ToUINT16(curpos,handle->params.reg.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); curpos = curpos + handle->params.reg.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.reg.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); curpos = curpos + handle->params.reg.scopelistlen; /* attr list */ ToUINT16(curpos,handle->params.reg.attrlistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); curpos = curpos + handle->params.reg.attrlistlen; /* attr auths*/ *(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_SRVREG, bufsize, CallbackSrvReg, handle); FINISHED: if(buf) free(buf); return result; }