Service Location Working Group                            Erik Guttman
 Internet Draft                                  Sun Microsystems, Inc.
 Expires in six months                                       Don Provan
                                                           Novell, Inc.


                       An API for Service Location
                      <draft-ietf-svrloc-api-01.txt>



      This document is an Internet-Draft.  Internet-Drafts are working
      documents of the Internet Engineering Task Force (IETF), its
      areas, and its working groups.  Note that other groups may also
      distribute working documents as Internet-Drafts.

      Internet-Drafts are draft documents valid for a maximum of six
      months and may be updated, replaced, or obsoleted by other
      documents at any time.  It is inappropriate to use Internet-
      Drafts as reference material or to cite them other than as
      ``work in progress.''

      To learn the current status of any Internet-Draft, please check
      the ``1id-abstracts.txt'' listing contained in the Internet-
      Drafts Shadow Directories on ftp.is.co.za (Africa),
      nic.nordu.net (Europe), munnari.oz.au (Pacific Rim),
      ds.internic.net (US East Coast), or ftp.isi.edu (US West Coast).


Abstract

   The Service Location Protocol coupled with the Service Location API
   provide a new way for clients to dynamically discovery network
   services.  It is simple to offer highly available services which
   require no user configuration or communication with network
   administrators prior to use.  The document includes examples and
   applications.

   Client software modified to use Service Location can make very simple
   requests to find service by type or by characteristic. The latter
   capability allows the client to choose intelligently between services
   of the same type.  Service software modified to use Service Location
   may dynamically advertise its characteristics and existence.

   Remaining Issues:

    1. Should query results have their own types, or is the current
       scheme using Result alright (for the C interface)?

    2. Should the SLP authentication framework be exposed at the
       API level?  This could allow programs to do their own



Guttman,Provan                                                  [Page 1]


Internet Draft        An API for Service Location          24 March 1997


       cryptographic key assignment, to require authentication,
       etc.

    3. Replies to SLP requests may be very large.  Should there
       be a mechanism to allow iterative return of results?  This
       way all 10000 attributes would not have to be returned at
       once, for example.  An application could obtain them 100
       at a time, etc.

    4. Review the adequacy of the SLP Config File format presented
       in this draft.

    5. Is the language precise enough about what to do with multiple
       replies?  (Some may contain error messages, others are OK...)


Table of Contents

      1. Introduction
      2. Glossary
      3. Interfaces
         3.1.  SL_Open
         3.2.  SL_Close
         3.3.  SL_Register
         3.4.  SL_DeRegister
         3.5.  SL_GetScopes
         3.6.  SL_GetServiceTypes
         3.7.  SL_GetService
         3.8.  SL_GetAttrs
         3.9.  SL_Free
         3.10. SL_Binary2Opaque
      4. API programming notes
         4.1. Multithreading Issues
         4.2. Nonstandard Service Types are easy
         4.3. Typical Client Scenarios
         4.4. Top level information
         4.5. Example applications of SLP
              4.5.1. Coarse dynamic load balancing
              4.5.2. Mobile user finds the nearest printer
              4.5.3. Providing highly available services
      5. API implementation issues
      6. Language specific API specification and examples
         6.1. SLP API C bindings
              6.1.1. Header file definitions
              6.1.2. Interface clarification
              6.1.3. Examples
         6.2. SLP API Java bindings
              6.2.1. Class definitions
              6.2.2. Examples
         6.3. Syntax for string parameters
              6.3.1. Character Escapes



Guttman,Provan                                                  [Page 2]


Internet Draft        An API for Service Location          24 March 1997


              6.3.2. String Matching
              6.3.3. Query Syntax
                     6.3.3.1. List Query Syntax
                     6.3.3.2. General Query Syntax
                     6.3.3.3. White Space
              6.3.4. Attribute Registration List
              6.3.5. Attribute Deregistration List
              6.3.6. Attribute Selection List Syntax
         6.4. Configuration File Format
      7. Interpretation of SLP error values
      8. Security Considerations
      9. Internationalization Considerations
         9.1. Character Set identification and use
         9.2. Language identification and translation
     10. Bibliography
     11. Author's Address

1. Introduction

   The Service Location API allows client and service programs to
   be modified in a very simple manner to provide dynamic service
   discovery and selection.

   The underlying protocol makes use of strings extensively, as
   does the interface.  String syntax for the List Query, General
   Query, Attribute Deregistration List and Attribute Registration
   List and Attribute Filter List are defined below, in the
   appropriate sections.

   The API bindings are given in C and Java.  The semantics are
   discussed in a language and implementation neutral way, with
   these details left to later sections.

   Applications which are modified to use this API will be
   source compatible with different SLP framework implementations.

2. Glossary

   Service Location Protocol (SLP)

      The underlying protocol allowing dynamic and scalable
      service discovery.  This protocol is specified in the Service
      Location Protocol [SLP].

   SLP framework

      When a 'Service Location framework' is mentioned, it refers
      to all existing SLP agents in the network, the SLP implementation
      and interface implementation; ie. whatever provides the SLP
      functionality to user level programs.  The SLP framework is
      transparent to applications using the SLP API, which is to say



Guttman,Provan                                                  [Page 3]


Internet Draft        An API for Service Location          24 March 1997


      they do not need to know whether there are DAs, whether DHCP
      is being used, and so on.

   Directory Agent (DA)

      A service which automatically gathers service advertisements
      from SAs in order to provide them to UAs.

   User Agent (UA)

      This is the Service Location process or library which allows
      SLP requests to be made on behalf of a client process.  UAs
      direct requests to DAs when they exist automatically when
      they exist.  In their absence, UAs make requests directly
      from SAs.

   Service Agent (SA)

      This is the Service Location process or library which allows
      service software to register and deregister itself with the
      SLP framework.  The SA SHOULD also respond to UA requests
      directly in the absense of DAs.

   Service advertisement

      A service: URL possibly combined with service attributes.
      When a service 'makes' a service advertisement, it uses the
      SL_Register API.  This distributes the service advertisements
      to Directory Agents and in the SLP framework.

   The service: URL

      A service of a particular type announces its availability
      with a service: URL which includes its service access point
      (domain name and possibly its port number) and optionally
      basic configuration parameters.

   Service Attributes

      The attributes associated with a given service.  The values
      that can be assigned to service attributes are defined by the
      Service Type template.

   Service Type template

      A document which describes the syntax of the service: URL for
      a given Service Type, the protocol the client will use to make
      use of the service and a definition of all service attributes:
      the meaning, defaults, constraints of each value the attributes
      can take on.  Each Service Type is identified by a string
      (usually the same name as the protocol used to deliver the



Guttman,Provan                                                  [Page 4]


Internet Draft        An API for Service Location          24 March 1997


      service.)  See "The service: URL Scheme" [SRV].

   Scope

      A string used to control the availability of service
      advertisements.  Scopes are assigned by site administrators to
      group services for many purposes, but chiefly as a means of
      scalability.  DAs assigned a scope will store only services
      advertised with the same scope value.  Scopes SHOULD be used
      only when there are DAs assigned a scope, see section 3.5
      below.

   Protected Scope

      A Protected Scope is a Scope for which SAs have cryptographic
      keying material sufficient to provide a digitial signature
      over service URL and attributes which are registered or
      deregistered.  A DA will reject SA registrations and
      deregistrations for protected scopes for which the digital
      signature is absent or fails to show the SA belongs to the
      protected Scope.  Similarly, UAs may verify the signatures
      for URLs and Attributes (if they request ALL attributes) to
      determine if the service registration is from the protected
      scope.  This gives the UA confidence that the Service can
      be trusted to be what it purports to be.

   Closure

      The set of attributes supported by all the services in a
      network of a particular type.  For instance, the collected
      attributes of all printers may be obtained.  Closures are
      used to discover the range of possible values for services.
      Service queries are constructed by selecting combinations
      of desirable characteristics from this range.

   Naming Authority (NA)

      This is a 'suffix' to the service type string.  It completely
      changes the meaning of the service type.   NAs SHOULD only be
      used for private definitions of well known Service Types and
      experimental Service Type extensions.  The default NA is
      "IANA", which may be omitted.

