ONC+ Developer's Guide

Bottom-Level Interface

The bottom-level interface to RPC enables the application to control all options. clnt_tli_create() and the other expert-level RPC interface routines are based on these routines. You rarely use these low-level routines.

Bottom-level routines create internal data structures, buffer management, RPC headers, and so on. Callers of these routines, like the expert-level routine clnt_tli_create(), must initialize the cl_netid and cl_tp fields in the client handle. For a created handle, cl_netid is the network identifier (for example, udp) of the transport and cl_tp is the device name of that transport (for example, /dev/udp). The routines clnt_dg_create() and clnt_vc_create() set the clnt_ops and cl_private fields.

Client Side of the Bottom-Level Interface

The following code example shows calls to clnt_vc_create() and clnt_dg_create().


Example 4–14 Client for Bottom Level

/*
 * variables are:
 * cl: CLIENT *
 * tinfo: struct t_info returned from either t_open or t_getinfo
 * svcaddr: struct netbuf *
 */
	switch(tinfo.servtype) {
		case T_COTS:
		case T_COTS_ORD:
			cl = clnt_vc_create(fd, svcaddr,
			 prog, vers, sendsz, recvsz);
			break;
		case T_CLTS:
			cl = clnt_dg_create(fd, svcaddr,
			 prog, vers, sendsz, recvsz);
			break;
		default:
			goto err;
	}

These routines require that the file descriptor be open and bound. svcaddr is the address of the server.

Server Side of the Bottom-Level Interface

The following code example is an example of creating a bottom-level server.


Example 4–15 Server for Bottom Level

/*
 * variables are:
 * xprt: SVCXPRT *
 */
switch(tinfo.servtype) {
	case T_COTS_ORD:
	case T_COTS:
		xprt = svc_vc_create(fd, sendsz, recvsz);

		break;
	case T_CLTS:
		xprt = svc_dg_create(fd, sendsz, recvsz);

		break;
	default:
		goto err;
}