Service Location Protocol (SLP) APIs

Service Location Protocol provides a flexible and scalable framework for providing hosts with access to information about the existence, location, and configuration of network services.

Any TCP/IP application can take advantage of this protocol. SLP is based on RFC 2608 and RFC 2614.

m This sections shows sample code on how to use the SLP APIs. The SLP APIs are as follows. Documentation for these APIs can be found in AIX® Version 7.1 Technical Reference: Communications, Volume 2.
  • SLPOpen
  • SLPClose
  • SLPFree
  • SLPFindSrvs
  • SLPFindSrvTypes
  • SLPFindAttrs
  • SLPEscape
  • SLPUnescape
  • SLPParseSrvURL
  • SLPFindScopes
  • SLPGetProperty
  • SLPSrvTypeCallback
  • SLPSrvURLCallback
  • SLPAttrCallback
  • SLPReg
  • SLPDereg
  • SLPRegReport

 * To compile it this sample code:
 * cc -o samplecode samplecode.c -lslp
 *
 * To run the program:
 * samplecode -s <scopes> -p <predicate> -a <attrids> -t <service_type> \
              -u <url_string> -n <naming_authority>
 */

#include <stdio.h>
#include <slp.h>

extern       int       optind;
extern       char      *optarg;

int    s_flag = 0,
       p_flag = 0,
       a_flag = 0,
       t_flag = 0,
       u_flag = 0,
       n_flag = 0;

void arginit(int argc, char *argv[]);
void Usage(void);

char   *service_type = NULL,       /* For service type                   
         */
       scopes = NULL,              /* For scopes list                    
        */
       *predicate = NULL,          /* For precicate list                 
           */
       *attrids = NULL,            /* For attribute ids                  
          */
       *url = NULL,              /* For URL string                       
     */
       *na = NULL;              /* For naming authority string           
    */

SLPBoolean SrvURLCallback (SLPHandle hslp,
                          const char *pcSrvURL,
                          unsigned short sLifetime,
                          SLPError errCode,
                          void *pvCookie)
{
       SLPSrvURL* ppSrvURL;
       SLPError err;

       if ( errCode == SLP_LAST_CALL)
       {
              *(SLPError *) pvCookie = errCode;
              return (SLP_FALSE);   /* last call, no more data available */
       }
       else if (errCode != SLP_OK)
       {
              *(SLPError *) pvCookie = errCode;
              return (SLP_FALSE);  /* error happened. don't want any more
data */
       }
       else 
       {              
               printf("pcSrvURL is: %s\n", pcSrvURL);
               printf("sLifetime is: %d\n", sLifetime);
              *(SLPError *) pvCookie = errCode;

              /* Will parse the pcSrvURL string. */
              err = SLPParseSrvURL((char *)pcSrvURL, &ppSrvURL);
                 if (err != SLP_OK)
                 {
                        SLPFree((void *)ppSrvURL);  /* release the dynamically
allocated memory */
                     return(SLP_FALSE);  /* don't want any more data */
                 }
                 SLPFree((void *)ppSrvURL);  /* release the dynamically allocated
memory */
       
              return(SLP_TRUE);  /* want more data */
       }
}

SLPBoolean SrvTypeCallback (SLPHandle hslp,
                                const char *pcSrvTypes,
                           SLPError errCode,
                           void *pvCookie)
{
        if ( errCode == SLP_LAST_CALL)
        {
              *(SLPError *) pvCookie = errCode;
                return (SLP_FALSE);    /* last call, no more data available
*/
        }
        else if (errCode != SLP_OK)
        {
              *(SLPError *) pvCookie = errCode;
                return (SLP_FALSE);  /* error happened. don't want any more
data */
        }
        else
        {
                printf("pcSrvTypes is: %s\n", pcSrvTypes);
              *(SLPError *) pvCookie = errCode;
              return(SLP_TRUE);  /* want more data */
        }
}

