From 4edd78302d2a019fa4ca496531e4da0ebc9ca8a4 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 16 Mar 2014 16:03:19 -0700 Subject: [PATCH] PORTMAPv3: Add NULL and DUMP commands. Also add portmap example client. --- examples/Makefile.am | 3 +- examples/nfsclient-raw.c | 4 +- examples/portmap-client.c | 275 +++++++++++++++++++++++++++++++++++ include/nfsc/libnfs-raw.h | 39 ++++- portmap/libnfs-raw-portmap.c | 59 +++++++- portmap/libnfs-raw-portmap.h | 120 ++++++++++----- portmap/portmap.c | 65 +++++++-- portmap/portmap.x | 53 +++++-- 8 files changed, 544 insertions(+), 74 deletions(-) create mode 100644 examples/portmap-client.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 10fd9ea..d72e757 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ -noinst_PROGRAMS = nfsclient-async nfsclient-raw nfsclient-sync nfsclient-bcast nfsclient-listservers nfs-ls nfs-cp nfs-io +noinst_PROGRAMS = nfsclient-async nfsclient-raw nfsclient-sync nfsclient-bcast nfsclient-listservers nfs-ls nfs-cp nfs-io portmap-client AM_CPPFLAGS = \ -I$(abs_top_srcdir)/include \ @@ -27,3 +27,4 @@ nfsclient_bcast_SOURCES = nfsclient-bcast.c nfsclient_listservers_SOURCES = nfsclient-listservers.c +portmap_example_SOURCES = portmap-example.c diff --git a/examples/nfsclient-raw.c b/examples/nfsclient-raw.c index 85897eb..8b7d727 100644 --- a/examples/nfsclient-raw.c +++ b/examples/nfsclient-raw.c @@ -349,8 +349,8 @@ void pmap_getport1_cb(struct rpc_context *rpc, int status, void *data, void *pri 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; + struct pmap2_dump_result *dr = data; + struct pmap2_mapping_list *list = dr->list; if (status == RPC_STATUS_ERROR) { printf("portmapper null call failed with \"%s\"\n", (char *)data); diff --git a/examples/portmap-client.c b/examples/portmap-client.c new file mode 100644 index 0000000..d3866e6 --- /dev/null +++ b/examples/portmap-client.c @@ -0,0 +1,275 @@ +/* + Copyright (C) by Ronnie Sahlberg 2014 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +/* Example program using the lowlevel raw interface. + * This allow accurate control of the exact commands that are being used. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include "win32_compat.h" +#endif + +#ifdef HAVE_POLL_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#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 { + int is_finished; +}; + +void pmap2_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + struct pmap2_dump_result *dr = data; + struct pmap2_mapping_list *list = dr->list; + + if (status == RPC_STATUS_ERROR) { + printf("PORTMAP2/DUMP call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP2/DUMP call failed, status:%d\n", status); + exit(10); + } + + printf("PORTMAP2/DUMP:\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; + } + client->is_finished = 1; +} + +void pmap3_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + struct pmap3_dump_result *dr = data; + struct pmap3_mapping_list *list = dr->list; + + if (status == RPC_STATUS_ERROR) { + printf("PORTMAP3/DUMP call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP3/DUMP call failed, status:%d\n", status); + exit(10); + } + + printf("PORTMAP3/DUMP:\n"); + while (list) { + printf(" Prog:%d Vers:%d Netid:%s Addr:%s Owner:%s\n", + list->map.prog, + list->map.vers, + list->map.netid, + list->map.addr, + list->map.owner); + list = list->next; + } + client->is_finished = 1; +} + +void pmap2_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + + if (status == RPC_STATUS_ERROR) { + printf("PORTMAP2/NULL call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP2/NULL call failed, status:%d\n", status); + exit(10); + } + + printf("PORTMAP2/NULL responded and server is alive\n"); + client->is_finished = 1; +} + +void pmap3_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) +{ + struct client *client = private_data; + + if (status == RPC_STATUS_ERROR) { + printf("PORTMAP3/NULL call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP3/NULL call failed, status:%d\n", status); + exit(10); + } + + printf("PORTMAP3/NULL responded and server is alive\n"); + client->is_finished = 1; +} + +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("PORTMAP/NULL call failed with \"%s\"\n", (char *)data); + exit(10); + } + if (status != RPC_STATUS_SUCCESS) { + printf("PORTMAP/NULL call failed, status:%d\n", status); + exit(10); + } + + client->is_finished = 1; +} + +void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) +{ + struct client *client = private_data; + + if (status != RPC_STATUS_SUCCESS) { + printf("connection to portmapper failed\n"); + exit(10); + } + + if (rpc_pmap2_null_async(rpc, pmap_null_cb, client) != 0) { + printf("Failed to send null request\n"); + exit(10); + } +} + + +static void wait_until_finished(struct rpc_context *rpc, struct client *client) +{ + struct pollfd pfd; + + client->is_finished = 0; + for (;;) { + pfd.fd = rpc_get_fd(rpc); + pfd.events = rpc_which_events(rpc); + + if (poll(&pfd, 1, -1) < 0) { + printf("Poll failed"); + exit(10); + } + if (rpc_service(rpc, pfd.revents) < 0) { + printf("rpc_service failed\n"); + break; + } + if (client->is_finished) { + break; + } + } +} + +int main(int argc _U_, char *argv[] _U_) +{ + struct rpc_context *rpc; + struct client client; + char *server = NULL; + int i; + int null2 = 0; + int dump2 = 0; + int null3 = 0; + int dump3 = 0; + int command_found = 0; + + rpc = rpc_init_context(); + if (rpc == NULL) { + printf("failed to init context\n"); + exit(10); + } + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "dump2")) { + dump2 = 1; + command_found++; + } else if (!strcmp(argv[i], "null2")) { + null2 = 1; + command_found++; + } else if (!strcmp(argv[i], "dump3")) { + dump3 = 1; + command_found++; + } else if (!strcmp(argv[i], "null3")) { + null3 = 1; + command_found++; + } else { + server = argv[i]; + } + } + if (command_found == 0 || server == NULL) { + fprintf(stderr, "Usage: portmap-client \n"); + exit(10); + } + + if (rpc_connect_async(rpc, server, 111, pmap_connect_cb, &client) != 0) { + printf("Failed to start connection\n"); + exit(10); + } + wait_until_finished(rpc, &client); + + if (null2) { + if (rpc_pmap2_null_async(rpc, pmap2_null_cb, &client) != 0) { + printf("Failed to send NULL2 request\n"); + exit(10); + } + wait_until_finished(rpc, &client); + } + if (dump2) { + if (rpc_pmap2_dump_async(rpc, pmap2_dump_cb, &client) != 0) { + printf("Failed to send DUMP2 request\n"); + exit(10); + } + wait_until_finished(rpc, &client); + } + if (null3) { + if (rpc_pmap3_null_async(rpc, pmap3_null_cb, &client) != 0) { + printf("Failed to send NULL3 request\n"); + exit(10); + } + wait_until_finished(rpc, &client); + } + if (dump3) { + if (rpc_pmap3_dump_async(rpc, pmap3_dump_cb, &client) != 0) { + printf("Failed to send DUMP3 request\n"); + exit(10); + } + wait_until_finished(rpc, &client); + } + + + rpc_destroy_context(rpc); + rpc=NULL; + return 0; +} diff --git a/include/nfsc/libnfs-raw.h b/include/nfsc/libnfs-raw.h index ccbb1f8..90bcfcd 100644 --- a/include/nfsc/libnfs-raw.h +++ b/include/nfsc/libnfs-raw.h @@ -195,7 +195,7 @@ EXTERN int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int versi * * 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_dump_result. + * data is struct pmap2_dump_result. * 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. @@ -219,6 +219,43 @@ EXTERN int rpc_pmap2_dump_async(struct rpc_context *rpc, rpc_cb cb, void *privat */ EXTERN int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data); +/* + * PORTMAP v3 FUNCTIONS + */ + +/* + * Call PORTMAPPER3/NULL + * 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 NULL. + * 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_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/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 pmap3_dump_result. + * 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_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + + /* * MOUNT v3 FUNCTIONS */ diff --git a/portmap/libnfs-raw-portmap.c b/portmap/libnfs-raw-portmap.c index a07a1e6..967b126 100644 --- a/portmap/libnfs-raw-portmap.c +++ b/portmap/libnfs-raw-portmap.c @@ -7,7 +7,7 @@ #include "libnfs-raw-portmap.h" bool_t -zdr_pmap_mapping (ZDR *zdrs, pmap_mapping *objp) +zdr_pmap2_mapping (ZDR *zdrs, pmap2_mapping *objp) { register int32_t *buf; buf = NULL; @@ -63,7 +63,7 @@ zdr_pmap_mapping (ZDR *zdrs, pmap_mapping *objp) } bool_t -zdr_pmap_call_args (ZDR *zdrs, pmap_call_args *objp) +zdr_pmap2_call_args (ZDR *zdrs, pmap2_call_args *objp) { register int32_t *buf; buf = NULL; @@ -119,7 +119,7 @@ zdr_pmap_call_args (ZDR *zdrs, pmap_call_args *objp) } bool_t -zdr_pmap_call_result (ZDR *zdrs, pmap_call_result *objp) +zdr_pmap2_call_result (ZDR *zdrs, pmap2_call_result *objp) { register int32_t *buf; buf = NULL; @@ -132,25 +132,68 @@ zdr_pmap_call_result (ZDR *zdrs, pmap_call_result *objp) } bool_t -zdr_pmap_mapping_list (ZDR *zdrs, pmap_mapping_list *objp) +zdr_pmap2_mapping_list (ZDR *zdrs, pmap2_mapping_list *objp) { register int32_t *buf; buf = NULL; - if (!zdr_pmap_mapping (zdrs, &objp->map)) + if (!zdr_pmap2_mapping (zdrs, &objp->map)) return FALSE; - if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap_mapping_list), (zdrproc_t) zdr_pmap_mapping_list)) + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) return FALSE; return TRUE; } bool_t -zdr_pmap_dump_result (ZDR *zdrs, pmap_dump_result *objp) +zdr_pmap2_dump_result (ZDR *zdrs, pmap2_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)) + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) + return FALSE; + return TRUE; +} + +bool_t +zdr_pmap3_mapping (ZDR *zdrs, pmap3_mapping *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_u_int (zdrs, &objp->prog)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->vers)) + return FALSE; + if (!zdr_string (zdrs, &objp->netid, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->owner, ~0)) + return FALSE; + return TRUE; +} + +bool_t +zdr_pmap3_mapping_list (ZDR *zdrs, pmap3_mapping_list *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_pmap3_mapping (zdrs, &objp->map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) + return FALSE; + return TRUE; +} + +bool_t +zdr_pmap3_dump_result (ZDR *zdrs, pmap3_dump_result *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) return FALSE; return TRUE; } diff --git a/portmap/libnfs-raw-portmap.h b/portmap/libnfs-raw-portmap.h index 1930f37..7b1270e 100644 --- a/portmap/libnfs-raw-portmap.h +++ b/portmap/libnfs-raw-portmap.h @@ -15,15 +15,15 @@ extern "C" { #define PMAP_PORT 111 -struct pmap_mapping { +struct pmap2_mapping { u_int prog; u_int vers; u_int prot; u_int port; }; -typedef struct pmap_mapping pmap_mapping; +typedef struct pmap2_mapping pmap2_mapping; -struct pmap_call_args { +struct pmap2_call_args { u_int prog; u_int vers; u_int proc; @@ -32,27 +32,47 @@ struct pmap_call_args { char *args_val; } args; }; -typedef struct pmap_call_args pmap_call_args; +typedef struct pmap2_call_args pmap2_call_args; -struct pmap_call_result { +struct pmap2_call_result { u_int port; struct { u_int res_len; char *res_val; } res; }; -typedef struct pmap_call_result pmap_call_result; +typedef struct pmap2_call_result pmap2_call_result; -struct pmap_mapping_list { - pmap_mapping map; - struct pmap_mapping_list *next; +struct pmap2_mapping_list { + pmap2_mapping map; + struct pmap2_mapping_list *next; }; -typedef struct pmap_mapping_list pmap_mapping_list; +typedef struct pmap2_mapping_list pmap2_mapping_list; -struct pmap_dump_result { - struct pmap_mapping_list *list; +struct pmap2_dump_result { + struct pmap2_mapping_list *list; }; -typedef struct pmap_dump_result pmap_dump_result; +typedef struct pmap2_dump_result pmap2_dump_result; + +struct pmap3_mapping { + u_int prog; + u_int vers; + char *netid; + char *addr; + char *owner; +}; +typedef struct pmap3_mapping pmap3_mapping; + +struct pmap3_mapping_list { + pmap3_mapping map; + struct pmap3_mapping_list *next; +}; +typedef struct pmap3_mapping_list pmap3_mapping_list; + +struct pmap3_dump_result { + struct pmap3_mapping_list *list; +}; +typedef struct pmap3_dump_result pmap3_dump_result; #define PMAP_PROGRAM 100000 #define PMAP_V2 2 @@ -62,20 +82,20 @@ typedef struct pmap_dump_result pmap_dump_result; extern void * pmap2_null_2(void *, CLIENT *); extern void * pmap2_null_2_svc(void *, struct svc_req *); #define PMAP2_SET 1 -extern bool_t * pmap2_set_2(pmap_mapping *, CLIENT *); -extern bool_t * pmap2_set_2_svc(pmap_mapping *, struct svc_req *); +extern bool_t * pmap2_set_2(pmap2_mapping *, CLIENT *); +extern bool_t * pmap2_set_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_UNSET 2 -extern bool_t * pmap2_unset_2(pmap_mapping *, CLIENT *); -extern bool_t * pmap2_unset_2_svc(pmap_mapping *, struct svc_req *); +extern bool_t * pmap2_unset_2(pmap2_mapping *, CLIENT *); +extern bool_t * pmap2_unset_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_GETPORT 3 -extern u_int * pmap2_getport_2(pmap_mapping *, CLIENT *); -extern u_int * pmap2_getport_2_svc(pmap_mapping *, struct svc_req *); +extern u_int * pmap2_getport_2(pmap2_mapping *, CLIENT *); +extern u_int * pmap2_getport_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_DUMP 4 -extern pmap_dump_result * pmap2_dump_2(void *, CLIENT *); -extern pmap_dump_result * pmap2_dump_2_svc(void *, struct svc_req *); +extern pmap2_dump_result * pmap2_dump_2(void *, CLIENT *); +extern pmap2_dump_result * pmap2_dump_2_svc(void *, struct svc_req *); #define PMAP2_CALLIT 5 -extern pmap_call_result * pmap2_callit_2(pmap_call_args *, CLIENT *); -extern pmap_call_result * pmap2_callit_2_svc(pmap_call_args *, struct svc_req *); +extern pmap2_call_result * pmap2_callit_2(pmap2_call_args *, CLIENT *); +extern pmap2_call_result * pmap2_callit_2_svc(pmap2_call_args *, struct svc_req *); extern int pmap_program_2_freeresult (SVCXPRT *, zdrproc_t, caddr_t); #else /* K&R C */ @@ -92,29 +112,55 @@ extern bool_t * pmap2_unset_2_svc(); extern u_int * pmap2_getport_2(); extern u_int * pmap2_getport_2_svc(); #define PMAP2_DUMP 4 -extern pmap_dump_result * pmap2_dump_2(); -extern pmap_dump_result * pmap2_dump_2_svc(); +extern pmap2_dump_result * pmap2_dump_2(); +extern pmap2_dump_result * pmap2_dump_2_svc(); #define PMAP2_CALLIT 5 -extern pmap_call_result * pmap2_callit_2(); -extern pmap_call_result * pmap2_callit_2_svc(); +extern pmap2_call_result * pmap2_callit_2(); +extern pmap2_call_result * pmap2_callit_2_svc(); extern int pmap_program_2_freeresult (); #endif /* K&R C */ +#define PMAP_V3 3 + +#if defined(__STDC__) || defined(__cplusplus) +#define PMAP3_NULL 0 +extern void * pmap3_null_3(void *, CLIENT *); +extern void * pmap3_null_3_svc(void *, struct svc_req *); +#define PMAP3_DUMP 4 +extern pmap3_dump_result * pmap3_dump_3(void *, CLIENT *); +extern pmap3_dump_result * pmap3_dump_3_svc(void *, struct svc_req *); +extern int pmap_program_3_freeresult (SVCXPRT *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define PMAP3_NULL 0 +extern void * pmap3_null_3(); +extern void * pmap3_null_3_svc(); +#define PMAP3_DUMP 4 +extern pmap3_dump_result * pmap3_dump_3(); +extern pmap3_dump_result * pmap3_dump_3_svc(); +extern int pmap_program_3_freeresult (); +#endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) -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*); +extern bool_t zdr_pmap2_mapping (ZDR *, pmap2_mapping*); +extern bool_t zdr_pmap2_call_args (ZDR *, pmap2_call_args*); +extern bool_t zdr_pmap2_call_result (ZDR *, pmap2_call_result*); +extern bool_t zdr_pmap2_mapping_list (ZDR *, pmap2_mapping_list*); +extern bool_t zdr_pmap2_dump_result (ZDR *, pmap2_dump_result*); +extern bool_t zdr_pmap3_mapping (ZDR *, pmap3_mapping*); +extern bool_t zdr_pmap3_mapping_list (ZDR *, pmap3_mapping_list*); +extern bool_t zdr_pmap3_dump_result (ZDR *, pmap3_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 (); +extern bool_t zdr_pmap2_mapping (); +extern bool_t zdr_pmap2_call_args (); +extern bool_t zdr_pmap2_call_result (); +extern bool_t zdr_pmap2_mapping_list (); +extern bool_t zdr_pmap2_dump_result (); +extern bool_t zdr_pmap3_mapping (); +extern bool_t zdr_pmap3_mapping_list (); +extern bool_t zdr_pmap3_dump_result (); #endif /* K&R C */ diff --git a/portmap/portmap.c b/portmap/portmap.c index e156b38..aadc934 100644 --- a/portmap/portmap.c +++ b/portmap/portmap.c @@ -25,7 +25,9 @@ #include "libnfs-private.h" #include "libnfs-raw-portmap.h" - +/* + * PORTMAP v2 + */ int rpc_pmap2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; @@ -48,7 +50,7 @@ int rpc_pmap2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; - struct pmap_mapping m; + struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_GETPORT, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { @@ -60,7 +62,7 @@ int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, i m.vers = version; m.prot = protocol; m.port = 0; - if (zdr_pmap_mapping(&pdu->zdr, &m) == 0) { + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/GETPORT call"); rpc_free_pdu(rpc, pdu); return -1; @@ -78,7 +80,7 @@ int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, i int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; - struct pmap_mapping m; + struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { @@ -90,7 +92,7 @@ int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int p m.vers = version; m.prot = protocol; m.port = port; - if (zdr_pmap_mapping(&pdu->zdr, &m) == 0) { + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/SET call"); rpc_free_pdu(rpc, pdu); return -1; @@ -108,7 +110,7 @@ int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int p int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; - struct pmap_mapping m; + struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { @@ -120,7 +122,7 @@ int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int version, int m.vers = version; m.prot = protocol; m.port = port; - if (zdr_pmap_mapping(&pdu->zdr, &m) == 0) { + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/UNSET call"); rpc_free_pdu(rpc, pdu); return -1; @@ -139,7 +141,7 @@ int rpc_pmap2_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, PMAP2_DUMP, cb, private_data, (zdrproc_t)zdr_pmap_dump_result, sizeof(pmap_dump_result)); + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_DUMP, cb, private_data, (zdrproc_t)zdr_pmap2_dump_result, sizeof(pmap2_dump_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/DUMP call"); return -1; @@ -157,9 +159,9 @@ int rpc_pmap2_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) int rpc_pmap2_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; - struct pmap_call_args ca; + struct pmap2_call_args ca; - pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap_call_result, sizeof(pmap_call_result)); + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap2_call_result, sizeof(pmap2_call_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/CALLIT call"); return -1; @@ -171,7 +173,7 @@ int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, in ca.args.args_len = datalen; ca.args.args_val = data; - if (zdr_pmap_call_args(&pdu->zdr, &ca) == 0) { + if (zdr_pmap2_call_args(&pdu->zdr, &ca) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/CALLIT call"); rpc_free_pdu(rpc, pdu); return -1; @@ -184,3 +186,44 @@ int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, in return 0; } + +/* + * PORTMAP v3 + */ +int rpc_pmap3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/NULL call"); + return -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP3/NULL call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_pmap3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_DUMP, cb, private_data, (zdrproc_t)zdr_pmap3_dump_result, sizeof(pmap3_dump_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/DUMP call"); + return -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/DUMP pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} diff --git a/portmap/portmap.x b/portmap/portmap.x index fc4f224..13ac967 100644 --- a/portmap/portmap.x +++ b/portmap/portmap.x @@ -4,32 +4,49 @@ const PMAP_PORT = 111; /* portmapper port number */ -struct pmap_mapping { +struct pmap2_mapping { unsigned int prog; unsigned int vers; unsigned int prot; unsigned int port; }; -struct pmap_call_args { +struct pmap2_call_args { unsigned int prog; unsigned int vers; unsigned int proc; opaque args<>; }; -struct pmap_call_result { +struct pmap2_call_result { unsigned int port; opaque res<>; }; -struct pmap_mapping_list { - pmap_mapping map; - pmap_mapping_list *next; +struct pmap2_mapping_list { + pmap2_mapping map; + pmap2_mapping_list *next; }; -struct pmap_dump_result { - struct pmap_mapping_list *list; +struct pmap2_dump_result { + struct pmap2_mapping_list *list; +}; + +struct pmap3_mapping { + unsigned int prog; + unsigned int vers; + string netid<>; + string addr<>; + string owner<>; +}; + +struct pmap3_mapping_list { + pmap3_mapping map; + pmap3_mapping_list *next; +}; + +struct pmap3_dump_result { + struct pmap3_mapping_list *list; }; program PMAP_PROGRAM { @@ -38,19 +55,27 @@ program PMAP_PROGRAM { PMAP2_NULL(void) = 0; bool - PMAP2_SET(pmap_mapping) = 1; + PMAP2_SET(pmap2_mapping) = 1; bool - PMAP2_UNSET(pmap_mapping) = 2; + PMAP2_UNSET(pmap2_mapping) = 2; unsigned int - PMAP2_GETPORT(pmap_mapping) = 3; + PMAP2_GETPORT(pmap2_mapping) = 3; - pmap_dump_result + pmap2_dump_result PMAP2_DUMP(void) = 4; - pmap_call_result - PMAP2_CALLIT(pmap_call_args) = 5; + pmap2_call_result + PMAP2_CALLIT(pmap2_call_args) = 5; } = 2; + version PMAP_V3 { + void + PMAP3_NULL(void) = 0; + + pmap3_dump_result + PMAP3_DUMP(void) = 4; + + } = 3; } = 100000; -- 2.34.1