Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Automate client management with the Service Location Protocol

Help network clients help themselves

M. Tim Jones, Consultant Engineer, Emulex
M. Tim Jones
M. Tim Jones is an embedded software engineer and the author of GNU/Linux Application Programming, AI Application Programming, and BSD Sockets Programming from a Multilanguage Perspective. His engineering background ranges from the development of kernels for geosynchronous spacecraft to embedded systems architecture and networking protocols development. Tim is a senior principal engineer at Emulex Corp.

Summary:  The Service Location Protocol (SLP) is an Internet Standard RFC and software framework that allows networking applications to discover and configure network services. You can use SLP to develop zero-configuration applications and simplify administration of networked devices. This article introduces SLP and its architecture, and then demonstrates the protocol's use with an open source implementation.

Date:  22 Feb 2006
Level:  Introductory
Also available in:   Russian  Japanese

Activity:  8201 views
Comments:  

Service discovery is the ability to find the services in a network that are necessary for operation. For example, if you install a new desktop system on a network, how do you configure it for the mail server, the default gateway (where non-local connections should be routed), or the available printers? Typically, this information is communicated by a systems administrator and then manually configured at each machine -- a time-consuming process that, given the changes that inevitably occur in networks, requires recurring maintenance.

Therefore, you can see the value in being able to automatically discover services on a network in addition to rediscovering them if they are removed or if they change location. In this article, I'll introduce you to a protocol designed to simplify this process -- the Service Location Protocol (SLP) -- and delve into the protocol's architecture for service advertisement and discovery.

The history of discovery

Service discovery is an interesting aspect of modern networks; if you look around, you'll find it in use today. The Dynamic Host Configuration Protocol (DHCP) offers a first level of service discovery that provides not only IP address leases but Domain Name Service (DNS) identification so that URLs, such as domain names, can be successfully resolved.

DNS was extended by RFC 2782 to allow queries of services or protocols that return address records (where the service can be found). This RFC is commonly referred to as the DNS SRV (or DNS for Service Discovery -- DNS SD). Much like a traditional DNS that resolves fully qualified domain names to IP addresses, DNS SRV allows the resolution of services/protocols to IP addresses. For example, the code

_mail._tcp.mtjones.com
_ntp._udp.mtjones.com

requests the IP addresses for the TCP-based SMTP mail server and the User Datagram Protocol-based NTP time server in the domain mtjones.com.

You can find several protocols that provide service discovery in some form or another. Table 1 lists some of the competing technologies. As you can see, there are a number of competing standards. Some are complementary (such as DHCP and DNS which are commonplace today), but others are competitive (such as SLP and Universal Plug and Play, or UPnP).


Table 1. Protocols that provide some form of service discovery
Protocol Description
DHCPDynamic Host Configuration Protocol (IETF Standard)
DNSDomain Name Service (IETF Standard)
ZeroConfZero Configuration IP Networking (IETF Standard)
SSDPSimple Service Discovery Protocol (IETF Standard, used in Microsoft® UPnP)
LDAPLightweight Directory Access Protocol (IETF Standard)
NISNetwork Information Service
BonjourApple® Computer's name for ZeroConf (previously Rendezvous)
JiniJava™ open architecture that includes dynamic discovery (Sun Microsystems)
SalutationService discovery protocol (Salutation Consortium)
SLPService Location Protocol (IETF Standard)

But enough about the competing standards. Now, let's dig in to SLP to see what it does, how it works, and how you can apply it to your applications.


SLP architecture

SLP is a dynamic configuration protocol for applications operating in local area networks (LANs) or wide area networks (WANs). As a client, SLP can be used to find services using service types and attributes (such as type printer and attribute color). As a service provider, SLP can be used to advertise a service as well as specific attributes of the available service.

SLP can also operate in a number of architectures, including those with a central server caching service advertisements and a decentralized architecture in which the advertisers respond to queries themselves.


SLP actors

Let's first look at the actors in an SLP-enabled network. SLP has three types of actors:

  • User-Agent (UA)
  • Service-Agent (SA)
  • The optional Directory-Agent (DA)

Although I define these distinctions, it's important to note that an application can both request and advertise services and thus be a UA and an SA at the same time.

The UA is the client in SLP. The UA operates on behalf of an application to identify a given service on the network. The UA does this either by communicating with the DA (if available) or directly to the SA. I explain this concept more when I explore SLP organization.

The SA operates on behalf of applications that provide services on a network. If a DA is present, the SA communicates the services that are available and their location to the DA. Otherwise, the SA responds directly to the UA when a request is made.

