From 8ae943f608237ed4dcaf80131ce35588598069ea Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 16 Mar 2014 14:15:34 -0700 Subject: [PATCH] PORTMAP: Add support for V3 DUMP command This implements the missing procedure from Issue #65 --- examples/Makefile.am | 2 +- examples/nfsclient-raw.c | 37 ++++++++++++++++++++++++++++++++++-- include/nfsc/libnfs-raw.h | 16 ++++++++++++++++ lib/libnfs-win32.def | 1 + portmap/libnfs-raw-portmap.c | 24 +++++++++++++++++++++++ portmap/libnfs-raw-portmap.h | 24 ++++++++++++++++++++++- portmap/portmap.c | 19 ++++++++++++++++++ portmap/portmap.x | 12 ++++++++++++ 8 files changed, 131 insertions(+), 4 deletions(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index 39f5a17..10fd9ea 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -5,8 +5,8 @@ AM_CPPFLAGS = \ -I$(abs_top_srcdir)/include/nfsc \ -I$(abs_top_srcdir)/mount \ -I$(abs_top_srcdir)/nfs \ - -I$(abs_top_srcdir)/rquota \ -I$(abs_top_srcdir)/portmap \ + -I$(abs_top_srcdir)/rquota \ "-D_U_=__attribute__((unused))" AM_LDFLAGS = ../lib/.libs/libnfs.la -lpopt diff --git a/examples/nfsclient-raw.c b/examples/nfsclient-raw.c index 28dd45c..fd6575f 100644 --- a/examples/nfsclient-raw.c +++ b/examples/nfsclient-raw.c @@ -44,6 +44,7 @@ #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" +#include "libnfs-raw-portmap.h" #include "libnfs-raw-rquota.h" struct client { @@ -345,9 +346,11 @@ void pmap_getport1_cb(struct rpc_context *rpc, int status, void *data, void *pri } } -void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +void pmap_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; + struct pmap_dump_result *dr = data; + struct pmap_mapping_list *list = dr->list; if (status == RPC_STATUS_ERROR) { printf("portmapper null call failed with \"%s\"\n", (char *)data); @@ -358,7 +361,16 @@ void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private exit(10); } - printf("Got reply from server for PORTMAP/NULL procedure.\n"); + printf("Got reply from server for PORTMAP/DUMP procedure.\n"); + while (list) { + printf("Prog:%d Vers:%d Protocol:%d Port:%d\n", + list->map.prog, + list->map.vers, + list->map.prot, + list->map.port); + list = list->next; + } + printf("Send getport request asking for MOUNT port\n"); if (rpc_pmap_getport_async(rpc, RQUOTA_PROGRAM, RQUOTA_V1, IPPROTO_TCP, pmap_getport1_cb, client) != 0) { printf("Failed to send getport request\n"); @@ -366,6 +378,27 @@ void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private } } +void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + + if (status == RPC_STATUS_ERROR) { + printf("portmapper null call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("portmapper null call to server %s failed, status:%d\n", client->server, status); + exit(10); + } + + printf("Got reply from server for PORTMAP/NULL procedure.\n"); + printf("Send PMAP/DUMP command\n"); + if (rpc_pmap_dump_async(rpc, pmap_dump_cb, client) != 0) { + printf("Failed to send getport request\n"); + exit(10); + } +} + void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; diff --git a/include/nfsc/libnfs-raw.h b/include/nfsc/libnfs-raw.h index c5eeb90..9d6b0ec 100644 --- a/include/nfsc/libnfs-raw.h +++ b/include/nfsc/libnfs-raw.h @@ -187,6 +187,22 @@ EXTERN int rpc_pmap_set_async(struct rpc_context *rpc, int program, int version, */ EXTERN int rpc_pmap_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); +/* + * Call PORTMAPPER/DUMP. + * 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 struct *pmap_mapping_list. + * 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_pmap_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + /* * Call PORTMAPPER/CALLIT. * Function returns diff --git a/lib/libnfs-win32.def b/lib/libnfs-win32.def index 100f0cb..7eae952 100644 --- a/lib/libnfs-win32.def +++ b/lib/libnfs-win32.def @@ -100,6 +100,7 @@ rpc_pmap_null_async rpc_pmap_getport_async rpc_pmap_set_async rpc_pmap_unset_async +rpc_pmap_dump_async rpc_pmap_callit_async rpc_mount_null_async rpc_mount_mnt_async diff --git a/portmap/libnfs-raw-portmap.c b/portmap/libnfs-raw-portmap.c index 3477564..a07a1e6 100644 --- a/portmap/libnfs-raw-portmap.c +++ b/portmap/libnfs-raw-portmap.c @@ -130,3 +130,27 @@ zdr_pmap_call_result (ZDR *zdrs, pmap_call_result *objp) return FALSE; return TRUE; } + +bool_t +zdr_pmap_mapping_list (ZDR *zdrs, pmap_mapping_list *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_pmap_mapping (zdrs, &objp->map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap_mapping_list), (zdrproc_t) zdr_pmap_mapping_list)) + return FALSE; + return TRUE; +} + +bool_t +zdr_pmap_dump_result (ZDR *zdrs, pmap_dump_result *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap_mapping_list), (zdrproc_t) zdr_pmap_mapping_list)) + return FALSE; + return TRUE; +} diff --git a/portmap/libnfs-raw-portmap.h b/portmap/libnfs-raw-portmap.h index df88b67..f8d9a45 100644 --- a/portmap/libnfs-raw-portmap.h +++ b/portmap/libnfs-raw-portmap.h @@ -6,7 +6,8 @@ #ifndef _PORTMAP_H_RPCGEN #define _PORTMAP_H_RPCGEN -#include + + #ifdef __cplusplus extern "C" { @@ -42,6 +43,17 @@ struct pmap_call_result { }; typedef struct pmap_call_result pmap_call_result; +struct pmap_mapping_list { + pmap_mapping map; + struct pmap_mapping_list *next; +}; +typedef struct pmap_mapping_list pmap_mapping_list; + +struct pmap_dump_result { + struct pmap_mapping_list *list; +}; +typedef struct pmap_dump_result pmap_dump_result; + #define PMAP_PROGRAM 100000 #define PMAP_V2 2 @@ -58,6 +70,9 @@ extern bool_t * pmap_unset_2_svc(pmap_mapping *, struct svc_req *); #define PMAP_GETPORT 3 extern u_int * pmap_getport_2(pmap_mapping *, CLIENT *); extern u_int * pmap_getport_2_svc(pmap_mapping *, struct svc_req *); +#define PMAP_DUMP 4 +extern pmap_mapping_list * pmap_dump_2(void *, CLIENT *); +extern pmap_mapping_list * pmap_dump_2_svc(void *, struct svc_req *); #define PMAP_CALLIT 5 extern pmap_call_result * pmap_callit_2(pmap_call_args *, CLIENT *); extern pmap_call_result * pmap_callit_2_svc(pmap_call_args *, struct svc_req *); @@ -76,6 +91,9 @@ extern bool_t * pmap_unset_2_svc(); #define PMAP_GETPORT 3 extern u_int * pmap_getport_2(); extern u_int * pmap_getport_2_svc(); +#define PMAP_DUMP 4 +extern pmap_mapping_list * pmap_dump_2(); +extern pmap_mapping_list * pmap_dump_2_svc(); #define PMAP_CALLIT 5 extern pmap_call_result * pmap_callit_2(); extern pmap_call_result * pmap_callit_2_svc(); @@ -88,11 +106,15 @@ extern int pmap_program_2_freeresult (); extern bool_t zdr_pmap_mapping (ZDR *, pmap_mapping*); extern bool_t zdr_pmap_call_args (ZDR *, pmap_call_args*); extern bool_t zdr_pmap_call_result (ZDR *, pmap_call_result*); +extern bool_t zdr_pmap_mapping_list (ZDR *, pmap_mapping_list*); +extern bool_t zdr_pmap_dump_result (ZDR *, pmap_dump_result*); #else /* K&R C */ extern bool_t zdr_pmap_mapping (); extern bool_t zdr_pmap_call_args (); extern bool_t zdr_pmap_call_result (); +extern bool_t zdr_pmap_mapping_list (); +extern bool_t zdr_pmap_dump_result (); #endif /* K&R C */ diff --git a/portmap/portmap.c b/portmap/portmap.c index d1c1488..5042e8c 100644 --- a/portmap/portmap.c +++ b/portmap/portmap.c @@ -135,6 +135,25 @@ int rpc_pmap_unset_async(struct rpc_context *rpc, int program, int version, int return 0; } +int rpc_pmap_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP_DUMP, cb, private_data, (zdrproc_t)zdr_pmap_dump_result, sizeof(pmap_dump_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for portmap/dump call"); + return -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue portmap/dump pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + int rpc_pmap_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; diff --git a/portmap/portmap.x b/portmap/portmap.x index ef9f08e..17fd980 100644 --- a/portmap/portmap.x +++ b/portmap/portmap.x @@ -23,6 +23,15 @@ struct pmap_call_result { opaque res<>; }; +struct pmap_mapping_list { + pmap_mapping map; + pmap_mapping_list *next; +}; + +struct pmap_dump_result { + struct pmap_mapping_list *list; +}; + program PMAP_PROGRAM { version PMAP_V2 { void @@ -37,6 +46,9 @@ program PMAP_PROGRAM { unsigned int PMAP_GETPORT(pmap_mapping) = 3; + pmap_mapping_list + PMAP_DUMP(void) = 4; + pmap_call_result PMAP_CALLIT(pmap_call_args) = 5; } = 2; -- 2.34.1