From 729266a7963b30d5c44da0fc491dd8f819bcbb53 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 17 Mar 2014 21:05:18 -0700 Subject: [PATCH] PORTMAP: Add PMAP v3 UADDR2TADDR support --- examples/portmap-client.c | 41 ++++++++++++++++++++++++++++++++++++ include/nfsc/libnfs-raw.h | 16 ++++++++++++++ lib/libnfs-win32.def | 1 + portmap/libnfs-raw-portmap.c | 13 ++++++++++++ portmap/libnfs-raw-portmap.h | 17 +++++++++++++++ portmap/portmap.c | 24 +++++++++++++++++++++ portmap/portmap.x | 8 +++++++ 7 files changed, 120 insertions(+) diff --git a/examples/portmap-client.c b/examples/portmap-client.c index 73c7ab2..c9cde39 100644 --- a/examples/portmap-client.c +++ b/examples/portmap-client.c @@ -145,6 +145,34 @@ void pmap3_gettime_cb(struct rpc_context *rpc, int status, void *data, void *pri client->is_finished = 1; } +void pmap3_uaddr2taddr_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + struct pmap3_netbuf *nb = data; + int i; + + if (status == RPC_STATUS_ERROR) { + printf("PORTMAP3/UADDR2TADDR call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP3/UADDR2TADDR call failed, status:%d\n", status); + exit(10); + } + + printf("PORTMAP3/UADDR2TADDR:\n"); + printf(" MaxLen:%d\n", nb->maxlen); + printf(" "); + for (i = 0; i < nb->maxlen; i++) { + printf("%02x ", nb->buf.buf_val[i]); + if (i %16 == 15) { + printf("\n "); + } + } + printf("\n"); + client->is_finished = 1; +} + void pmap2_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; @@ -246,10 +274,12 @@ int main(int argc _U_, char *argv[] _U_) int getaddr3 = 0; int dump3 = 0; int gettime3 = 0; + int u2t3 = 0; int command_found = 0; int getaddr3prog, getaddr3vers; char *getaddr3netid; + char *u2t3string; rpc = rpc_init_context(); if (rpc == NULL) { @@ -270,6 +300,10 @@ int main(int argc _U_, char *argv[] _U_) } else if (!strcmp(argv[i], "gettime3")) { gettime3 = 1; command_found++; + } else if (!strcmp(argv[i], "u2t3")) { + u2t3 = 1; + u2t3string = argv[++i]; + command_found++; } else if (!strcmp(argv[i], "getaddr3")) { getaddr3 = 1; getaddr3prog = atoi(argv[++i]); @@ -329,6 +363,13 @@ int main(int argc _U_, char *argv[] _U_) } wait_until_finished(rpc, &client); } + if (u2t3) { + if (rpc_pmap3_uaddr2taddr_async(rpc, u2t3string, pmap3_uaddr2taddr_cb, &client) != 0) { + printf("Failed to send UADDR2TADDR3 request\n"); + exit(10); + } + wait_until_finished(rpc, &client); + } if (getaddr3) { struct pmap3_mapping map; diff --git a/include/nfsc/libnfs-raw.h b/include/nfsc/libnfs-raw.h index b8330a6..f3113a6 100644 --- a/include/nfsc/libnfs-raw.h +++ b/include/nfsc/libnfs-raw.h @@ -336,6 +336,22 @@ EXTERN int rpc_pmap3_callit_async(struct rpc_context *rpc, int program, int vers */ EXTERN int rpc_pmap3_gettime_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +/* + * Call PORTMAPPER3/UADDR2TADDR. + * Function returns + * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. + * <0 : An error occured when trying to set up the connection. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. + * data is a struct pmap3_netbuf *. + * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_pmap3_uaddr2taddr_async(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data); + /* * MOUNT v3 FUNCTIONS */ diff --git a/lib/libnfs-win32.def b/lib/libnfs-win32.def index d6bc077..81ec68e 100644 --- a/lib/libnfs-win32.def +++ b/lib/libnfs-win32.def @@ -109,6 +109,7 @@ rpc_pmap3_getaddr_async rpc_pmap3_dump_async rpc_pmap3_callit_async rpc_pmap3_gettime_async +rpc_pmap3_uaddr2taddr_async rpc_mount_null_async rpc_mount_mnt_async rpc_mount_dump_async diff --git a/portmap/libnfs-raw-portmap.c b/portmap/libnfs-raw-portmap.c index 30ff664..293b0a1 100644 --- a/portmap/libnfs-raw-portmap.c +++ b/portmap/libnfs-raw-portmap.c @@ -277,3 +277,16 @@ zdr_pmap3_call_result (ZDR *zdrs, pmap3_call_result *objp) return FALSE; return TRUE; } + +bool_t +zdr_pmap3_netbuf (ZDR *zdrs, pmap3_netbuf *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_u_int (zdrs, &objp->maxlen)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->buf.buf_val, (u_int *) &objp->buf.buf_len, ~0)) + return FALSE; + return TRUE; +} diff --git a/portmap/libnfs-raw-portmap.h b/portmap/libnfs-raw-portmap.h index c888263..1c5ec05 100644 --- a/portmap/libnfs-raw-portmap.h +++ b/portmap/libnfs-raw-portmap.h @@ -99,6 +99,15 @@ struct pmap3_call_result { }; typedef struct pmap3_call_result pmap3_call_result; +struct pmap3_netbuf { + u_int maxlen; + struct { + u_int buf_len; + char *buf_val; + } buf; +}; +typedef struct pmap3_netbuf pmap3_netbuf; + #define PMAP_PROGRAM 100000 #define PMAP_V2 2 @@ -168,6 +177,9 @@ extern pmap3_call_result * pmap3_callit_3_svc(pmap3_call_args *, struct svc_req #define PMAP3_GETTIME 6 extern u_int * pmap3_gettime_3(void *, CLIENT *); extern u_int * pmap3_gettime_3_svc(void *, struct svc_req *); +#define PMAP3_UADDR2TADDR 7 +extern pmap3_netbuf * pmap3_uaddr2taddr_3(char **, CLIENT *); +extern pmap3_netbuf * pmap3_uaddr2taddr_3_svc(char **, struct svc_req *); extern int pmap_program_3_freeresult (SVCXPRT *, zdrproc_t, caddr_t); #else /* K&R C */ @@ -192,6 +204,9 @@ extern pmap3_call_result * pmap3_callit_3_svc(); #define PMAP3_GETTIME 6 extern u_int * pmap3_gettime_3(); extern u_int * pmap3_gettime_3_svc(); +#define PMAP3_UADDR2TADDR 7 +extern pmap3_netbuf * pmap3_uaddr2taddr_3(); +extern pmap3_netbuf * pmap3_uaddr2taddr_3_svc(); extern int pmap_program_3_freeresult (); #endif /* K&R C */ @@ -209,6 +224,7 @@ extern bool_t zdr_pmap3_mapping_list (ZDR *, pmap3_mapping_list*); extern bool_t zdr_pmap3_dump_result (ZDR *, pmap3_dump_result*); extern bool_t zdr_pmap3_call_args (ZDR *, pmap3_call_args*); extern bool_t zdr_pmap3_call_result (ZDR *, pmap3_call_result*); +extern bool_t zdr_pmap3_netbuf (ZDR *, pmap3_netbuf*); #else /* K&R C */ extern bool_t zdr_pmap2_mapping (); @@ -222,6 +238,7 @@ extern bool_t zdr_pmap3_mapping_list (); extern bool_t zdr_pmap3_dump_result (); extern bool_t zdr_pmap3_call_args (); extern bool_t zdr_pmap3_call_result (); +extern bool_t zdr_pmap3_netbuf (); #endif /* K&R C */ diff --git a/portmap/portmap.c b/portmap/portmap.c index 5c0633b..e6aea82 100644 --- a/portmap/portmap.c +++ b/portmap/portmap.c @@ -352,3 +352,27 @@ int rpc_pmap3_callit_async(struct rpc_context *rpc, int program, int version, in return 0; } + +int rpc_pmap3_uaddr2taddr_async(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UADDR2TADDR, cb, private_data, (zdrproc_t)zdr_pmap3_netbuf, sizeof(pmap3_netbuf)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UADDR2TADDR call"); + return -1; + } + + if (zdr_string(&pdu->zdr, &uaddr, 255) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UADDR2TADDR call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/UADDR2TADDR pdu: %s", rpc_get_error(rpc)); + return -1; + } + + return 0; +} diff --git a/portmap/portmap.x b/portmap/portmap.x index 238656f..45c87af 100644 --- a/portmap/portmap.x +++ b/portmap/portmap.x @@ -65,6 +65,11 @@ struct pmap3_call_result { opaque res<>; }; +struct pmap3_netbuf { + unsigned int maxlen; + opaque buf<>; +}; + program PMAP_PROGRAM { version PMAP_V2 { void @@ -106,6 +111,9 @@ program PMAP_PROGRAM { unsigned int PMAP3_GETTIME(void) = 6; + + pmap3_netbuf + PMAP3_UADDR2TADDR(string) = 7; } = 3; } = 100000; -- 2.34.1