Home | History | Annotate | Download | only in librpc
      1 #include <rpc/rpc.h>
      2 
      3 /*
      4  * Functions to compose RPC messages from XDR primitives
      5  */
      6 
      7 bool_t xdr_call_msg_start(
      8     xdr_s_type *xdr,
      9     uint32 prog,
     10     uint32 ver,
     11     uint32 proc,
     12     opaque_auth *cred,
     13     opaque_auth *verf)
     14 {
     15   uint32 vers = RPC_MSG_VERSION;
     16 
     17   xdr->x_prog = prog;
     18   xdr->x_proc = proc;
     19 
     20   return (XDR_MSG_START(xdr, RPC_MSG_CALL) &&
     21           XDR_SEND_UINT32(xdr, &vers) &&
     22           XDR_SEND_UINT32(xdr, &prog) &&
     23           XDR_SEND_UINT32(xdr, &ver) &&
     24           XDR_SEND_UINT32(xdr, &proc) &&
     25           xdr_send_auth(xdr, cred) &&
     26           xdr_send_auth(xdr, verf));
     27 } // xdr_call_msg_start
     28 
     29 bool_t xdr_reply_msg_start(
     30     xdr_s_type *xdr,
     31     opaque_auth *verf)
     32 {
     33   int32 stat   = (int32) RPC_MSG_ACCEPTED;
     34   int32 accept = (int32) RPC_ACCEPT_SUCCESS;
     35 
     36   return(XDR_MSG_START(xdr, RPC_MSG_REPLY) &&
     37           XDR_SEND_INT32(xdr, &stat) &&
     38           xdr_send_auth(xdr, verf) &&
     39           XDR_SEND_INT32(xdr, &accept));
     40 } // xdr_reply_msg_start
     41 
     42 static bool_t xdr_send_accepted_reply_header(
     43     xdr_s_type *xdr,
     44     struct rpc_accepted_reply_header const *accreply)
     45 {
     46   if (!xdr_send_auth(xdr, &accreply->verf))
     47       return FALSE;
     48 
     49   if (!XDR_SEND_ENUM(xdr, &accreply->stat))
     50       return FALSE;
     51 
     52   switch ((*accreply).stat){
     53   case RPC_PROG_MISMATCH:
     54     if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.low))
     55         return FALSE;
     56 
     57     if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.high))
     58         return FALSE;
     59     break;
     60 
     61   case RPC_ACCEPT_SUCCESS:
     62   case RPC_PROG_UNAVAIL:
     63   case RPC_PROC_UNAVAIL:
     64   case RPC_GARBAGE_ARGS:
     65   case RPC_SYSTEM_ERR:
     66   case RPC_PROG_LOCKED:
     67       // case ignored
     68       break;
     69 
     70   default:
     71       return FALSE;
     72   }
     73 
     74   return TRUE;
     75 } /* xdr_send_accepted_reply_header */
     76 
     77 static bool_t xdr_send_denied_reply(
     78     xdr_s_type *xdr,
     79     struct rpc_denied_reply const *rejreply)
     80 {
     81     if (!XDR_SEND_ENUM(xdr, &rejreply->stat))
     82         return FALSE;
     83 
     84     switch ((*rejreply).stat){
     85     case RPC_MISMATCH:
     86         if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.low))
     87             return FALSE;
     88         if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.high))
     89             return FALSE;
     90         break;
     91     case RPC_AUTH_ERROR:
     92         if (!XDR_SEND_ENUM(xdr, &rejreply->u.why))
     93             return FALSE;
     94         break;
     95     default:
     96         return FALSE;
     97     }
     98 
     99     return TRUE;
    100 } /* xdr_send_denied_reply */
    101 
    102 bool_t xdr_send_reply_header(
    103     xdr_s_type *xdr,
    104     rpc_reply_header const *reply)
    105 {
    106     if (!XDR_SEND_ENUM(xdr, &reply->stat))
    107         return FALSE;
    108 
    109     switch ((*reply).stat) {
    110     case RPC_MSG_ACCEPTED:
    111         if (!xdr_send_accepted_reply_header(xdr, &reply->u.ar))
    112             return FALSE;
    113         break;
    114     case RPC_MSG_DENIED:
    115         if (!xdr_send_denied_reply(xdr, &reply->u.dr))
    116             return FALSE;
    117         break;
    118     default:
    119         return FALSE;
    120     }
    121 
    122     return TRUE;
    123 } /* xdr_send_reply_header */
    124 
    125 #include <stdio.h>
    126 
    127 bool_t
    128 xdr_send_auth(xdr_s_type *xdr, const opaque_auth *auth)
    129 {
    130 #define FAILIF(x) do { if (x) return FALSE; } while(0)
    131 
    132     switch (sizeof(auth->oa_flavor)) {
    133     case 1:
    134         FAILIF(!XDR_SEND_INT8(xdr, (int8_t *)&auth->oa_flavor));
    135         break;
    136     case 2:
    137         FAILIF(!XDR_SEND_INT16(xdr, (int16_t *)&auth->oa_flavor));
    138         break;
    139     case 4:
    140         FAILIF(!XDR_SEND_INT32(xdr, (int32_t *)&auth->oa_flavor));
    141         break;
    142     default:
    143         return FALSE;
    144     }
    145 
    146     return (XDR_SEND_UINT(xdr, (uint32_t *)&auth->oa_length) &&
    147             (auth->oa_length == 0 ||
    148              XDR_SEND_BYTES(xdr, (uint8_t *)auth->oa_base, auth->oa_length)));
    149 }
    150 
    151 void xdr_free(xdrproc_t proc, char *objp)
    152 {
    153     XDR x;
    154     x.x_op = XDR_FREE;
    155     (*proc)(&x, objp);
    156 }
    157