SLPBoolean AttrCallback (SLPHandle hslp,
                               const char *pcAttrList,
                         SLPError errCode,
                         void *pvCookie)
{
        if ( errCode == SLP_LAST_CALL)
        {
              *(SLPError *) pvCookie = errCode;
                return (SLP_FALSE);     /* last call, no more data available
*/
        }
        else if (errCode != SLP_OK)
        {
              *(SLPError *) pvCookie = errCode;
                return (SLP_FALSE);    /* error happened. don't want any more
data */
        }
        else
        {
                printf("pcAttrList is: %s\n", pcAttrList);
              *(SLPError *) pvCookie = errCode;
              return(SLP_TRUE);  /* want more data */
        }
}

int main (int argc, char *argv[])
{
       SLPHandle slph;
          SLPError callbackerr;
           SLPError err;

       arginit(argc, argv);

           err = SLPOpen("en", SLP_FALSE, &slph);
       if (err != SLP_OK)
       {
                   printf("SLPOpen returns error, err = %d\n", err);
              exit(1);
       }
       
       err = SLPFindSrvs (slph,
                           service_type,
                           scopes,       /* if NULL, use static configuration
in /etc/slp.conf */
                        predicate,
                           SrvURLCallback,
                           &callbackerr);
        if (err != SLP_OK)
        {
                   printf("SLPFindSrvs returns error, err = %d\n", err);
                  exit(1);
        }

       err = SLPFindSrvTypes (slph,
                                na,
                                scopes, /* if NULL, use static configuration
in /etc/slp.conf*/
                                SrvTypeCallback,
                                &callbackerr);
        if (err != SLP_OK)
        {
                   printf("SLPFindSrvTypes returns error, err = %d\n", err);
              exit(1);
        }

       err = SLPFindAttrs(slph,
                           url,
                           scopes,       /* if NULL, use static configuration
in /etc/slp.conf */
                           attrids,
                           AttrCallback,
                           &callbackerr);
        if (err != SLP_OK)
        {
                   printf("SLPFindAttrs returns error, err = %d\n", err);
              exit(1);       
        }

       SLPClose(slph);

       return (err);
}

void Usage(void)
{
       printf("\n***Usage: samplecode -s <scopes> -p <predicate> -a
<attrids>\n");
       printf("\t  -t <service_type> -u <url_string> -n <naming_authority>
\n");
       printf("Where:\n");
       printf("\t -s <scopes>, a scopes string. e.g. \"david,bob\"\n");
       printf("\t -p <predicate>, a predicate string. e.g. \"(cn=Hard Rock)\"
\n");
       printf("\t -a <attrids>, attribute string, e.g \"\"\n");
       printf("\t -t <service_type>, e.g. \"service:ftp\"\n");
       printf("\t -u <url>, e.g. \"service:ftp\", or \"service:ftp://9.3.149.20\"\n");
       printf("\t -n <naming_authority>, e.g. \"\", or \"*\" \n");
       exit(1);
}

void arginit(int argc, char *argv[])
{
       char       *opts = "s:p:a:t:u:n:";       
       int       i;

       if (argc <=1)
              Usage();       


       while ((i=getopt(argc, argv, opts)) != EOF ) {
              switch (i)   {
                     case 's':
                            if (++s_flag > 1)
                                   Usage();
                            scopes = optarg;
                            break;
                     case 'p':
                            if (++p_flag > 1)
                                   Usage();
                            predicate = optarg;
                            break;
                     case 'a':
                            if (++a_flag > 1)
                                   Usage();
                            attrids = optarg;
                            break;
                     case 't':
                            if (++t_flag > 1)
                                   Usage();
                            service_type = optarg;
                            break;
                     case 'u':
                            if (++u_flag > 1)
                                   Usage();
                            url = optarg;
                            break;
                     case 'n':
                            if (++n_flag > 1)
                                   Usage();
                            na = optarg;
                            break;
                     default:
                            Usage();
              }
       }
}