Novell is now a part of Micro Focus

SLP DA Configuration after NetWare to OES Linux Migration

Novell Cool Solutions: Feature
By Simon Tideswell

Digg This - Slashdot This

Posted: 14 Mar 2007


We are a NetWare site completing our migration to OES Linux. Under NetWare we had developed an SLP infrastructure with an SLP DA at each WAN location and all of them sharing the same scope in DS. The nice thing about this way of doing it is that local service registrations were replicated through DS synchronisation to all DA's serving up the same scope. Moving to OES Linux and OpenSLP means we have to change this and we were encountering the following problems ...

  1. OpenSLP doesn't retain service information after being restarted. Consequently if you bounce slpd then there are no registered services immediately afterwards and services will only gradually repopulate on the DA.

  2. This should be able to be mitigated by having multiple DA's. However my testing has found that if you configure multiple DA's in the Novell client (via DHCP for instance) that if you shut down one DA it will indeed use the other. However if the primary is simply restarted, and consequently has no service information, that the client will only use this DA and will also not see any services. i.e. the service information the client sees is not the aggregate of the two DA's but is the view of whatever DA it can contact.

This was not satisfactory to me. I wanted to have a DA at each site running on OES Linux and for that DA to retain information about important services between restarts. Otherwise we are at risk of client PC's experiencing the dreaded "Tree Not Found" error.


To achieve this we used the fact that service registrations can be entered into a file under /etc/slp.reg.d. Every time slpd is restarted it reads the registrations entered in this file and accordingly registers the services. This solution uses a perl script and a configuration file to generate this service registration file. Additionally the directory /etc/slp.reg.d is served up by an instance of rsyncd. Remote servers running slpd download a copy of the registration file periodically and if it has changed they integrate the new copy and bounce slpd. This way SLP registrations can be maintained from a single site with a simple configuration file and service registrations will be persistent across restarts of slpd.

Note that this method requires manual configuration: new services will not be added dynamically and so-called WinSock GUID's need to be found out and entered in the configuration file, this might not suit large dynamic sites. For us, with a static server base and only a few tens of servers it works very well.

First let's discuss how to build an SLP registration file given some basic knowledge of SLP entries.

Using the linux program slptool we can see what sort of information should be available about any particular service. There are lots of services that can be registered but I'm only really concerned about making the DA serve up the services bindery.novell and ndap.novell in order to assist connectivity/discovery of the main client-facing services delivered over NCP.

To gather information about NCP server fsten01 I'd type:

buten02:~ # slptool unicastfindattrs service:bindery.novell:///fsten01
buten02:~ #

Here is the IP of a SLP DA. Other documents describe how svcaddr-ws=2-1-6-0a140118020c000000000000000000 translates to UDP (where 0a140118 or is the IP address of the server) and svcaddr-ws=2-2-17-0a140118020c000000000000000000 translates to TCP So this portion really means that server fsten01 is listening for NCP connections on UDP and TCP The version-ws=1055279-0 corresponds to the DS version and the svcid-ws=000b0004-0000-0000-c000-000000000046 corresponds to the Winsock GUID. Don't have the foggiest what the Winsock GUID is, but empirically the Winsock GUID for OES Linux boxes appears to be the same whereas the Winsock GUID for NetWare 5.1 servers is something else but identical to each other. Therefore the Winsock GUID's I know of are:

OES Linux = 000b0004-0000-0000-c000-000000000046
NetWare 5.1 = 359F7793-44CA-4DFB-810D-4224D75A1DEB

To gather information about eDirectory replica NTL-TREE (our [Root]) I'd type:

buten02:~ # slptool unicastfindattrs service:ndap.novell:///NTL-TREE.
(svcname-ws=NTL-TREE.),(svcaddr-ws=2-1-6-0a1e0102020c000000000000000000,2-2-17-0a1e0102020c000000000000000000,2-1-6-0a14010d020c000000000000000000,2-2-17-0a14010d020c000000000000000000,2-1-6-0a14010b020c000000000000000000,2-2-17-0a14010b020c000000000000000000),(svcid-ws=000b0278-0000-0000-c000-000000000046),(version-ws=1055336-0),(nds version=1055336),(host-ws=0),(enabled-ws=TRUE),(scope=NTL-SCOPE)
buten02:~ #

