|
@@ -75,6 +75,37 @@ enum {
|
|
|
#define RPCB_OWNER_STRING "0"
|
|
|
#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
|
|
|
|
|
|
+/*
|
|
|
+ * XDR data type sizes
|
|
|
+ */
|
|
|
+#define RPCB_program_sz (1)
|
|
|
+#define RPCB_version_sz (1)
|
|
|
+#define RPCB_protocol_sz (1)
|
|
|
+#define RPCB_port_sz (1)
|
|
|
+#define RPCB_boolean_sz (1)
|
|
|
+
|
|
|
+#define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
|
|
|
+#define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
|
|
|
+#define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
|
|
|
+
|
|
|
+/*
|
|
|
+ * XDR argument and result sizes
|
|
|
+ */
|
|
|
+#define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
|
|
|
+ RPCB_protocol_sz + RPCB_port_sz)
|
|
|
+#define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
|
|
|
+ RPCB_netid_sz + RPCB_addr_sz + \
|
|
|
+ RPCB_ownerstring_sz)
|
|
|
+
|
|
|
+#define RPCB_getportres_sz RPCB_port_sz
|
|
|
+#define RPCB_setres_sz RPCB_boolean_sz
|
|
|
+
|
|
|
+/*
|
|
|
+ * Note that RFC 1833 does not put any size restrictions on the
|
|
|
+ * address string returned by the remote rpcbind database.
|
|
|
+ */
|
|
|
+#define RPCB_getaddrres_sz RPCB_addr_sz
|
|
|
+
|
|
|
static void rpcb_getport_done(struct rpc_task *, void *);
|
|
|
static void rpcb_map_release(void *data);
|
|
|
static struct rpc_program rpcb_program;
|
|
@@ -122,6 +153,7 @@ static void rpcb_map_release(void *data)
|
|
|
|
|
|
rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
|
|
|
xprt_put(map->r_xprt);
|
|
|
+ kfree(map->r_addr);
|
|
|
kfree(map);
|
|
|
}
|
|
|
|
|
@@ -268,12 +300,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
|
|
|
const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
|
|
|
struct rpcbind_args *map = msg->rpc_argp;
|
|
|
unsigned short port = ntohs(sin->sin_port);
|
|
|
- char buf[32];
|
|
|
+ int result;
|
|
|
|
|
|
- /* Construct AF_INET universal address */
|
|
|
- snprintf(buf, sizeof(buf), "%pI4.%u.%u",
|
|
|
- &sin->sin_addr.s_addr, port >> 8, port & 0xff);
|
|
|
- map->r_addr = buf;
|
|
|
+ map->r_addr = rpc_sockaddr2uaddr(sap);
|
|
|
|
|
|
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
|
|
"local rpcbind\n", (port ? "" : "un"),
|
|
@@ -284,7 +313,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
|
|
|
if (port)
|
|
|
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
|
|
|
|
|
- return rpcb_register_call(RPCBVERS_4, msg);
|
|
|
+ result = rpcb_register_call(RPCBVERS_4, msg);
|
|
|
+ kfree(map->r_addr);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -296,16 +327,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
|
|
|
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
|
|
|
struct rpcbind_args *map = msg->rpc_argp;
|
|
|
unsigned short port = ntohs(sin6->sin6_port);
|
|
|
- char buf[64];
|
|
|
+ int result;
|
|
|
|
|
|
- /* Construct AF_INET6 universal address */
|
|
|
- if (ipv6_addr_any(&sin6->sin6_addr))
|
|
|
- snprintf(buf, sizeof(buf), "::.%u.%u",
|
|
|
- port >> 8, port & 0xff);
|
|
|
- else
|
|
|
- snprintf(buf, sizeof(buf), "%pI6.%u.%u",
|
|
|
- &sin6->sin6_addr, port >> 8, port & 0xff);
|
|
|
- map->r_addr = buf;
|
|
|
+ map->r_addr = rpc_sockaddr2uaddr(sap);
|
|
|
|
|
|
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
|
|
"local rpcbind\n", (port ? "" : "un"),
|
|
@@ -316,7 +340,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
|
|
|
if (port)
|
|
|
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
|
|
|
|
|
- return rpcb_register_call(RPCBVERS_4, msg);
|
|
|
+ result = rpcb_register_call(RPCBVERS_4, msg);
|
|
|
+ kfree(map->r_addr);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
|
|
@@ -428,7 +454,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
|
|
|
struct rpc_message msg = {
|
|
|
.rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
|
|
|
.rpc_argp = &map,
|
|
|
- .rpc_resp = &map.r_port,
|
|
|
+ .rpc_resp = &map,
|
|
|
};
|
|
|
struct rpc_clnt *rpcb_clnt;
|
|
|
int status;
|
|
@@ -458,7 +484,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
|
|
|
struct rpc_message msg = {
|
|
|
.rpc_proc = proc,
|
|
|
.rpc_argp = map,
|
|
|
- .rpc_resp = &map->r_port,
|
|
|
+ .rpc_resp = map,
|
|
|
};
|
|
|
struct rpc_task_setup task_setup_data = {
|
|
|
.rpc_client = rpcb_clnt,
|
|
@@ -539,6 +565,7 @@ void rpcb_getport_async(struct rpc_task *task)
|
|
|
goto bailout_nofree;
|
|
|
}
|
|
|
|
|
|
+ /* Parent transport's destination address */
|
|
|
salen = rpc_peeraddr(clnt, sap, sizeof(addr));
|
|
|
|
|
|
/* Don't ever use rpcbind v2 for AF_INET6 requests */
|
|
@@ -589,11 +616,22 @@ void rpcb_getport_async(struct rpc_task *task)
|
|
|
map->r_prot = xprt->prot;
|
|
|
map->r_port = 0;
|
|
|
map->r_xprt = xprt_get(xprt);
|
|
|
- map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
|
|
- map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
|
|
|
- map->r_owner = "";
|
|
|
map->r_status = -EIO;
|
|
|
|
|
|
+ switch (bind_version) {
|
|
|
+ case RPCBVERS_4:
|
|
|
+ case RPCBVERS_3:
|
|
|
+ map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
|
|
+ map->r_addr = rpc_sockaddr2uaddr(sap);
|
|
|
+ map->r_owner = "";
|
|
|
+ break;
|
|
|
+ case RPCBVERS_2:
|
|
|
+ map->r_addr = NULL;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
+
|
|
|
child = rpcb_call_async(rpcb_clnt, map, proc);
|
|
|
rpc_release_client(rpcb_clnt);
|
|
|
if (IS_ERR(child)) {
|
|
@@ -656,176 +694,278 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
|
|
|
* XDR functions for rpcbind
|
|
|
*/
|
|
|
|
|
|
-static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
|
|
|
- struct rpcbind_args *rpcb)
|
|
|
+static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p,
|
|
|
+ const struct rpcbind_args *rpcb)
|
|
|
{
|
|
|
- dprintk("RPC: encoding rpcb request (%u, %u, %d, %u)\n",
|
|
|
+ struct rpc_task *task = req->rq_task;
|
|
|
+ struct xdr_stream xdr;
|
|
|
+
|
|
|
+ dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
|
|
|
+ task->tk_pid, task->tk_msg.rpc_proc->p_name,
|
|
|
rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
|
|
|
+
|
|
|
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
|
|
|
+
|
|
|
+ p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz);
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
*p++ = htonl(rpcb->r_prog);
|
|
|
*p++ = htonl(rpcb->r_vers);
|
|
|
*p++ = htonl(rpcb->r_prot);
|
|
|
- *p++ = htonl(rpcb->r_port);
|
|
|
+ *p = htonl(rpcb->r_port);
|
|
|
|
|
|
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
|
|
|
- unsigned short *portp)
|
|
|
+static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p,
|
|
|
+ struct rpcbind_args *rpcb)
|
|
|
{
|
|
|
- *portp = (unsigned short) ntohl(*p++);
|
|
|
- dprintk("RPC: rpcb getport result: %u\n",
|
|
|
- *portp);
|
|
|
+ struct rpc_task *task = req->rq_task;
|
|
|
+ struct xdr_stream xdr;
|
|
|
+ unsigned long port;
|
|
|
+
|
|
|
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
|
|
|
+
|
|
|
+ rpcb->r_port = 0;
|
|
|
+
|
|
|
+ p = xdr_inline_decode(&xdr, sizeof(__be32));
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ port = ntohl(*p);
|
|
|
+ dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid,
|
|
|
+ task->tk_msg.rpc_proc->p_name, port);
|
|
|
+ if (unlikely(port > USHORT_MAX))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ rpcb->r_port = port;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
|
|
|
- unsigned int *boolp)
|
|
|
+static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p,
|
|
|
+ unsigned int *boolp)
|
|
|
{
|
|
|
- *boolp = (unsigned int) ntohl(*p++);
|
|
|
- dprintk("RPC: rpcb set/unset call %s\n",
|
|
|
+ struct rpc_task *task = req->rq_task;
|
|
|
+ struct xdr_stream xdr;
|
|
|
+
|
|
|
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
|
|
|
+
|
|
|
+ p = xdr_inline_decode(&xdr, sizeof(__be32));
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ *boolp = 0;
|
|
|
+ if (*p)
|
|
|
+ *boolp = 1;
|
|
|
+
|
|
|
+ dprintk("RPC: %5u RPCB_%s call %s\n",
|
|
|
+ task->tk_pid, task->tk_msg.rpc_proc->p_name,
|
|
|
(*boolp ? "succeeded" : "failed"));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p,
|
|
|
- struct rpcbind_args *rpcb)
|
|
|
+static int encode_rpcb_string(struct xdr_stream *xdr, const char *string,
|
|
|
+ const u32 maxstrlen)
|
|
|
{
|
|
|
- dprintk("RPC: encoding rpcb request (%u, %u, %s)\n",
|
|
|
- rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
|
|
|
- *p++ = htonl(rpcb->r_prog);
|
|
|
- *p++ = htonl(rpcb->r_vers);
|
|
|
+ u32 len;
|
|
|
+ __be32 *p;
|
|
|
|
|
|
- p = xdr_encode_string(p, rpcb->r_netid);
|
|
|
- p = xdr_encode_string(p, rpcb->r_addr);
|
|
|
- p = xdr_encode_string(p, rpcb->r_owner);
|
|
|
+ if (unlikely(string == NULL))
|
|
|
+ return -EIO;
|
|
|
+ len = strlen(string);
|
|
|
+ if (unlikely(len > maxstrlen))
|
|
|
+ return -EIO;
|
|
|
|
|
|
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
|
|
|
+ p = xdr_reserve_space(xdr, sizeof(__be32) + len);
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ return -EIO;
|
|
|
+ xdr_encode_opaque(p, string, len);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
|
|
|
- unsigned short *portp)
|
|
|
+static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p,
|
|
|
+ const struct rpcbind_args *rpcb)
|
|
|
{
|
|
|
- char *addr;
|
|
|
- u32 addr_len;
|
|
|
- int c, i, f, first, val;
|
|
|
+ struct rpc_task *task = req->rq_task;
|
|
|
+ struct xdr_stream xdr;
|
|
|
|
|
|
- *portp = 0;
|
|
|
- addr_len = ntohl(*p++);
|
|
|
+ dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
|
|
|
+ task->tk_pid, task->tk_msg.rpc_proc->p_name,
|
|
|
+ rpcb->r_prog, rpcb->r_vers,
|
|
|
+ rpcb->r_netid, rpcb->r_addr);
|
|
|
|
|
|
- if (addr_len == 0) {
|
|
|
- dprintk("RPC: rpcb_decode_getaddr: "
|
|
|
- "service is not registered\n");
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
|
|
|
|
|
|
- /*
|
|
|
- * Simple sanity check.
|
|
|
- */
|
|
|
- if (addr_len > RPCBIND_MAXUADDRLEN)
|
|
|
- goto out_err;
|
|
|
-
|
|
|
- /*
|
|
|
- * Start at the end and walk backwards until the first dot
|
|
|
- * is encountered. When the second dot is found, we have
|
|
|
- * both parts of the port number.
|
|
|
- */
|
|
|
- addr = (char *)p;
|
|
|
- val = 0;
|
|
|
- first = 1;
|
|
|
- f = 1;
|
|
|
- for (i = addr_len - 1; i > 0; i--) {
|
|
|
- c = addr[i];
|
|
|
- if (c >= '0' && c <= '9') {
|
|
|
- val += (c - '0') * f;
|
|
|
- f *= 10;
|
|
|
- } else if (c == '.') {
|
|
|
- if (first) {
|
|
|
- *portp = val;
|
|
|
- val = first = 0;
|
|
|
- f = 1;
|
|
|
- } else {
|
|
|
- *portp |= (val << 8);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ p = xdr_reserve_space(&xdr,
|
|
|
+ sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz));
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ return -EIO;
|
|
|
+ *p++ = htonl(rpcb->r_prog);
|
|
|
+ *p = htonl(rpcb->r_vers);
|
|
|
|
|
|
- /*
|
|
|
- * Simple sanity check. If we never saw a dot in the reply,
|
|
|
- * then this was probably just garbage.
|
|
|
- */
|
|
|
- if (first)
|
|
|
- goto out_err;
|
|
|
+ if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN))
|
|
|
+ return -EIO;
|
|
|
+ if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN))
|
|
|
+ return -EIO;
|
|
|
+ if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN))
|
|
|
+ return -EIO;
|
|
|
|
|
|
- dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp);
|
|
|
return 0;
|
|
|
-
|
|
|
-out_err:
|
|
|
- dprintk("RPC: rpcbind server returned malformed reply\n");
|
|
|
- return -EIO;
|
|
|
}
|
|
|
|
|
|
-#define RPCB_program_sz (1u)
|
|
|
-#define RPCB_version_sz (1u)
|
|
|
-#define RPCB_protocol_sz (1u)
|
|
|
-#define RPCB_port_sz (1u)
|
|
|
-#define RPCB_boolean_sz (1u)
|
|
|
+static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p,
|
|
|
+ struct rpcbind_args *rpcb)
|
|
|
+{
|
|
|
+ struct sockaddr_storage address;
|
|
|
+ struct sockaddr *sap = (struct sockaddr *)&address;
|
|
|
+ struct rpc_task *task = req->rq_task;
|
|
|
+ struct xdr_stream xdr;
|
|
|
+ u32 len;
|
|
|
|
|
|
-#define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
|
|
|
-#define RPCB_addr_sz (1+XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
|
|
|
-#define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN))
|
|
|
+ rpcb->r_port = 0;
|
|
|
|
|
|
-#define RPCB_mappingargs_sz RPCB_program_sz+RPCB_version_sz+ \
|
|
|
- RPCB_protocol_sz+RPCB_port_sz
|
|
|
-#define RPCB_getaddrargs_sz RPCB_program_sz+RPCB_version_sz+ \
|
|
|
- RPCB_netid_sz+RPCB_addr_sz+ \
|
|
|
- RPCB_ownerstring_sz
|
|
|
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
|
|
|
|
|
|
-#define RPCB_setres_sz RPCB_boolean_sz
|
|
|
-#define RPCB_getportres_sz RPCB_port_sz
|
|
|
-
|
|
|
-/*
|
|
|
- * Note that RFC 1833 does not put any size restrictions on the
|
|
|
- * address string returned by the remote rpcbind database.
|
|
|
- */
|
|
|
-#define RPCB_getaddrres_sz RPCB_addr_sz
|
|
|
+ p = xdr_inline_decode(&xdr, sizeof(__be32));
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ goto out_fail;
|
|
|
+ len = ntohl(*p);
|
|
|
|
|
|
-#define PROC(proc, argtype, restype) \
|
|
|
- [RPCBPROC_##proc] = { \
|
|
|
- .p_proc = RPCBPROC_##proc, \
|
|
|
- .p_encode = (kxdrproc_t) rpcb_encode_##argtype, \
|
|
|
- .p_decode = (kxdrproc_t) rpcb_decode_##restype, \
|
|
|
- .p_arglen = RPCB_##argtype##args_sz, \
|
|
|
- .p_replen = RPCB_##restype##res_sz, \
|
|
|
- .p_statidx = RPCBPROC_##proc, \
|
|
|
- .p_timer = 0, \
|
|
|
- .p_name = #proc, \
|
|
|
+ /*
|
|
|
+ * If the returned universal address is a null string,
|
|
|
+ * the requested RPC service was not registered.
|
|
|
+ */
|
|
|
+ if (len == 0) {
|
|
|
+ dprintk("RPC: %5u RPCB reply: program not registered\n",
|
|
|
+ task->tk_pid);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
+ if (unlikely(len > RPCBIND_MAXUADDRLEN))
|
|
|
+ goto out_fail;
|
|
|
+
|
|
|
+ p = xdr_inline_decode(&xdr, len);
|
|
|
+ if (unlikely(p == NULL))
|
|
|
+ goto out_fail;
|
|
|
+ dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
|
|
|
+ task->tk_msg.rpc_proc->p_name, (char *)p);
|
|
|
+
|
|
|
+ if (rpc_uaddr2sockaddr((char *)p, len, sap, sizeof(address)) == 0)
|
|
|
+ goto out_fail;
|
|
|
+ rpcb->r_port = rpc_get_port(sap);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+out_fail:
|
|
|
+ dprintk("RPC: %5u malformed RPCB_%s reply\n",
|
|
|
+ task->tk_pid, task->tk_msg.rpc_proc->p_name);
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Not all rpcbind procedures described in RFC 1833 are implemented
|
|
|
* since the Linux kernel RPC code requires only these.
|
|
|
*/
|
|
|
+
|
|
|
static struct rpc_procinfo rpcb_procedures2[] = {
|
|
|
- PROC(SET, mapping, set),
|
|
|
- PROC(UNSET, mapping, set),
|
|
|
- PROC(GETPORT, mapping, getport),
|
|
|
+ [RPCBPROC_SET] = {
|
|
|
+ .p_proc = RPCBPROC_SET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_mapping,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_mappingargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_SET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "SET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_UNSET] = {
|
|
|
+ .p_proc = RPCBPROC_UNSET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_mapping,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_mappingargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_UNSET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "UNSET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_GETPORT] = {
|
|
|
+ .p_proc = RPCBPROC_GETPORT,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_mapping,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_getport,
|
|
|
+ .p_arglen = RPCB_mappingargs_sz,
|
|
|
+ .p_replen = RPCB_getportres_sz,
|
|
|
+ .p_statidx = RPCBPROC_GETPORT,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "GETPORT",
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static struct rpc_procinfo rpcb_procedures3[] = {
|
|
|
- PROC(SET, getaddr, set),
|
|
|
- PROC(UNSET, getaddr, set),
|
|
|
- PROC(GETADDR, getaddr, getaddr),
|
|
|
+ [RPCBPROC_SET] = {
|
|
|
+ .p_proc = RPCBPROC_SET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_SET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "SET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_UNSET] = {
|
|
|
+ .p_proc = RPCBPROC_UNSET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_UNSET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "UNSET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_GETADDR] = {
|
|
|
+ .p_proc = RPCBPROC_GETADDR,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_getaddrres_sz,
|
|
|
+ .p_statidx = RPCBPROC_GETADDR,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "GETADDR",
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static struct rpc_procinfo rpcb_procedures4[] = {
|
|
|
- PROC(SET, getaddr, set),
|
|
|
- PROC(UNSET, getaddr, set),
|
|
|
- PROC(GETADDR, getaddr, getaddr),
|
|
|
- PROC(GETVERSADDR, getaddr, getaddr),
|
|
|
+ [RPCBPROC_SET] = {
|
|
|
+ .p_proc = RPCBPROC_SET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_SET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "SET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_UNSET] = {
|
|
|
+ .p_proc = RPCBPROC_UNSET,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_set,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_setres_sz,
|
|
|
+ .p_statidx = RPCBPROC_UNSET,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "UNSET",
|
|
|
+ },
|
|
|
+ [RPCBPROC_GETADDR] = {
|
|
|
+ .p_proc = RPCBPROC_GETADDR,
|
|
|
+ .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
|
|
|
+ .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
|
|
|
+ .p_arglen = RPCB_getaddrargs_sz,
|
|
|
+ .p_replen = RPCB_getaddrres_sz,
|
|
|
+ .p_statidx = RPCBPROC_GETADDR,
|
|
|
+ .p_timer = 0,
|
|
|
+ .p_name = "GETADDR",
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static struct rpcb_info rpcb_next_version[] = {
|