3. Interfaces

   Of the interfaces listed below, three are for use only in a C API:
   SL_Open, SL_Close and SL_Free.  The first two interfaces are
   unnecessary in an object oriented interface, as the object
   initialization and finalization code will perform all the needed
   resource allocation and freeing.  Further, the object providing SLP
   interfaces will encapsulate preference variables.  SL_Free is



Guttman,Provan                                                  [Page 5]


Internet Draft        An API for Service Location          24 March 1997


   included solely as a convenience, for freeing Result data structures.
   In an object-oriented language, resource freeing will be handled by
   the result objects themselves.

   The C API requires the use of a SL_SrvHandle, which is created by
   SL_Open and passed into each interface.  The analogous entity for the
   Java API is the ServiceLocator object which encapsulates all the
   information and functionality that the SL_SrvHandle provides.  For
   Java interface implementors:  The semantics of SL_Open and SL_Close
   must be followed even if SL_SrvHandles are not required.

   Note that proper use of Scopes is critical for correct and scalable
   use of Service Location.  The important notes about the use of Scopes
   are included in section 3.5, below.

3.1. SL_Open

   This interface is used to create a "SL_SrvHandle", which encapsulates
   the program's default settings set by this call.

   SL_Open may also be used to modify the settings associated with an
   existing SL_SrvHandle.  SL_Open must be used to generate a
   SL_SrvHandle before any other API functions are used:  The library
   should be initialized at this point.

   The settings which are configurable by SL_Open determine how service
   requests will be issued.  They include the Language tag, character
   set, the maximum time to wait for a response, and whether to "get all
   services" or just "return the first one found." These settings apply
   only to service requests. Registrations and deregistrations have
   parameters to pass this information explicitly.

   The SL_SrvHandle is entirely implementation dependent.  It is a
   simple mechanism which allows instrumentation, resource tracking and
   avoidance of global state.  The SL_SrvHandle will also allow the API
   implementation to refer to some synchronization state, to provide the
   synchronous and sequential access semantics described in Section 4.1.

3.2. SL_Close

   This interface closes and frees all resources associated with the
   SL_SrvHandle.  It sets the SL_SrvHandle to NULL.   When the last
   SL_SrvHandle is closed, the library frees all its resources.

3.3. SL_Register

   The service supplies a service: URL, and possibly service attributes.
   The attributes to use, their defaults and interpretation, are all
   given in the Service Type template. The service also specifies the
   Lifetime of the service (how long it can be cached), as well as the
   Language tag and character set used.



Guttman,Provan                                                  [Page 6]


Internet Draft        An API for Service Location          24 March 1997


   A call to SL_Register with a URL which has already been registered
   will be an 'update'.  It will replace the attributes previously
   registered, if the update contains attributes of the same name and
   language.  For example: If the first registration has attributes

      "(A=1),(B=2),(C=3)"

   and the subsequent registration has attributes

      "(C=30),(D=40)"

   the registration will end up with

      "(A=1),(B=2),(C=30),(D=40)".

   An Attribute Registration list string is used for registration. The
   above are examples of such strings.

   Service advertisements may be made multiple times for the same URL,
   in different languages.  A service program may provide different
   translations of the services offered in this way.  For example, the
   service could be registered with service attributes translated to
   English, Russian and Arabic, with the appropriate character sets.
   The same service: URL may now be obtained by users with different
   language skills.

   A service registered without a scope may only be available from DAs
   which have not been configured with any scopes.  UAs must explicitly
   request services which are unscoped.   For these reasons, it is
   highly recommended that scopes be used if they have been defined for
   a given site.  A service is registered in a scope by including a
   scope attribute.  For instance, if a service is in scope
   ADMINISTRATION and WESTERN CAMPUS, the following attribute is
   registered:

      "(SCOPE=ADMINISTRATION,WESTERN CAMPUS)"

   The iLifetime parameter is the time, in seconds, that the service
   should be maintained in caches. In other words, this parameter
   supplies the SA with the value to use in the lifetime field of URL
   block.  The SA is responsible for refreshing the service before the
   lifetime expires.  It can take any value from 0-65535 (seconds).

   The values zero (SL_LIFETIME_NONE) and 0xFFFF (SL_LIFETIME_DEFAULT)
   are reserved.  SL_LIFETIME_NONE indicates the API implementation must
   reregister the advertisement, so that it will be continuously
   available.  SL_LIFETIME DEFAULT will use CONFIG_INTERVAL_1 from the
   SLP specification as the lifetime.

3.4. SL_DeRegister




Guttman,Provan                                                  [Page 7]


Internet Draft        An API for Service Location          24 March 1997


   The service: URL of the service to deregister must be provided. If
   this is the only information provided, the service advertisement will
   be deregistered in every language and character set it has been
   registered in.

   If a Language tag, character set and Attribute Deregistration List
   are provided the attributes indicated by the attribute tags in the
   Deregistration list will be removed from the service advertisement.

3.5. SL_GetScopes

   This returns an array of strings with all available scope values. The
   list of scopes could be configured manually, determined with DHCP, or
   built from the DA discovery process.  The order in which the scopes
   are returned indicates the order of preference:  The first scope in
   the Scope array should be prefered to the second, etc.

   Scopes which are not obtained from DAs, DHCP or static configuration
   MUST NOT be returned.  It is possible that a SA advertises a service
   in such a scope, but not at all recommended.  SL_GetScopes must not
   return scopes which are present only in advertisements from SAs and
   unscoped DAs.  The Scope list MUST represent only scoped DAs and the
   configuration obtained from DHCP and static configuration files.

   UAs SHOULD use a scope obtained from SL_GetScopes in requests
   whenever possible.  If this Scope is omitted, scoped services
   information will not be returned.  If there are no scoped DAs, UAs
   SHOULD NOT include a scope string in requests and SAs SHOULD NOT
   advertise services with a scope attribute.

3.6. SL_GetServiceTypes

   This returns an array of strings with all available service types.
   Service Types with NAs will be returned as distinct Service Types,
   ie.  "blah" and "blah.xyz" are not the same.

   This request may include a Scope.  If it does not, it will only
   return the Service Types of service advertisements made without a
   Scope.

   The request may also include a Naming Authority.  If it does not,
   only service types with the default NA will be returned ("IANA", or
   no explicit NA.)  If a specific NA is desired, this must be passed
   in.  If all Service Types are desired, irrespective of the NA, the
   string "*" must be provided as the NA parameter.

3.7. SL_GetService

   This interface takes a Query String.   This string includes three
   parts:




Guttman,Provan                                                  [Page 8]


Internet Draft        An API for Service Location          24 March 1997


      Service Type - (can be discovered using SL_GetServiceTypes)
      Scope            - (can be discovered using SL_GetScopes)
      Query            - (can be either a list or general query.
                          The attributes used in the query can be
                          discovered using SL_GetAttrs).

   The Query portion of the parameter allows the caller to specify
   exactly what service advertisement or advertisements are desired. See
   section 6.3.3 for the string syntax of the Query.

   This returns one or more service: URLs, their Lifetime in seconds and
   address information ready to be used in networking calls.

3.8. SL_GetAttrs

   If the URL supplied is a complete service: URL, the attribute
   information returned will be for that particular service.

   The service type string may include a NA suffix.  The syntax for
   including this is:

      service-type-with-NA = srvtype-string "." NA-string
      restricted-string    = DIGIT / ALPHA / "+" / "-"
      srvtype-string       = 1*restricted-string
      NA-string            = 1*restricted-string

   Attributes will only be returned for the service registered with the
   Scope provided in the SL_GetAttrs call.

   Finally, the result may be filtered with a Attribute Request Filter
   string parameter.  If this is not supplied, ALL attributes are
   returned.  If it is supplied, only those attributes on the list are.
   An attribute tag with a '*' at the beginning, ending or both matches
   all attributes whose attribute tag ends, starts or or contains the
   substring, respectively.

      "bob*" matches "bob" and "bobkat"
      "*bob" matches "bob" and "some bob"
      "*bob*" matches "bob", "bobkat", "some bob" and
                      "a bob example".

   A Service Type string may be passed in as the URL parameter instead
   of providing a complete service: URL.  In this case, the results
   which are returned are the attributes for ALL services of the
   specified Service Type.