Finally, the DA is an optional actor in SLP that serves as a central point for advertisements and queries. If a DA is present, service advertisements that SAs send are cached in the DA. Then, when UAs query for services, the DA responds directly. Having a DA means that it's not necessary for every service provider to advertise services. A single entity can register services on behalf of those services, minimizing their overhead.


SLP organization

Because the DA is an optional element of SLP, the methods for which SLP actors communicate can differ greatly. But first, how do SAs and UAs determine whether a DA is actually present?

Discovering a DA in a network is done two ways in SLP:

  • The first, called Active DA Discovery, uses SLP itself to find a DA service. The UA sends out a multicast request for a service:directory-agent. Any DAs that receive this request respond directly to the UA with their addresses.
  • The second method for DA discovery is called Passive DA Discovery. In this mode, the DA periodically sends out DA advertisements so that UAs and SAs know that it's there. In the event the UDP response to an Active DA Discovery is lost, the periodic advertisement from Passive DA Discovery automatically resolves the issue.

This architecture gives SLP quite a bit of flexibility, but when the DA is absent, it can be a burden to the SAs.

Unicast, broadcast, and multicast UDP

Unicast communication occurs between two endpoints (between one and the other). Broadcast communication describes communication from one endpoint to all other endpoints on a LAN. Multicast communication refers to communication between endpoints within a group.

Discovering services without a DA

Let's start with the decentralized organization of SLP. In this topology, a DA is not present on the network; therefore, UAs communicate their requests indirectly to SAs. See Figure 1 for a graphical description. Because no DA is present, SAs are not able to cache their services and therefore must respond to UA requests directly.


Figure 1. Service discovery without a DA
Service discovery without a DA

From Figure 1, the UA sends out a service request identifying the service that is needed. Because no DA is present, the request is sent as a multicast. Any SAs that provide the requested service respond to the User-Agent in a unicast response. The response identifies the service and its location (address and port).

Discovering services with a DA

When a DA is available on the network, UAs and SAs communicate with the DA directly for the their service requests and advertisements. The DA is discovered through either passive or active DA discovery. In the example shown in Figure 2, both the User and Service Agent find the DA through passive discovery (via a multicast from the DA). This discovery is communicated in a DAAdvert message from the DA.


Figure 2. Service discovery with a DA
Service discovery with a DA

The SA advertises its service to the DA through an SAAdvert message to which the DA responds with a SrvAck to acknowledge receipt of the advertisement. As the DA is known to the SA, its request is unicast to the DA in a UDP frame.

The UA requests the location of a service from the DA in a SrvRqst message. The DA responds with a unicast UDP SrvRply containing the address and port for the service.

