315aa0afd7f45eb04bd155d5aba8cf6c09c8828e
2 Copyright (C) 2012 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * This file contains definitions for the built in ZDR implementation.
19 * This is a very limited ZDR subset that can only marshal to/from a momory buffer,
20 * i.e. zdrmem_create() buffers.
21 * It aims to be compatible with normal rpcgen generated functions.
26 #include "libnfs-zdr.h"
28 struct opaque_auth _null_auth
;
30 bool_t
libnfs_zdr_setpos(ZDR
*zdrs
, uint32_t pos
)
35 uint32_t libnfs_zdr_getpos(ZDR
*zdrs
)
40 void libnfs_zdrmem_create(ZDR
*zdrs
, const caddr_t addr
, uint32_t size
, enum zdr_op xop
)
49 static void *zdr_malloc(ZDR
*zdrs
, uint32_t size
)
53 mem
= malloc(sizeof(struct zdr_mem
));
54 mem
->next
= zdrs
->mem
;
56 mem
->buf
= malloc(mem
->size
);
62 void libnfs_zdr_destroy(ZDR
*zdrs
)
64 while (zdrs
->mem
!= NULL
) {
65 struct zdr_mem
*mem
= zdrs
->mem
->next
;
72 bool_t
libnfs_zdr_u_int(ZDR
*zdrs
, uint32_t *u
)
74 if (zdrs
->pos
+ 4 > zdrs
->size
) {
80 *(uint32_t *)&zdrs
->buf
[zdrs
->pos
] = htonl(*u
);
85 *u
= ntohl(*(uint32_t *)&zdrs
->buf
[zdrs
->pos
]);
94 bool_t
libnfs_zdr_int(ZDR
*zdrs
, int32_t *i
)
96 return libnfs_zdr_u_int(zdrs
, (uint32_t *)i
);
99 bool_t
libnfs_zdr_u_quad_t(ZDR
*zdrs
, uint64_t *u
)
101 if (zdrs
->pos
+ 8 > zdrs
->size
) {
105 switch (zdrs
->x_op
) {
107 *(uint32_t *)&zdrs
->buf
[zdrs
->pos
] = htonl((*u
>> 32));
109 *(uint32_t *)&zdrs
->buf
[zdrs
->pos
] = htonl((*u
& 0xffffffff));
114 *u
= ntohl(*(uint32_t *)&zdrs
->buf
[zdrs
->pos
]);
117 *u
|= ntohl(*(uint32_t *)&zdrs
->buf
[zdrs
->pos
]);
126 bool_t
libnfs_zdr_quad_t(ZDR
*zdrs
, int64_t *i
)
128 return libnfs_zdr_u_quad_t(zdrs
, (uint64_t *)i
);
131 bool_t
libnfs_zdr_bytes(ZDR
*zdrs
, char **bufp
, uint32_t *size
, uint32_t maxsize
)
133 if (!libnfs_zdr_u_int(zdrs
, size
)) {
137 if (zdrs
->pos
+ *size
> zdrs
->size
) {
141 switch (zdrs
->x_op
) {
143 memcpy(&zdrs
->buf
[zdrs
->pos
], *bufp
, *size
);
145 zdrs
->pos
= (zdrs
->pos
+ 3) & ~3;
149 *bufp
= zdr_malloc(zdrs
, *size
);
151 memcpy(*bufp
, &zdrs
->buf
[zdrs
->pos
], *size
);
153 zdrs
->pos
= (zdrs
->pos
+ 3) & ~3;
161 bool_t
libnfs_zdr_enum(ZDR
*zdrs
, int32_t *e
)
163 return libnfs_zdr_u_int(zdrs
, (uint32_t *)e
);
166 bool_t
libnfs_zdr_bool(ZDR
*zdrs
, bool_t
*b
)
168 return libnfs_zdr_u_int(zdrs
, (uint32_t *)b
);
171 bool_t
libnfs_zdr_void(void)
176 bool_t
libnfs_zdr_pointer(ZDR
*zdrs
, char **objp
, uint32_t size
, zdrproc_t proc
)
180 more_data
= (*objp
!= NULL
);
182 if (!libnfs_zdr_bool(zdrs
, &more_data
)) {
185 if (more_data
== 0) {
190 if (zdrs
->x_op
== ZDR_DECODE
) {
191 *objp
= zdr_malloc(zdrs
, size
);
195 memset(*objp
, 0, size
);
197 return proc(zdrs
, *objp
);
200 bool_t
libnfs_zdr_opaque(ZDR
*zdrs
, char *objp
, uint32_t size
)
202 switch (zdrs
->x_op
) {
204 memcpy(&zdrs
->buf
[zdrs
->pos
], objp
, size
);
206 zdrs
->pos
= (zdrs
->pos
+ 3) & ~3;
209 memcpy(objp
, &zdrs
->buf
[zdrs
->pos
], size
);
211 zdrs
->pos
= (zdrs
->pos
+ 3) & ~3;
218 bool_t
libnfs_zdr_string(ZDR
*zdrs
, char **strp
, uint32_t maxsize
)
222 if (zdrs
->x_op
== ZDR_ENCODE
) {
223 size
= strlen(*strp
);
226 if (!libnfs_zdr_u_int(zdrs
, &size
)) {
230 if (zdrs
->pos
+ size
> zdrs
->size
) {
234 switch (zdrs
->x_op
) {
236 return libnfs_zdr_opaque(zdrs
, *strp
, size
);
238 *strp
= zdr_malloc(zdrs
, size
+ 1);
243 return libnfs_zdr_opaque(zdrs
, *strp
, size
);
249 bool_t
libnfs_zdr_array(ZDR
*zdrs
, char **arrp
, uint32_t *size
, uint32_t maxsize
, uint32_t elsize
, zdrproc_t proc
)
253 if (!libnfs_zdr_u_int(zdrs
, size
)) {
257 if (zdrs
->pos
+ *size
* elsize
> zdrs
->size
) {
261 if (zdrs
->x_op
== ZDR_DECODE
) {
262 *arrp
= zdr_malloc(zdrs
, *size
* elsize
);
266 memset(*arrp
, 0, *size
* elsize
);
269 for (i
= 0; i
< *size
; i
++) {
270 if (proc(zdrs
, *arrp
+ i
* elsize
)) {
277 void libnfs_zdr_free(zdrproc_t proc
, char *objp
)
281 static bool_t
libnfs_opaque_auth(ZDR
*zdrs
, struct opaque_auth
*auth
)
283 if (!libnfs_zdr_u_int(zdrs
, &auth
->oa_flavor
)) {
287 if (!libnfs_zdr_bytes(zdrs
, &auth
->oa_base
, &auth
->oa_length
, &auth
->oa_length
)) {
294 static bool_t
libnfs_rpc_call_body(ZDR
*zdrs
, struct call_body
*cmb
)
296 if (!libnfs_zdr_u_int(zdrs
, &cmb
->cb_rpcvers
)) {
300 if (!libnfs_zdr_u_int(zdrs
, &cmb
->cb_prog
)) {
304 if (!libnfs_zdr_u_int(zdrs
, &cmb
->cb_vers
)) {
308 if (!libnfs_zdr_u_int(zdrs
, &cmb
->cb_proc
)) {
312 if (!libnfs_opaque_auth(zdrs
, &cmb
->cb_cred
)) {
316 if (!libnfs_opaque_auth(zdrs
, &cmb
->cb_verf
)) {
321 static bool_t
libnfs_accepted_reply(ZDR
*zdrs
, struct accepted_reply
*ar
)
323 if (!libnfs_opaque_auth(zdrs
, &ar
->ar_verf
)) {
327 if (!libnfs_zdr_u_int(zdrs
, &ar
->ar_stat
)) {
331 switch (ar
->ar_stat
) {
333 if (!ar
->ar_results
.proc(zdrs
, ar
->ar_results
.where
)) {
338 if (!libnfs_zdr_u_int(zdrs
, &ar
->ar_vers
.low
)) {
341 if (!libnfs_zdr_u_int(zdrs
, &ar
->ar_vers
.high
)) {
352 static bool_t
libnfs_rejected_reply(ZDR
*zdrs
, struct rejected_reply
*RP_dr
)
354 printf("rejected reply\n");
358 static bool_t
libnfs_rpc_reply_body(ZDR
*zdrs
, struct reply_body
*rmb
)
360 if (!libnfs_zdr_u_int(zdrs
, &rmb
->rp_stat
)) {
364 switch (rmb
->rp_stat
) {
366 if (!libnfs_accepted_reply(zdrs
, &rmb
->rp_acpt
)) {
371 if (!libnfs_rejected_reply(zdrs
, &rmb
->rp_rjct
)) {
380 static bool_t
libnfs_rpc_msg(ZDR
*zdrs
, struct rpc_msg
*msg
)
382 if (!libnfs_zdr_u_int(zdrs
, &msg
->rm_xid
)) {
386 if (!libnfs_zdr_u_int(zdrs
, &msg
->rm_direction
)) {
390 switch (msg
->rm_direction
) {
392 return libnfs_rpc_call_body(zdrs
, &msg
->ru
.RM_cmb
);
395 return libnfs_rpc_reply_body(zdrs
, &msg
->ru
.RM_rmb
);
402 bool_t
libnfs_zdr_callmsg(ZDR
*zdrs
, struct rpc_msg
*msg
)
404 return libnfs_rpc_msg(zdrs
, msg
);
407 bool_t
libnfs_zdr_replymsg(ZDR
*zdrs
, struct rpc_msg
*msg
)
409 return libnfs_rpc_msg(zdrs
, msg
);
412 AUTH
*authnone_create(void)
416 auth
= malloc(sizeof(AUTH
));
418 auth
->ah_cred
.oa_flavor
= AUTH_NONE
;
419 auth
->ah_cred
.oa_length
= 0;
420 auth
->ah_cred
.oa_base
= NULL
;
422 auth
->ah_verf
.oa_flavor
= AUTH_NONE
;
423 auth
->ah_verf
.oa_length
= 0;
424 auth
->ah_verf
.oa_base
= NULL
;
426 auth
->ah_private
= NULL
;
431 AUTH
*libnfs_authunix_create(char *host
, uint32_t uid
, uint32_t gid
, uint32_t len
, uint32_t *groups
)
438 size
= 4 + 4 + ((strlen(host
) + 3) & ~3) + 4 + 4 + 4 + len
* 4;
439 auth
= malloc(sizeof(AUTH
));
440 auth
->ah_cred
.oa_flavor
= AUTH_UNIX
;
441 auth
->ah_cred
.oa_length
= size
;
442 auth
->ah_cred
.oa_base
= malloc(size
);
444 buf
= auth
->ah_cred
.oa_base
;
446 buf
[idx
++] = htonl(time(NULL
));
447 buf
[idx
++] = htonl(strlen(host
));
448 memcpy(&buf
[2], host
, strlen(host
));
450 idx
+= (strlen(host
) + 3) >> 2;
451 buf
[idx
++] = htonl(uid
);
452 buf
[idx
++] = htonl(gid
);
453 buf
[idx
++] = htonl(len
);
455 buf
[idx
++] = htonl(*groups
++);
458 auth
->ah_verf
.oa_flavor
= AUTH_NONE
;
459 auth
->ah_verf
.oa_length
= 0;
460 auth
->ah_verf
.oa_base
= NULL
;
462 auth
->ah_private
= NULL
;
467 AUTH
*libnfs_authunix_create_default(void)
469 return libnfs_authunix_create("libnfs", getuid(), -1, 0, NULL
);
472 void libnfs_auth_destroy(AUTH
*auth
)
474 if (auth
->ah_cred
.oa_base
) {
475 free(auth
->ah_cred
.oa_base
);
477 if (auth
->ah_verf
.oa_base
) {
478 free(auth
->ah_verf
.oa_base
);