3.9. SL_Free

   This API is only available for a C language interface.  This function
   frees all resources associated with the data passed in.  The Result
   pointer passed in will be modified to be NULL.



Guttman,Provan                                                  [Page 9]


Internet Draft        An API for Service Location          24 March 1997


3.10 SL_Binary2Opaque

   This API allows a buffer of arbitrary bytes to be encoded in a string
   value appropriate for inclusion in a service advertisement.

4. API programming notes

4.1. Multithreading issues

   Each SL_SrvHandle (C) or ServiceLocator Object (Java) will only allow
   one concurrent access at a time.  Interfaces are synchronous and will
   block until they are complete.  If a second thread attempts to use
   the same SL_SrvHandle or ServiceLocator Object to perform a SLP API
   function which has been labeled as 'synchronous', it will block until
   the first thread completes its synchronous operation.

   A multithreaded program may create multiple SL_SrvHandles or
   ServiceLocator objects to make concurrent use of SLP interfaces.

4.2. Nonstandard Services Types are easy

   It is trivial to register and discover services of nonstandard types.
   Simply make up a Service Type string (by convention, nonstandard
   service types begin with the string "x-").

4.3. Typical Client Scenarios

   There are two typical use scenarios:

     - canned query:  Issue a SL_GetService.  Try each service in turn
       in the reply until one works.

     - browse for a service:  Issue SL_GetScopes.  Issue SL_GetAttrs for
       the desired Service Type using the selected Scope.  Construct a
       query string, then use SL_GetService.  If the user wishes, call
       SL_GetAttrs to get all (or some more) attributes for the service
       returned by the SL_GetService.

4.4. Top level information

   The SL_GetServiceTypes is used to implement network service browsers
   and administrative tools.  Normally a client application knows what
   Service Type it will need.

   Use the Service Template as a guide to designing client query and
   service profile user interfaces.  It can also be used for designing a
   user interface for system administrators who will define the
   attributes of a service.  Service Templates are themselves a service
   which can be discovered.  See "The service: URL Scheme" [SRV].

4.5. Example applications of SLP



Guttman,Provan                                                 [Page 10]


Internet Draft        An API for Service Location          24 March 1997


   The most common use of SLP will simply be for clients to locate their
   server by type and attribute.  Many distributed applications require
   discovery at configuration time.  The SLP framework provides a
   lightweight standard mechanism for doing this.  Example domains which
   might benefit are:  Client-Server Database systems, network based
   games, and distributed object systems.

   Some more sophisticated examples are described below:

4.5.1. Coarse dynamic load balancing

   One approach to load balancing simply distributes work on a rotating
   basis among a set of servers.  This rotation may be achieved using
   redirection at various levels.  This is a static approach:  It has an
   distribution algorithm which does not change depending on the actual
   state of the servers.

   A better approach could be to have the services provide feedback, so
   as to allow dynamic load balancing.  In this approach, the state of
   the load of the services themselves determines the amount of work to
   shift away or to the server.

   To achieve this, services would have to be instrumented so as to
   provide a "load metric."  This attribute could be advertised using
   SL_Register, updating the current service advertisement.  The finest
   granularity achievable given the timing of SLP would be on the order
   of seconds.  This is why I call the dynamic load balancing "coarse."

   Clients seeking to dynamically discover a server with the lowest
   "load metric" would first issue a SL_GetAttrs to obtain the range of
   the attribute.  Then, the SL_GetService function would be used, with
   the query selecting the lowest load metric value.  This would return
   the service: URL to use.

4.5.2.  Mobile user finds the nearest printer

   A mobile user could use SL_GetAttrs to on the lpr service type,
   requesting all "Location Description" and "Location Address"
   attribute values be returned.  The user is presented with this list
   and selects the closest location.  SL_GetServices is used to obtain
   the service: URL which has this location attribute.  The user may now
   print and know where to find the result.

4.5.3.  Providing highly available services

   When a vital service needs to be brought down, users often suffer
   down time.  This requires network administrators to communicate with
   their user community, defer nonessential maintenance and upgrades and
   to schedule them at off hours.

   Using Service Location, system administrators would need only start a



Guttman,Provan                                                 [Page 11]


Internet Draft        An API for Service Location          24 March 1997


   back up service and bring down the primary server. Client software
   could simply rediscover the necessary service by type and
   characteristic, reconnect and proceed.

   This sounds harder than it would be in practice:  The client software
   would only need to be changed in one respect.  The error path which
   announced the client "lost contact with the server" would be changed.
   The same code the client used for dynamically discovering the service
   in the first place would be used again.  Only if this rediscovery
   fails need the software decry its sad disconnection.

5. API implementation issues

   The primary goal of the API is to provide implementation independence
   and SLP framework transparency.  Some SLP transactions are
   request/reply from one host to another, others require repeated
   multicast and convergence, from one host to many.  The SLP API
   implementation must hide the details of this from the application
   using it, so that only performance will vary given differences in the
   SLP framework.

   Results of requests should always be collated to remove duplicates.
   This is especially important for the results of SL_GetAttrs and
   SL_GetTypes when there are no DAs:  The request will be multicast to
   all SAs, and the results will no doubt include duplicate values.

   An SA implementation requires as a minimum that service
   advertisements be registered with a DA.  They SHOULD be able to
   respond to UA queries directly in the absense of a DA.

   If the latter feature is implemented, the SA will run on the same
   host, and need some way to service UA requests on behalf of all the
   hosts services.  This SA must listen for TCP requests. Since only one
   process per host may be bound to a particular TCP port, the SA
   process will have to be a shared resource and communicate with the
   different service processes using some form of interprocess
   communication.

   If the SA and DA are on the same host, it is possible that a request
   might arrive which could be answered by both of them.  It is never
   wrong to reply with more information than the SLP semantics would
   normally return.

   The UA should evaluate the type of any given attribute by applying
   the following algorithm. First, if the attribute's value is "TRUE" or
   "FALSE", the attribute type is SL_BOOL_VAL. If the attribute's value
   is a string representing a number between -2147483648 and 2147483647,
   the type is SL_INT_VAL. If the attributes value is a string matching
   the syntax '(' 1*DIGIT ':' radix-64-chars ')', it is SL_OPAQUE_VAL.
   If none of these apply, then the attribute's type is SL_STR_VAL.




Guttman,Provan                                                 [Page 12]


Internet Draft        An API for Service Location          24 March 1997


   If an attribute has multiple values, the type of the values is
   determined the following way:  If ALL the values are consistent,
   return the type of the values (ie. SL_INT_VAL for multiple integers.)
   If the values are inconsistent, as for "(A=one, 1, true, (3:0000))",
   the return type is SL_STR_VAL; all of A's values are considered
   strings.

6. Language specific API specification and examples

   The interfaces presented below are not equivalent, though they both
   have the semantics described in sections 3, 4 and 5 above.

6.1 SLP API C bindings