The result basically tells me which servers have copies of Master or Read-Write replicas of this partition using the same addressing format as discussed above (i.e. 2-1-6-0a14010d etc. translates to UDP


The following configuration file needs to be constructed



The fields in this file are server name, IP address, Winsock GUID, eDirectory version and then a comma-separated list of the replicas this server holds. The list of replicas is actually a list of abbreviated names for replicas: the real replica name is found from the perl hash %replicas in the code below which you will need to modify for your site. Note the trailing dot in the %replicas hash, e.g. ADS.NTL.NTL-TREE. is supposed to be there.

#! /usr/bin/perl
use strict;

my %replicas=( NTL => 'NTL-TREE.',
               ADS => 'ADS.NTL.NTL-TREE.',
               ATV => 'ATV.NTL.NTL-TREE.',
               CAN => 'CAN.NTL.NTL-TREE.',
               DR => 'DR.NTL.NTL-TREE.',
               EYEMEL => 'EYEMEL.NTL.NTL-TREE.',
               EYESYD => 'EYESYD.NTL.NTL-TREE.',
               NEW => 'NEW.NTL.NTL-TREE.',
               TCPIP => 'TCPIP.NTL.NTL-TREE.',
               TEN => 'TEN.NTL.NTL-TREE.',
               TEN_DXML => 'TEN_DXML.TEN.NTL.NTL-TREE.',
               TVQ => 'TVQ.NTL.NTL-TREE.');
my ($key, $line, $server, $ip, $wsock, $dsversion, $a, $b, $c, $d);
my (%replica_ring, @partitions, $INFILE, $OUTFILE);


while ($line=<INFILE>) {

    $line =~ tr/\n//d;
    ($server,$ip,$wsock,$dsversion,@partitions) = split (/,/,$line);
    print OUTFILE "service:bindery.novell:///$server,en,65535\n";
    print OUTFILE "svcname-ws=$server\n";
    ($a,$b,$c,$d) = split(/\./,$ip);
    printf OUTFILE "svcaddr-ws=2-1-6-%02x%02x%02x%02x020c000000000000000000,2-2-17-%02x%02x%02x%02x020c000000000000000000\n",$a, $b, $c, $d, $a, $b, $c, $d;
    print OUTFILE "svcid-ws=$wsock\n";
    print OUTFILE "version-ws=$dsversion-0\n";
    print OUTFILE "host-ws=0\nenabled-ws=TRUE\nscope=NTL-SCOPE\n\n";

    foreach $key (@partitions) {
          if ($replica_ring{$key}) {
              $replica_ring{$key} = "$replica_ring{$key},".sprintf("2-1-6-%02x%02x%02x%02x020c000000000000000000,2-2-17-%02x%02x%02x%02x020c000000000000000000",$a, $b, $c, $d, $a, $b, $c, $d);
          } else {
              $replica_ring{$key} = sprintf("2-1-6-%02x%02x%02x%02x020c000000000000000000,2-2-17-%02x%02x%02x%02x020c000000000000000000",$a, $b, $c, $d, $a, $b, $c, $d);

    print OUTFILE "\n";


for $key (sort keys %replica_ring) {

    print OUTFILE "service:ndap.novell:///$replicas{$key},en,65535\n";
    print OUTFILE "svcname-ws=$replicas{$key}\n";
    print OUTFILE "svcaddr-ws=$replica_ring{$key}\n";
    print OUTFILE "svcid-ws=000b0278-0000-0000-c000-000000000046\n";
    print OUTFILE "version-ws=1055336-0\n";
    print OUTFILE "nds version=1055336\n";
    print OUTFILE "host-ws=0\n";
    print OUTFILE "enabled-ws=TRUE\n";
    print OUTFILE "scope=NTL-SCOPE\n\n";


The purpose of this code is to build an SLP registration file that can be copied to /etc/slp.reg.d.

The program is run thus:

buten02# /root/bin/slpregistrations.txt /etc/slp.reg.d/ntl_custom.reg

... where slpregistrations.txt is your configuration file and ntl_custom.reg is the output file.

The output file looks like this:



nds version=1055336

nds version=1055336

... plus entries for other servers and partitions.

If this file is copied to /etc/slp.reg.d and slpd is bounced then you now have a DA with all services entered manually in the configuration file being available immediately - assuming no typos/mistakes :)

This has got one DA up and running but now the bit that gets the other DA's reading from the same page. The SLP registration folder is served up over rsync to all the other SLP DA's (one at each WAN site)

path = /etc/slp.reg.d
read only = yes
list = yes
hosts allow =

You need to change the "hosts allow" entry to reflect what IP addresses are allowed to download the SLP registration file over rsync. Then you need to restart xinetd (assuming you are running rsync from xinetd which is the default).

On each remote SLP DA a cron job runs the following script. Essentially the central SLP registration file is downloaded to the local server via rsync. If this file differs from the current one being used the new file is copied over and slpd is restarted.

#! /bin/bash

LOGGER="/bin/logger -t SLPREG"
BTEST="slptool unicastfindsrvs bindery.novell"
NTEST="slptool unicastfindsrvs ndap.novell"
server=`uname -n`
site=`echo ${site#bu} | awk '{ print toupper($1) }'`

/usr/bin/rsync ${SRC}/$REG $WKGDIR
diff -q ${SLPDIR}/$REG ${WKGDIR}/$REG
if [ $RESULT -ne 0 ]; then
   $LOGGER "SLP registration files differ"
   /etc/init.d/slpd restart
   btest=`$BTEST | grep -i $server`
   ntest=`$NTEST | grep -v DXML | grep -i $site`
   if [ "$btest" != "$server" ] || [ "$ntest" != "$site" ]; then
       $BTEST | mutt -s "SLP problems on $server" 


OES Linux, OpenSLP, eDirectory

Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions.

© Copyright Micro Focus or one of its affiliates