예제 #1
0
/** Thread start procedure for asynchronous service registration.
 *
 * @param[in] handle - Contains the request parameters.
 *
 * @return An SLPError code.
 *
 * @internal
 */
static SLPError AsyncProcessSrvReg(SLPHandleInfo * handle)
{
   SLPError serr = ProcessSrvReg(handle);
   xfree((void *)handle->params.reg.url);
   xfree((void *)handle->params.reg.srvtype);
   xfree((void *)handle->params.reg.scopelist);
   xfree((void *)handle->params.reg.attrlist);
   SLPSpinLockRelease(&handle->inUse);
   return serr;
}
예제 #2
0
/*-------------------------------------------------------------------------*/ 
SLPError AsyncProcessSrvReg(PSLPHandleInfo handle)
/*-------------------------------------------------------------------------*/
{
    SLPError result = ProcessSrvReg(handle);

    xfree((void*)handle->params.reg.url);
    xfree((void*)handle->params.reg.srvtype);
    xfree((void*)handle->params.reg.scopelist);
    xfree((void*)handle->params.reg.attrlist);

    handle->inUse = SLP_FALSE;

    return result;
}
예제 #3
0
/*=========================================================================*/
int SLPDProcessMessage(SLPDPeerInfo* peerinfo,
                       SLPBuffer recvbuf,
                       SLPBuffer sendbuf)
