/*-------------------------------------------------------------------------*/ int ProcessSrvTypeRqst(struct sockaddr_in* peeraddr, SLPMessage message, SLPBuffer* sendbuf, int errorcode) /*-------------------------------------------------------------------------*/ { int i; int size = 0; int count = 0; int found = 0; SLPDDatabaseSrvType* srvtypearray = 0; SLPBuffer result = *sendbuf; /*-------------------------------------------------*/ /* Check for one of our IP addresses in the prlist */ /*-------------------------------------------------*/ if(SLPIntersectStringList(message->body.srvtyperqst.prlistlen, message->body.srvtyperqst.prlist, G_SlpdProperty.interfacesLen, G_SlpdProperty.interfaces)) { result->end = result->start; goto FINISHED; } /* TODO: check the spi list of the message and return */ /* AUTHENTICATION_UNKNOWN since we do not do authentication yet */ /*------------------------------------*/ /* Make sure that we handle the scope */ /*------ -----------------------------*/ if(SLPIntersectStringList(message->body.srvtyperqst.scopelistlen, message->body.srvtyperqst.scopelist, G_SlpdProperty.useScopesLen, G_SlpdProperty.useScopes) != 0) { /*------------------------------------*/ /* Find service types in the database */ /*------------------------------------*/ while(found == count) { count += G_SlpdProperty.maxResults; if(srvtypearray) free(srvtypearray); srvtypearray = (SLPDDatabaseSrvType*)malloc(sizeof(SLPDDatabaseSrvType) * count); if(srvtypearray == 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; break; } found = SLPDDatabaseFindType(&(message->body.srvtyperqst), srvtypearray, count); if(found < 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; break; } } /* remember the amount found if is really big for next time */ if(found > G_SlpdProperty.maxResults) { G_SlpdProperty.maxResults = found; } } else { errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED; } /*----------------------------------------------------------------*/ /* Do not send error codes or empty replies to multicast requests */ /*----------------------------------------------------------------*/ if(found == 0 || errorcode != 0) { if(message->header.flags & SLP_FLAG_MCAST || ISMCAST(peeraddr->sin_addr)) { result->end = result->start; goto FINISHED; } } /*-----------------------------------------------------------------*/ /* ensure the buffer is big enough to handle the whole srvtyperply */ /*-----------------------------------------------------------------*/ size = message->header.langtaglen + 18; /* 14 bytes for header */ /* 2 bytes for error code */ /* 2 bytes for srvtype list length */ for(i=0;i<found;i++) { size += srvtypearray[i].typelen + 1; /* 1 byte for comma */ } if(found) size--; /* remove the extra comma */ result = SLPBufferRealloc(result,size); if(result == 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; goto FINISHED; } /*----------------*/ /* Add the header */ /*----------------*/ /*version*/ *(result->start) = 2; /*function id*/ *(result->start + 1) = SLP_FUNCT_SRVTYPERPLY; /*length*/ ToUINT24(result->start + 2,size); /*flags*/ ToUINT16(result->start + 5, size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0); /*ext offset*/ ToUINT24(result->start + 7,0); /*xid*/ ToUINT16(result->start + 10,message->header.xid); /*lang tag len*/ ToUINT16(result->start + 12,message->header.langtaglen); /*lang tag*/ memcpy(result->start + 14, message->header.langtag, message->header.langtaglen); /*-----------------------------*/ /* Add rest of the SrvTypeRply */ /*-----------------------------*/ result->curpos = result->start + 14 + message->header.langtaglen; /* error code*/ ToUINT16(result->curpos, errorcode); result->curpos += 2; /* length of srvtype-list */ ToUINT16(result->curpos, size - (message->header.langtaglen + 18)); result->curpos += 2; if(errorcode == 0) { for(i=0;i<found;i++) { memcpy(result->curpos, srvtypearray[i].type, srvtypearray[i].typelen); result->curpos += srvtypearray[i].typelen; if(i < found - 1) *result->curpos++ = ','; } } FINISHED: if(srvtypearray) free(srvtypearray); *sendbuf = result; return errorcode; }
/*-------------------------------------------------------------------------*/ int v1ProcessSrvTypeRqst(struct sockaddr_in* peeraddr, SLPMessage message, SLPBuffer* sendbuf, int errorcode) /*-------------------------------------------------------------------------*/ { int i, typelen; int size = 0; int count = 0; int found = 0; SLPDDatabaseSrvType* srvtypearray = 0; SLPBuffer result = *sendbuf; /*-------------------------------------------------*/ /* Check for one of our IP addresses in the prlist */ /*-------------------------------------------------*/ if(SLPIntersectStringList(message->body.srvtyperqst.prlistlen, message->body.srvtyperqst.prlist, G_SlpdProperty.interfacesLen, G_SlpdProperty.interfaces)) { result->end = result->start; goto FINISHED; } /*------------------------------------*/ /* Make sure that we handle the scope */ /*------------------------------------*/ if(SLPIntersectStringList(message->body.srvtyperqst.scopelistlen, message->body.srvtyperqst.scopelist, G_SlpdProperty.useScopesLen, G_SlpdProperty.useScopes) != 0) { /*------------------------------------*/ /* Find service types in the database */ /*------------------------------------*/ while(found == count) { count += G_SlpdProperty.maxResults; if(srvtypearray) free(srvtypearray); srvtypearray = (SLPDDatabaseSrvType*)malloc(sizeof(SLPDDatabaseSrvType) * count); if(srvtypearray == 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; break; } found = SLPDDatabaseFindType(&(message->body.srvtyperqst), srvtypearray, count); if(found < 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; break; } } /* remember the amount found if is really big for next time */ if(found > G_SlpdProperty.maxResults) { G_SlpdProperty.maxResults = found; } } else { errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED; } /*----------------------------------------------------------------*/ /* Do not send error codes or empty replies to multicast requests */ /*----------------------------------------------------------------*/ if(message->header.flags & SLP_FLAG_MCAST) { if(found == 0 || errorcode != 0) { result->end = result->start; goto FINISHED; } } /*-----------------------------------------------------------------*/ /* ensure the buffer is big enough to handle the whole srvtyperply */ /*-----------------------------------------------------------------*/ size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes for srvtype count */ if(errorcode == 0) { for(i=0;i<found;i++) { typelen = INT_MAX; errorcode = SLPv1ToEncoding(0, &typelen, message->header.encoding, srvtypearray[i].type, srvtypearray[i].typelen); if(errorcode) break; size += typelen + 2; /* 2 byte for length */ } } result = SLPBufferRealloc(result,size); if(result == 0) { found = 0; errorcode = SLP_ERROR_INTERNAL_ERROR; } /*----------------*/ /* Add the header */ /*----------------*/ /*version*/ *(result->start) = 1; /*function id*/ *(result->start + 1) = SLP_FUNCT_SRVTYPERPLY; /*length*/ ToUINT16(result->start + 2, size); /*flags - TODO set the flags correctly */ *(result->start + 4) = message->header.flags | (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0); /*dialect*/ *(result->start + 5) = 0; /*language code*/ memcpy(result->start + 6, message->header.langtag, 2); ToUINT16(result->start + 8, message->header.encoding); /*xid*/ ToUINT16(result->start + 10, message->header.xid); /*-----------------------------*/ /* Add rest of the SrvTypeRply */ /*-----------------------------*/ result->curpos = result->start + 12; /* error code*/ ToUINT16(result->curpos, errorcode); result->curpos += 2; /* service type count */ ToUINT16(result->curpos, found); result->curpos += 2; /* TODO - make sure we don't return generic types */ for(i=0;i<found;i++) { typelen = size; SLPv1ToEncoding(result->curpos + 2, &typelen, message->header.encoding, srvtypearray[i].type, srvtypearray[i].typelen); ToUINT16(result->curpos, srvtypearray[i].typelen); result->curpos += 2 + typelen; } FINISHED: if(srvtypearray) free(srvtypearray); *sendbuf = result; return errorcode; }