In large networks, having a DA is desirable because it cuts down on the number of multicast messages that are sent on the network. Without a DA, all SAs and UAs receive all multicast messages; most are ignored (because they're not the target of the message), so the host processor is wasted.

Defining services

A service in SLP is defined by a service URL. The URL has the form

service:<service-type>://<addrspec>

where <service-type> is the type of service being advertised and <addrspec> is the service's location (domain name or IP address and port number). For example, the following example advertises a mail server at mail.com on port 25:

service:mail://mail.com:25

If the UA requested the location of "service:mail", it would be returned with the service URL defining its location. Note that multiple services may be returned and it's up to the UA to decide which to use. For services in which you expect only one to be returned, SLP provides a way to limit your search. It's called a scope and it allows you to segment services for specific users.

When an SA advertises a new service, it can optionally advertise it within a scope. A scope is just a string to identify a particular zone. For example, if you had two printers, one on the first floor and another on the second, you could define the scopes as first_floor and second_floor. When your UA made a request for service:printer, the scope for the particular floor would be applied, limiting the search to the assets on that floor (in the scope).

You can use scopes to define the proximity to the service (such as on the same floor) or the administrative ownership of the service (such as accounting or sales). A service may also be advertised multiple times with different scopes if the service is shared.

SLP messages

SLP implements a number of messages, some of which you saw in Figures 1 and 2. In addition to registering and finding services, messages are provided to deregister services that are no longer available, search for all services based upon their type, and request the attributes of a particular service.

Table 2 defines the messages in SLP. I provide these only for completeness; I won't dig into them any further. If you use the Ethereal protocol analyzer with the SLP plug-in, you'll see these messages and their parsed data.


Table 2. Messages communicated in SLP
MessageFromToDescription
SrvRegSADARegister (advertise) a service
SrvDeRegSADADeregister a service
SrvAckDASAResponse to SrvReg and SrvDereg messages
SrvRqstUASA/DARequest the location of a service
SrvRplySA/DAUAResponse to SrvRqst of a desired service location
SrvTypeRqstUASA/DARequest the location of a service based upon the defined type
SrvTypeReplySA/DAUAResponse to SrvTypeRqst of a desired service location
AttrRqstUASA/DARequest attributes for a given service
AttrRplySA/DAUAResponse from AttrRqst with attributes for a service
DAAdvertDAUA/SASent by DAs to notify UAs and SAs of their existence and location
SAAdvertSAUASent by SAs to notify UAs of their existence and location


An SLP implementation: OpenSLP

OpenSLP is an open source implementation of SLP. It consists of an API library from which you can write SAs and UAs. It also comes with a DA called slpd that you can configure using its configuration file at /etc/slp.conf.

The OpenSLP API uses a callback architecture. You make a request using one of the API functions; and, in the context of that API function, a callback function is called with the resulting response data or status. Table 3 lists the API functions in OpenSLP and their purpose. The SLPReg, SLPDereg, and SLPFind* functions all use a callback to return their status and optional data.


Table 3. The primary functions of the OpenSLP library
FunctionDescription
SLPOpenOpen an OpenSLP API instance
SLPCloseClose an OpenSLP API instance
SLPRegRegister a service and URL
SLPDeregDeregister a URL for a service
SLPFindSrvsFind a registered service given a service type
SLPFindSrvTypesFind all service types registered for the scope

In addition to the API library, OpenSLP comes with slptool which you can use to interactively perform most of the SLP functions. This tool can be useful for registering a service or finding a service. For example, the following snippet shows how you can find a daytime service:

$ slptool findsrvs service:daytime
service:daytime://www.mtjones.com:45667,65535
$

The Resources section provides links for more information on the OpenSLP API and its associated tools.


Example use

Now, let's look at an example of server and client applications that use the OpenSLP API. In this example, I create a daytime socket server: when a client connects to it, it emits an ASCII string of the current time. First I discuss the source of the applications, and then you'll see both applications in action.

SLP-enabled daytime server

Listing 1 shows the SLP-enabled daytime server. I've split the code into three sections to more easily describe its functionality:

  • Section 1 is a simple socket setup.
  • Section 2 performs the service registration.
  • Section 3 implements the daytime service.

The first section is socket setup for the daytime server. I create a socket, enable address reuse for it with setsockopt, bind an address and port to the socket, and finally allow incoming connections by calling listen (which places the TCP server socket into the listening state).

Section 2 performs the service registration with the OpenSLP API. First, I create a new SLP handle with SLPOpen and then register my service with SLPReg. Recall that the service URL contains the service name (daytime), the location of the service (www.mtjones.com), and the TCP port number at which the service can be accessed (45667). After the SLPReg callback is called (slpRegCallback), the SLPReg function finishes and I close the SLP handle with SLPClose. My service is now registered with the DA.

With service registration complete, I move on to Section 3, which implements the daytime server. I await a new connection with accept, and, upon receiving a new client connection, I grab the current time, convert it to a string, and then write it to the client socket with the write API function. The client closes the socket and awaits a new client connection.


Listing 1. SLP-enabled daytime server
#include <stdio.h>
#include <slp.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

#define MAX_BUFFER      80

void slpRegCallback( SLPHandle hslp, SLPError errcode, void *cookie )
{

  if (errcode == SLP_OK) {
    printf("Service registered\n");
  }

  *(SLPError *)cookie = errcode;

  return;
}


int main()
{
  SLPError err, callback_err;
  SLPHandle hslp;
  int servsock, clisock, on = 1;
  struct sockaddr_in sa;
  time_t t;
  char timeBuffer[MAX_BUFFER+1];

  /* --------------------------------------
   * Section 1 -- Daytime Server Setup
   * -------------------------------------*/

  /* Create a new socket */
  if ((servsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("socket");
    return servsock;
  }

  /* Enable address reuse */
  if ((setsockopt( servsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) {
    perror("setsockopt");
    return -1;
  }

  /* Bind our socket to port 45667 and all interfaces */
  memset( &sa, 0, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_port = htons(45667);
  sa.sin_addr.s_addr = htonl(INADDR_ANY);

  if (bind(servsock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    perror("bind");
    return -1;
  }

  /* Place the socket into the listening state (able to accept new
   * connections).
   */
  listen( servsock, 5 );

  /* -------------------------------------------
   * Section 2 -- SLP Service Registration
   * ------------------------------------------*/

  /* Open an SLP API instance */
  err = SLPOpen( "en", SLP_FALSE, &hslp );
  if (err != SLP_OK) {
    printf("SLPOpen failed %d\n", err);
    return err;
  }

  /* Register the service with SLP */
  err = SLPReg( hslp, "service:daytime://www.mtjones.com:45667",
                 SLP_LIFETIME_MAXIMUM, 0, "", SLP_TRUE,
                 slpRegCallback, &callback_err );

  if ((err != SLP_OK) || (callback_err != SLP_OK)) {
    printf("SLPReg failed %d/%d\n", err, callback_err);
    return err;
  }

  /* Registration is complete, close the SLP instance */
  SLPClose( hslp );

  /* -------------------------------------
   * Section 3 -- Daytime Server Loop
   * ------------------------------------*/

  /* Service was successfully registered, start the daytime server.  */
  while (1) {

    /* Await a client connection */
    if ((clisock = accept( servsock, (struct sockaddr *)NULL, NULL)) < 0) {
      perror("accept");
      close(servsock);
      return clisock;
    }

    /* Get the time and send it to the client */
    t = time(NULL);
    snprintf( timeBuffer, MAX_BUFFER, "%s\n", ctime(&t) );

    write( clisock, timeBuffer, strlen(timeBuffer) );
    close( clisock );

  }

  close( servsock );

  return 0;
}

SLP-enabled daytime client

I've split the SLP-enabled daytime client into two functions (see Listing 2). The first is the SLP callback function (for the SLPFindSrvs function), and the second is the main function which implements the daytime client.

Rather than describe these two functions independently, I discuss them in terms of their flow. The main function is split into two sections. Section 1 of main performs the SLP service location. After getting a new SLP handle from SLPOpen, I call SLPFindSrvs looking for service service:daytime (with the scope default). The callback for this SLP call is slpSrvURLCallback. This function is called for every service that's returned. Inside the callback, I parse the service URL returned with SLPParseSrvURL and store the IP address of the service and its port number for later use. Note the use of the resolve_name function here: this function is available in the accompanying .ZIP file, but I avoid it here for brevity. Its sole purpose is to resolve the string domain name to a 32-bit IP address.

After all the services have been returned, control is returned from SLPFindSrvs to main and the SLP handle closed with SLPClose. I then check to see if a service was found (I use the last one that I find); if no service was found, I exit.

The final section, Section 2, is the daytime socket client. Given the IP address and port number found through SLP, I create a new socket and connect to the server. Upon connect, I read from the socket and then print the response (the current time).

That's it! The SLP portions of both the client and the server were small, even in this tiny demonstration.


Listing 2. SLP-enabled daytime client
#include <stdio.h>
#include <slp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>


#define MAX_BUFFER      80

int found = 0;

struct sockaddr_in sa;
int    port;


SLPBoolean slpSrvURLCallback( SLPHandle hslp, const char *srvurl,
                              unsigned short lifetime, SLPError errcode,
                              void *cookie )
{
  SLPSrvURL *parsedURL;
  SLPError  err;

  /* Check the callback for success */
  if (errcode == SLP_OK) {

    printf("srvurl = %s\n", srvurl);

    /* Parse the service string into its basic elements */
    err = SLPParseSrvURL( srvurl, &parsedURL );

    /* If the parse was successful, grab the necessary elements and
     * cache them for the application. */
    if (err == SLP_OK) {

      printf("Found %s\n", parsedURL->s_pcSrvType);
      printf("at host %s\n", parsedURL->s_pcHost);
      printf("port number %d\n", parsedURL->s_iPort);

      found = 1;

      /* Resolve the fully qualified domain name to an IP address */
      printf("Resolving host to IP address\n");
      if (resolve_name( &sa, parsedURL->s_pcHost ) == 0) {

        printf("Resolved to %s\n", inet_ntoa(sa.sin_addr));
        port = parsedURL->s_iPort;

      }

      SLPFree( (void *)parsedURL );

    }

    *(SLPError *)cookie = SLP_OK;

  } else if (errcode == SLP_LAST_CALL) {

    /* no action */
    printf("Final call -- slp find done.\n");

  } else {

    *(SLPError *)cookie = errcode;

  }

  return SLP_TRUE;
}


int main()
{
  SLPError err, callback_err;
  SLPHandle hslp;
  char timeBuffer[MAX_BUFFER+1];
  int sock, in;

  /* -------------------------------------
   * Section 1 -- SLP Service Request
   * ------------------------------------*/

  /* Open a new SLP API instance */
  err = SLPOpen( "en", SLP_FALSE, &hslp );
  if (err != SLP_OK) {
    printf("SLPOpen failed %d\n", err);
    return err;
  }

  /* Try to find the desired service */
  err = SLPFindSrvs( hslp, "service:daytime", "default", 0,
                      slpSrvURLCallback, &callback_err );

  if ((err != SLP_OK) || (callback_err != SLP_OK)) {
    printf("SLPFind failed %d/%d\n", err, callback_err);
    return err;
  }

  /* Close this SLP API instance */
  SLPClose( hslp );

  /* If the service wasn't found, exit now */
  if (!found) {
    close(sock);
    printf("Service not found.\n");
    return -1;
  }

  /* --------------------------------------
   * Section 2 -- Daytime Client Setup
   * -------------------------------------*/

  /* Create a new socket */
  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("socket");
    return sock;
  }

  /* Bind the socket to the discovered service (address and port) */
  memset( &sa, 0, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);

  printf("Connecting to service\n");
  if (connect( sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    close(sock);
    perror("connect");
    return -1;
  }

  /* Read the time from the daytime server */
  in = read(sock, timeBuffer, MAX_BUFFER);
  timeBuffer[in] = 0;

  printf("Client received: %s\n", timeBuffer);

  close(sock);

  return 0;
}

Demonstrating the server and client

Listing 3 shows the server and client in action. I build the SLP server and client with the make utility. I start the slpd utility (the SLP DA) and then start the server (slpreg). Now that the server is running and presumably registered, I use the slptool as an optional step to see if the DA now knows about the service. From the return of slptool, my registration worked, so I try out my client slpfind. This application looks for the service and then, after parsing the resulting service URL, connects to the server and gets back the current time.

You can download slpreg, slpfind, and the makefile from the Download section, below.


Listing 3. Demonstrating the SLP server and client
# make
gcc -Wall -o slpreg slpreg.c -lslp
gcc -Wall -o slpfind slpfind.c -lslp
# slpd
# ./slpreg &
[1] 9275
Service registered
# slptool findsrvs service:daytime
service:daytime://www.mtjones.com:45667,65535

# ./slpfind
srvurl = service:daytime://www.mtjones.com:45667
Found service:daytime
at host www.mtjones.com
port number 45667
Resolving host to IP address
Resolved to 66.54.202.174
Final call -- slp find done.
Connecting to service
Client received: Sat Apr 16 14:04:26 2005

#


The future of SLP

SLP has been released in a variety of products from a number of companies. Some of the companies and products are listed in Table 4.


Table 4. Products with integrated SLP
CompanyProduct
Axis CommunicationNetwork printers and cameras
GroupLogicExtremeZ-IP file- and printer-sharing product
IBMCommunications Server; TotalStorage SAN Volume Controller; TotalStorage Multiple Device Manager (MDM); TN3270 Terminal
Open Door NetworksShareway IP file-sharing product
SymantecNorton Personal Firewall for Macintosh
WBEM SolutionsJ WBEM Server

A number of modern operating systems also include support for SLP, including GNU/Linux®, IBM AIX, HP-UX, NetBSD, Sun Solaris 8, Mac OS X, and Novell SuSE Enterprise Server 9. You can also write your application for SLP in more than just C. Several languages support bindings for SLP, including C/C++, Java™, and Python.

Finally, SLP can also be found in numerous RFCs recommending its use (for example, iSCSI and FCIP). Despite its integration into numerous operating systems, products, and language support, there is dissent over SLP's more broad acceptance. The number of protocols occupying the service discovery space is large, but none has yet achieved a de facto standard status.



Download

DescriptionNameSizeDownload method
Demonstration SLP client and serverl-slp-demo.zip3KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

M. Tim Jones

M. Tim Jones is an embedded software engineer and the author of GNU/Linux Application Programming, AI Application Programming, and BSD Sockets Programming from a Multilanguage Perspective. His engineering background ranges from the development of kernels for geosynchronous spacecraft to embedded systems architecture and networking protocols development. Tim is a senior principal engineer at Emulex Corp.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux
ArticleID=104465
ArticleTitle=Automate client management with the Service Location Protocol
publish-date=02222006
author1-email=mtj@mtjones.com
author1-email-cc=tomyoung@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers