diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 81 |
1 files changed, 9 insertions, 72 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bfc14d879ea1..96a742308cee 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, | |||
897 | return NULL; | 897 | return NULL; |
898 | } | 898 | } |
899 | 899 | ||
900 | /* a helper function for parse_callback */ | ||
901 | static int | ||
902 | parse_octet(unsigned int *lenp, char **addrp) | ||
903 | { | ||
904 | unsigned int len = *lenp; | ||
905 | char *p = *addrp; | ||
906 | int n = -1; | ||
907 | char c; | ||
908 | |||
909 | for (;;) { | ||
910 | if (!len) | ||
911 | break; | ||
912 | len--; | ||
913 | c = *p++; | ||
914 | if (c == '.') | ||
915 | break; | ||
916 | if ((c < '0') || (c > '9')) { | ||
917 | n = -1; | ||
918 | break; | ||
919 | } | ||
920 | if (n < 0) | ||
921 | n = 0; | ||
922 | n = (n * 10) + (c - '0'); | ||
923 | if (n > 255) { | ||
924 | n = -1; | ||
925 | break; | ||
926 | } | ||
927 | } | ||
928 | *lenp = len; | ||
929 | *addrp = p; | ||
930 | return n; | ||
931 | } | ||
932 | |||
933 | /* parse and set the setclientid ipv4 callback address */ | ||
934 | static int | ||
935 | parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp) | ||
936 | { | ||
937 | int temp = 0; | ||
938 | u32 cbaddr = 0; | ||
939 | u16 cbport = 0; | ||
940 | u32 addrlen = addr_len; | ||
941 | char *addr = addr_val; | ||
942 | int i, shift; | ||
943 | |||
944 | /* ipaddress */ | ||
945 | shift = 24; | ||
946 | for(i = 4; i > 0 ; i--) { | ||
947 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
948 | return 0; | ||
949 | } | ||
950 | cbaddr |= (temp << shift); | ||
951 | if (shift > 0) | ||
952 | shift -= 8; | ||
953 | } | ||
954 | *cbaddrp = cbaddr; | ||
955 | |||
956 | /* port */ | ||
957 | shift = 8; | ||
958 | for(i = 2; i > 0 ; i--) { | ||
959 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
960 | return 0; | ||
961 | } | ||
962 | cbport |= (temp << shift); | ||
963 | if (shift > 0) | ||
964 | shift -= 8; | ||
965 | } | ||
966 | *cbportp = cbport; | ||
967 | return 1; | ||
968 | } | ||
969 | |||
970 | static void | 900 | static void |
971 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | 901 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) |
972 | { | 902 | { |
@@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | |||
976 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) | 906 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) |
977 | goto out_err; | 907 | goto out_err; |
978 | 908 | ||
979 | if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val, | 909 | cb->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val, |
980 | &cb->cb_addr, &cb->cb_port))) | 910 | se->se_callback_addr_len, |
911 | (struct sockaddr *) &cb->cb_addr, | ||
912 | sizeof(cb->cb_addr)); | ||
913 | |||
914 | if (!cb->cb_addrlen || cb->cb_addr.ss_family != AF_INET) | ||
981 | goto out_err; | 915 | goto out_err; |
916 | |||
982 | cb->cb_minorversion = 0; | 917 | cb->cb_minorversion = 0; |
983 | cb->cb_prog = se->se_callback_prog; | 918 | cb->cb_prog = se->se_callback_prog; |
984 | cb->cb_ident = se->se_callback_ident; | 919 | cb->cb_ident = se->se_callback_ident; |
985 | return; | 920 | return; |
986 | out_err: | 921 | out_err: |
922 | cb->cb_addr.ss_family = AF_UNSPEC; | ||
923 | cb->cb_addrlen = 0; | ||
987 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " | 924 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " |
988 | "will not receive delegations\n", | 925 | "will not receive delegations\n", |
989 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); | 926 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); |