|
@@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/* a helper function for parse_callback */
|
|
|
-static int
|
|
|
-parse_octet(unsigned int *lenp, char **addrp)
|
|
|
-{
|
|
|
- unsigned int len = *lenp;
|
|
|
- char *p = *addrp;
|
|
|
- int n = -1;
|
|
|
- char c;
|
|
|
-
|
|
|
- for (;;) {
|
|
|
- if (!len)
|
|
|
- break;
|
|
|
- len--;
|
|
|
- c = *p++;
|
|
|
- if (c == '.')
|
|
|
- break;
|
|
|
- if ((c < '0') || (c > '9')) {
|
|
|
- n = -1;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (n < 0)
|
|
|
- n = 0;
|
|
|
- n = (n * 10) + (c - '0');
|
|
|
- if (n > 255) {
|
|
|
- n = -1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- *lenp = len;
|
|
|
- *addrp = p;
|
|
|
- return n;
|
|
|
-}
|
|
|
-
|
|
|
-/* parse and set the setclientid ipv4 callback address */
|
|
|
-static int
|
|
|
-parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
|
|
|
-{
|
|
|
- int temp = 0;
|
|
|
- u32 cbaddr = 0;
|
|
|
- u16 cbport = 0;
|
|
|
- u32 addrlen = addr_len;
|
|
|
- char *addr = addr_val;
|
|
|
- int i, shift;
|
|
|
-
|
|
|
- /* ipaddress */
|
|
|
- shift = 24;
|
|
|
- for(i = 4; i > 0 ; i--) {
|
|
|
- if ((temp = parse_octet(&addrlen, &addr)) < 0) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- cbaddr |= (temp << shift);
|
|
|
- if (shift > 0)
|
|
|
- shift -= 8;
|
|
|
- }
|
|
|
- *cbaddrp = cbaddr;
|
|
|
-
|
|
|
- /* port */
|
|
|
- shift = 8;
|
|
|
- for(i = 2; i > 0 ; i--) {
|
|
|
- if ((temp = parse_octet(&addrlen, &addr)) < 0) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- cbport |= (temp << shift);
|
|
|
- if (shift > 0)
|
|
|
- shift -= 8;
|
|
|
- }
|
|
|
- *cbportp = cbport;
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
static void
|
|
|
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
|
|
|
{
|
|
@@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
|
|
|
if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
|
|
|
goto out_err;
|
|
|
|
|
|
- if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
|
|
|
- &cb->cb_addr, &cb->cb_port)))
|
|
|
+ cb->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val,
|
|
|
+ se->se_callback_addr_len,
|
|
|
+ (struct sockaddr *) &cb->cb_addr,
|
|
|
+ sizeof(cb->cb_addr));
|
|
|
+
|
|
|
+ if (!cb->cb_addrlen || cb->cb_addr.ss_family != AF_INET)
|
|
|
goto out_err;
|
|
|
+
|
|
|
cb->cb_minorversion = 0;
|
|
|
cb->cb_prog = se->se_callback_prog;
|
|
|
cb->cb_ident = se->se_callback_ident;
|
|
|
return;
|
|
|
out_err:
|
|
|
+ cb->cb_addr.ss_family = AF_UNSPEC;
|
|
|
+ cb->cb_addrlen = 0;
|
|
|
dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
|
|
|
"will not receive delegations\n",
|
|
|
clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
|