root/usr/src/stand/lib/fs/nfs/clnt.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 * clnt.h - Client side remote procedure call interface.
 * Stripped down sockets based client for boot.
 */

#ifndef _RPC_CLNT_H
#define _RPC_CLNT_H

#pragma ident   "%Z%%M% %I%     %E% SMI"

#include <sys/types.h>
#include <rpc/clnt_stat.h>
#include <rpc/auth.h>
#include <netinet/in.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * Error info.
 */
struct rpc_err {
        enum clnt_stat re_status;
        union {
                int RE_errno;           /* realated system error */
                enum auth_stat RE_why;  /* why the auth error occurred */
        } ru;
#define re_errno        ru.RE_errno
#define re_why          ru.RE_why
};


/*
 * Client rpc handle.
 * Created by individual implementations, see e.g. rpc_udp.c.
 * Client is responsible for initializing auth, see e.g. auth_none.c.
 */
typedef struct __client {
        AUTH    *cl_auth;                       /* authenticator */
        struct clnt_ops {
                                /* call remote procedure */
                enum clnt_stat  (*cl_call)(struct __client *, rpcproc_t,
                                        xdrproc_t, caddr_t, xdrproc_t,
                                        caddr_t, struct timeval);
                                /* abort a call */
                void            (*cl_abort)(/* various */);
                                /* get specific error code */
                void            (*cl_geterr)(struct __client *,
                                        struct rpc_err *);
                                /* frees results */
                bool_t          (*cl_freeres)(struct __client *, xdrproc_t,
                                        caddr_t);
                                /* destroy this structure */
                void            (*cl_destroy)(struct __client *);
                                /* the ioctl() of rpc */
                bool_t          (*cl_control)(struct __client *, int, char *);
        } *cl_ops;
        caddr_t                 cl_private;     /* private stuff */
} CLIENT;


/*
 * client side rpc interface ops
 *
 * Parameter types are:
 *
 */

/*
 * enum clnt_stat
 * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
 *      CLIENT *rh;
 *      ulong_t proc;
 *      xdrproc_t xargs;
 *      caddr_t argsp;
 *      xdrproc_t xres;
 *      caddr_t resp;
 *      struct timeval timeout;
 */
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)     \
        ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))

/*
 * void
 * CLNT_ABORT(rh);
 *      CLIENT *rh;
 */
#define CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))

/*
 * struct rpc_err
 * CLNT_GETERR(rh);
 *      CLIENT *rh;
 */
#define CLNT_GETERR(rh, errp)   ((*(rh)->cl_ops->cl_geterr)(rh, errp))

/*
 * bool_t
 * CLNT_FREERES(rh, xres, resp);
 *      CLIENT *rh;
 *      xdrproc_t xres;
 *      caddr_t resp;
 */
#define CLNT_FREERES(rh, xres, resp) ((*(rh)->cl_ops->cl_freeres)\
        (rh, xres, resp))

/*
 * bool_t
 * CLNT_CONTROL(cl, request, info)
 *      CLIENT *cl;
 *      uint_t request;
 *      char *info;
 */
#define CLNT_CONTROL(cl, rq, in) ((*(cl)->cl_ops->cl_control)(cl, rq, in))

/*
 * control operations that apply to both udp and tcp transports
 */
#define CLSET_TIMEOUT           1   /* set timeout (timeval) */
#define CLGET_TIMEOUT           2   /* get timeout (timeval) */
#define CLGET_SERVER_ADDR       3   /* get server's address (sockaddr) */
#define CLGET_FD                6   /* get connections file descriptor */
#define CLSET_FD_CLOSE          8   /* close fd while clnt_destroy */
#define CLSET_FD_NCLOSE         9   /* Do not close fd while clnt_destroy */
/*
 * udp only control operations
 */
#define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
#define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */

/*
 * void
 * CLNT_DESTROY(rh);
 *      CLIENT *rh;
 */
#define CLNT_DESTROY(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))

/*
 * By convention, procedure 0 takes null arguments and returns them
 */

#define NULLPROC ((ulong_t)0)

/*
 * Below are the client handle creation routines for the various
 * implementations of client side rpc.  They can return NULL if a
 * creation failure occurs.
 */

/*
 * UDP based rpc.
 * CLIENT *
 * clntbudp_create(raddr, program, version, wait, sockp)
 *      struct sockaddr_in *raddr;
 *      ulong_t program;
 *      ulong_t version;
 *      struct timeval wait;
 *      int *sockp;
 *
 * Same as above, but you specify max packet sizes.
 * CLIENT *
 * clntbudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
 *      struct sockaddr_in *raddr;
 *      ulong_t program;
 *      ulong_t version;
 *      struct timeval wait;
 *      int *sockp;
 *      uint_t sendsz;
 *      uint_t recvsz;
 */
extern CLIENT *clntbudp_create(struct sockaddr_in *raddr, rpcprog_t program,
                                rpcvers_t version, struct timeval wait,
                                int *sockp);
extern CLIENT *clntbudp_bufcreate(struct sockaddr_in *raddr, rpcprog_t program,
                                rpcvers_t version, struct timeval wait,
                                int *sockp, uint_t sendsz, uint_t recvsz);

/*
 * TCP based rpc.
 * CLIENT *
 * clntbtcp_create(raddr, program, version, wait, sockp, sendsz, recvsz)
 *      struct sockaddr_in *raddr;
 *      ulong_t program;
 *      ulong_t version;
 *      struct timeval wait;
 *      int *sockp;
 *      uint_t sendsz;
 *      uint_t recvsz;
 *
 */
extern CLIENT *clntbtcp_create(struct sockaddr_in *raddr, rpcprog_t program,
                                rpcvers_t version, struct timeval wait,
                                int *sockp, uint_t sendsz, uint_t recvsz);
/*
 * If a creation fails, the following allows the user to figure out why.
 */
struct rpc_createerr {
        enum clnt_stat cf_stat;
        struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
};

extern struct rpc_createerr rpc_createerr;

#define UDPMSGSIZE      8800    /* rpc imposed limit on udp msg size */
#define RPCSMALLMSGSIZE 400     /* a more reasonable packet size */
#define TCPMSGSIZE      (32 * 1024) /* reasonably sized RPC/TCP msg */
#ifdef  __cplusplus
}
#endif

#endif /* !_RPC_CLNT_H */