6.1.1. Header file definitions

   /*
    * The SLP API definition.
    *
    * Published in: draft-ietf-svrloc-api-01.txt
    * Erik Guttman
    * Sun Microsystems, Inc.
    * March, 1997
    *
    */

   /*-------------------------------------------------------------
    * type declarations for service location
     */

   #ifndef SLP_H
   #define SLP_H

   #ifdef __cplusplus
   extern "C" {
   #endif /* for C++ use of C interface */

   typedef enum {
     SL_LIFETIME_DEFAULT = 0xFFFF,   /* use CONFIG_INTERVAL_1 */
     SL_LIFETIME_NONE = 0            /* register indefinitely */
   } SL_SpecialLifetime;

   typedef enum {
     SL_CHAR_ASCII = 3, SL_CHAR_LATIN1 = 4, SL_CHAR_UTF8 = 6
   } SL_CharType;

   typedef enum {
     SL_TYPE_RESULT = 1, SL_ATTR_RESULT = 2, SL_SRV_RESULT = 3,
     SL_SCOPE_RESULT = 4
   } SL_ResType;




Guttman,Provan                                                 [Page 13]


Internet Draft        An API for Service Location          24 March 1997


   typedef enum {
     SL_STR_VAL = 1, SL_INT_VAL = 2,  SL_OPAQUE_VAL = 3,
     SL_BOOL_VAL = 4
   } SL_ValType;
   /*-----------------------------------------------------------------
    * SLP errors, can be received from a DA or SA.
    */

   typedef enum {
     SLP_OK                     = 0,
     SLP_LANG_NOT_SUPPORTED     = 0x01,
     SLP_PROTOCOL_PARSE_ERR     = 0x02,
     SLP_INVALID_REGISTRATION   = 0x03,
     SLP_SCOPE_NOT_SUPPORTED    = 0x04,
     SLP_CHARSET_NOT_UNDERSTOOD = 0x05,
     SLP_AUTHENTICATION_INVALID = 0x06,

     /*-----------------------------------------------------------------
      * Interface errors.
      */

     SLP_NOT_SUPPORTED_YET            = 0x10,
     SLP_REQUEST_TIMED_OUT            = 0x11,
     SLP_COULD_NOT_INIT_NET_RESOURCES = 0x12,
     SLP_COULD_NOT_ALLOCATE_MEMORY    = 0x13,
     SLP_PARAMETER_BAD                = 0x14,
     SLP_INTERNAL_NET_ERROR           = 0x15,
     SLP_INTERNAL_SYSTEM_ERROR        = 0x16
   } SL_Error ;

   typedef enum {
     SL_Srv_IgnoreCache    = 0x01, /* Will ignore UA caches            */
     SL_Srv_DoNotResolve   = 0x02, /* Will not resolve URL domain name */
                                   /* to struct sockaddr_in            */
     SL_Srv_ForceMulticast = 0x04  /* Will not use DA, will multicast  */
   } SL_SrvFlags;

   typedef struct servicetag {
     char               *s_pcURL;
     struct sockaddr_in  s_sin;
     int                 s_iLifetime;
   } SL_Service;

   typedef struct opaquetag {
     int      op_iLen;
     char    *op_pcVal;
   } SL_Opaque;

   typedef union {
     long      intval;
     int       boolval;



Guttman,Provan                                                 [Page 14]


Internet Draft        An API for Service Location          24 March 1997


     SL_Opaque opaqueval;
     char     *pcStrVal;
   } SL_Value;

   typedef struct attrtag {
     int         a_iNumVals;
     char       *a_pcAttrTag;
     SL_ValType  a_slvaltype;
     SL_Value   *a_pslValue;
   } SL_Attribute;

   typedef union {
     SL_Service    i_sl_service;
     SL_Attribute  i_sl_attribute;
     char         *i_pcSrvtype;
     char         *i_pcScope;
   } SL_ResInfo;

   typedef struct resulttag {
     SL_Error    r_iErrorCode;
     int         r_iNumValues;
     int         r_iCharEncoding;
     char       *r_pcLang;
     SL_ResType  r_sl_restype;
     SL_ResInfo *r_psl_Info;
   } SL_Result;

   typedef void* SL_SrvHandle;

   /*------------------------------------------------------------
    * Ease-of-use macros, to enable dereferencing of structures.
    *
    *    res_srv_url        returns the URL of the i'th service
    *                          in the service result
    *    res_srv_sin        returns the struct sockaddr_in of the
    *                          i'th service in the service result
    *    res_srv_life       returns the lifetime in seconds of the
    *                          i'th service in the service result
    *    res_srvtype        returns the string of the i'th service
    *                          type in the service type result
    *    res_scope          returns the scope string of the i'th
    *                          scope result
    *    res_attr_numval    returns the number of attr values for
    *                          the i'th attr in the attr result.
    *    res_attr_tag       returns the tag string for the i'th
    *                          attr in the attr result
    *    res_attr_type      returns the type for the i'th attr
    *                          in the attr result
    *    res_attr_str       returns the j'th string value of the
    *                          i'th attr in the attr result
    *    res_attr_int       returns the j'th int value of the i'th



Guttman,Provan                                                 [Page 15]


Internet Draft        An API for Service Location          24 March 1997


    *                          attr in the attr_result
    *    res_attr_bool      returns the j'th boolean value of the
    *                          i'th attr in the attr result
    *    res_attr_opaque    returns the j'th opaque value of the
    *                          i'th attr in the attr result
    */

   #define res_srv_url(i)     r_psl_Info[(i)].i_sl_service.s_pcURL
   #define res_srv_sin(i)     r_psl_Info[(i)].i_sl_service.s_sin
   #define res_srv_life(i)    r_psl_Info[(i)].i_sl_service.s_iLifetime
   #define res_srvtype(i)     r_psl_Info[(i)].i_pcSrvtype
   #define res_scope(i)       r_psl_Info[(i)].i_pcScope
   #define res_attr_numval(i) r_psl_Info[(i)].i_sl_attribute.a_iNumVals
   #define res_attr_tag(i)    r_psl_Info[(i)].i_sl_attribute.a_pcAttrTag
   #define res_attr_type(i)   r_psl_Info[(i)].i_sl_attribute.a_slvaltype
   #define res_attr_str(i,j)               r_psl_Info[(i)].i_sl_attribute.a_pslValue[(j)].pcStrVal
   #define res_attr_int(i,j)               r_psl_Info[(i)].i_sl_attribute.a_pslValue[(j)].intval
   #define res_attr_bool(i,j)              r_psl_Info[(i)].i_sl_attribute.a_pslValue[(j)].boolval
   #define res_attr_opaque(i,j)            r_psl_Info[(i)].i_sl_attribute.a_pslValue[(j)].opaqueval

   /*-------------------------------------------------------------------
    * General interfaces for all clients
    *
    * The term "EXPORT" is included so as to make the interface portable
    * to Win32.  For Unix environments, etc. EXPORT is defined as nothing.
    * For Win32, EXPORT is __declspec(dllimport) for the client library
    * and __declspec(dllexport) for the library implementation.
    */

     /*------------------------------------------------------------------*/
     EXPORT SL_SrvHandle SL_Open(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open   */
            const char  *pcLangPref,       /* Set to the ISO 639 code    */
            int          iDialect,         /* Set to 0, reserved         */
            int          iMonoling,        /* 1 = Monolingual, 0 = not   */
            int          iMaxWait,         /* # seconds max, 0 = default */
            int          iMultiple,        /* 0 = return first result,   */
                                           /* 1 = return all results     */
            SL_CharType  slchartype,       /* Type for characters used.  */
            SL_Error    *pErrValue);       /* 0 unless an error occurred */

     /*------------------------------------------------------------------*/
     EXPORT void       SL_Close(
            SL_SrvHandle *pSL_SrvHandle);  /* pSrvState from SL_Open  */

   /*------------------------------------------------------------------
    * SA interfaces
    */

     /*------------------------------------------------------------------*/
     EXPORT SL_Error SL_Register(



Guttman,Provan                                                 [Page 16]


Internet Draft        An API for Service Location          24 March 1997


            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            const char  *pcURL,            /* Unique URL (of reg.)      */
            const char  *pcLang,           /* Language code of reg.     */
            int          iDialect,         /* Set to 0, reserved.       */
            SL_CharType  slchartype,       /* Character type of reg.    */
            const char  *pcAttributes,     /* Service Attribute list    */
            int          iLifetime);       /* 1..65534 = # of seconds   */

     /*------------------------------------------------------------------*/
     EXPORT SL_Error SL_DeRegister(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            const char  *pcURL,            /* URL (of service todereg.) */
            const char  *pcLang,           /* Language code of dereg.   */
            int          iDialect,         /* Set to 0, reserved.       */
            SL_CharType  slchartype,       /* Character type of dereg.  */
            const char  *pcAttrTags);      /* Tags of attrs to dereg.   */


     /*------------------------------------------------------------------*/
     /* SL_Binary2Opaque -
      *
      *   This utility routine allows a service to convert a binary
      *   value into the opaque attribute value encoding used by
      *   Service Location.  A binary buffer must be converted into
      *   a Radix-64 format so as to be transmitable in the string
      *   syntax.
      *
      *   The SL_Opaque value is passed in for conversion.  The
      *       caller must set both the fields: op_iLen (to the
      *       length of the buffer) and op_pcVal (to the buffer).
      *   The pcOpaqueBuffer is the buffer used by the library to
      *       store the results of the conversion from binary to
      *       opaque representation.
      *   The iLenOpaqueBuffer is the length of the buffer to store
      *       the string into.  Note that this length must be ATLEAST
      *       (iLenBinaryBuffer*4)/3 + iLenOpaqueBuffer/10 + 5.
      *
      *   If either buffer is not supplied or the lenght is insufficient
      *       the library will return a SLP_PARAMETER_BAD error.
      */
     EXPORT SL_Error SL_Binary2Opaque(
         const SL_Opaque *pslo,         /* Opaque to convert         */
         char       *pcOpaqueBuffer,    /* User supplied data buffer */
         int         iLenOpaqueBuffer); /* Length of data buffer     */


   /*------------------------------------------------------------------
    *  UA interfaces
    */

     /*------------------------------------------------------------------*/



Guttman,Provan                                                 [Page 17]


Internet Draft        An API for Service Location          24 March 1997


     /* SL_Result -
      *
      *   Returns the list of scopes for DAs which have been discovered.
      *   If the UA or SA has been configured to use only a particular
      *   set of Scopes, (via DHCP or a static configuration file),
      *   these are the Scope strings which are returned.
      *
      *   SL_Result is allocated by the library and must be freed using
      *   SL_FreeResult(SL_Result*).
      */

     EXPORT SL_Result * SL_GetScopes(
            SL_SrvHandle hSL_SrvHandle);   /* State created by SL_Open  */

     /*------------------------------------------------------------------*/
     EXPORT SL_Result * SL_GetSrvTypes(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            const char  *pcNamingAuth,     /* NULL = default            */
            const char  *pcScope);         /* NULL = none               */

     /*------------------------------------------------------------------*/
     EXPORT SL_Result * SL_GetAttrs(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            const char  *pcURL,            /* Either full or partial    */
            const char  *pcScope,          /* Scope of attrs to get     */
            const char  *pcAttrTags);      /* Tags for 'selected' attrs */

    /*------------------------------------------------------------------*/
     EXPORT SL_Result * SL_GetService(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            const char  *pcRequest,        /* Request string to supply  */
            int          iFlags);          /* 0 = none, otherwise '|'   */
                                           /* 'SL_Srv' flags, see above */

     /*------------------------------------------------------------------*/
     EXPORT void    SL_FreeResult(
            SL_SrvHandle hSL_SrvHandle,    /* State created by SL_Open  */
            SL_Result  **ppResult);        /* SL_Result to be freed     */

   #ifdef __cplusplus
   }
   #endif /* for C++ use of C interface */

   #endif /* End of the SLP API definition */
   /*------------------------------------------------------------------*/

