Service Location Working Group                               James Kempf
INTERNET DRAFT                                              Erik Guttman
                                                        Sun Microsystems
                                                              Don Provan
28 Feburary 1998                                            Novell, Inc.

                      An API for Service Location
                      draft-ietf-svrloc-api-03.txt


Status of This Memo

   This document is a submission by the Service Location Working Group
   of the Internet Engineering Task Force (IETF).  Comments should be
   submitted to the srvloc@srvloc.org mailing list.

   Distribution of this memo is unlimited.

   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), ftp.nordu.net (North
   Europe), ftp.nis.garr.it (South Europe), munnari.oz.au (Pacific Rim),
   ds.internic.net (US East Coast), or ftp.isi.edu (US West Coast).


Abstract

   The Service Location Protocol (SLP) provides a new way for clients to
   dynamically discovery network services.  With SLP, it is simple to
   offer highly available services that require no user configuration or
   assistance from network administrators prior to use.  This document
   describes standardized API's for SLP in C and Java.  The API's are
   modular and are designed to allow implementions to offer just the
   feature set needed.  In addition, standardized file formats for
   configuration and serialized registrations is defined, allowing SLP
   agents to set network and other parameters in a portable way.  The
   serialized file format allows legacy services to be registered with
   SLP directory agents in cases where modifying the legacy service







Kempf, Guttman, Provan          Expires 28 August 1998          [Page i]


Internet Draft           Service Location API           28 Feburary 1998


   program code is difficult or impossible, and to portably save and
   restore a registration database.


















































Kempf, Guttman, Provan         Expires 28 August 1998          [Page ii]


Internet Draft           Service Location API           28 Feburary 1998




                                Contents


Status of This Memo                                                    i

Abstract                                                               i

 1. Introduction                                                       1
     1.1. Goals . . . . . . . . . . . . . . . . . . . . . . . . . .    1
     1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . .    2

 2. File Formats                                                       4
     2.1. Configuration File Format . . . . . . . . . . . . . . . .    4
           2.1.1. DA configuration  . . . . . . . . . . . . . . . .    5
           2.1.2. Static Scope Configuration  . . . . . . . . . . .    5
           2.1.3. Tracing and Logging . . . . . . . . . . . . . . .    7
           2.1.4. Serialized Proxy Registrations  . . . . . . . . .    7
           2.1.5. Networking Configuration Parameters . . . . . . .    7
           2.1.6. UA Configuration  . . . . . . . . . . . . . . . .    8
           2.1.7. Security  . . . . . . . . . . . . . . . . . . . .    9
     2.2. Serialized Registration File  . . . . . . . . . . . . . .   10
     2.3. Proccessing Serialized Registration and Configuration
             Files  . . . . . . . . . . . . . . . . . . . . . . . .   11

 3. Binding Independent Implementation Considerations                 11
     3.1. Multithreading  . . . . . . . . . . . . . . . . . . . . .   11
     3.2. Type Checking for Service Types . . . . . . . . . . . . .   12
     3.3. Refreshing Registrations  . . . . . . . . . . . . . . . .   12
     3.4. Configuration File Processing . . . . . . . . . . . . . .   12
     3.5. Attribute Types . . . . . . . . . . . . . . . . . . . . .   12
     3.6. Removal of Duplicates . . . . . . . . . . . . . . . . . .   13
           3.6.1. Character Set Encoding  . . . . . . . . . . . . .   13
     3.7. Error Semantics . . . . . . . . . . . . . . . . . . . . .   13

 4. C Language Binding                                                15
     4.1. Constant Types  . . . . . . . . . . . . . . . . . . . . .   16
           4.1.1. URL Lifetimes . . . . . . . . . . . . . . . . . .   16
           4.1.2. Error Codes . . . . . . . . . . . . . . . . . . .   17
     4.2. Struct Types  . . . . . . . . . . . . . . . . . . . . . .   17
           4.2.1. SLPSrvURL . . . . . . . . . . . . . . . . . . . .   17
           4.2.2. SLPSrvAccessPt  . . . . . . . . . . . . . . . . .   18
           4.2.3. SLPHandle . . . . . . . . . . . . . . . . . . . .   19
           4.2.4. SLPOpaque . . . . . . . . . . . . . . . . . . . .   19
     4.3. Opening and Closing the SLP Library . . . . . . . . . . .   19
           4.3.1. SLPOpen . . . . . . . . . . . . . . . . . . . . .   19
           4.3.2. SLPClose  . . . . . . . . . . . . . . . . . . . .   20
     4.4. Protocol API  . . . . . . . . . . . . . . . . . . . . . .   20



Kempf, Guttman, Provan         Expires 28 August 1998         [Page iii]


Internet Draft           Service Location API           28 Feburary 1998


           4.4.1. SLPReg  . . . . . . . . . . . . . . . . . . . . .   20
           4.4.2. SLPDereg  . . . . . . . . . . . . . . . . . . . .   22
           4.4.3. SLPDelAttrs . . . . . . . . . . . . . . . . . . .   23
           4.4.4. SLPFindSrvTypes . . . . . . . . . . . . . . . . .   23
           4.4.5. SLPFindSrvs . . . . . . . . . . . . . . . . . . .   25
           4.4.6. SLPFindAttrs  . . . . . . . . . . . . . . . . . .   27
     4.5. Miscellaneous Functions . . . . . . . . . . . . . . . . .   28
     4.6. SLPFindScopes . . . . . . . . . . . . . . . . . . . . . .   28
     4.7. SLPParseSrvURL  . . . . . . . . . . . . . . . . . . . . .   29
     4.8. SLPFree . . . . . . . . . . . . . . . . . . . . . . . . .   30
           4.8.1. SLPOpaqueToEscaped  . . . . . . . . . . . . . . .   31
           4.8.2. SLPEscapedToOpaque  . . . . . . . . . . . . . . .   32
           4.8.3. SLPEscape . . . . . . . . . . . . . . . . . . . .   32
           4.8.4. SLPUnescape . . . . . . . . . . . . . . . . . . .   33
           4.8.5. SLPGetProperty  . . . . . . . . . . . . . . . . .   34
           4.8.6. SLPSetProperty  . . . . . . . . . . . . . . . . .   35
     4.9. Implementation Notes  . . . . . . . . . . . . . . . . . .   35
           4.9.1. Syntax for String Parameters  . . . . . . . . . .   35
           4.9.2. Client Side Syntax Checking . . . . . . . . . . .   36
           4.9.3. System Properties . . . . . . . . . . . . . . . .   36
           4.9.4. Memory Management . . . . . . . . . . . . . . . .   36
    4.10. Examples  . . . . . . . . . . . . . . . . . . . . . . . .   36
          4.10.1. Discovering one's mailbox . . . . . . . . . . . .   36

 5. Java Language Binding                                             38
     5.1. Introduction  . . . . . . . . . . . . . . . . . . . . . .   38
     5.2. Exceptions and Errors . . . . . . . . . . . . . . . . . .   39
           5.2.1. Class ServiceLocationException  . . . . . . . . .   39
     5.3. Basic Data Structures . . . . . . . . . . . . . . . . . .   40
           5.3.1. Class ServiceLocationAttribute  . . . . . . . . .   40
           5.3.2. Class ServiceURL  . . . . . . . . . . . . . . . .   42
     5.4. SLP Access Interfaces . . . . . . . . . . . . . . . . . .   45
           5.4.1. Interface Advertiser  . . . . . . . . . . . . . .   45
           5.4.2. Interface Locator . . . . . . . . . . . . . . . .   47
     5.5. The Service Location Manager  . . . . . . . . . . . . . .   51
           5.5.1. Class ServiceLocationManager  . . . . . . . . . .   51
     5.6. Service Template Introspection  . . . . . . . . . . . . .   52
           5.6.1. Abstract Class TemplateRegistry . . . . . . . . .   52
           5.6.2. Interface ServiceLocationAttributeVerifier  . . .   55
           5.6.3. Interface ServiceLocationAttributeDescriptor  . .   57
     5.7. Implementation Notes  . . . . . . . . . . . . . . . . . .   60
           5.7.1. Client Side Syntax Checking . . . . . . . . . . .   60
           5.7.2. Language Locale Handling  . . . . . . . . . . . .   60
           5.7.3. Setting SLP System Properties . . . . . . . . . .   60
           5.7.4. Implementing register() and addAttributes() . . .   61
           5.7.5. Multithreading  . . . . . . . . . . . . . . . . .   61
           5.7.6. Unscoped requests . . . . . . . . . . . . . . . .   61
           5.7.7. Modular Implementations . . . . . . . . . . . . .   61
     5.8. Examples  . . . . . . . . . . . . . . . . . . . . . . . .   62



Kempf, Guttman, Provan         Expires 28 August 1998          [Page iv]


Internet Draft           Service Location API           28 Feburary 1998


 6. Internationalization Considerations                               64
     6.1. service:  URL . . . . . . . . . . . . . . . . . . . . . .   64
     6.2. Character Set Encoding  . . . . . . . . . . . . . . . . .   65
     6.3. Language Tagging  . . . . . . . . . . . . . . . . . . . .   65

 7. Security Considerations                                           65


1. Introduction

   The Service Location API is designed for standardized access the
   Service Location Protocol (SLP). The APIs allow client and service
   programs to be be written or modified in a very simple manner to
   provide dynamic service discovery and selection.  Bindings in the
   C and Java languages are defined in this document.  In addition,
   a standardized format for configuration files and for serialized
   registration files is presented.  These files allow SLP agents to
   configure network parameters, to register legacy services that have
   not been SLP enabled, and to portably save and restore registration
   databases.


1.1. Goals

   The overall goal of the API is to enable source portability of
   applications that use the API between different implementations of
   SLP. The result should facilitate the adoption of SLP, and conversion
   of clients and service programs to SLP.

   The goals of the C binding are to create a minimal but complete
   access to the functionality of the SLP protocol, allowing for simple
   memory management and limited code size.

   The Java API provides for modular implementations (where unneeded
   features can be omitted) and an object oriented interface to the
   complete set of SLP data and functionality.

   The standardized configuration file and serialized file formats
   provide a simple syntax with complete functional coverage of the
   protocol, but without including secure information such as private
   keys.











Kempf, Guttman, Provan          Expires 28 August 1998          [Page 1]


Internet Draft           Service Location API           28 Feburary 1998


1.2. Terminology

      Service Location Protocol (SLP)

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

      SLP framework

         When a 'Service Location framework' is mentioned, it refers to
         both the SLP implementation and interface implementation; ie.
         whatever provides the SLP functionality to user level programs.

      Directory Agent (DA)

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

      User Agent (UA)

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

      Service Agent (SA)

         This is the Service Location process or library that allows
         service software to register and deregister itself with the SLP
         framework.  SAs MUST respond to UA service requests, detect DAs
         and register service advertisements with them.

      SA Server

         Many operating system platforms only allow a single process to
         listen on a particular port number.  Since SAs are required
         to listen on a multicast address for SLP service requests,
         implementaions of the SLP framework on such platforms that want
         to support multiple SAs on one machine need to arrange for a
         single process to do the listening while the advertising SAs
         communicate with that process through another mechanism.  The
         single listening process is called an SA server.  SA servers
         share many characteristics with DAs, but they are not the same.








Kempf, Guttman, Provan          Expires 28 August 1998          [Page 2]


Internet Draft           Service Location API           28 Feburary 1998


      Service Advertisement

         A service:  URL possibly combined with service attributes.
         These are made available to UAs by SAs, either directly or via
         a DA.

      Locale

         The language localization that applies to strings passed into
         or returned from the SLP API. The Locale is expressed using a
         Language Tag [14].  All attribute strings are associated with a
         particular locale.

      Service Template

         A document that describes the syntax of the service:  URL for a
         given service type and a definition of all service attributes
         including the meaning, defaults, and constraints on values the
         attributes may take.  See [16] for more information on service
         templates.

      The service:  URL

         A service of a particular type announces its availability
         with a service:  URL that includes its service access point
         (domain name or ip address, and possibly its port number) and
         optionally basic configuration parameters.  The syntax of the
         service:  URL is defined in the service template.

      Service Attributes

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

      Scope

         A string used to control the availability of service
         advertisements.  Every SLP Agent is configured with one or more
         scope strings.  Scopes are assigned by site administrators to
         group services for many purposes, but chiefly as a means of
         scalability.  DAs store only services advertised having a scope
         string matching the scopes with which they are configured.  UAs
         MUST specify a scope string in requests if the UA is configured
         with scope strings.







