static DIR *nfs_opendir(struct device_d *dev, const char *pathname) { struct file_priv *priv; struct stat s; int ret; void *buf; struct nfs_dir *dir; int len; priv = nfs_do_open(dev, pathname); if (IS_ERR(priv)) return NULL; ret = nfs_attr_req(priv, &s); if (ret) return NULL; if (!S_ISDIR(s.st_mode)) return NULL; dir = xzalloc(sizeof(*dir)); dir->priv = priv; buf = nfs_readdirattr_req(priv, &len, 0); if (!buf) return NULL; xdr_init(&dir->stream, buf, len); return &dir->dir; }
ULONG CAN_slice(lstring* buffer, lstring* slice, bool_t direction, /*USHORT sdl_length,*/ UCHAR* sdl) { /************************************** * * C A N _ s l i c e * ************************************** * * Functional description * encode and decode canonical backup. * **************************************/ XDR xdr; XDR* xdrs = &xdr; xdr_init(xdrs, buffer, direction ? XDR_ENCODE : XDR_DECODE); xdr_slice(xdrs, slice, /*sdl_length,*/ sdl); return (xdrs->x_private - xdrs->x_base); }
/* * Create an RPC service */ struct svc_serv * svc_create(struct svc_program *prog, unsigned int bufsize, unsigned int xdrsize) { struct svc_serv *serv; xdr_init(); if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL))) return NULL; memset(serv, 0, sizeof(*serv)); serv->sv_program = prog; serv->sv_nrthreads = 1; serv->sv_stats = prog->pg_stats; serv->sv_bufsz = bufsize? bufsize : 4096; serv->sv_xdrsize = xdrsize; serv->sv_name = prog->pg_name; /* Remove any stale portmap registrations */ svc_register(serv, 0, 0); return serv; }
ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t direction) { /************************************** * * C A N _ e n c o d e _ d e c o d e * ************************************** * * Functional description * encode and decode canonical backup. * **************************************/ const burp_fld* field; SSHORT n; XDR xdr; XDR* xdrs = &xdr; xdr_init(xdrs, buffer, direction ? XDR_ENCODE : XDR_DECODE); RCRD_OFFSET offset = 0; for (field = relation->rel_fields; field; field = field->fld_next) { if (field->fld_flags & FLD_computed) continue; UCHAR* p = data + field->fld_offset; const bool array_fld = ((field->fld_flags & FLD_array) != 0); const FLD_LENGTH length = array_fld ? 8 : field->fld_length; if (field->fld_offset >= offset) offset = field->fld_offset + length; if (field->fld_type == blr_varying && !array_fld) offset += sizeof(SSHORT); SSHORT dtype; if (field->fld_type == blr_blob || array_fld) dtype = dtype_blob; else dtype = (SSHORT) gds_cvt_blr_dtype[field->fld_type]; switch (dtype) { case dtype_text: if (!xdr_opaque(xdrs, reinterpret_cast<char*>(p), length)) { return FALSE; } break; case dtype_varying: { vary* pVary = reinterpret_cast<vary*>(p); if (!xdr_short(xdrs, reinterpret_cast<SSHORT*>(&pVary->vary_length))) { return FALSE; } if (!xdr_opaque(xdrs, reinterpret_cast<SCHAR*>(pVary->vary_string), MIN(pVary->vary_length, length))) { return FALSE; } } break; case dtype_cstring: if (xdrs->x_op == XDR_ENCODE) n = static_cast<SSHORT>(MIN(strlen(reinterpret_cast<const char*>(p)), length)); if (!xdr_short(xdrs, &n)) return FALSE; if (!xdr_opaque(xdrs, reinterpret_cast<SCHAR*>(p), n)) return FALSE; if (xdrs->x_op == XDR_DECODE) p[n] = 0; break; case dtype_short: if (!xdr_short(xdrs, (SSHORT *) p)) return FALSE; break; case dtype_long: case dtype_sql_time: case dtype_sql_date: if (!xdr_long(xdrs, (SLONG *) p)) return FALSE; break; case dtype_real: if (!xdr_float(xdrs, (float *) p)) return FALSE; break; case dtype_double: if (!xdr_double(xdrs, (double *) p)) return FALSE; break; case dtype_timestamp: if (!xdr_long(xdrs, &((SLONG*) p)[0])) return FALSE; if (!xdr_long(xdrs, &((SLONG*) p)[1])) return FALSE; break; case dtype_quad: case dtype_blob: if (!xdr_quad(xdrs, (SQUAD*) p)) return FALSE; break; case dtype_int64: if (!xdr_hyper(xdrs, (SINT64*) p)) return FALSE; break; case dtype_boolean: if (!xdr_opaque(xdrs, (SCHAR*) p, length)) return FALSE; break; default: fb_assert(FALSE); return FALSE; } } // Next, get null flags for (field = relation->rel_fields; field; field = field->fld_next) { if (field->fld_flags & FLD_computed) continue; offset = FB_ALIGN(offset, sizeof(SSHORT)); UCHAR* p = data + offset; if (!xdr_short(xdrs, (SSHORT*) p)) return FALSE; offset += sizeof(SSHORT); } return (xdrs->x_private - xdrs->x_base); }
int interpret_rpc(int flags, char *rpc, int fraglen, int type) { ulong_t xid; int direction; struct cache_struct *x; int rpcvers, prog, vers, proc; int status, astat, rstat, why; char *lp; unsigned recmark; int markpos; extern int pi_frame; int lo, hi; xdr_init(rpc, fraglen); if (setjmp(xdr_err)) { if (flags & F_DTAIL) (void) sprintf(get_line(0, 0), "---- short frame ---"); return (fraglen); } if (type == IPPROTO_TCP) { /* record mark */ markpos = getxdr_pos(); recmark = getxdr_long(); } xid = getxdr_u_long(); direction = getxdr_long(); if (direction == CALL) { rpcvers = getxdr_long(); pos = getxdr_pos(); prog = getxdr_long(); vers = getxdr_long(); proc = getxdr_long(); stash_xid(xid, pi_frame, prog, vers, proc); if (!(flags & (F_SUM | F_DTAIL))) protoprint(flags, CALL, xid, prog, vers, proc, rpc, fraglen); } else { x = find_xid(xid); } if (flags & F_SUM) { switch (direction) { case CALL: (void) sprintf(get_sum_line(), "RPC C XID=%lu PROG=%d (%s) VERS=%d PROC=%d", xid, prog, nameof_prog(prog), vers, proc); if (getxdr_long() == RPCSEC_GSS) { /* Cred auth type */ extract_rpcsec_gss_cred_info(xid); /* RPCSEC_GSS cred auth data */ } else { xdr_skip(getxdr_long()); /* non RPCSEC_GSS cred auth data */ } xdr_skip(4); /* Verf auth type */ xdr_skip(RNDUP(getxdr_long())); /* Verf auth data */ protoprint(flags, CALL, xid, prog, vers, proc, rpc, fraglen); break; case REPLY: lp = get_sum_line(); if (x == NULL) (void) sprintf(lp, "RPC R XID=%lu", xid); else (void) sprintf(lp, "RPC R (#%d) XID=%lu", x->xid_frame, xid); lp += strlen(lp); status = getxdr_long(); switch (status) { case MSG_ACCEPTED: /* eat flavor and verifier */ (void) getxdr_long(); xdr_skip(RNDUP(getxdr_long())); astat = getxdr_long(); (void) sprintf(lp, " %s", nameof_astat(astat)); lp += strlen(lp); switch (astat) { case SUCCESS: if (x) { protoprint(flags, REPLY, xid, x->xid_prog, x->xid_vers, x->xid_proc, rpc, fraglen); } break; case PROG_UNAVAIL : case PROG_MISMATCH: case PROC_UNAVAIL : lo = getxdr_long(); hi = getxdr_long(); (void) sprintf(lp, " (low=%d, high=%d)", lo, hi); break; case GARBAGE_ARGS: case SYSTEM_ERR: default: ; } break; case MSG_DENIED: rstat = getxdr_long(); switch (rstat) { case RPC_MISMATCH: lo = getxdr_long(); hi = getxdr_long(); (void) sprintf(lp, " Vers mismatch (low=%d, high=%d)", lo, hi); break; case AUTH_ERROR: why = getxdr_u_long(); (void) sprintf(lp, " Can't authenticate (%s)", nameof_why(why)); break; } } break; } } if (flags & F_DTAIL) { show_header("RPC: ", "SUN RPC Header", fraglen); show_space(); if (type == IPPROTO_TCP) { /* record mark */ (void) sprintf(get_line(markpos, markpos+4), "Record Mark: %s fragment, length = %d", recmark & LAST_FRAG ? "last" : "", recmark & ~LAST_FRAG); } (void) sprintf(get_line(0, 0), "Transaction id = %lu", xid); (void) sprintf(get_line(0, 0), "Type = %d (%s)", direction, direction == CALL ? "Call":"Reply"); switch (direction) { case CALL: rpc_detail_call(flags, xid, rpcvers, prog, vers, proc, rpc, fraglen); break; case REPLY: rpc_detail_reply(flags, xid, x, rpc, fraglen); break; } } return (fraglen); }
static struct dirent *nfs_readdir(struct device_d *dev, DIR *dir) { struct nfs_dir *ndir = (void *)dir; __be32 *p; int ret; int len; struct xdr_stream *xdr = &ndir->stream; again: p = xdr_inline_decode(xdr, 4); if (!p) goto out_overflow; if (*p++ == xdr_zero) { p = xdr_inline_decode(xdr, 4); if (!p) goto out_overflow; if (*p++ == xdr_zero) { void *buf; int len; /* * End of current entries, read next chunk. */ free(ndir->stream.buf); buf = nfs_readdirattr_req(ndir->priv, &len, ndir->cookie); if (!buf) return NULL; xdr_init(&ndir->stream, buf, len); goto again; } return NULL; /* -EINVAL */ } p = xdr_inline_decode(xdr, 4); if (!p) goto out_overflow; ret = decode_filename(xdr, ndir->ent.d_name, &len); if (ret) return NULL; /* * The type (size and byte order) of nfscookie isn't defined in * RFC 1094. This implementation assumes that it's an XDR uint32. */ p = xdr_inline_decode(xdr, 4); if (!p) goto out_overflow; ndir->cookie = be32_to_cpup(p); return &ndir->ent; out_overflow: printf("nfs: overflow error\n"); return NULL; }