6.1.2. Interface clarification

   The values #defined with SLP_ as their prefixes are the return values
   of the interfaces.  In the case of SL_Open, the return value is set
   via an integer parameter supplied by the caller.  In SL_Register and



Guttman,Provan                                                 [Page 18]


Internet Draft        An API for Service Location          24 March 1997


   SL_DeRegister the int is returned directly. In the case of all the
   queries beginning with "SL_Get", the result code is in the Result
   value returned, in the r_iErrorCode field of the structure.  In the
   case of an error, results MAY be returned on a best effort basis.

   SL_Open

      Pass NULL in as the SrvHandle parameter to create a new SrvHandle.
      Pass an existing SrvHandle parameter to modify the default values
      associated with it.

   SL_Register

      The pcLang and slchartype parameter must be set.  See [SLP] for
      a table of legitimate values for pcLang.  iDialect MUST be set
      to 0.  See Section 6.3.4. for the syntax of pcAttributes.

      A special service handle, SL_PERM_SRV_HANDLE, can be used to
      register permanent services. Such services must be explicitly
      deregistered: they would not be automatically deregistered when
      the registering applications exits.

   SL_DeRegister

      The pcURL paramter must be set.  Instead of deregistering the
      service, one can deregister attributes.  In this case the pcLang
      and slchartype parameter must be set.  iDialect MUST be set
      to 0.  See Section 6.3.5. for the syntax of pcAttrTags.

      SL_PERM_SRV_HANDLE can be used to deregister permanent services.

   SL_GetSrvTypes

      The parameters may be NULL.

   SL_GetAttrs

      The pcURL parameter must be supplied.  It can either be a
      complete service: URL or merely a Service Type string.  The
      semantics of the call vary in this case.

      The psScope parameter may be NULL.

      The pcAttrTags parameter may be NULL.  If it is not, it follows
      the grammar in Section 6.3.6.

   SL_GetService

      The pcQuery must be supplied.  It follows the grammar in Section
      6.3.3.




Guttman,Provan                                                 [Page 19]


Internet Draft        An API for Service Location          24 March 1997


   SL_Free

      The value of the Result will be freed, as well as the pointer
      passed in.

   SL_Binary2Opaque

      The caller supplies a SL_Opaque to be converted and the buffer
      into which the converted value will be copied.

6.1.3. Examples

   Suppose web servers register themselves with Service Location.
   The attributes they register are their Scope as well as an
   index of all the 'home pages' available on the server.  The
   home pages are listed as

      <relative URL> "::" <title> "::" <description>

      The web server could do the following:

         int err = SLP_OK;
         SrvHandle sh = SL_Open(
            NULL,       /* NULL indicates: Create the SrvHandle */
            "en", 0,    /* Select English as default language   */
            1,          /* Monolingual results for replies      */
            10,         /* 10 seconds max blocking on calls     */
            1,          /* Return all results                   */
            CHAR_UTF8,  /* All requests and replies in UTF8     */
            &err);      /* error value will be returned in err. */
         if (err != SLP_OK) ; /* do something better here       */
         err = SL_Register(
            sh,                              /* supply the SrvHandle   */
            "service:http://myhost.sun.com", /* supply the URL         */
            "en", 0,                         /* reg in English         */
            CHAR_ASCII,                      /* reg in UTF8            */
            "(SCOPE=ENGINEERING),"           /* declare attributes     */
            "(HOME PAGES="
              "schedule/index.html::Schedule::"
                 "This site contains updated time lines for all the work in"
                 "the F.L.O.R.B. project,"
              "snort/releases.html::Bob Snort's Home::"
                 "Release engineer Bob posts results of all the builds here,"
              "specs/index.html::Specs galore::"
                 "Technical specifications for the F.L.O.R.B. and X872"
                 "projects.)",
               SL_LIFETIME_DEFAULT);          /* use default lifetime   */

         if (err != SLP_OK) ; // do something better here

      A web browser could use Service Location to find a particular web site



Guttman,Provan                                                 [Page 20]


Internet Draft        An API for Service Location          24 March 1997


      this way.  Unlike web indexing search engines, SLP will keep information
      up to date and it will be available within a few seconds after a web
      server registers itself.

         /*
          * The client calls SL_Open, exactly as above.
          */
         char *pcPageDescr = NULL;
         Result *pr = SL_GetAttrs(
            sh,                /* The SrvHandle from SL_Open  */
            "http",            /* The service type desired    */
            "ENGINEERING",     /* The request's scope         */
            "HOME PAGES");     /* The attribute to return.    */
         if (pr->r_iErrorCode != SLP_OK) ; // do something better here

         /*
          * The client will examine the AttrResult and choose a HOME PAGE
          */
         SL_Free(&pr); /* free previous result */
         pr = SL_GetService(sh, "http/engineering/HOME PAGE ="
              "specs/index.html::Specs galore::"
                 "Technical specifications for the F.L.O.R.B. and X872"
                 "projects./");

         The service URL returned indicates the web server's address.

            "service:http://myhost.sun.com"

         The application can append on the "specs/index.html" from the
         attribute to obtain a URL for the browser to use:

            "http://myhost.sun.com/specs/index.html"

6.2. SLP API Java bindings

   The ServiceLocator is created using a 'singleton' interface.  This
   allows the implementation to keep track of state pertains to all
   instances of the class.  The AttributeResult provides the same
   information as the C interface, though in a different form.  The
   ServiceResult allows the creation of a Socket for immediate use of
   the application protocol.