/* Processes the recvbuf and places the results in sendbuf                 */
/*                                                                         */
/* recvfd   - the socket the message was received on                       */
/*                                                                         */
/* recvbuf  - message to process                                           */
/*                                                                         */
/* sendbuf  - results of the processed message                             */
/*                                                                         */
/* Returns  - zero on success SLP_ERROR_PARSE_ERROR or                     */
/*            SLP_ERROR_INTERNAL_ERROR on ENOMEM.                          */
/*=========================================================================*/
{
    SLPMessage  message   = 0;
    int         result  = 0;

    message = SLPMessageAlloc();
    if(message == 0)
    {
        return SLP_ERROR_INTERNAL_ERROR;
    }

    result = SLPMessageParseBuffer(recvbuf, message);
    if(result == 0)
    {
        switch(message->header.functionid)
        {
        case SLP_FUNCT_SRVRQST:
            ProcessSrvRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVREG:
            ProcessSrvReg(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVDEREG:
            ProcessSrvDeReg(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVACK:
            ProcessSrvAck(peerinfo,message,sendbuf);        
            break;
    
        case SLP_FUNCT_ATTRRQST:
            ProcessAttrRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_DAADVERT:
            ProcessDAAdvert(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVTYPERQST:
            ProcessSrvTypeRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SAADVERT:
            ProcessSAAdvert(peerinfo,message,sendbuf);
            break;
    
        default:
            /* this will NEVER happen */
            break;
        }

        /* Log traceMsg of message was received and the one that will be sent */
        if(G_SlpdProperty.traceMsg)
        {
            SLPDLogTraceMsg(peerinfo,recvbuf,sendbuf);
        }
    }
    else
    {
        /* TODO: Log here? */
    }
    
    SLPMessageFree(message);

    return result;
}                
예제 #4
0
/*=========================================================================*/
SLPError SLPReg(SLPHandle   hSLP,
                const char  *srvUrl,
                const unsigned short lifetime,
                const char  *srvType,
                const char  *attrList,
                SLPBoolean  fresh,
                SLPRegReport callback,
                void *cookie)
/*                                                                         */
/* See slplib.h for detailed documentation                                 */
/*=========================================================================*/
{
    PSLPHandleInfo      handle      = 0;
    SLPError            result      = SLP_OK;
    SLPSrvURL*          parsedurl   = 0;

    /*------------------------------*/
    /* check for invalid parameters */
    /*------------------------------*/
    if(hSLP        == 0 ||
       *(unsigned int*)hSLP != SLP_HANDLE_SIG ||
       srvUrl      == 0 ||
       *srvUrl     == 0 ||  /* srvUrl can't be empty string */
       lifetime    == 0 ||  /* lifetime can not be zero */
       attrList    == 0 ||
       callback    == 0)
    {
        return SLP_PARAMETER_BAD;
    }

    /*-----------------------------------------*/
    /* We don't handle fresh registrations     */
    /*-----------------------------------------*/
    if(fresh == SLP_FALSE)
    {
        return SLP_NOT_IMPLEMENTED;
    }


    /*-----------------------------------------*/
    /* cast the SLPHandle into a SLPHandleInfo */
    /*-----------------------------------------*/
    handle = (PSLPHandleInfo)hSLP;


    /*-----------------------------------------*/
    /* Check to see if the handle is in use    */
    /*-----------------------------------------*/
    if(handle->inUse == SLP_TRUE)
    {
        return SLP_HANDLE_IN_USE;
    }
    handle->inUse = SLP_TRUE;

    /*------------------*/
    /* Parse the srvurl */
    /*------------------*/
    result = SLPParseSrvURL(srvUrl,&parsedurl);
    if(result)
    {
        if(result == SLP_PARSE_ERROR)
        {
            result = SLP_INVALID_REGISTRATION;
        }

        if(parsedurl) SLPFree(parsedurl);
        handle->inUse = SLP_FALSE;
        return result;
    }

    /*-------------------------------------------*/
    /* Set the handle up to reference parameters */
    /*-------------------------------------------*/
    handle->params.reg.fresh         = fresh;
    handle->params.reg.lifetime      = lifetime;
    handle->params.reg.urllen        = strlen(srvUrl);
    handle->params.reg.url           = srvUrl;
    handle->params.reg.srvtype       = parsedurl->s_pcSrvType;
    handle->params.reg.srvtypelen    = strlen(handle->params.reg.srvtype);
    handle->params.reg.scopelist     = SLPGetProperty("net.slp.useScopes");
    if(handle->params.reg.scopelist)
    {
        handle->params.reg.scopelistlen  = strlen(handle->params.reg.scopelist);
    }
    handle->params.reg.attrlistlen   = strlen(attrList);
    handle->params.reg.attrlist      = attrList;
    handle->params.reg.callback      = callback;
    handle->params.reg.cookie        = cookie; 

#ifdef ENABLE_ASYNC_API
    /*----------------------------------------------*/
    /* Check to see if we should be async or sync   */
    /*----------------------------------------------*/
    if(handle->isAsync)
    {
        /* Copy all of the referenced parameters before making thread */
        handle->params.reg.url = xstrdup(handle->params.reg.url);
        handle->params.reg.srvtype = xstrdup(handle->params.reg.url);
        handle->params.reg.scopelist = xstrdup(handle->params.reg.scopelist);
        handle->params.reg.attrlist = xstrdup(handle->params.reg.attrlist);

        /* make sure that the strdups did not fail */
        if(handle->params.reg.url &&
           handle->params.reg.srvtype &&
           handle->params.reg.scopelist &&
           handle->params.reg.attrlist)
        {
            result = ThreadCreate((ThreadStartProc)AsyncProcessSrvReg,handle);
        }
        else
        {
            result = SLP_MEMORY_ALLOC_FAILED;    
        }

        if(result)
        {
            if(handle->params.reg.url) xfree((void*)handle->params.reg.url);
            if(handle->params.reg.srvtype) xfree((void*)handle->params.reg.srvtype);
            if(handle->params.reg.scopelist) xfree((void*)handle->params.reg.scopelist);
            if(handle->params.reg.attrlist) xfree((void*)handle->params.reg.attrlist);
            handle->inUse = SLP_FALSE;
        }
    }
    else
#endif //ffdef ENABLE_ASYNC_API    
    {
        result = ProcessSrvReg(handle);            
        handle->inUse = SLP_FALSE;
    }

    if(parsedurl) SLPFree(parsedurl);

    return result;
}
예제 #5
0
/** Register a service URL through OpenSLP.
 *
 * Registers the URL in @p pcSrvURL having the lifetime usLifetime with
 * the attribute list in pcAttrs. The @p pcAttrs list is a comma separated
 * list of attribute assignments in the wire format (including escaping
 * of reserved characters). The @p usLifetime parameter must be nonzero
 * and less than or equal to SLP_LIFETIME_MAXIMUM. If the @p fresh flag
 * is SLP_TRUE, then the registration is new (the SLP protocol FRESH flag
 * is set) and the registration replaces any existing registrations.
 * The @p pcSrvType parameter is a service type name and can be included
 * for service URLs that are not in the service: scheme. If the URL is
 * in the service: scheme, the @p pcSrvType parameter is ignored. If the
 * @p fresh flag is SLP_FALSE, then an existing registration is updated.
 * Rules for new and updated registrations, and the format for @p pcAttrs
 * and @p pcScopeList can be found in [RFC 2608]. Registrations and 
 * updates take place in the language locale of the @p hSLP handle.
 *
 * @par
 * The API library is required to perform the operation in all scopes
 * obtained through configuration.
 *
 * @param[in] hSLP - The language-specific SLPHandle on which to register
 *    the advertisement.
 * @param[in] srvUrl - The URL to register. May not be the empty string. 
 *    May not be NULL. Must conform to SLP Service URL syntax. 
 *    SLP_INVALID_REGISTRATION will be returned if not.
 * @param[in] lifetime - An unsigned short giving the life time of the 
 *    service advertisement, in seconds. The value must be an unsigned
 *    integer less than or equal to SLP_LIFETIME_MAXIMUM, and greater
 *    than zero. If SLP_LIFETIME_MAXIMUM is used, the registration 
 *    will remain for the life of the calling process. Also, OpenSLP,
 *    will not allow registrations to be made with SLP_LIFETIME_MAXIMUM 
 *    unless SLP_REG_FLAG_WATCH_PID is also used. Note that RFC 2614
 *    defines this parameter as const unsigned short. The 'const' is 
 *    superfluous.
 * @param[in] srvType - The service type. If @p pURL is a "service:" 
 *    URL, then this parameter is ignored. (ALWAYS ignored since the SLP 
 *    Service URL syntax required for the @p pcSrvURL encapsulates the 
 *    service type.)
 * @param[in] attrList -  A comma separated list of attribute assignment 
 *    expressions for the attributes of the advertisement. Use empty 
 *    string ("") for no attributes.
 * @param[in] fresh - An SLPBoolean that is SLP_TRUE if the registration 
 *    is new or SLP_FALSE if a RE-registration. Use of non-fresh 
 *    registrations is deprecated (post RFC 2614). SLP_TRUE must be 
 *    passed in for this parameter or SLP_BAD_PARAMETER will be returned. 
 *    It also appears that this flag has been overloaded to accept certain 
 *    specific values of "true" for internal purposes... (jmc)
 * @param[in] callback - A callback to report the operation completion 
 *    status.
 * @param[in] cookie - Memory passed to the callback code from the 
 *    client. May be NULL.
 *
 * @return If an error occurs in starting the operation, one of the 
 *    SLPError codes is returned.
 */
SLPEXP SLPError SLPAPI SLPReg(
      SLPHandle hSLP,
      const char * srvUrl,
      unsigned short lifetime,
      const char * srvType,
      const char * attrList,
      SLPBoolean fresh,
      SLPRegReport callback,
      void * cookie)
{
   bool inuse;
   SLPError serr;
   SLPSrvURL * parsedurl = 0;
   SLPHandleInfo * handle = hSLP;

   /** @todo Add code to accept non- "service:" scheme 
    * URL's - normalize with srvType parameter info. 
    */
   (void)srvType; /* not used yet */

   /* Check for invalid parameters. */
   SLP_ASSERT(handle != 0);
   SLP_ASSERT(handle->sig == SLP_HANDLE_SIG);
   SLP_ASSERT(srvUrl != 0);
   SLP_ASSERT(*srvUrl != 0);
   SLP_ASSERT(lifetime != 0);
   SLP_ASSERT(attrList != 0);
   SLP_ASSERT(callback != 0);

   if (handle == 0 || handle->sig != SLP_HANDLE_SIG 
         || srvUrl == 0 || *srvUrl == 0 
         || lifetime == 0
         || attrList == 0 
         || callback == 0)
      return SLP_PARAMETER_BAD;

   /** @todo Handle non-fresh registrations in SLPReg. */
   if (fresh == SLP_FALSE)
      return SLP_NOT_IMPLEMENTED;

   /* Check to see if the handle is in use. */
   inuse = SLPSpinLockTryAcquire(&handle->inUse);
   SLP_ASSERT(!inuse);
   if (inuse)
      return SLP_HANDLE_IN_USE;

   /* Parse the srvurl - mainly for service type info. */
   serr = SLPParseSrvURL(srvUrl, &parsedurl);
   if (serr)
   {
      SLPSpinLockRelease(&handle->inUse);
      return serr == SLP_PARSE_ERROR? SLP_INVALID_REGISTRATION: serr;
   }

   /* Set the handle up to reference parameters. */
   handle->params.reg.fresh = fresh;
   handle->params.reg.lifetime = lifetime;
   handle->params.reg.urllen = strlen(srvUrl);
   handle->params.reg.url = srvUrl;
   handle->params.reg.srvtype = parsedurl->s_pcSrvType;
   handle->params.reg.srvtypelen = strlen(handle->params.reg.srvtype);
   handle->params.reg.scopelist = SLPPropertyGet("net.slp.useScopes", 0, 0);
   handle->params.reg.scopelistlen = strlen(handle->params.reg.scopelist);
   handle->params.reg.attrlistlen = strlen(attrList);
   handle->params.reg.attrlist = attrList;
   handle->params.reg.callback = callback;
   handle->params.reg.cookie = cookie; 

#ifdef ENABLE_ASYNC_API
   if (handle->isAsync)
   {
      /* Copy all of the referenced parameters before creating thread. */
      handle->params.reg.url = xstrdup(handle->params.reg.url);
      handle->params.reg.srvtype = xstrdup(handle->params.reg.url);
      handle->params.reg.scopelist = xstrdup(handle->params.reg.scopelist);
      handle->params.reg.attrlist = xstrdup(handle->params.reg.attrlist);

      /* Ensure strdups and thread create succeed. */
      if (handle->params.reg.url == 0
            || handle->params.reg.srvtype == 0
            || handle->params.reg.scopelist == 0
            || handle->params.reg.attrlist == 0
            || (handle->th = SLPThreadCreate((SLPThreadStartProc)
                  AsyncProcessSrvReg, handle)) == 0)
      {
         serr = SLP_MEMORY_ALLOC_FAILED;    
         xfree((void *)handle->params.reg.url);
         xfree((void *)handle->params.reg.srvtype);
         xfree((void *)handle->params.reg.scopelist);
         xfree((void *)handle->params.reg.attrlist);
         SLPSpinLockRelease(&handle->inUse);
      }
   }
   else
#endif
   {
      /* Reference all the parameters. */
      serr = ProcessSrvReg(handle);            
      SLPSpinLockRelease(&handle->inUse);
   }
   SLPFree(parsedurl);
   return serr;
}
예제 #6
0
/** Processes the recvbuf and places the results in sendbuf
 *
 * @param[in] peerinfo - The remote address the message was received from.
 * @param[in] localaddr - The local address the message was received on.
 * @param[in] recvbuf - The message to process.
 * @param[out] sendbuf - The address of storage for the results of the 
 *    processed message.
 * @param[out] sendlist - if non-0, this function will prune the message 
 *    with the processed xid from the sendlist.
 *
 * @return Zero on success if @p sendbuf contains a response to send, 
 *    or a non-zero value if @p sendbuf does not contain a response
 *    to send.
 */
int SLPDProcessMessage(struct sockaddr_storage * peerinfo, 
      struct sockaddr_storage * localaddr, SLPBuffer recvbuf,
      SLPBuffer * sendbuf, SLPList * psendlist)
{
   SLPHeader header;
   SLPMessage * message = 0;
   int errorcode = 0;

#ifdef DEBUG
   char addr_str[INET6_ADDRSTRLEN];
#endif

   SLPDLogMessage(SLPDLOG_TRACEMSG_IN, peerinfo, localaddr, recvbuf);

   /* set the sendbuf empty */
   if (*sendbuf)
      (*sendbuf)->end = (*sendbuf)->start;

   /* zero out the header before parsing it */
   memset(&header, 0, sizeof(header));

   /* Parse just the message header */
   recvbuf->curpos = recvbuf->start;
   errorcode = SLPMessageParseHeader(recvbuf, &header);

   /* Reset the buffer "curpos" pointer so that full message can be 
      parsed later 
    */
   recvbuf->curpos = recvbuf->start;

#if defined(ENABLE_SLPv1)   
   /* if version == 1 and the header was correct then parse message as a version 1 message */
   if ((errorcode == 0) && (header.version == 1))
      errorcode = SLPDv1ProcessMessage(peerinfo, recvbuf, sendbuf);
   else
#endif
   if (errorcode == 0)
   {
      /* TRICKY: Duplicate SRVREG recvbufs *before* parsing them
       * we do this because we are going to keep track of in the 
       * registration database.
       */
      if (header.functionid == SLP_FUNCT_SRVREG 
            || header.functionid == SLP_FUNCT_DAADVERT)
      {
         recvbuf = SLPBufferDup(recvbuf);
         if (recvbuf == 0)
            return SLP_ERROR_INTERNAL_ERROR;
      }

      /* Allocate the message descriptor */
      message = SLPMessageAlloc();
      if (message)
      {
         /* Parse the message and fill out the message descriptor */
         errorcode = SLPMessageParseBuffer(peerinfo, localaddr,
               recvbuf, message);
         if (errorcode == 0)
         {
            /* Process messages based on type */
            switch (message->header.functionid)
            {
               case SLP_FUNCT_SRVRQST:
                  errorcode = ProcessSrvRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SRVREG:
                  errorcode = ProcessSrvReg(message, recvbuf, 
                        sendbuf, errorcode);
                  if (errorcode == 0)
                     SLPDKnownDAEcho(message, recvbuf);         
                  break;

               case SLP_FUNCT_SRVDEREG:
                  errorcode = ProcessSrvDeReg(message, sendbuf, errorcode);
                  if (errorcode == 0)
                     SLPDKnownDAEcho(message, recvbuf);         
                  break;

               case SLP_FUNCT_SRVACK:
                  errorcode = ProcessSrvAck(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_ATTRRQST:
                  errorcode = ProcessAttrRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_DAADVERT:
                  errorcode = ProcessDAAdvert(message, recvbuf, 
                        sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SRVTYPERQST:
                  errorcode = ProcessSrvTypeRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SAADVERT:
                  errorcode = ProcessSAAdvert(message, sendbuf, errorcode);
                  break;

               default:
                  /* Should never happen... but we're paranoid */
                  errorcode = SLP_ERROR_PARSE_ERROR;
                  break;
            }
         }
         else
            SLPDLogParseWarning(peerinfo, recvbuf);

       /*If there was a send list, prune the xid, since the request has been processed*/
       if(psendlist)
       {
          SLPHeader bufhead;
          SLPBuffer pnext;
          SLPBuffer pbuf = (SLPBuffer) psendlist->head;

          while(pbuf)
          {
            pnext = (SLPBuffer) pbuf->listitem.next;

            if((0 == SLPMessageParseHeader(pbuf, &bufhead)) && (bufhead.xid == header.xid))
               SLPBufferFree((SLPBuffer)SLPListUnlink(psendlist, (SLPListItem*)pbuf));
            else 
               pbuf->curpos = pbuf->start;  /*We parsed the buffer enough to attempt the xid check, we need to reset it for the next parse*/

            pbuf = pnext;
          }
       }

         if (header.functionid == SLP_FUNCT_SRVREG 
               || header.functionid == SLP_FUNCT_DAADVERT)
         {
            /* TRICKY: If this is a reg or daadvert message we do not free 
             * the message descriptor or duplicated recvbuf because they are 
             * being kept in the database!
             */
            if (errorcode == 0)
               goto FINISHED;

            /* TRICKY: If there is an error we need to free the 
             * duplicated recvbuf
             */
            SLPBufferFree(recvbuf);                    
         }
         SLPMessageFree(message);
      }
      else
         errorcode = SLP_ERROR_INTERNAL_ERROR;  /* out of memory */
   }
   else
      SLPDLogParseWarning(peerinfo,recvbuf);

FINISHED:

#ifdef DEBUG
   if (errorcode)
      SLPDLog("\n*** DEBUG *** errorcode %i during processing "
            "of message from %s\n", errorcode, SLPNetSockAddrStorageToString(
            peerinfo, addr_str, sizeof(addr_str)));
#endif

   /* Log message silently ignored because of an error */
   if (errorcode)
      if (*sendbuf == 0 || (*sendbuf)->end == (*sendbuf)->start)
         SLPDLogMessage(SLPDLOG_TRACEDROP,peerinfo,localaddr,recvbuf);

   /* Log trace message */
   SLPDLogMessage(SLPDLOG_TRACEMSG_OUT, peerinfo, localaddr, *sendbuf);

   return errorcode;
}                
예제 #7
0
/*=========================================================================*/
int SLPDProcessMessage(struct sockaddr_in* peerinfo,
                       SLPBuffer recvbuf,
                       SLPBuffer* sendbuf)
/* Processes the recvbuf and places the results in sendbuf                 */
/*                                                                         */
/* recvfd   - the socket the message was received on                       */
/*                                                                         */
/* recvbuf  - message to process                                           */
/*                                                                         */
/* sendbuf  - results of the processed message                             */
/*                                                                         */
/* Returns  - zero on success SLP_ERROR_PARSE_ERROR or                     */
/*            SLP_ERROR_INTERNAL_ERROR on ENOMEM.                          */
/*=========================================================================*/
{
    SLPMessage  message   = 0;
    int         errorcode  = 0;

    message = SLPMessageAlloc();
    if(message == 0)
    {
        return SLP_ERROR_INTERNAL_ERROR;
    }

    errorcode = SLPMessageParseBuffer(recvbuf, message);

#if defined(ENABLE_SLPv1)
    if(message->header.version == 1)
        return SLPDv1ProcessMessage(peerinfo, recvbuf, sendbuf,
                                    message, errorcode);
#endif




    /* Log trace message */
    SLPDLogTraceMsg("IN",peerinfo,recvbuf);

    switch(message->header.functionid)
    {
    case SLP_FUNCT_SRVRQST:
        errorcode = ProcessSrvRqst(peerinfo, message, sendbuf, errorcode);
        break;

    case SLP_FUNCT_SRVREG:
        errorcode = ProcessSrvReg(peerinfo, message,sendbuf, errorcode);
        if(errorcode == 0)
        {
            SLPDKnownDAEcho(peerinfo, message, recvbuf);
        }
        break;

    case SLP_FUNCT_SRVDEREG:
        errorcode = ProcessSrvDeReg(peerinfo, message,sendbuf, errorcode);
        if(errorcode == 0)
        {
            SLPDKnownDAEcho(peerinfo, message, recvbuf);
        }
        break;

    case SLP_FUNCT_SRVACK:
        errorcode = ProcessSrvAck(peerinfo, message,sendbuf, errorcode);        
        break;

    case SLP_FUNCT_ATTRRQST:
        errorcode = ProcessAttrRqst(peerinfo, message,sendbuf, errorcode);
        break;

    case SLP_FUNCT_DAADVERT:
        errorcode = ProcessDAAdvert(peerinfo, message, sendbuf, errorcode);
        /* If necessary log that we received a DAAdvert */
        SLPDLogDATrafficMsg("IN", peerinfo, message);
        break;

    case SLP_FUNCT_SRVTYPERQST:
        errorcode = ProcessSrvTypeRqst(peerinfo, message, sendbuf, errorcode);
        break;

    case SLP_FUNCT_SAADVERT:
        errorcode = ProcessSAAdvert(peerinfo, message, sendbuf, errorcode);
        break;

    default:
        /* This may happen on a really early parse error or version not */
        /* supported error */

        /* TODO log errorcode here */

        break;
    }

    /* Log traceMsg of message was received and the one that will be sent */
    SLPDLogTraceMsg("OUT",peerinfo,*sendbuf);

    SLPMessageFree(message);

    /* Log reception of important errors */
    switch(errorcode)
    {
    case SLP_ERROR_DA_BUSY_NOW:
        SLPLog("DA_BUSY from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_INTERNAL_ERROR:
        SLPLog("INTERNAL_ERROR from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_PARSE_ERROR:
        SLPLog("PARSE_ERROR from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_VER_NOT_SUPPORTED:
        SLPLog("VER_NOT_SUPPORTED from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;                    
    }

    return errorcode;
}