Kempf, Guttman, Provan          Expires 28 August 1998          [Page 3]


Internet Draft           Service Location API           28 Feburary 1998


      Naming Authority (NA)

         This is a 'suffix' to the service type string.  It completely
         changes the meaning of the service type.  NAs are used
         for private definitions of well known Service Types and
         experimental Service Type extensions.  The default NA is
         "IANA", which MUST NOT be explicitely included.  Service types
         with the IANA naming authority are registered with the Internet
         Assigned Numbers Authority (see [16] for more information on
         the registration procedure).


2. File Formats

   This section describes the configuration and serialized registration
   file formats.  Both files are defined in the UTF8 character set [11].

   String values in the configuration file allow escaped characters
   to be included.  These include reserved characters (like newlines)
   or multibyte UTF8 characters, enabling characters outside of the
   ASCII range to be included in an ASCII format file, if full UTF8
   support is not available in the platform's file system.  An example
   of a character encoded this way is 'e accent aigu' character,
   which is 0x00e9 in Unicode, 0xc3a9 in UTF8, or `\c3\a9' escaped.
   Escaped characters are transformed back into (potentially multibyte)
   characters as the configuration file is read.

   The location and name of the configuration file is system-dependent,
   but implementations of the API are encouraged to locate it together
   with other configuration files and name it consistently.


2.1. Configuration File Format

   The configuration file format consists of a newline delimited list
   of zero or more property definitions.  Each property definition
   corresponds to a particular configurable SLP, network, or other
   parameter in one or more of the three SLP agents.  The file format
   grammer in ABNF [13] syntax is:


      config-file   =  line-list
      line-list     =  line / line line-list
      line          =  property-line / comment-line
      comment-line  =  ( "#" / ";" ) 1*allchar newline
      property-line =  property newline
      property      =  prop | prop "." property
      prop          =  1*char
      value         =  integer / boolean / vector / string



Kempf, Guttman, Provan          Expires 28 August 1998          [Page 4]


Internet Draft           Service Location API           28 Feburary 1998


      integer       =  1*DIGIT
      boolean       =  "true" / "false" / "TRUE" / "FALSE"
      newline       =  CR / ( CRLF )
      vector        =  "[" value-list "]"
      value-list    =  value / value "," value-list
      string        =  1*allchar
      char          =  DIGIT / ALPHA / other
      other         =  %x21-%x2f / %x3a-%x40 /
                       %x5b-%x60 / %7b-%7e
      allchar       =  char / HT / SP / escape
      escape        =  "\" HEXDIG HEXDIG
                       ; Used for reserved characters


   The properties break down into seven general areas.  Each of the
   following subsections describes an area and its properties.


2.1.1. DA configuration

   Important configuration parameters for DAs are included in this
   section.  These are:

      net.slp.isDA

         A boolean indicating if the SLP server is to act as a DA. If
         false, not run as a DA. Default is false.

      net.slp.DAHeartBeat

         A 64 bit integer giving the number of milliseconds for the DA
         heartbeat.  Default is 3 hours (10800 seconds).  Ignored if
         isDA is false.

      net.slp.isDAStateful

         A boolean indicating if the DA starts statefully and saves
         state when it exits.  The DA restores service advertisements
         made before it went off line by reading a non-volatile store.
         Ignored if isDA is false.  Default is false.


2.1.2. Static Scope Configuration

   These parameters allow various aspects of scope handling to be
   configured.






Kempf, Guttman, Provan          Expires 28 August 1998          [Page 5]


Internet Draft           Service Location API           28 Feburary 1998


      net.slp.OKUnscopedRqst

         A boolean indicating whether the SA or DA accepts unscoped
         requests.  Unscoped requests are handled by ignoring scope
         when calculating a reply.  If false and an unscoped request
         is unicast to the SA or DA, a SCOPE_NOT_SUPPORTED error is
         returned to the UA making the request.  Default is false.

      net.slp.useScopes

         A vector of strings indicating the only scopes a UA or SA
         is allowed to use when making requests or registring, or
         the scopes a DA must support.  If absent, then there are no
         restrictions on scopes for UAs and SAs, and DAs are unscoped.
         If another scope is used by a UA or SA, a SCOPE_NOT_SUPPORTED
         error may be returned.  Default is unscoped.  Unlike other
         parameters, this parameter is ``read-only'', so attempts to
         change it after the configuration file has been read are
         ignored.

      net.slp.DAAddresses

         A vector of IP addresses or DNS-resolvable names giving the
         DAs to use f4) or statically configured UAs and SAs, along
         with their scopes.  Ignored if isDA is true.  Default is none.
         Addresses obtained via DHCP take precedence over these.

         The following grammer describes the property:


               addresses     =  line-list
               addresses     =  "[" addr-list "]"
               addr-list     =  addr / addr "," addr-list
               addr          =  addrrep [ "[" scope-list "]" ]
               addrrep       =  ipv4-addr / ipv6-addr / fqdn
               ipv4-addr     =  1*3DIGIT 3( "." 1*3DIGIT )
               ipv6-addr     =  64HEXDIGIT
               fqdn          =  ALPHA / ALPHA *[ anum / "-" ] anum
               anum          =  ALPHA / DIGIT
               scope-list    =  scope / scope "," scope-list
               scope         =  1*allchar
                             =  ; See grammar of Section 2.1


         Scoped DAs are listed with a comma delimited list inside
         brackets following the DA address.  For example:


               [da1.freeb.org,da2.freeb.org[scope1,scope2],da3.freeb.org[scope3]]



Kempf, Guttman, Provan          Expires 28 August 1998          [Page 6]


Internet Draft           Service Location API           28 Feburary 1998




         Here da1 has no scope, da2 has scope1 and scope2, da3 has only
         scope3.


2.1.3. Tracing and Logging

   This section allows tracing and logging information to be printed by
   the various agents.

      net.slp.traceDATraffic

         A boolean controlling printing of messges about traffic with
         DAs.  Default is false.

      net.slp.traceReg

         A boolean controlling printing of messages upon registration
         and deregistration, including the dumping of registration
         records of all existing registrations.  Default is false.

      net.slp.traceDrop

         A boolean controlling printing of a message when a SLP message
         is dropped for any reason.  Default is false.


2.1.4. Serialized Proxy Registrations

   These properties control the reading and writing of serialized
   registrations.

      net.slp.serializedRegURL

         A string containing a URL pointing to a document containing
         serialized registrations that should be processed when the DA
         or SA server starts up.  Default is none.


2.1.5. Networking Configuration Parameters

   The properties in this section allow various network configuration
   parameters to be set.

      net.slp.isBroadcastOnly

         A boolean indicating if broadcast should be used instead of
         multicast.  Default is false.



Kempf, Guttman, Provan          Expires 28 August 1998          [Page 7]


Internet Draft           Service Location API           28 Feburary 1998


      net.slp.multicastRadius

         A positive integer less than or equal to 32, giving the
         multicast radius.  Default is 32.

      net.slp.maxWait

         A 32 bit integer giving the timeout in milliseconds on all
         requests.  Default is 10000 ms.

      net.slp.multicastTimeouts

         A vector of 16 bit integers used as timeouts, in milliseconds,
         to implement the multicast convergence alorithm.  Each
         value specifies the time to wait before sending the next
         request, or until nothing new has been learned from a
         subsequent request.  Ignored if isDA is true.  Default is:
         [3000,3000,3000,3000,3000].  In a fast network the agressive
         values of 1000,1250,1500 allow better performance.

      net.slp.passiveDADetection

         A boolean indicating whether passive DA detection should be
         used.  Default is true.

      net.slp.DADiscoveryTimeout

         A 16 bit integer indicating the timeout for multicast
         convergence, in milliseconds, for active DA discovery.  Default
         is [2000,2000,2000].

      net.slp.MTU

         A 16 bit integer giving the network packet MTU, in bytes.
         This is the maximum size of any datagram to send, but the
         implementation might receive a larger datagram.  Default is
         1400.

      net.slp.multicastInterfaces

         Vector of strings giving the names of network interfaces on
         which a DA or SA should listen for multicast.  Default is
         empty, i.e.  just listen on the default network interface.


2.1.6. UA Configuration

   This section contains configuration parameters for the UA.




Kempf, Guttman, Provan          Expires 28 August 1998          [Page 8]


Internet Draft           Service Location API           28 Feburary 1998


      net.slp.locale

         A RFC 1766 Language Tag [14] for the language locale.  Setting
         this property causes the property value to become the default
         locale for SLP messages.  Default is "en".

      net.slp.maximumResults

         A 16 bit integer giving the maximum number of results to return
         for a request.  Positive integers and -1 are legal values.  If
         -1, indicates that all results should be returned.  Default
         value is -1.

         DAs and SAs always return all results that match the
         request.  This configuration value applies only to UAs, that
         filter incoming results and only return as many values as
         net.slp.maximumResults indicates.


2.1.7. Security

   The properties in this section allow security parameters to be
   configured.

      net.slp.URLSignature

         A boolean indicating whether the SA should sign URLs.  URLs are
         signed if true.  Default is false.

      net.slp.attributeSignature

         A boolean indicating whether the SA should sign attributes.
         Attributes are signed if true.  Default is false.

      net.slp.protectedScopePublicKeys

         A comma separated list of a radix-64 [17] public keys and
         scopes for DAs and UAs.  DAs and UAs should use the public
         key to authenticate URLs and attributes obtained from the
         corresponding protected scope.

         The value of this configuration option has the following
         syntax:


               value         =  sc-key-list
               sc-key-list   =  sc key / sc key "," sc-key-list
               sc            =  1*allchars
                                ; Scope, as Section 2.1



Kempf, Guttman, Provan          Expires 28 August 1998          [Page 9]


Internet Draft           Service Location API           28 Feburary 1998


               key           =  4*r64char
               r64char       =  ALPHA / DIGIT / "+" / "/" / "="


      net.slp.DAAdvertPublicKey

         This is a radix-64 encoded public key for UAs and SAs.  If
         this value is configured, the UA or SA accepts only DA
         advertisements that can be verified using the public key.

      net.slp.cryptoalgorithm

         A string indicating the cryptoalgorthm to use for
         authenticating URLs and attributes.  Ignored if publicKey is
         absent.  The default is "id-dsa-with-sha1".  Other standard
         values are "md5withRSAEncryption" and "HMAC-with-keyed-MD5".
         Ignored if none of the other security parameters are set.


2.2. Serialized Registration File

   The serialized registration file contains a group of registrations
   that a DA or SA server (if one exists) registers when it starts up.
   These registrations are primarily for older service programs that do
   not internally support SLP and cannot be converted.  The character
   format of the registrations is required to be UTF8.

   The syntax of the serialized registration file, in ABNF format [13],
   is as follows:


      ser-file      =  reg-list
      reg-list      =  reg / reg reg-list
      reg           =  creg / ser-reg
      creg          =  comment-line ser-reg
      comment-line  =  ( "#" / ";" ) 1*allchar newline
      ser-reg       =  url-props attr-list newline
      url-props     =  service-url sep lang
      sep           =  *WSP "," *WSP
      service-url   =  ;The registration's service:  URL. See
                       ; [16] for syntax.
      language      =  2*3ALPHA [ "-" 1*ALPHA ]
                       ;RFC 1766 Language Tag see [14].
      attr-list     =  attr-def / attr-def attr-list
      attr-def      =  attr / keyword
      keyword       =  attr-id
      attr          =  attr-id assgn-op attr-val-list newline
      assgn-op      =  *WSP "=" *WSP
      attr          =  ;Attribute id, see [15] for syntax.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 10]


Internet Draft           Service Location API           28 Feburary 1998


      attr-val-list =  attr-val / attr-val sep attr-val-list
      attr-val      =  ;Attribute value, see [15] for syntax.
      char          =  DIGIT / ALPHA / other
                       ;'other' defined in section 2.1.
      allchar       =  char / WSP


   The syntax for attributes and attribute values requires escapes for
   special characters as specified in [15], in addition to nonASCII
   characters.  DAs and SA servers that process serialized registrations
   MUST handle them exactly as if they were registered by an SA. The
   registrations are made in all scopes (if any) supported by the DA or,
   for SA servers, specified in the net.slp.useScopes parameter, and are
   forwarded to DAs that support these scopes.  The registrations are
   valid for the life time of the executing DA or SA server, or until
   explicitly deregistered.


2.3. Proccessing Serialized Registration and Configuration Files

   Implementations are encouraged to make processing of configuration
   and serialized files as transparent as possible to clients of
   the API. At the latest, errors MUST be caught when the relevent
   configuration item is used.  At the earliest, errors MAY be caught
   when the relevent file is loaded into the executing agent.  Errors
   SHOULD be reported by logging to the appropriate platform logging
   file, error output, or log device, and the default value substituted.
   Serialized registration file entries SHOULD be caught and reported
   when the file is loaded.

   Configuration file loading MUST be complete prior to the initiation
   of the first networking connection.  Serialized registration MUST be
   complete before the DA accepts the first network request.


3. Binding Independent Implementation Considerations

   This section discusses a number of implementation considerations
   independent of language binding, with language specific notes where
   applicable.


3.1. Multithreading

   Implementations of both the C and Java APIs are required to make API
   calls thread-safe.  Access to data structures shared between threads
   must be co-ordinated to avoid corruption or invalid access.  One way
   to achieve this goal is to allow only one thread at a time in the
   implementing library.  Performance in such an implementation suffers,



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 11]


Internet Draft           Service Location API           28 Feburary 1998


   however.  Therefore, where possible, implementations are encouraged
   to allow multiple threads within the SLP API library.


3.2. Type Checking for Service Types

   Service templates [16] allow SLP registrations to be type checked
   for correctness.  Implementations of the API are free to make use of
   service type information for type checking, but are not required to
   do so.


3.3. Refreshing Registrations

   SLP advertisements carry an explicit lifetime with them.  After the
   lifetime expires, the DA flushes the registration from its cache.
   Implementations of the SA API are encouraged to provide an automatic
   refreshing capability, so that service advertiser applications can
   simply register their services for as long as they continue running.
   The SA API is required to deregister any such advertisements as soon
   as the calling application exits.  The APIs provide constants that
   can be used as URL life times for specifying that the registration
   should be permanent.


3.4. Configuration File Processing

   DAs, SAs and UAs processing the configuration file, and DAs and SA
   servers processing the serialized registration file are required
   to log any errors using whatever underlying error mechanism is
   appropriate for the platform.  Examples include include writing error
   messages to the standard output, writing to a system logging device,
   or displaying the errors to a logging window.  After the error is
   reported, the offending parameter must be set to the default and
   program execution continued.  An agent MUST NOT fail if a file format
   error occurs.


3.5. Attribute Types

   String encoded attribute values do not include explicit type
   information.  All UA implementations and those SA and DA
   implementations that choose to support type checking should use the
   type rules described in [16] in order to convert from the string
   representation on the wire to an object typed appropriately.







Kempf, Guttman, Provan         Expires 28 August 1998          [Page 12]


Internet Draft           Service Location API           28 Feburary 1998


3.6. Removal of Duplicates

   The UA implementation should always collate results to remove
   duplicates.  This is especially important in the case of the SLP
   find attributes request for a service type and the find service type
   request when there are no DAs.  The request is multicast to all SAs,
   and the results no doubt include duplicate values.


3.6.1. Character Set Encoding

   Characters in both C and Java are all represented in Unicode
   internally.  On the wire, all characters are converted to UTF8.
   Inside URLs, characters that are not allowed by URL syntax ( [2])
   must be escaped according to the URL escape character convention.
   Strings that are included in SLP messages may include reserved
   characters and are escaped by convenience functions by the API. The
   character code used to encode the characters is UTF8.


3.7. Error Semantics

   All errors encountered processing SLP messages SHOULD be logged.  An
   error is only returned to an API client if no successful replies were
   received from any SLP framework entity.  If an error occured among
   one or several successful replies, then the error should be logged
   and the successful replies returned.

   Both the Java and C APIs contain language specific error code
   mechanisms for returning error information.  The names of the error
   codes are consistent between the two implementations, however.

   The following error codes are returned from a remote agent (DA or
   SA):

      LANGUAGE_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.

      PARSE_ERROR

         The SLP message was rejected by a remote SLP agent.  The API
         returns this error only when no information was retrieved, and
         at least one SA or DA indicated a protocol error.  The data
         supplied through the API may be malformed or a may have been
         damaged in transit.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 13]


Internet Draft           Service Location API           28 Feburary 1998


      INVALID_REGISTRATION

         The API may return this error if an attempt to register a
         service was rejected by all DAs because of a malformed URL or
         attributes.  SLP does not return the error if at least one DA
         accepted the registration.

      AUTHENTICATION_INVALID

         If the SLP framework supports authentication, this error arises
         when a remote DA fails to accept a registration.

      INTERNAL_ERROR

         A remote DA has failed for a reason other than a message sent
         to it by the UA or SA.

   The following errors result from interactions with remote agents.

      AUTHENTICATION_FAILED

         If the SLP framework supports authentication, this error arises
         when a authentication on an SLP message received from a remote
         SLP agent failed.

      SCOPE_NOT_SUPPORTED

         The API returns this error if the UA or SA has been configured
         with net.slp.useScopes vector of scopes and the UA or SA
         request did not specify one or more of these allowable scopes,
         and no others.  It may also be returned by a DA if the scope
         included in a request is not supported by a DA.

   The following errors are generated through a program interacting with
   the API implementation.  They do not involve a remote SLP agent.

      NOT_IMPLEMENTED

         If an unimplemented feature is used, this error is returned.

      BUFFER_OVERFLOW

         This error is returned when the buffer passed down by the API
         client is too small to hold the results returned.

      NETWORK_INIT_FAILED

         If the network cannot initialize properly, this error is
         returned.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 14]


Internet Draft           Service Location API           28 Feburary 1998


      NETWORK_TIMED_OUT

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

      NETWORK_ERROR

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

      MEMORY_ALLOC_FAILED

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

      PARAMETER_BAD

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

      INTERNAL_SYSTEM_ERROR

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

   The error code OK indicates that no error occured.

   Some error codes are handled differently in the Java API. These
   differences are discussed in Section 5.

   The errors OPTION_NOT_UNDERSTOOD, VER_NOT_SUPPORTED, and DA_BUSY_NOW
   should be handled internally and not surfaced to clients through the
   API.


4. C Language Binding

   The C language binding presents a minimal overhead implemention that
   maps directly into the protocol.  There is one C language function
   per protocol request, with the exception of the SLPDereg() and
   SLPDelAttrs() functions, which map into different uses of the SLP
   deregister request.  Parameters are string values or arrays of simple
   structs.  Memory management is kept simple by requiring the user
   to supply memory where possible, and having an explicit SLPFree()
   function where the appearance of differently sized data structures
   from the network make user-supplied memory impossible.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 15]


Internet Draft           Service Location API           28 Feburary 1998


   To conform with standard C practice, all character strings passed to
   and returned through the API are null terminated, even though the
   SLP protocol does not use null terminated strings.  Strings passed
   as parameters are assumed to be encoded in the UTF8 character set.
   This means that ASCII character strings may be passed through as per
   normal C strings.  Other characters, outside of the ASCII range are
   multibyte characters but they may still be passed as a C string (a
   null terminated sequence of bytes.)

   The return value from each function is a long (a signed 32 bit
   integer).  If the function returned successfully, then the value
   contains the number of returned items, the size of the dynamically
   allocated buffer returned, etc.  If an error occured, the return
   value is a negative integer error code.  If no values were returned,
   then the return value is zero.  Clients can differentiate between
   errors and successful returns by checking whether the return value is
   negative or positive.


4.1. Constant Types

4.1.1. URL Lifetimes

4.1.1.1. Synopsis


   typedef enum {
     SLP_LIFETIME_NONE = 0,
     SLP_LIFETIME_DEFAULT = 108000,
     SLP_LIFETIME_PERMANENT = -1
   } SLPURLLifetime;



4.1.1.2. Description

   The SLPURLLifetime enum type contains URL lifetime values that are
   frequently used.

   The SLP_LIFETIME_NONE value should be used when creating a SLPSrvURL
   for SLPDereg() or SLPDelAttrs(), since, in all cases, the lifetime of
   the URL is irrelevant.  The SLP_LIFETIME_PERMANENT parameter should
   be used with SLPReg() to register a URL for the lifetime of the SA
   process.








Kempf, Guttman, Provan         Expires 28 August 1998          [Page 16]


Internet Draft           Service Location API           28 Feburary 1998


4.1.2. Error Codes

4.1.2.1. Synopsis


   typedef enum {
     SLP_OK                           = 0,
     SLP_LANGUAGE_NOT_SUPPORTED       = -1,
     SLP_PARSE_ERROR                  = -2,
     SLP_INVALID_REGISTRATION         = -3,
     SLP_SCOPE_NOT_SUPPORTED          = -4,
     SLP_AUTHENTICATION_INVALID       = -6,
     SLP_AUTHENTICATION_FAILED        = -7,
     SLP_INTERNAL_ERROR               = -8,
     SLP_NOT_IMPLEMENTED              = -17,
     SLP_BUFFER_OVERFLOW              = -18,
     SLP_NETWORK_TIMED_OUT            = -19,
     SLP_NETWORK_INIT_FAILED          = -20,
     SLP_MEMORY_ALLOC_FAILED          = -21,
     SLP_PARAMETER_BAD                = -22,
     SLP_NETWORK_ERROR                = -23,
     SLP_INTERNAL_SYSTEM_ERROR        = -24

   } SLPError ;



4.1.2.2. Description

   The SLPError enum contains error codes that are returned from API
   functions.


4.2. Struct Types

4.2.1. SLPSrvURL

4.2.1.1. Synopsis


   typedef struct srvurl {
     char *s_pcURL;
     long  s_lifetime;
   } SLPSrvURL;








Kempf, Guttman, Provan         Expires 28 August 1998          [Page 17]


Internet Draft           Service Location API           28 Feburary 1998


4.2.1.2. Description

   Arrays of SLPSrvURL structs are passed to the SLPReg() function to
   register services and to the SLPFindSrvs() function to hold services
   returned from a query.  The values of s_lifetime are restricted to 0
   to 65535, or -1 to indicate permanent registration.  If a nonnegative
   integer, the s_lifetime field indicates the number of seconds that
   the advertisment should remain valid.


4.2.2. SLPSrvAccessPt

4.2.2.1. Synopsis


   typedef struct srvaccesspt {
     char *s_pcSrvType;
     char *s_pcHost;
     int   s_iPort;
     char *s_pcSrvPart;
   } SLPSrvAccessPt;



4.2.2.2. Description

   The SLPSrvAccessPt structure is filled in by the SLPParseSrvURL()
   function with information parsed from the service:  URL. The fields
   correspond to different parts of the service:  URL, as follows:

      s_pcSrvType

         A pointer to a character string containing the service type
         name, including naming authority.

      s_pcHost

         A pointer to a character string containing the host name or
         Internet address.

      s_iPort

         The port number, or zero if none.

      s_pcSrvPart

         The remainder of the service:  URL, after the host and port
         part.




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 18]


Internet Draft           Service Location API           28 Feburary 1998


   The host and port should be sufficient to open a socket to the
   machine hosting the service, and the remainder of the service:  URL
   should allow further differentiation of the service.


4.2.3. SLPHandle

4.2.3.1. Synopsis


   typedef void* SLPHandle;


   The SLPHandle type is returned by SLPOpen() and is a parameter to all
   SLP functions.  It serves as a handle for all resources allocated on
   behalf of the process by the SLP library.  The type is opaque, since
   the exact nature differs depending on the implementation.


4.2.4. SLPOpaque

4.2.4.1. Synopsis


   typedef unsigned char* SLPOpaque;


   The SLPOpaque type models the SLP OPAQUE attribute value type.
   Opaques are converted to strings for transmission across the wire,
   but can be used to model any other type.


4.3. Opening and Closing the SLP Library

4.3.1. SLPOpen

4.3.1.1. Synopsis


   long SLPOpen(const char *pcLang, SLPHandle *phSLP);



4.3.1.2. Description

   Returns a SLPHandle handle in the phSLP parameter for the language
   locale passed in as the pcLang parameter.  The handle encapsulates
   the language locale for SLP requests issued through the handle, and
   any other resources required by the implementation.  SLP properties



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 19]


Internet Draft           Service Location API           28 Feburary 1998


   are not encapsulated by the handle, they are global.  The return
   value of the function is zero for success, or an SLPError code if a
   failure occurs.  Upon failure, the phSLP parameter is NULL.


4.3.1.3. Parameters

      pcLang

         A pointer to an array of characters containing the RFC 1766
         Language Tag [14] for the natural language locale of requests
         issued on the handle.  May not be NULL.


4.3.2. SLPClose

4.3.2.1. Synopsis


   void SLPClose(SLPHandle hSLP);



4.3.2.2. Description

   Frees all resources associated with the handle.  If the handle was
   invalid, the function returns silently.


4.3.2.3. Parameters

      SLPHandle

         A SLPHandle handle returned from a call to SLPOpen().


4.4. Protocol API

4.4.1. SLPReg

4.4.1.1. Synopsis


   long SLPReg(SLPHandle   hSLP,
               SLPSrvURL  *pURL,
               const char *pcScopeList,
               const char *pcAttrs
               const char cNew);




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 20]


Internet Draft           Service Location API           28 Feburary 1998


4.4.1.2. Description

   Registers the service:  URL in the pURL struct with the attribute
   list in pcAttr.  The registration is done in scopes that are part of
   pcScopeList, a comma separated list of scopes.  If the cNew flag is
   nonzero, then the registration is new (the SLP protocol FRESH flag
   is set) and the registration replaces any existing registrations.
   If the cNew flag is zero, then the registration updates an existing
   registration.  For an update, existing attribute values are NOT
   replaced by new attributes, instead, the new attribute values are
   added to existing attributes.  New attributes are also added, and the
   URL's lifetime is refreshed.

   Registrations and updates take place in the language locale of the
   hSLP handle.

   The pcScope parameter supplies a comma delimited list of scopes for
   the registration.  This parameter MUST NOT be NULL or the empty
   string, ``''.  The scopes in the scope list SHOULD be one or more of
   the scopes obtainable from SLPFindScopes().  If an unsupported scope
   is specified, a SLP_SCOPE_NOT_SUPPORTED error MAY be returned.  If
   the net.slp.useScopes parameter has been configured, then the pcScope
   parameter MUST be a supported scope.

   "SCOPE" is not a valid attribute id, and SLP_PARSE_ERROR is returned
   if an attempt is made to register an attribute with ``SCOPE'' as an
   id.


4.4.1.3. Parameters

      hSLP

         The language specific SLPHandle on which to register the
         advertisement.  May not be NULL.

      pURL

         The service:  URL to register.  May not be NULL or the empty
         string.

      pcScopeList

         The comma separated list of scopes applying to the
         registration.  May not be NULL.







Kempf, Guttman, Provan         Expires 28 August 1998          [Page 21]


Internet Draft           Service Location API           28 Feburary 1998


      pcAttrs

         A comma separated list of attribute assignment expressions for
         the attributes of the advertisement.  See Section 9.  in [15]
         for a description of the list format.  May not be NULL. Use
         empty string, "" for no attributes.


4.4.1.4. Returns

   If no error occurs the return value is 0.  Otherwise, if an error
   occurs, one of the SLPError codes is returned.


4.4.2. SLPDereg

4.4.2.1. Synopsys


   long SLPDereg(SLPHandle  hSLP,
                 SLPSrvURL *pURL);



4.4.2.2. Description

   Deregisters the advertisment for service:  URL pURL in all scopes
   where the service is registered and all language locales, not just
   the locale of the SLPHandle.


4.4.2.3. Parameters

      hSLP

         The language specific SLPHandle to use for deregistering.  May
         not be NULL.

      pURL

         The service:  URL to deregister.  May not be NULL.


4.4.2.4. Returns

   If no error occurs, the return value is 0.  Otherwise, if an error
   occurs, one of the SLPError codes is returned.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 22]


Internet Draft           Service Location API           28 Feburary 1998


4.4.3. SLPDelAttrs

4.4.3.1. Synopsys


   long SLPDelAttrs(SLPHandle   hSLP,
                    SLPSrvURL  *pURL,
                    const char *pcAttrs);



4.4.3.2. Description

   Delete the selected attributes in the locale of the SLPHandle.


4.4.3.3. Parameters

      hSLP

         The language specific SLPHandle on which to use for deleting
         attributes.  May not be NULL.

      pURL

         The service:  URL of the advertisement from which the
         attributes should be deleted.  May not be NULL.

      pcAttrs

         A comma separated list of attribute ids for the attributes to
         deregister.  See Section 9.8 in [15] for a description of the
         list format.  May not be NULL.


4.4.3.4. Returns

   If no error occurs, the return value is 0.  Otherwise, if an error
   occurs, one of the SLPError codes is returned.


4.4.4. SLPFindSrvTypes

4.4.4.1. Synopsis


   long SLPFindSrvTypes(SLPHandle    hSLP,
                        const char  *pcNamingAuthority,
                        const char  *pcScopeList,



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 23]


Internet Draft           Service Location API           28 Feburary 1998


                        char       **ppcSrvTypes,
                        long         lSize);


   The SLPFindSrvType() function issues an SLP service type request for
   service types in the scopes indicated by the pcScopeList and returns
   the result as an array of pointers to char in ppcSrvTypes.  The lSize
   parameter indicates the size of the ppcSrvTypes array.  The service
   types are returned independent of language locale, but only for
   services registered in one of scopes and for the indicated naming
   authority.

   If pcScopeList is an empty list, ie.  "", then scope is not applied
   to matching the service types.  If the net.slp.useScopes parameter
   has been configured, one or more of the configured scopes MUST be
   used.  A SLP_SCOPE_NOT_SUPPORTED error MAY be returned otherwise.

   If the naming authority is "*", then results are returned for all
   naming authorities.  If the naming authority is the empty string,
   i.e.  "", then the default naming authority, "IANA", is used.  "IANA"
   is not a valid naming authority name, and is ignored if included.

   The service type names are returned with the naming authority
   included, i.e.  as:


          service-type "." naming-authority


   unless the naming authority is the default, in which case, just the
   service type name is returned.


4.4.4.2. Parameters

      hSLP

         The SLPHandle on which to search for types.  May not be NULL.

      pcNamingAuthority

         The naming authority to search.  Use "*" for all naming
         authorities and the empty string, "", for the default naming
         authority.  May not be NULL.

      pcScope

         A pointer to a char containing comma separated list of scope
         names to search for service types.  May not be NULL. Use



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 24]


Internet Draft           Service Location API           28 Feburary 1998


         empty string, "", to indicate that scope should be ignored in
         searching for service type names.

      ppcSrvTypes

         A pointer to an array of char* in which the returned service
         type strings are placed.  The service type strings themselves
         should be deallocated using SLPFree() when no longer needed.
         If the number of strings is less than the lSize parameter, the
         array element after the last string is NULL. May not be NULL.

      lSize

         The number of array items in the ppcSrvTypes array.


4.4.4.3. Returns

   If no error occurs, the return value is the number of returned
   strings in ppcSrvTypes.  Otherwise, if an error occurs, one of the
   SLPError codes is returned.  If the ppcSrvTypes array does not
   contain enough storage for all the returned strings, the return value
   is SLP_BUFFER_OVERFLOW, but the array contents are usable.


4.4.5. SLPFindSrvs

4.4.5.1. Synopsis


   long SLPFindSrvs(SLPHandle  hSLP,
                   const char *pcServiceType,
                   const char *pcScopeList,
                   const char *pcSearchFilter,
                   SLPSrvURL  *pSrvURL,
                   long        lSize);


4.4.5.2. Description

   Issue the query for services on the language specific SLPHandle and
   return the results in pSrvURL. The parameters determine the results










Kempf, Guttman, Provan         Expires 28 August 1998          [Page 25]


Internet Draft           Service Location API           28 Feburary 1998


4.4.5.3. Parameters

      hSLP

         The language specific SLPHandle on which to search for
         services.  May not be NULL.

      pcServiceType

         The Service Type String for the request, such as can be
         discovered using SLPSrvTypes().  This could be, for example
         "service:printer:lpr" or "service:nfs".  May not be NULL.

      pcScopeList

         The comma separated list of scope names to use for the request,
         such as can be discovered using SLPFindScopes().  If the scope
         list is an empty list, ie.  "", then scope is not applied to
         the request.  If "net.slp.useScopes" has been configured,
         one or more of the configured scopes MUST be used, othewise
         a SLP_SCOPE_NOT_SUPPORTED error MAY be returned.  May not be
         NULL.

      pcSearchFilter

         A query formulated of attribute pattern matching expressions in
         the form of a LDAPv3 Search Filter, see [12].  If this filter
         is empty, ie.  "", all services of the requested type (in the
         specified scopes) are returned.  May not be NULL.

      pSrvURL

         A pointer to an array of SLPSrvURL structs in which the
         returned service:  URLs are placed.  The SLPSrvURL s_pcURL
         strings should be deallocated using SLPFree() when no longer
         needed.  If the number of array elements is less than the lSize
         parameter, the s_pcURL field of the array element after the
         last string is NULL. May not be NULL.

      lSize

         The number of array items in the pSrvURL array.


4.4.5.4. Returns

   If no error occurs, the return value is the number of returned
   array items in pSrvURL. Otherwise, if an error occurs, one of the
   SLPError codes is returned.  If the pSrvURL array does not contain



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 26]


Internet Draft           Service Location API           28 Feburary 1998


   enough storage for all the returned strings, the return value is
   SLP_BUFFER_OVERFLOW, but the array contents are usable.


4.4.6. SLPFindAttrs

4.4.6.1. Synopsis


   long SLPFindAttrs(SLPHandle   hSLP,
                     const char *pcURL,
                     const char *pcScope,
                     const char *pcAttrIds,
                     char       *pcAttrs,
                     long        lSize);



4.4.6.2. Description

   This function returns service attributes matching the attribute
   ids for the indicated full or partial URL. If pcURL is a complete
   service:  URL, the attribute information returned is for that
   particular service in the language locale of the SLPHandle.  If
   pcURL is a partial URL, then all attributes for the service type are
   returned regardless of the language of registration.

   The result is filtered with an SLP attribute request filter string
   parameter, the syntax of which is described in Section 9.8 of [15].
   If the filter string is the empty string, i.e.  "", all attributes
   are returned.


4.4.6.3. Parameters

      hSLP

         The language specific SLPHandle on which to search for
         attributes.  May not be NULL.

      pcURL

         The full or partial URL. See Section 4.1 of [15] for partial
         URL syntax.  May not be NULL.

      pcScope

         The scope name.  Use empty string, "", to indicate an
         unscoped request.  If the net.slp.useScopes property has been



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 27]


Internet Draft           Service Location API           28 Feburary 1998


         configured, the scope name should be one of the supported
         scopes, or a SCOPE_NOT_SUPPORTED error may occur.  May not be
         NULL.

      pcAttrIds

         The filter string indicating which attribute values to return.
         Use empty string, "", to indicate all values.  Wildcards
         matching all attribute ids having a particular prefix or suffix
         are also possible.  See Section 9.8 of [15] for the exact
         format of the filter string.  May not be NULL.

      pcAttrs

         A pointer to a buffer of char where the character string
         containing a comma separated list of attribute assignment
         expressions for the return is put.  May not be NULL.

      lSize

         The number of array items in the pcAttrs array.


4.4.6.4. Returns

   If no error occurs, the return value is the number of characters in
   pcAttrs.  Otherwise, if an error occurs, one of the SLPError codes is
   returned.  If the pcAttrs array does not contain enough storage for
   all the returned attributes, the return value is SLP_BUFFER_OVERFLOW.


4.5. Miscellaneous Functions

4.6. SLPFindScopes

4.6.0.5. Synopsis


   long SLPFindScopes(SLPHandle hSLP,
                      char** ppcScopes,
                      long lSize);



4.6.0.6. Description

   Returns an array of strings with all available scope values.  The
   list of scopes comes from a variety of sources:  the configuration
   file's net.slp.useScopes property and the net.slp.DAAddresses



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 28]


Internet Draft           Service Location API           28 Feburary 1998


   property, DHCP, or through the DA discovery process.  If there is
   any order to the scopes, preferred scopes are listed before less
   desirable scopes.  There is always at least one string in the array,
   the default scope, "DEFAULT".


4.6.0.7. Parameters

      hSLP

         The SLPHandle on which to search for scopes.  May not be NULL.

      ppcScopes

         An array of pointers to char supplied by the caller to hold
         the results.  If the number of strings is less than the lSize
         parameter, the array element after the last string is NULL. The
         strings should be freed using SLPFree() when no longer needed.
         May not be NULL.

      lSize

         The number of array items in the ppcScopes array.


4.6.0.8. Returns

   If no error occurs, the return value is the number of strings in
   the ppcScopes array.  Otherwise, if an error occurs, one of the
   SLPError codes is returned.  If the ppcScopes array does not contain
   enough storage for all the returned attributes, the return value is
   SLP_BUFFER_OVERFLOW, but the array contents are usable.


4.7. SLPParseSrvURL

4.7.0.9. Synopsis


   long SLPParseSrvURL(SLPSrvURL* pSrvURL,
                       SLPSrvAccessPt* pSrvAccessPt);



4.7.0.10. Description

   Parses the service:  URL passed in as the argument into the
   service access point structure.  If a parse error occurs, returns
   SLP_PROTOCOL_PARSE_ERROR. The character strings returned in the



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 29]


Internet Draft           Service Location API           28 Feburary 1998


   pSrvAccessPt structure should be freed with SLPFree().  If the URL
   has no service part, the s_pcSrvPart string should be the empty
   string, ``'', i.e.  not NULL.

   This function may be left unsupported by small-memory configurations.


4.7.0.11. Parameters

      pSrvURL

         A pointer to the SLPSrvURL structure containing the service:
         URL to parse.  May not be NULL.

      pSrvAccessPt

         A pointer to the SLPSrvAccessPt structure to received the
         parsed service:  URL. May not be NULL.


4.7.0.12. Returns

   If no error occurs, the return value is the SLP_OK. Otherwise, if
   an error occurs, one of the SLPError codes is returned.  If no
   memory is available to allocate the character strings, returns
   SLP_COULD_NOT_ALLOCATE_MEMORY. If a parse error occurs, returns
   SLP_PROTOCOL_PARSE_ERROR.


4.8. SLPFree

4.8.0.13. Synopsis


   void SLPFree(char* pcStorage);



4.8.0.14. Description

   Frees the storage pcStorage allocated by the SLP API. The
   only storage that needs freeing are the char* returned from
   SLPFindSrvTypes() and SLPFindScopes(), the s_pcURL field
   char* returned as part of the SLPSrvURL structs returned from
   SLPFindSrvs(), and the strings returned in the SLPSrvAccessPt struct.







Kempf, Guttman, Provan         Expires 28 August 1998          [Page 30]


Internet Draft           Service Location API           28 Feburary 1998


4.8.0.15. Parameters

      pcStorage

         A pointer to the storage allocated through the SLP API. Ignored
         if NULL.


4.8.1. SLPOpaqueToEscaped

4.8.1.1. Synopsis


   long SLPOpaqueToEscaped(const SLPOpaque  opaque,
                           const long       lOSize,
                           char            *pcBuf,
                           long             lSize);



4.8.1.2. Description

   This converts a buffer into an escaped sequence of bytes.  The escape
   sequence is always three times as long as the opaque buffer to
   encode, plus one, as each byte is encoded as "\" HEXDIGIT HEXDIGIT.


4.8.1.3. Parameters

      opaque

         The binary buffer to convert.

      lOSize

         The number of bytes in the opaque.

      pcBuf

         A client supplied buffer into which the null terminated escaped
         value is put.  May not be NULL.

      lSize

         The number of array elements in the pcBuf array.  Must be (3 *
         lOSize) + 1.






Kempf, Guttman, Provan         Expires 28 August 1998          [Page 31]


Internet Draft           Service Location API           28 Feburary 1998


4.8.1.4. Returns

   Returns the number of characters in pcBuf or SLP_BUFFER_OVERFLOW
   error if the buffer overflows.


4.8.2. SLPEscapedToOpaque

4.8.2.1. Synopsis


   long SLPEscapedToOpaque(const char *pcEscaped,
                           SLPOpaque   opaque,
                           long        lSize);



4.8.2.2. Description

   Convert an escaped string encoding of a SLPOpaque into binary format.
   The buffer in SLPOpaque must be at least one third the length of the
   string pointed to by pcEscaped.


4.8.2.3. Parameters

      pcEscaped

         The escaped value to convert, as a null terminated string.  May
         not be NULL.

      opaque

         A buffer containing storage for where the binary opaque should
         be placed.  May not be NULL.

      lOSize

         The number of bytes in the opaque.  Must be at least the length
         of the string pointed to by pcEscaped divided by 3.


4.8.3. SLPEscape

4.8.3.1. Synopsis


   long SLPEscape(const char *pcEscapee
                  char       *pcBuf,



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 32]


Internet Draft           Service Location API           28 Feburary 1998


                  long        lSize);



4.8.3.2. Description

   Escape any reserved characters in pcEscapee into the escape format
   described in [15].


4.8.3.3. Parameters

      pcEscapee

         Null terminated string to escape.  May not be NULL.

      pcBuf

         A buffer containing storage for where the escaped string is to
         be placed.  May not be NULL.

      lSize

         The number of bytes in pcBuf.


4.8.3.4. Returns

   If no error, returns the number of bytes in pcBuf.  If an error
   ocurs, returns SLP_BUFFER_OVERFLOW error if the buffer overflows.


4.8.4. SLPUnescape

4.8.4.1. Synopsis


   long SLPUnescape(const char* pcUnescapee
                    char* pcBuf,
                    long lSize);



4.8.4.2. Description

   Unescape any escapable characters in pcUnescapee out of the escape
   format described in [15].





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 33]


Internet Draft           Service Location API           28 Feburary 1998


4.8.4.3. Parameters

      pcUnescapee

         Null terminated string to escape.  May not be NULL.

      pcBuf

         A buffer containing storage for where the unescaped string is
         to be placed.  May not be NULL.

      lSize

         The number of bytes in pcBuf.


4.8.4.4. Returns

   If no error, returns the number of bytes in pcBuf.  If an error
   ocurs, returns SLP_BUFFER_OVERFLOW error if the buffer overflows.


4.8.5. SLPGetProperty

4.8.5.1. Synopsis


   const char* SLPGetProperty(const char* pcName);



4.8.5.2. Description

   Returns the value of the corresponding SLP property name, or NULL if
   none.


4.8.5.3. Parameters

      pcName

         Null terminated string with the property name, from
         Section 2.1.  May not be NULL.


4.8.5.4. Returns

   If no error, returns a pointer to the property value.  If an error
   occurs, returns NULL. The returned string should NOT be freed.  NOTE:



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 34]


Internet Draft           Service Location API           28 Feburary 1998


   The returned string is encoded in the UTF8 character set so it MAY
   include multibyte characters.


4.8.6. SLPSetProperty

4.8.6.1. Synopsis


   void SLPSetProperty(const char *pcName,
                       const char *pcValue);



4.8.6.2. Description

   Sets the value of the SLP property to the new value.  The pcValue
   parameter should be the property value as a string.


4.8.6.3. Parameters

      pcName

         Null terminated string with the property name, from
         Section 2.1.  May not be NULL.

      pcValue

         Null terminated string with the property value, in character
         format.  May not be NULL.


4.9. Implementation Notes

4.9.1. Syntax for String Parameters

   Query strings, attribute registration lists, attribute deregistration
   lists, and attribute selection lists follow the syntax described
   in [15] for the appropriate requests.  The API directly reflects the
   strings passed in from clients into protocol requests, and directly
   reflects out strings returned from protocol replies to clients.
   As a consequence, clients are responsible for formatting request
   strings, including escaping and converting opaque values to escaped
   byte encoded strings.  Similarly, on output, clients are required
   to unescape strings and convert escaped string encoded opaques to
   binary.  Utility functions are included to help in the process.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 35]


Internet Draft           Service Location API           28 Feburary 1998


4.9.2. Client Side Syntax Checking

   Implementations may do syntax checking of scope names, naming
   authority names, and service type names on the client side, but
   are not required to do so.  Since the C API is designed to be a
   thin layer over the protocol, some low memory SA implementations
   may find extensive syntax checking on the client side to be
   burdensome.  If syntax checking uncovers an error in a parameter, the
   SLP_PARAMETER_BAD error must be returned.  If any parameter is NULL
   and is required to be nonNULL, SLP_PARAMETER_BAD is returned.


4.9.3. System Properties

   The system properties established in the configuration file are
   accessable through the SLPGetProperty() and SLPSetProperty()
   functions.  The SLPSetProperty() function only modifies properties
   in the running process, not in the configuration file.  Errors
   are checked when the property is used and, as with parsing the
   configuration file, are logged.  Program execution continues without
   interruption by substituting the default for the erroneous parameter.
   In general, individual agents should rarely be required to override
   these properties, since they reflect properties of the SLP network
   that are not of concern to individual agents.  If changes are
   required, system administrators should modify the configuration file.


4.9.4. Memory Management

   Character strings returned via the SLPFindSrvTypes(), SLPFindSrvs(),
   SLPFindScopes(), and SLPParseSrvURL() functions should be freed when
   no longer needed via the SLPFree() function.  Character strings
   returned via the SLPGetProperty() function should NOT be freed.  Most
   functions require the client to pass in an array of the appropriate
   data type and an array size, and return the number of items in the
   array, or an error if a buffer overflow occured.


4.10. Examples

4.10.1. Discovering one's mailbox

   A POP3 server might register itself with the SLP framework.  The
   attributes it registers are "USER", a comma delimited list of all
   users whose mail is available through the POP3 server.

   The POP3 server code could be the following:





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 36]


Internet Draft           Service Location API           28 Feburary 1998


   SLPHandle slph;

   long err = SLPOpen("en", &slph)  /* Create an English SLPHandle */

   if( sh == NULL ) ; /* Deal with error. */

   /* Create the service: URL and attribute parameters. */

   SLPSrvURL surl =
     { "service:pop3://mail.netsurf.de", /* the URL */
       SLP_LIFETIME_DEFAULT };           /* default lifetime */

   const char *pcScopeList = "default,engineering";

   const char *pcAttrs = "(user=sally,sue,sandra,zsuzsa)"

   err = SLPReg(sh,&surl,pcScopeList,pcAttrs);

   if (err < 0 ) ; /*Deal with error.*/

   The POP3 client may locate the server for the user:

   /*
    * The client calls SLPOpen(), exactly as above.
    */

   const char *pcSrvType   = "service:pop3"; /* the service type  */
   const char *pcScopeList = "default";      /* the scope         */
   const char *pcFilter    = "(user=sue)";   /* the search filter */

   SLPSrvURL surl;

   err = SLPFindSrvs(sh,pcSrvType,pcScopeList,pcFilter,&surl,1);

   if( err < 0 ); /* Deal with error. */
   else {

     SLPSrvAccessPt pSrvAccessPt;
     err = SLPParseSrvURL(&surl, &pSrvAccessPt);

     if (err < 0); /* Deal with error. */
     else {

       /* get the server's address */

       struct hostent *phe = gethostbyname(pSrvAccessPt.s_pcHost);

       /* use hostname in pSrvAccessPt to connect to the POP3 server
        *     . . .



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 37]


Internet Draft           Service Location API           28 Feburary 1998


        */

      SLPFree(pSrvAccessPt.s_pcSrvType); /* Free the pSrvAccessPt storage */
      SLPFree(pSrvAccessPt.s_pcHost);
      SLPFree(pSrvAccessPt.s_pcSrvPart);
   }

   SLPFree(surl.s_pcURL);             /* Free the surl storage */


   A client that wanted to discover all the users receiving mail at the
   server could do so with the following query:

   /*
    * The client calls SLPOpen(), exactly as above. We assume the
    * service: URL was retrieved into surl.
    */

   const char *pcScopeList = "default";      /* the scope         */
   const char *pcAttrFilter    = "use";      /* the attribute filter */
   char pcAttrVals[MAXBUF];                  /* the return buffer */

   err =
     SLPFindSrvs(sh,surl.s_pcURL,pcScopeList,pcAttrFilter,pcAttrVals,MAXBUF);

   if( err < 0 ); /* Deal with error. */
   else {

/* parse the returned attribute values */

   }


5. Java Language Binding

5.1. Introduction

   The Java API is designed to model the various SLP entities in
   classes and objects.  APIs are provided for SA, UA, and service type
   template access capabilities.  The ServiceLocationManager class
   contains methods that return instances of objects implementing SA
   and UA capability.  Each of these is modelled in an interface.  The
   Locator interface provides UA capability and the Advertiser interface
   provides SA capability.  The TemplateRegistry abstract class contains
   methods that return objects for template introspection and attribute
   type checking.  The ServiceURL class and ServiceLocationAttribute
   class model the basic service:  URL and attribute concepts.  A
   concrete subclass instance of TemplateRegistry is returned by a class
   method.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 38]


Internet Draft           Service Location API           28 Feburary 1998


   All SLP classes and interfaces are located within a single package.
   The package name should begin with the name of the implementation
   and conclude with the suffix "net.slp".  Thus, the name for a
   hypothetical implementation from the University of Michigan would
   look like:

                           edu.umich.net.slp

   This follows the Java convention of prepending the top level DNS
   domain name for the organization implementing the package onto the
   organization's name and using that as the package prefix.


5.2. Exceptions and Errors

   Most parameters to API methods are required to be nonnull.  The
   API description indicates if a null parameter is acceptable, or
   if other restrictions constrain a parameter.  When parameters
   are checked for validity (such as not being null) or their
   syntax is checked, an error results in the RuntimeException
   subclass IllegalArgumentException being thrown.  Clients of the
   API are reminded that IllegalArgumentException, derived from
   RuntimeException, is unchecked by the compiler.  Clients should
   thus be careful to include try/catch blocks for it if the relevent
   parameters could be erroneous.

   Standard Java practice is to encode every exceptional condition as a
   seperate subclass of Exception.  Because of the relatively high cost
   in code size of Exception subclasses, the API contains only a single
   Exception subclass with different conditions being determined by an
   integer error code property.  A subset, appropriate to Java, of the
   error codes described in Section 3 are available as constants on the
   ServiceLocationException class.  The subset excludes error codes such
   as MEMORY_ALLOC_FAILED, which are not appropriate for Java.


5.2.1. Class ServiceLocationException

5.2.1.1. Synopsis


   public class ServiceLocationException
   extends Exception









Kempf, Guttman, Provan         Expires 28 August 1998          [Page 39]


Internet Draft           Service Location API           28 Feburary 1998


5.2.1.2. Description

   The ServiceLocationException class is thrown by all methods when
   exceptional conditions occur in the SLP framework.  The error
   code property determines the exact nature of the condition, and an
   optional message may provide more information.


5.2.1.3. Fields


   public static final short OK;
   public static final short LANGUAGE_NOT_SUPPORTED;
   public static final short PARSE_ERROR;
   public static final short INVALID_REGISTRATION;
   public static final short SCOPE_NOT_SUPPORTED;
   public static final short AUTHENTICATION_INVALID;
   public static final short AUTHENTICATION_ABSENT;
   public static final short INTERNAL_ERROR;
   public static final short NETWORK_INIT_FAILED;
   public static final short NETWORK_TIMED_OUT;
   public static final short NETWORK_ERROR;
   public static final short INTERNAL_SYSTEM_ERROR;



5.2.1.4. Instance Methods


   public short getErrorCode()


   Return the error code.  The error code takes on one of the static
   field values.


5.3. Basic Data Structures

5.3.1. Class ServiceLocationAttribute

5.3.1.1. Synopsis


   public final class ServiceLocationAttribute
     extends Object implements Serializable







Kempf, Guttman, Provan         Expires 28 August 1998          [Page 40]


Internet Draft           Service Location API           28 Feburary 1998


5.3.1.2. Description

   The ServiceLocationAttribute class models SLP attributes.  Instances
   of this class are returned by Locator.findAttributes() and are
   communicated along with register/deregister requests.


5.3.1.3. Constructors


   public ServiceLocationAttribute(String id,Vector values)


   Construct a service location attribute.

   Parameters:

      id

         The attribute name.  The String can consist of any Unicode
         character.

      values

         A Vector of one or more attribute values.  Vector contents
         must be uniform in type and one of Integer, String, Boolean,
         or byte[].  If the attribute is a keyword attribute, then
         parameter should be null.  String values can consist of any
         Unicode character.

   Throws:

      IllegalArgumentException

         Thrown if either parameter is null, id is the empty string, or
         the Vector contents has a type mismatch.


5.3.1.4. Instance Methods


   public final Vector getValues()


   Returns a cloned vector of attribute values, or null if the attribute
   is a keyword attribute.  If the attribute is single-valued, then the
   vector contains only one object.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 41]


Internet Draft           Service Location API           28 Feburary 1998


   public final String getId()


   Returns the attribute's name.


   public final String getEscapedId()


   Returns an escaped version of the id, suitable for inclusion in a
   query.  Any special characters are escaped using UTF8 encoding.


   public final Vector getEscapedValues()


   Returns a Vector containing the escaped values as Strings, suitable
   for inclusion in a query.  All reserved characters in the values are
   converted into an escaped form, in UTF8 encoding.


   public boolean equals(Object o)


   Overrides Object.equals().


   public String toString()


   Overrides Object.toString().


5.3.2. Class ServiceURL

5.3.2.1. Synopsis


   public class ServiceURL extends Object implements Serializable



5.3.2.2. Description

   The ServiceURL object models the SLP service:  URL. These objects are
   returned from service lookup requests, and describe the registered
   services.  This class should be a subclass of java.net.URL but can't
   since that class is final.




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 42]


Internet Draft           Service Location API           28 Feburary 1998


5.3.2.3. Class Variables


   public static final int NO_PORT


   Indicates that no port information is required or was returned for
   this service:  URL.


   public static final short LIFETIME_NONE


   Indicates that the service:  URL has a zero lifetime.


   public static final short LIFETIME_DEFAULT


   The default service:  URL lifetime.


   public static final short LIFETIME_PERMANENT


   The service should last as long as the registering application
   continues in execution.


5.3.2.4. Constructors


   public ServiceURL(String URL,short lifetime)


   Construct a service:  URL object having the specified lifetime.

   Parameters:

      URL

         The service:  URL as a string.

      lifetime

         The service advertisement lifetime in seconds.  This value may
         be 0x0001 to 0xFFFF, or one of the special life time field
         values.




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 43]


Internet Draft           Service Location API           28 Feburary 1998


5.3.2.5. Methods


   public final String getServiceType()


   Returns the service type name.


   public final String getServicePart()


   Returns the service part (host + port + URL path).


   public final String getHost()


   Returns the machine name or IP address.


   public final int getPort()


   Returns the port number, if any.


   public final String getURLPath()


   Returns the URL path description, if any.


   public final short getLifetime()


   Returns the service advertisement lifetime.


   public final String getNamingAuthority()


   Returns the naming authority for the ServiceURL. An empty string
   means the default.


   public final String getServiceTypeAndNamingAuthority()





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 44]


Internet Draft           Service Location API           28 Feburary 1998


   Returns the service type and naming authority concatenated into a
   single string with a '.'  character between them.


   public final boolean equals(Object obj)


   Compares the object to the ServiceURL and returns true if the two are
   the same.  Lifetimes are not compared.

   Overrides Object.equals().


   public final String toString()


   Returns formatted string with the service:  URL.

   Overrides Object.toString().


5.4. SLP Access Interfaces

5.4.1. Interface Advertiser

5.4.1.1. Synopsis


   public interface Advertiser



5.4.1.2. Description

   The Advertiser is the SA interface, allowing clients to register new
   service instances with SLP, to change the attributes of existing
   services, and to deregister service instances.  New registrations
   and modifications of attributes are made in the language locale
   with which the Advertiser was created, deregistrations of service
   instances are made for all locales.


5.4.1.3. Instance Methods


   public abstract Locale getLocale()


   Return the language locale with which this object was created.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 45]


Internet Draft           Service Location API           28 Feburary 1998



   public abstract void register(ServiceURL URL,
                                 Vector     scopes,
                                 Vector     attributes)
   throws ServiceLocationException

   Register a new service with SLP.


   Parameters:

      URL

         The service:  URL for the service.

      scopes

         The SLP scopes of the service.  One or more value MUST be
         supplied.  Use ServiceLocationManager.findScopes() to obtain
         them, see Section 5.5.1.3.

      attributes

         A vector of ServiceLocationAttribute objects describing the
         service.


   public abstract void deregister(ServiceURL URL)
   throws ServiceLocationException


   Deregister a service from the SLP framework.  This has the effect of
   deregistering the service from every language locale and scope under
   which it was registered.

   Parameters:

      URL

         The service:  URL for the service.


   public abstract void
   addAttributes(ServiceURL URL,
                 Vector scopes,
                 Vector attributes)
   throws ServiceLocationException





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 46]


Internet Draft           Service Location API           28 Feburary 1998


   Update the registration by adding the given attributes.

   Parameters:

      URL

         The service:  URL for the service.

      scopes

         Vector of scope name Strings.  May not be null, or empty.  The
         scope names must match the names of scopes in which the service
         was registered.

      attributes

         A Vector of ServiceLocationAttribute objects to add to the
         existing registration.


   public abstract void
   deleteAttributes(ServiceURL URL,
                    Vector attributeIds)
   throws ServiceLocationException


   Delete the attributes from a service:  URL in all scopes for the
   locale with which the Advertiser was created.

   Parameters:

      URL

         The service:  URL for the service.

      attributeIds

         A vector of Strings indicating the ids of the attributes to
         remove.  Use null to indicate all attributes.


5.4.2. Interface Locator

5.4.2.1. Synopsis


   public interface Locator





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 47]


Internet Draft           Service Location API           28 Feburary 1998


5.4.2.2. Description

   The Locator is the UA interface, allowing clients to query the SLP
   framework about existing service types, services instances, and about
   the attributes of an existing service instance or service type.
   Queries for services and attributes are made in the locale with which
   the Locator was created, queries for service types are independent of
   locale.


5.4.2.3. Instance Methods


   public abstract Locale getLocale()


   Return the language locale with which this object was created.


   public abstract Vector
   findServiceTypes(String namingAuthority,
                    Vector scopes)
   throws ServiceLocationException


   Returns a vector Strings giving known service types for the supplied
   scopes and naming authority.  If no service types are found, an empty
   vector is returned.  The service type names are returned with the
   naming authority included, i.e.  as:


          service-type "." naming-authority


   Parameters:

      namingAuthority

         The naming authority.  Use "" for the default naming authority
         and "*" for all naming authorities.

      scopes

         A Vector of scope names.  A vector with no elements indicates
         that no Scopes is requested.  Scope Strings SHOULD be selected
         from the results of a findScopes() API invocation.


   public abstract Vector



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 48]


Internet Draft           Service Location API           28 Feburary 1998


   findServices(String serviceType,
                String namingAuthority,
                Vector scopes,
                String searchFilter)
   throws ServiceLocationException


   Returns a vector of ServiceURL objects for services matching the
   query.  If no services are found, an empty vector is returned.

   Parameters:

      serviceType

         The SLP service type of the service.

      namingAuthority

         The naming authority for the type.  Use empty string, "", for
         default.

      scopes

         A Vector of scope name Strings.  Use a Vector with no elements
         if no scope is selected.

      serviceType

         The service type of the service requested.

      searchFilter

         An LDAPv3 [12] string encoded query.  If the filter is empty,
         ie.  "", all services of the requested type in the specified
         scopes are returned.


   public abstract Vector
   findAttributes(ServiceURL URL,
                  Vector     scopes,
                  Vector     attributeIds)
   throws ServiceLocationException


   For the service:  URL and scope, return a Vector of
   ServiceLocationAttribute objects whose ids match the String
   patterns in the attributeIds Vector.  The request is made in the
   language locale of the Locator.  If no attributes match, an empty
   vector is returned.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 49]


Internet Draft           Service Location API           28 Feburary 1998


   Parameters:

      URL

         The service:  URL for which the attributes are desired.

      scopes

         A Vector of scope name Strings.  Use a Vector with no elements
         to indicate that no scopes are to be used in the request.  One
         or more scope Strings from ServiceLocationManager.findScopes()
         SHOULD be used to set this parameter.

      attributeIds

         A Vector of String patterns identifying the desired attributes.
         An empty vector means return all attributes.  As described
         in [15], Section 12., the patterns may include wildcards to
         match all prefixes or suffixes.  The patterns may include
         escapable characters.


   public abstract Vector
   findAttributes(String serviceType,
                  String namingAuthority,
                  Vector scopes,
                  Vector attributeIds)
   throws ServiceLocationException


   For the type and scope, return a Vector of all ServiceLocationAttribute
   objects whose ids match the String patterns in the attributeIds
   Vector.  The request is made independent of language locale.  If no
   attributes are found, an empty vector is returned.

   Parameters:

      serviceType

         The service type.

      namingAuthority

         The naming authority for the type.  Use the empty string, "",
         for default.







Kempf, Guttman, Provan         Expires 28 August 1998          [Page 50]


Internet Draft           Service Location API           28 Feburary 1998


      scopes

         A Vector of scope name Strings.  Use a Vector with no elements
         to indicate that no scopes are to be used in the request.  One
         or more scope Strings from ServiceLocationManager.findScopes()
         SHOULD be used to set this parameter.

      attributeIds

         A Vector of String patterns identifying the desired attributes.
         An empty vector means return all attributes.  As described
         in [15], Section 12., the patterns may include wildcards to
         match all prefixes or suffixes.  The patterns may include
         escapable characters.


5.5. The Service Location Manager

5.5.1. Class ServiceLocationManager

5.5.1.1. Synopsis


    public class ServiceLocationManager
    extends Object



5.5.1.2. Description

   The ServiceLocationManager manages access to the service location
   framework.  Clients obtain the Locator and Advertiser objects
   for UA and SA, and a Vector of known scope names from the
   ServiceLocationManager.


5.5.1.3. Class Methods


 public abstract Vector findScopes()


   Returns an Vector of strings with all available scope names.  The
   list of scopes comes from a variety of sources:  the configuration
   file's net.slp.useScopes property and the net.slp.DAAddresses
   property, DHCP, or through the DA discovery process.  If there is
   any order to the scopes, preferred scopes are listed before less
   desirable scopes.  There is always at least one string in the Vector,
   the default scope, "DEFAULT".



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 51]


Internet Draft           Service Location API           28 Feburary 1998



   public static Locator
   getLocator(Locale locale)
   throws ServiceLocationException


   Return a Locator object for the given language Locale.  If the
   implementation does not support UA functionality, returns null.

   Parameters:

      locale

         The language locale of the Locator.  The default locale is used
         if null.


   public static Advertiser
   getAdvertiser(Locale locale)
   throws ServiceLocationException


   Return an Advertiser object for the given language locale.  If the
   implementation does not support SA functionality, returns null.

   Parameters:

      locale

         The language locale of the Advertiser.  The default locale is
         used if null.


5.6. Service Template Introspection

5.6.1. Abstract Class TemplateRegistry

5.6.1.1. Synopsis


   public abstract class TemplateRegistry



5.6.1.2. Description

   Subclasses of the TemplateRegistry abstract class provide
   access to service location templates [16].  Classes implementing
   TemplateRegistry perform a variety of functions.  They manage the



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 52]


Internet Draft           Service Location API           28 Feburary 1998


   registration and access of service type template documents.  They
   create attribute verifiers from service templates, for verification
   of attributes and introspection on template documents.  Note that
   clients of the Advertiser are not required to verify attributes
   before registering.


5.6.1.3. Class Methods


   public static TemplateRegistry getTemplateRegistry();


   Returns the distinguished TemplateRegistry object for performing
   operations on and with service templates.


5.6.1.4. Instance Methods


   public abstract void
   registerServiceTemplate(String serviceType,
                           String documentURL,
                           Locale locale,
                           String version)
   throws ServiceLocationException


   Register the service template with the template registry.

   Parameters:

      serviceType

         The service type name, including naming authority.

      documentURL

         The URL of the template document.

      locale

         A Locale object containing the language locale of the template.

      version

         The version number of template document.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 53]


Internet Draft           Service Location API           28 Feburary 1998


   public abstract void
   deregisterServiceTemplate(String serviceType,
                             Locale locale,
                             String version)
   throws ServiceLocationException


   Deregister the template for the service type.

   Parameters:

      serviceType

         The service type name, including naming authority.

      locale

         A Locale object containing the language locale of the template.

      version

         A String containing the version number.  Use null to indicate
         the latest version.


   public abstract
   String findTemplateURL(String serviceType,
                          Locale locale,
                          String version)
   throws ServiceLocationException


   Returns the URL for the template document.

   Parameters:

      serviceType

         A String containing the name of the service type, including
         naming authority.

      locale

         A Locale object containing the language locale of the template.

      version

         A String containing the version number.  Use null to
         indicatethe latest version.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 54]


Internet Draft           Service Location API           28 Feburary 1998



   public abstract
   ServiceLocationAttributeVerifier
   attributeVerifier(String documentURL)
   throws ServiceLocationException


   Reads the template document URL and returns an attribute verifier
   for the service type.  The attribute verifier can be used for
   verifying that registration attributes match the template, and for
   introspection on the template definition.

   Parameters:

      documentURL

         A String containing the template document's URL.


5.6.2. Interface ServiceLocationAttributeVerifier

5.6.2.1. Synopsis


   public interface ServiceLocationAttributeVerifier



5.6.2.2. Description

   The ServiceLocationAttributeVerifier provides access to service
   templates.  Classes implementing this interface parse SLP template
   definitions, provide information on attribute definitions for
   service types, and verify whether a ServiceLocationAttribute object
   matches a template for a particular service type.  Clients obtain
   ServiceLocationAttributeVerifier objects for specific SLP service
   types through the TemplateRegistry.


5.6.2.3. Instance Methods


   public abstract String getServiceType()


   Returns the SLP service type for which this is the verifier.


   public abstract Vector



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 55]


Internet Draft           Service Location API           28 Feburary 1998


   getTemplateAttributeDescriptors()


   Returns a Vector of ServiceLocationAttributeDescriptor objects
   describing the template service type attributes.  The template
   service type attributes are:

      service-type

         The SLP service type name.

      version

         The version number of the template.

      language

         The RFC 1766 [14] Language Tag locale of the template.

      description

         A natural language description of the service in the language
         of the language locale.

      url-syntax

         An ABNF [13] description for the service part of the service
         type's service:  URL.


   public abstract Vector
   getTemplateAttributes()


   Returns a Vector of ServiceLocationAttribute objects for the template
   attributes of this service type.  The template attributes are listed
   above.  The ServiceLocationAttribute objects in this vector has the
   actual values of the template attributes.


   public abstract Dictionary
   getAttributeDescriptors()


   Returns a Dictionary allowing introspection on the attribute
   definition in the service template.  The Dictionary has the attribute
   ids as the keys and ServiceLocationAttributeDescriptor objects for
   the attributes as values.  This method is primarily for GUI tools
   to display attribute information.  Programmatic verification of



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 56]


Internet Draft           Service Location API           28 Feburary 1998


   attributes should use the verifyAttribute() method.  Note that small
   memory implementations may want to implement the Dictionary so that
   attributes are parsed on demand rather than at creation time.


   public abstract void
   verifyAttribute(
     ServiceLocationAttribute attribute)
   throws ServiceLocationException


   Verify that the attribute matches the template definition.  If the
   attribute doesn't match, ServiceLocationException is thrown with the
   error code as ServiceLocationException.PARSE_ERROR.

   Parameters:

      attribute

         The ServiceLocationAttribute object to be verified.


   public abstract void
   verifyRegistration(
     Vector attributeVector)
   throws ServiceLocationException


   Verify that the Vector of ServiceLocationAttribute objects matches
   the template for this service type.  The vector must contain all the
   required attributes, and all attributes must match their template
   definitions.  If the attributes don't match, ServiceLocationException
   is thrown with the error code as ServiceLocationException.PARSE_ERROR

   Parameters:

      attributeVector

         A Vector of ServiceLocationAttribute objects for the
         registration.


5.6.3. Interface ServiceLocationAttributeDescriptor

5.6.3.1. Synopsis


   public interface
   ServiceLocationAttributeDescriptor



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 57]


Internet Draft           Service Location API           28 Feburary 1998





5.6.3.2. Description

   The ServiceLocationAttributeDescriptor interface provides
   introspection on a template attribute defintion.  Classes
   implementing the ServiceLocationAttributeDescriptor interface return
   information on a particular service location attribute definition
   from the service template.  This information is primarily for GUI
   tools.  Programmatic attribute verification should be done through
   the ServiceLocationAttributeVerifier.


5.6.3.3. Instance Methods


   public abstract String getId()


   Return a String containing the attribute's id.


   public abstract String getValueType()


   Return a String containing the fully package-qualified Java type of
   the attribute.  SLP types are translated into Java types as follows:

      STRING

         "java.lang.String"

      INTEGER

         "java.lang.Integer"

      BOOLEAN

         "java.lang.Boolean"

      OPAQUE

         "[B" (i.e.  array of byte, byte[])

      KEYWORD

         empty string, ""




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 58]


Internet Draft           Service Location API           28 Feburary 1998



 public abstract String getDescription()


   Return a String containing the attribute's help text.


   public abstract Enumeration
   getAllowedValues()


   Return an Enumeration of allowed values for the attribute type.
   For keyword attributes returns null.  For no allowed values
   (i.e.  unrestricted) returns an empty Enumeration.  Small memory
   implementations may want to parse values on demand rather than at the
   time the descriptor is created.


   public abstract Enumeration
   getDefaultValues()


   Return an Enumeration of default values for the attribute type.
   For keyword attributes returns null.  For no allowed values
   (i.e.  unrestricted) returns an empty Enumeration.  Small memory
   implementations may want to parse values on demand rather than at the
   time the descriptor is created.


   public abstract boolean getIsMultivalued()


   Returns true if the "M" flag is set.


   public abstract boolean getIsOptional()


   Returns true if the "O"" flag is set.


   public abstract boolean
   getRequiredAttribute()


   Returns true if the "X"" flag is set, indicating that the attribute
   SHOULD be included in an any Locator.findServices() request search
   filter.




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 59]


Internet Draft           Service Location API           28 Feburary 1998



   public abstract boolean getIsLiteral()


   Returns true if the "L" flag is set.


   public abstract boolean getIsKeyword()


   Returns true if the attribute is a keyword attribute.


5.7. Implementation Notes

5.7.1. Client Side Syntax Checking

   The syntax of scope names, service type names, naming authority
   names, and service:  URLs is described in [15] and [16].  The various
   methods and classes taking String parameters for these entities
   should type check the parameters for syntax errors on the client
   side, and throw an IllegalArgumentException if an error occurs.  In
   addition, character escaping should be implemented before network
   transmission for escapable characters in attribute ids and String
   values.  This reduces the number of error messages transmitted.  The
   ServiceLocationAttribute class provides methods for obtaining escaped
   attribute id and value strings to facilitate query construction.


5.7.2. Language Locale Handling

   The Locator and Advertiser interfaces are created with a Locale
   parameter.  The language locale with which these objects are
   created is used in all SLP requests issued through the object.  If
   the Locale parameter is null, the default is used.  The default
   locale is determined by, first, checking the net.slp.locale System
   property.  If that is unset, then the default Java locale is used.
   The net.slp.locale is the only SLP system property that a client of
   the API would routinely override.


5.7.3. Setting SLP System Properties

   SLP system properties that are originally set in the configuration
   file can be overridden programmatically in API clients by simply
   invoking the System.getProperties() operation to get a copy of the
   system properties, modifying or adding the SLP property in question,
   then using System.setProperties() to set the properties to the
   modified Property object.  Errors are checked when the property



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 60]


Internet Draft           Service Location API           28 Feburary 1998


   is used and, as with parsing the configuration file, are logged.
   Program execution continues without interruption by substituting the
   default for the erroneous parameter.  In general, individual agents
   should rarely be required to override these properties, since they
   reflect properties of the SLP network that are not of concern to
   individual agents.  If changes are required, system administrators
   should modify the configuration file.


5.7.4. Implementing register() and addAttributes()

   Advertiser.register() indicates a new registration has taken place,
   replacing previous registrations for the same URL and locale.  The
   SLPv2 'FRESH' flag is set in the header of the registration message,
   when it is forwarded to DAs to reflect this behavior.

   Advertiser.addAttributes(), on the other hand, does not replace
   the previous registration, but rather adds to it as described in
   Section 5.4.1.  The SLPv2 'FRESH' flag is NOT set in the header of
   the registration message, when it is forwarded to DAs.


5.7.5. Multithreading

   Thread-safe operation are relatively easy to achieve in Java.  By
   simply making each method in the classes implementing the Locator
   and Advertiser interfaces synchronized, and by synchronizing access
   to any shared data structures within the class the Locator and
   Advertiser interfaces are made safe.


5.7.6. Unscoped requests

   All services advertised in SLPv2 are advertised with a scope.  A UA
   may issue requests without specifying a scope.  It is possible that
   SAs and DAs are configured in such a way that an unscoped request is
   accepted (ie.  they are configured with net.slp.OKUnscopedRqst set to
   TRUE.)

   A UA with the net.slp.useScopes property configured never issues an
   unscoped request.

   Unscoped requests MAY always return a SCOPE_NOT_SUPPORTED exception.


5.7.7. Modular Implementations

   While, at first glance, the API may look rather heavyweight, the
   design has been carefully arranged so that modular implementations



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 61]


Internet Draft           Service Location API           28 Feburary 1998


   that provide only SA, only UA, or only service template access
   capability, or any combination of the three, are possible.

   Because the objects returned from the ServiceLocationManager.getLocator()
   and ServiceLocationManager.getAdvertiser() operations are interfaces,
   and because the objects returned through those interfaces are in
   the set of base data structures, an implementation is free to omit
   either UA or SA capability by simply returning null from the instance
   creation operation if the classes implementing the missing function
   is cannot be dynamically linked.  API clients are encouraged to check
   for such a contingency, and to signal an exception if it occurs.
   Similarly, the TemplateRegistry class can simply be omitted from an
   implementation that only supports UA and/or SA clients.  In this way,
   the API implementation can be taylored for the particular memory
   requirements at hand.


5.8. Examples

   In this example, a printer server advertises its availability to
   clients.  Additionally, the server advertises a service template for
   use by client software in validating service requests:


  //Get the Advertiser and TemplateRegistry.

  Advertiser adv = null;
  TemplateRegistry tr = null

  try {

    adv = ServiceLocationManager.getAdvertiser("en");

    tr = TemplateRegistry.getTemplateRegistry();

  } catch( ServiceLocationException ex ) { } //Deal with error.

  if( adv == null ) {

    //Serious error as printer can't be registered
    //  if the implementation doesn't support SA
    //  functionality.

  }

  //Get the scopes in which we are supposed to
  //  register.

  Vector scopes = ServiceLocationManager.findScopes();



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 62]


Internet Draft           Service Location API           28 Feburary 1998



  //Get the printer's attributes, from a file or
  //  otherwise. We assume that the attributes
  //  conform to the template, otherwise, we
  //  could register the template here and verify
  //  them.

  Vector attributes = getPrinterAttributes();

  //Create the service: URL for the printer.

  ServiceURL printerURL =
    new ServiceURL(
      "service:printer:lpr://printshop/color2",
      ServiceURL.LIFETIME_PERMANENT);

  try {

    //Register the printer all scopes.

    adv.register(printerURL, scopes, attributes);

    //If the template registry is available,
    //  register the printer's template.

    if( tr != null ) {
      tr.registerServiceTemplate(
        "service:printer",
        "http://shop.arv/printer/printer-lpr.slp",
        new Locale(``en'',''''),
        "1.0");

   }

  } catch( ServiceLocationException ex ) { } //Deal with error.


   Suppose a client is looking for color printer.  The following code
   might be used to issue a request for printer service:  URLs:


  Locator loc = null;
  TemplateRegistry tr = null;

  try {

    loc = ServiceLocationManager.getLocator("en");

  } catch( ServiceLocationException ex ) { } //Deal with error.



Kempf, Guttman, Provan         Expires 28 August 1998          [Page 63]


Internet Draft           Service Location API           28 Feburary 1998



  if( loc == null ) {

    //Serious error as client can't be located
    //  if the implementation doesn't support
    //  UA functionality.

  }

  //We want a color printer that does CMYK
  //  and prints at least 600 dpi.

  String query = ``(& (marker-type=CMYK) (resolution=600))'';

  //Get scopes.

  Vector scopes = ServiceLocationManager.findScopes();

  try {

    services = loc.findServices("service:printer",'''',scopes,query);

  } catch { } //Deal with error.

  if (services.size() > 0) {

    //Printers can now be used.
    ServiceURL surl = (ServiceURL) services.elementAt(0);

    Socket sock = new Socket(surl.getHost, surl.getPort());

    // Use the Socket...

  }



6. Internationalization Considerations

6.1. service:  URL

   The service:  URL itself must be encoded using the rules set forth
   in [2].  The character set encoding is limited to specific ranges
   within the UTF8 character set [11].

   The attribute information associated with the service:  URL may be
   expressed in any character set, and in any language.  See [16] for
   attribute internationalization guidelines.




Kempf, Guttman, Provan         Expires 28 August 1998          [Page 64]


Internet Draft           Service Location API           28 Feburary 1998


6.2. Character Set Encoding

   Configuration and serialized registration files are encoded in
   the UTF8 character set [11].  This is fully compatible with ASCII
   character values.  As it may be impossible to pass multibyte UTF8
   characters through the local platform's C file interface interface,
   an escaping convention has been provided:  UTF8 bytes are directly
   encoded in an escape sequence where each byte is rendered as "\"
   HEXDIGIT HEXDIGIT.

   At the API level, the character encoding is specified to be Unicode.
   Unicode is the default in Java.  C implementations need to supply
   Unicode support in a platform specific manner.


6.3. Language Tagging

   All SLP requests and registrations are tagged to indicate in which
   language the strings included are encoded.  This allows multiple
   languages to be supported.  It also presents the possibility that
   error conditions result when a request is made in a language that is
   not supported.  In this case, an error is only returned when there is
   data available, but not obtainable in the language requested.

   The dialect portion of the Language Tag is used on 'best effort'
   basis for matching strings by SLP. Dialects that match are prefered
   over those which don't.  Dialects that do not match will not prevent
   string matching or comparisons to occur.


7. Security Considerations

   SLP makes use of an existing host based authentication framework once
   it becomes available as an Internet Standard. [5]

   An adversary could delete valid service advertisements, provide false
   service information and deny UAs knowledge of existing services
   unless the mechanisms in SLP for authenticating SLP messages are
   used.  These mechanisms allow DA Adverts, Service URLs and Service
   Attributes to be verified using digital cryptography.  For this
   reason, all SLP agents SHOULD be configured to use protected scopes
   and DA Advertisement verifying cryptographic keys.  See [15] for a
   description of how these mechanisms work.









Kempf, Guttman, Provan         Expires 28 August 1998          [Page 65]


Internet Draft           Service Location API           28 Feburary 1998


References

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

    [2] T. Berners-Lee, R. Fielding, and L. Masinter.  Uniform Resource
        Locators (URL): Generic Syntax and Semantics.  RFC1738 as
        amended by RFC1808 and updated by draft-fielding-url-syntax-05.txt,
        May 1997.  (work in progress).

    [3] J. Veizades, E. Guttman, C. Perkins, and S. Kaplan.  Service
        Location Protocol.  RFC 2165, July 1997.

    [4] IANA  IANA Character Set Registry
        <URL:http://www.isi.edu/in-notes/iana/assignments/character-sets>

    [5] R. Atkinson  Security Architecture for the Internet  RFC 1825
        July 1995

    [6] J. Linn  Generic Security Application Program Interface, Version
        2  A work in progress  November 1996

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

    [8] Geneva ISO  Code for the representation of names of languages
        ISO 639:1998 (E/F)  1998

    [9] E. Guttman, C. Perkins, J. Kempf  Service Templates and service:
        Schemes  A work in progress  November 1997

   [10] N. Borenstein and N. Freed.  MIME (Multipurpose Internet Mail
        Extensions) Part One:  Mechanisms for Specifying and Describing
        the Format of Internet Message Bodies.  RFC 1521, September
        1993.

   [11] F. Yerfeau  UTF-8, a transformation format of ISO 10646.  RFC
        2279  January 1998.

   [12] T. Howes  The String Representation of LDAP Search Filters  RFC
        2254  December 1997.

   [13] D. Crocker and P Overell.  Augmented BNF for Syntax
        Specifications:  ABNF.  RFC 2234  November 1997.

   [14] H. Alvestrand.  Tags for the Identification of Languages.  RFC
        1766  March 1995.





Kempf, Guttman, Provan         Expires 28 August 1998          [Page 66]


Internet Draft           Service Location API           28 Feburary 1998


   [15] E. Guttman, C. Perkins, J. Veizades, and M. Day.  Service
        Location Protocol.  draft-ietf-svrloc-protocol-v2-02.txt  A work
        in progress  January 1998.

   [16] E. Guttman, C. Perkins, J. Kempf  Service Templates and service:
        Schemes  draft-ietf-svrloc-service-scheme-07.txt  A work in
        progress  February 1998.

   [17] N. Borenstein and N. Freed.  Multipurpose Internet Mail
        Extensions (MIME) Part One:  Format of Internet Message Bodies.
        RFC 2045  September 1996.









































Kempf, Guttman, Provan         Expires 28 August 1998          [Page 67]


Internet Draft           Service Location API           28 Feburary 1998


Authors' Addresses

   Questions about this memo can be directed to:

James Kempf           Erik Guttman           Don Provan
Sun Microsystems      Sun Microsystems       Novell, Inc.
901 San Antonio Rd.   Bahnstr. 2             2180 Fortune Drive
Palo Alto, CA, 94303  74915 Waibstadt        San Jose, CA, 94303
USA                   Germany                USA
+1 650 786 5890       +49 7263 911 701       +1 408 577 8440
+1 650 786 6445 (fax)
james.kempf@sun.com   erik.guttman@sun.com   donp@novell.com








































Kempf, Guttman, Provan         Expires 28 August 1998          [Page 68]