6.2.1. Class definitions

   public class AttributeResult {
     public static final int TYPE_STRING = 1;
     public static final int TYPE_INT    = 2;
     public static final int TYPE_OPAQUE = 3;
     public static final int TYPE_BOOL   = 4;

     public int getType();



Guttman,Provan                                                 [Page 21]


Internet Draft        An API for Service Location          24 March 1997


     public int getCharSet();
     public String getLanguage();
     public int getDialect();

     public Vector vAttributes;  // may have String, int, boolean or byte[]
   };

   public class ServiceResult {
     public void setURL(String s) { sURL = new String(s); }
     public void setLifetime(int i) { iLifetime = i; }
     public void setAddress(InetAddress ia) { iaServiceAddress = ia; }
     public void setPort(int i) { iPort = i; }

     public String getURL() { return sURL; }
     public int    getLifetime() { return iLifetime; }
     public InetAddress getAddress() { return iaServiceAddress; }
     public int         getPort() { return iPort; }
   };

   public class ServiceLocator {
     // No Constructor

     // Constants
     public static final int CHAR_ASCII   = 3;
     public static final int CHAR_LATIN1  = 4;
     public static final int CHAR_UTF8    = 6;
     public static final int CHAR_UNICODE = 1000;
     public static final int LIFETIME_NONE    =  0;
     public static final int LIFETIME_DEFAULT = -1;

     // Class Methods
     public static ServiceLocator getServiceLocator();

     // Instance Methods
     public String  getLanguage();    // default to "en" (English)
     public int     getsDialect();    // set to 0
     public boolean getMonolingual(); // default to true
     public int     getMaxWait();     // default to 10 (seconds)
     public boolean getMultiple();    // default to true

     public void    setLanguage(String sLanguage);
     public void    setDialect(int iDialect); // do not use this
     public void    setMonolingual(boolean bMonolingual);
     public void    setMaxWait(int iMaxWait);
     public void    setMultiple(boolean iGetMultipleResults);

     public synchronized void SL_Register(
        String sURL,
        String sLanguage,
        int    iDialect,
        int    iCharType,



Guttman,Provan                                                 [Page 22]


Internet Draft        An API for Service Location          24 March 1997


        String sAttributes[],
        int    iLifetime)
        throws SLPException;

     public synchronized void SL_DeRegister(
        String sURL,
        String sLanguage,
        int    iDialect,
        int    iCharType,
        String sAttributes)
        throws SLPException;

     public synchronized String[] SL_GetScopes();

     public synchronized String[] SL_GetServiceTypes(
        String sNamingAuthority,
        String sScope)
        throws SLPException;

     public synchronized SL_ServiceResult SL_GetService(
        String sQuery)
        throws SLPException;

     public synchronized AttributeResult SL_GetAttrs(
        String sURL,
        String sScope,
        String sAttributeTags)
        throws SLPException;

     public synchronized AttributeResult SL_GetAttrs(
        String sServiceType,
        String sScope,
        String sAttributeTags)
        throws SLPException;

     public String SL_Binary2Opaque(
        byte   bBinary[]);

   };

   public class SLPException extends SLPException {
     public SLPException();
     public SLPException(String s);
   };

   // Exceptions caused by error conditions detected due to
   //    interaction with remote SLP entities (SAs and DAs)

   public class SLPLanguageNotSupportedException extends SLPException {
     public SLPLanguageNotSupportedException();
     public SLPLanguageNotSupportedException(String s);



Guttman,Provan                                                 [Page 23]


Internet Draft        An API for Service Location          24 March 1997


   };

   // Note:  This error should never occur.  It indicates a flawed
   //        underlying SLP implementation.  Hence, it is an error
   //        not an exception.
   public class SLPParseError extends SLPException {
     public SLPParseException();
     public SLPParseException(String s);
   };

   public class SLPInvalidRegistrationException extends SLPExcpetion {
     public SLPInvalidRegistrationException();
     public SLPInvalidRegistrationException(String s);
   };

   public class SLPScopeNotSupportedException extends SLPException {
     public SLPScopeNotSupportedException();
     public SLPScopeNotSupportedException(String s);
   };

   public class SLPCharsetNotUnderstoodException extends SLPException {
     public SLPCharsetNotUnderstoodException();
     public SLPCharsetNotUnderstoodException(String s);
   };

   public class SLPAuthenticationAbsentException extends SLPException {
     public SLPAuthenticationAbsentException();
     public SLPAuthenticationAbsentException(String s);
   };

   public class SLPAuthenticationFailedException extends SLPException {
     public SLPAuthenticationFailedException();
     public SLPAuthenticationFailedException(String s);
   };

   // Exceptions caused by error conditions arising through
   //    the program's use of the API or failure of the SLP
   //    implementation.

   public class SLPNotSupportedYet extends SLPException {
     public SLPNotSupportedYet();
     public SLPNotSupportedYet(String s);
   };

   public class SLPTimeOutException extends SLPException {
     public SLPTimeOutException();
     public SLPTimeOutException(String s);
   };

   public class SLPInitNetException extends SLPException {
     public SLPInitNetException();



Guttman,Provan                                                 [Page 24]


Internet Draft        An API for Service Location          24 March 1997


     public SLPInitNetException(String s);
   };

   // The 'message' SHOULD indicate which parameter was bad.
   public class SLPParameterBadException extends SLPException {
     public SLPParameterBadException();
     public SLPParameterBadException(String s);
   };

   public class SLPInternalNetError extends SLPException {
     public SLPInternalNetError();
     public SLPInternalNetError(String s);
   };

   public class SLPInternalSystemError extends SLPException {
     public SLPInternalSystemError();
     public SLPInternalSystemError(String s);
   };

6.2.2. Examples

   A simplest application is: A server of type blah makes a service
   advertisement:

      try {
        ServiceLocator sl = ServiceLocator.getServiceLocator();
        sl.SL_Register("service:blah://myhost.sun.com", // service URL.
                       "en", 0,         // Attributes is in English.
                       CHAR_ASCII,      // Attribute uses ASCII.
                       "(SCOPE=ADMIN)", // The attribute.
                       12*60*60); // 12 hour lifetime
      } catch (SLPException slpe) {} // do something better here

   A blah client system can discover this with the following:

      try {
        ServiceLocator sl = ServiceLocator.getServiceLocator();
        ServiceResult  sr = sl.SL_GetService("blah/admin//");
      } catch (SLPException) {} // do something better here
      try { Socket     s  = new Socket(sr.iaServiceAddress, sr.iPort); }
      catch (IOException) {}    // do something better here

      // ... now use s to do blah client-server stuff ...

   Note that the scope matching is case insensitive.  The query string
   is omitted, so the request will return all blah services.  The client
   may then proceed to use the blah service, simply by creating a socket
   from the information in the ServiceResult.

6.3. Syntax for string parameters




Guttman,Provan                                                 [Page 25]


