[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]

Communications Programming Concepts


Dynamic Load API

The operating system supports name resolution from five different maps:

With the Dynamic Load Application Programming Interface (API), you can load your own modules to provide routines that supplement the maps provided by the operating system. The Dynamic Load API enables you to create dynamically loading APIs in any of the following map classes:

You can build your own user modules containing APIs for any or all of the map classes. The following sections define an API's function names and prototypes for each of the five classes. To instantiate each map accesssor, the operating system requires that a user-provided module use the specified function names and function prototypes for each map class.

See Configuring a Dynamic API for information about configuring a dynamically loading API.

Services Map Type

The following is the required prototype for a user-defined services map class:

  void *sv_pvtinit();
  void sv_close(void *private);
  struct servent * sv_byname(void *private, const char *name, const char *proto);
  struct servent * sv_byport(void *private, int port, const char *proto);
  struct servent * sv_next(void *private);
  void sv_rewind(void *private);
  void sv_minimize(void *private);

Function sv_pvtinit must exist. It is not required to return anything more than NULL. For example, the function can return NULL if the calling routine does not need private data.

Functions other than sv_pvtinit are optional for this class. The module can provide none or only part of the optional functions in its definition.

Protocols Map Type

The following is the required prototype for a user-defined protocols map class:

  void * pr_pvtinit();
  void pr_close(void *private);
  struct protoent * pr_byname(void *private, const char *name);
  struct protoent * pr_bynumber(void *private, int num);
  struct protoent * pr_next(void *private);
  void pr_rewind(void *private);
  void pr_minimize(void *private);

Function pr_pvtinit must exist. It is not required to return anything more than NULL. For example, the function can return NULL if the calling routine does not need private data.

Functions other than pr_pvtinit are optional for this class. The module can provide none or only part of the optional functions in its definition.

Hosts Map Type

The following is the required prototype for a user-defined hosts map class:

  void * ho_pvtinit();
  void ho_close(void *private);
  struct hostent * ho_byname(void *private, const char *name);
  struct hostent * ho_byname2(void *private, const char *name, int af);
  struct hostent * ho_byaddr(void *private, const void *addr, size_t len, int af);
  struct hostent * ho_next(void *private);
  void ho_rewind(void *private);
  void ho_minimize(void *private);

Function ho_pvtinit must exist. It is not required to return anything more than NULL. For example, the function can return NULL if the calling routine does not need private data.

Functions other than ho_pvtinit are optional for this class. The module can provide none or only part of the optional functions in its definition.

Networks Map Type

The following is the required prototype for a user-defined networks map class:

 void * nw_pvtinit();
 void nw_close(void *private);
 struct nwent * nw_byname(void *private, const char *name, int addrtype);
 struct nwent * nw_byaddr(void *private, void *net, int length, int addrtype);
 struct nwent * nw_next(void *private);
 void nw_rewind(void *private);
 void nw_minimize(void *private);

Function nw_pvtinit must exist. It is not required to return anything more than NULL. For example, the function can return NULL if the calling routine does not need private data.

Functions other than nw_pvtinit are optional for this class. The module can provide none or only part of the optional functions in its definition.

The operating system provides a data structure required to implement the networks map class, which uses this structure to communicate with the operating system.

   struct nwent {
        char *name;       /* official name of net */
        char **n_aliases; /* alias list */
        int n_addrtype;   /* net address type */
        void *n_addr;     /* network address */
        int n_length;     /* address length, in bits */
   };

Netgroup Map Type

The following is the required prototype for a user-defined netgroup map class:

void * ng_pvtinit();
void ng_rewind(void *private, const char *group);
void ng_close(void *private);
int ng_next(void *private, char **host, char **user, char **domain);
int ng_test(void *private, const char *name, const char *host, const char *user, 
const char *domain);
void ng_minimize(void *private);

Function ng_pvtinit must exist. It is not required to return anything more than NULL. For example, the function can return NULL if the calling routine does not need private data.

Functions other than ng_pvtinit are optional for this class. The module can provide none or only part of the optional functions in its definition.

Using the Dynamic Load API

You must name your user-defined module according to a pre-established convention. Also, you must configure it into the operating system before it will work. The following sections explain API module naming and configuration.

Naming the User-Provided Module

The names of modules containing user-defined APIs follow this general form:

NameAddressfamily

Where:

Name Is the name of the dynamic loadable module name. The length of the Name can be between one to eight characters.

The following key words are reserved as the user option name and may not be used as the name of the dynamically loadable module:

  • local
  • bind
  • dns
  • nis
  • ldap
Addressfamily Represents the address family and can be either 4 or 6. If no number is specified, the address family is AF_UNSPEC. If the number is 4, the address family is AF_INET. If the number is 6, the address family is AF_INET6.

Any other format for user options is not valid.

Note: If a user calls the gethostbyname2 system call from within the application, whatever the address family the user passed to the gethostbyname2 system call overwrites the address family in the user option. For example, a user option is david6 and there is a system call gethostbyname2(name, AF_INET) in the application. Given this example, the address family AF_INET overwrites the user option's address family (6, same as AF_INET6).

Configuring a Dynamic API

There are three ways to specify user-provided, dynamically loading resolver routines. You can use the NSORDER environment variable, the /etc/netsvc.conf configuration file, or the /etc/irs.conf configuration file. With any of these sources, you are not restricted in the number of options that you can enter, nor in the sequence in which they are entered. You are, however, restricted to a maximum number of 16 user modules that a user can specify from any of these sources.

The NSORDER environemnt variable is given the highest priority. Next is the /etc/netsvc.conf configuration file, then the /etc/irs.conf configuration file. A user option specified in a higher priority source (for example, NSORDER) causes any user options specified in the lower priority sources to be ignored.

NSORDER Environment Variable
You can specify zero or more user options in the environment variable NSORDER. For example, on the command line, you can type:

 export NSORDER=local, bind, bob, nis, david4, jason6

In this example, the operating system invokes the listed name resolution modules, left to right, until the name is resolved. The modules named local, bind, and nis are reserved by the operating system, but bob, david4, and jason6 are user-provided modules.

/etc/netsvc.conf Configuration File
You can specify zero or more user options in the configuration file /etc/netsvc.conf. For example:

  hosts=nis, jason4, david, local, bob6, bind

/etc/irs.conf Configuration File
You can specify zero or more user options in the configuration file /etc/irs.conf. For example:

  hosts dns continue
  hosts jason6 merge
  hosts david4

Procedures

To create and install a module containing a dynamically loading API, use the following procedure. The operating system provides a sample Makefile, sample export file, and sample user module file, which are located in the /usr/samples/tcpip/dynload directory.

  1. Create the dynamic loadable module based on operating system specifications.
  2. Create an export file (for example, rnd.exp) that exports all the symbols to be used.
  3. After compilation, put all the dynamic loadable object files in the /usr/lib/netsvc/dynload directory.
  4. Configure one of the sources described immediately before htis procedure (NSORDER, /etc/netsvc.conf, or /etc/irs.conf).


[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]