Internet Draft        An API for Service Location          24 March 1997


   The definitions which follow are cumulative.   The syntax is
   specified using Augmented BNF [ABNF].  There are some rules which
   specify explicitly what characters are NOT permitted.

   For the syntax of the service: URL, see [SRV].

   6.3.1. Character Escapes

   If any string used in SLP includes a reserved character, it must be
   escaped.  For URLs, the escape mechanism is to replace the reserved
   character with "%" HEX HEX where HEX is either a DIGIT or an ALPHA.
   The encoding is the ASCII value of the reserved character.  For
   example:

     service:http://www.zilch.net/some%20path%20with%20spaces

   If any other string used in SLP (such as in a query string, an
   attribute list used in registration or an attribute reply, and so
   on,) the character escape mechanism used is to replace the reserved
   character with "&#" 1*DIGIT ";".  Here DIGIT is to be interpreted as
   a decimal representation of the character to be escaped, given the
   character set of the string encoding.  For example:

     (attr=value with a comma&#44; and an asterix &#42;)

   6.3.2. string matching

   Attribute tags and values may be used by some protocols for directory
   look-up.  In this case, the following rules should be applied for
   string matching of attribute strings.

   String matching MUST be done after character escape encoding has been
   removed, white space has been trimmed.  In addition, string matching
   SHOULD be case insensitive.

6.3.3. Query Syntax

   This is used in SL_GetService (See Section 3.7.)

   A Query may take two forms.

      white = SPACE / TAB / CR / LF

      query = listquery /         ; conjunction query
              generalquery /      ; complex query
              *white              ; ie. the query matches everything

   These are defined in the next sections.  The list-query is a very
   simple form.  The general-query allows arbitrarily complex logical
   combinations of conditions.




Guttman,Provan                                                 [Page 26]


Internet Draft        An API for Service Location          24 March 1997


   Common syntax to both kinds of queries follows:

      predicate   = srvtype [ "." na ] "/" scope "/" query "/"

      schemechar  = DIGIT / ALPHA / "+" / "-"

      srvtype     = 1*schemechar

      na          = 1*schemechar
                      ; omit na when it is "IANA", the default

      scope       = ; Any string with the following restrictions:
                    ; "/", ",", and ":" are not allowed in this
                    ; string. "LOCAL" and "REMOTE" scope strings are
                    ; reserved.

      safe-char   = ; Any character with the following restrictions:
                    ; "(", ")", ",", "=", "!", ">", "<", "/", "*"
                    ; are not allowed.  They must be escaped (see
                    ; Section 6.3.1.).

      attr-tag    = 1*safe-char

      safer-char  = ; As safe-char but SPACE is also not allowed.

      keyword     = 1*safer-char

      query-item  =  keyword / attr-tag comp-op value

      comp-op     = "!=" / "==" / "<" / "<=" / ">" / ">="

      value       = string / integer / boolean / opaque / partial-str

      string      = 1*safe-char

      integer     = [-] 1*DIGIT
                      ; The integer MUST fall within the range of
                      ; values a 32 bit integer may take, ie.
                      ; "-2147483648" to "2147483647".

      boolean     = "TRUE" / "FALSE"
                      ; These values are the only exception to the
                      ; Internationalization rules in Section 8.0.
                      ; Independent of the translation of the
                      ; attributes, the boolean values remain the
                      ; indicated strings.

      rad64-char  = ALPHA / DIGIT / "+" / "-" / white-sp

      opaque      = 1*DIGIT ":" 4*rad64-char
                      ; The digits define the original length of the



Guttman,Provan                                                 [Page 27]


Internet Draft        An API for Service Location          24 March 1997


                      ; opaque value. The restricted character string
                      ; is the radix-64 encoding of the opaque value.
                      ; See [RFC 1521], Section 5.2.

                      ; NOTE:  White space is ignored in decoding
                      ; radix-64 values.

      partial-str = ["*"] string ["*"]
                      ; If preceded by a "*", it matches all string
                      ; values ending with the string.  If followed
                      ; by a "*", it matches all string values which
                      ; begin with the string.  If both followed and
                      ; preceded by a "*", it matches all string
                      ; values which contain the string.  Refer to
                      ; section 3.8 for examples.

6.3.3.1. List Query Syntax

      list-query = 1#query-item

6.3.3.2. General Query Syntax

      general-query   = "(" "&" general-query query-item-list ")" /
                        "(" "|" general-query query-item-list ")" /
                        "(" query-item ")"

      query-item-list = general-query /
                        general-query query-item-list


   6.3.3.3. White Space

   A string is considered to be a token in the case of a tag or
   <string> value.  In this case, the string is 'trimmed'.  White
   space interior to a string token is left alone, while white
   space between the tokens is removed.  For example:

         "  some  name  =  some  value , another  example "

      would be trimmed to

         "some  name" "=" "some  value" and "another  example".

6.3.4. Attribute Registration List

   This is used in SL_Register (See Section 3.3.)

      attr-reg-list = 1#attr-reg
      attr-reg      = keyword / "(" attr-tag = 1#value ")

6.3.5. Attribute Deregistration List



Guttman,Provan                                                 [Page 28]


Internet Draft        An API for Service Location          24 March 1997


   This is used in SL_DeRegister (See Section 3.4.)

      attr-dereg-list = 1#attr-dereg
      attr-dereg      = keyword / attr-tag

6.3.6. Attribute Selection List Syntax

   This is used in SL_GetAttrs (See Section 3.8.)

      attr_select_list = 1#attr-select
      attr_select      = keyword / attr-tag / partial-tag
      partial_tag      = 1*safe-char "*"

6.4. Configuration File Format

   The following configuration file format is included so that static
   configuration files for one implementation of the SLP framework will
   be useful for other implementations.

      config-file    = [discovery-opts] [policy] [timing]

      discovery-opts = [da-discovery] [scope-discovery]

      da-discovery   = "DA-DISCOVERY" "=" *disc-opts CRLF

      disc-opts      = ["NO-DYNAMIC"] /
                       ["DHCP"]       /
                       ["STATIC"]     /
                       ["STRICT"]

      scope-discovery= "SCOPE-DISCOVERY" "=" *disc-opts CRLF

      If da-discovery includes the "STATIC" option, a static
      list of DAs must be provided.  This list has the following
      format:

      da-list        = "DA" "=" da-def *(break da-def) CRLF

      da-def         = fqdn /
                       dotted-decimal-ipv4 /
                       dotted-decimal-ipv6

      break          = CRLF 1*SPACE
                       ; Note - terms not beginning on the first
                       ; column of the configuration file are
                       ; considered continuations of a pervious
                       ; configuration parameter's definition.

      If scope-discovery includes the "STATIC" option a
      static list of Scopes must be provided.  This list has
      the following format:



Guttman,Provan                                                 [Page 29]


Internet Draft        An API for Service Location          24 March 1997


      scope-list     = "SCOPE" "=" scope-def *(break scope-def) CRLF

      scope-chars    = ALPHA / DIGIT / "+" / "-"

      scope-def      = 1*scope-chars

      The meaning of the disc-opts are as follows:

         NO-DYNAMIC

           Do not use multicast or broadcast for discovery.  Use
           of these is the default for the Service Location Protocol
           so this must be explicitly turned off with this configuration
           option.

         DHCP

           Use DHCP to acquire a list of DAs or a list of Scopes to
           use.

         STATIC

           Use the static list of DAs or Scopes which is provided.
           The order of the DHCP and STATIC options is relevant, if
           both options are provided.  Whichever is first will take
           precedence over the other.  If NO-DYNAMIC is *not* present
           dynamic information will always take the last place in
           lists of Scopes and DAs.

         STRICT

           In the context of scope-discovery, strict means that no
           registration or request may be issued unless it uses a
           scope.

           In the context of da-discovery, this option indicates
           that passive DA discovery is disabled.

      policy         = *policy-options

      policy-options = ["USE-BROADCAST" CRLF]  /
                       ["MULTICAST-RADIUS" "=" radius] /
                       ["MTU" "=" size]

      radius         = 1..32
                     ; That is, an integer from 1 to 32

      size           = *DIGIT
                     ; This is the maximum transmission unit for
                     ; the link layer used.  The recommended default
                     ; for SLP is 1400.



Guttman,Provan                                                 [Page 30]


Internet Draft        An API for Service Location          24 March 1997


      timing         = *timing-opts
      timing-opts    = ["TIME-0-CACHE-REPLIES" "=" seconds] /
                       ["TIME-1-REG-LIFETIME"  "=" seconds] /
                       ["TIME-2-RETRY-MCAST-Q" "=" times]   /
                       ["TIME-3-WAIT-MCAST-Q"  "=" seconds] /
                       ["TIME-4-WAIT-REGISTER" "=" seconds] /
                       ["TIME-5-RETRY-DA-DISC" "=" times]   /
                       ["TIME-6-QUIT-DA-WAIT"  "=" seconds] /
                       ["TIME-7-QUIT-DA-DISC"  "=" seconds] /
                       ["TIME-8-QUIT-SA-Q"     "=" seconds] /
                       ["TIME-9-DA-HEARTBEAT"  "=" seconds] /
                       ["TIME-10-WAIT-REG-DA-PASSIVE" "=" seconds] /
                       ["TIME-11-WAIT-REG-DA-ACTIVE"  "=" seconds] /
                       ["TIME-12-QUIT-IDLE-CONNECTS"  "=" seconds]
                     ; Please refer to [SLP] for the definitions of
                     ; these configuration options.

7.0. Interpretation of SLP error values

   SLP will only return an error code when an operation fails
   completely. If the request is partially satisfied -- at least one
   service is discovered, for example -- then SLP_OK is returned.

   The following errors report SLP protocol problems. The problem could
   be in the data supplied by the application or in the interaction of
   the local SLP implementation with a remote agent. In the latter case,
   the error can only be taken as a hint. Different remote agents may
   have returned several different errors. SLP might pick one to return
   to the operation, but it cannot guarantee that's the primary cause of
   the failure.

   SLP_LANG_NOT_SUPPORTED

    No DA or SA has service advertisement information in the language
    requested, but at least one DA or SA indicated, via the
    LANGUAGE_NOT_SUPPORTED error code, that it might have information
    for that service in another language.

   SLP_PROTOCOL_PARSE_ERR

    The SLP message was rejected by a remote SLP entity.  SLP returns
    this error only when no information was retrieved, and at least one
    SA or DA indicated a protocol error. This suggests an implementation
    error in either the local implementation or some other SLP
    implementation on the network. On the other hand, it can also be
    caused by damage to the packet in the network.

   SLP_INVALID_REGISTRATION

    SLP may return this error if an attempt to register a service was
    rejected by all DAs because of a malformed URL or attributes. SLP



Guttman,Provan                                                 [Page 31]


Internet Draft        An API for Service Location          24 March 1997


    will not return the error if at least one DA accepted the
    registration.

   SLP_SCOPE_NOT_SUPPORTED

    SLP may return this error code if the indicated scope is not known
    to the system. For example, if SLP is configured to allow only
    particular scopes, a request using a scope not in that list would
    result in this error.

   SLP_CHARSET_NOT_UNDERSTOOD

    SLP returns this error code if it does not understand the indicated
    character set, or if the operation fails because no DA or SA
    understands the character set, and the request cannot be converted
    into a more common character set such as ASCII.

   SLP_AUTHENTICATION_ABSENT

    If the SLP framework supports authentication, this error will arise
    when a remote DA fails to accept a registration.  This will occur if
    a SA attempts to register a service into a protected scope without
    including an authenticator.

   SLP_AUTHENTICATION_INVALID

    If the SLP framework supports authentication, this error will arise
    when a remote DA fails to accept a registration or deregistration
    due to an invalid authenticator.  This error will not occur if a UA
    rejects a reply to a request:  The UA will simply silently discard
    (and possibly log) the rejected reply.

   The following errors are generated through a program interacting with
   the API and SLP implementation.  The operation failed.

   SLP_NOT_SUPPORTED_YET

    When a particular feature is used which is not implemented in the
    API, this error is returned.  This error SHOULD not occur.

   SLP_REQUEST_TIMED_OUT

    When no reply can be obtained in the time specified by the
    configured timeout interval, this error is returned instead.

   SLP_COULD_NOT_INIT_NET_RESOURCES

    If the SLP framework cannot initialize properly, this error will be
    returned.

   SLP_COULD_NOT_ALLOCATE_MEMORY



Guttman,Provan                                                 [Page 32]


Internet Draft        An API for Service Location          24 March 1997


    If the API or SLP implementation fails to allocate memory, the
    operation is aborted and returns this.

   SLP_PARAMETER_BAD

    If a parameter passed into an interface is bad, this error is
    returned.

   SLP_INTERNAL_NET_ERROR

    The failure of networking during normal operations causes this error
    to be returned.

   SLP_INTERNAL_SYSTEM_ERROR

    A basic failure of the SLP implementation causes this error to be
    returned.  This occurs when a system call or library fails.  The
    operation could not recover.

8. Security Considerations

    SLP will make use of an existing host based authentication framework
    once it becomes available as an Internet Standard.  [RFC1825]

    In the absence of this, it is extremely easy for anyone to register
    any service with Service Location.  SLP does not authenticate the
    source of service advertisements, either at the DA or when the UA
    receives it.

    For this reason, use of SLP on open networks, such as the Internet,
    should be avoided.  A DA may be provided on an open network with
    registration capabilities disabled; but this is of limited utility
    since a UA would not  be able to distinguish it from a DA full of
    impersonations.

    For this reason, SLP should only be used in 'private' networks, as
    those behind firewalls where  users are expected to perform in a
    responsible manner.

    SLP is neutral to the protocols clients and servers use between
    themselves.  Strong bidirectional authentication at higher levels
    (ie. transport level: "The SSL Protocol, Version 3" [SSH] or
    application level: "Generic Security Service Application Program
    Interface" [GSSAPI],) would obviate the risk of masquerading by an
    adversary using SLP.

    An adversary could delete valid service advertisements and deny UAs
    knowledge of existing services.

9. Internationalization Considerations




Guttman,Provan                                                 [Page 33]


Internet Draft        An API for Service Location          24 March 1997


    The service: URL itself must be encoded using the rules set forth in
    [RFC1738].  The character set encoding is limited to specific ranges
    within the US-ASCII character set [ASCII].

    The attribute information associated with the service: URL may be
    expressed in any character set, and in any language.

9.1. Character Set identification and use

    The way of identifying the character set used is the IANA Character
    Set registry MIB Enum value. [CHAR-REG]

    It can be assumed that US-ASCII [ASCII] will be supported.  Programs
    which register or request information using other character sets
    must be prepared for the possibility that the SLP framework is not
    capable of supporting it.  In this case, they should fall back to
    US-ASCII if possible.

    The service's identity is independent of the character set encoding
    used to register it. A service can be registered with one character
    set encoding, queried in another, and deregister in a third as long
    as all three encodings map to the same URL. Furthermore, a different
    character set may be used in packets transmitted to satisfy the
    operation.

9.2. Language identification and translation

    The language used in attribute string should be identified using a
    Language tag as defined by [ISO-639].  The dialect parameter to all
    interfaces should be ignored.  It is included for forward
    compatibility, as it is likely that the treatment of languages in
    the interface will change.

    A program registering a service should use the strings provided in
    the Service Type template which defines the range of standard
    values.  If this document provides translations to other languages,
    the service advertisement should be made in each.

    If however no translation exists, or there is no standardized
    Service Type template, translation may still be provided on a "best
    effort" basis.

    A service advertisement is made in multiple languages, one after the
    other.  The same information is registered using SL_Register, though
    the Language tag differs and the strings are translated.  Many
    attribute strings are 'literal' and will not be translated.  See
    [SRV] for details.

10. Bibliography

    [ABNF]      D. Crocker, "Augmented BNF for Syntax Specifications:



Guttman,Provan                                                 [Page 34]


Internet Draft        An API for Service Location          24 March 1997


                ABNF", Work in progress, November 1996.

    [ASCII]     "Coded Character Set -- 7-bit American Standard code
                for Information Interchange", ANSI X3.4-1986.

    [CHAR-REG]  IANA Character Set registry, <URL:http://www.isi.edu
                /in-notes/iana/assignments/character-sets>.

    [GSSAPI]    J. Linn, "Generic Security Service Application Program
                Interface", RFC 1508, September 1993.  Also:
                J. Linn, "Generic Security Service Application Program
                Interface, Version 2", A work in progress,
                November 1996.

    [RFC1825]   R. Atkinson, "Security Architecture for the Internet
                Protocol", RFC 1825,  July 1995.

    [SSH]       A. Freier, P. Karlton, P. Kocher, "The SSL Protocol,
                Version 3.0", A work in progress, November 1996.

    [SLP]       J. Veizades, E. Guttman, C. Perkins & S. Kaplan,
                Service Location Protocol", Work in progress,
                March 1997.

    [SRV]       E. Guttman, "The service: URL Scheme", Work in
                progress, November 1996.

    [ISO-639]   This standard is provided as Appendix A of [SLP].


























Guttman,Provan                                                 [Page 35]


Internet Draft        An API for Service Location          24 March 1997


11. Authors' Addresses

          Erik Guttman
          Sun Microsystems, Inc.
          Gaisbergstr. 6
          D-69115 Heidelberg
          Germany

          Phone: +1 49 6221 601649
          email: Erik.Guttman@eng.sun.com


          Don Provan
          Novell, Inc.
          2180 Fortune Drive
          San Jose, CA 95131
          USA

          Phone: +1 408 577 8440
          email: donp@novell.com








       This memo expires on September 24, 1997

























Guttman,Provan                                                 [Page 36]