Commit e4feee94 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] cifs: annotate TRANSACTION2_GET_DFS_REFER_{REQ,RESP}, minor endianness bugfix

missing le..._to_cpu() in debugging printk
Signed-off-by: default avatarAl Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f3db6d91
...@@ -1394,58 +1394,58 @@ typedef struct smb_com_transaction_qfsi_rsp { ...@@ -1394,58 +1394,58 @@ typedef struct smb_com_transaction_qfsi_rsp {
typedef struct smb_com_transaction2_get_dfs_refer_req { typedef struct smb_com_transaction2_get_dfs_refer_req {
struct smb_hdr hdr; /* wct = 15 */ struct smb_hdr hdr; /* wct = 15 */
__u16 TotalParameterCount; __le16 TotalParameterCount;
__u16 TotalDataCount; __le16 TotalDataCount;
__u16 MaxParameterCount; __le16 MaxParameterCount;
__u16 MaxDataCount; __le16 MaxDataCount;
__u8 MaxSetupCount; __u8 MaxSetupCount;
__u8 Reserved; __u8 Reserved;
__u16 Flags; __le16 Flags;
__u32 Timeout; __le32 Timeout;
__u16 Reserved2; __u16 Reserved2;
__u16 ParameterCount; __le16 ParameterCount;
__u16 ParameterOffset; __le16 ParameterOffset;
__u16 DataCount; __le16 DataCount;
__u16 DataOffset; __le16 DataOffset;
__u8 SetupCount; __u8 SetupCount;
__u8 Reserved3; __u8 Reserved3;
__u16 SubCommand; /* one setup word */ __le16 SubCommand; /* one setup word */
__u16 ByteCount; __le16 ByteCount;
__u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */ __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
__u16 MaxReferralLevel; __le16 MaxReferralLevel;
char RequestFileName[1]; char RequestFileName[1];
} TRANSACTION2_GET_DFS_REFER_REQ; } TRANSACTION2_GET_DFS_REFER_REQ;
typedef struct dfs_referral_level_3 { typedef struct dfs_referral_level_3 {
__u16 VersionNumber; __le16 VersionNumber;
__u16 ReferralSize; __le16 ReferralSize;
__u16 ServerType; /* 0x0001 = CIFS server */ __le16 ServerType; /* 0x0001 = CIFS server */
__u16 ReferralFlags; /* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */ __le16 ReferralFlags; /* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */
__u16 TimeToLive; __le16 TimeToLive;
__u16 Proximity; __le16 Proximity;
__u16 DfsPathOffset; __le16 DfsPathOffset;
__u16 DfsAlternatePathOffset; __le16 DfsAlternatePathOffset;
__u16 NetworkAddressOffset; __le16 NetworkAddressOffset;
} REFERRAL3; } REFERRAL3;
typedef struct smb_com_transaction_get_dfs_refer_rsp { typedef struct smb_com_transaction_get_dfs_refer_rsp {
struct smb_hdr hdr; /* wct = 10 */ struct smb_hdr hdr; /* wct = 10 */
__u16 TotalParameterCount; __le16 TotalParameterCount;
__u16 TotalDataCount; __le16 TotalDataCount;
__u16 Reserved; __u16 Reserved;
__u16 ParameterCount; __le16 ParameterCount;
__u16 ParameterOffset; __le16 ParameterOffset;
__u16 ParameterDisplacement; __le16 ParameterDisplacement;
__u16 DataCount; __le16 DataCount;
__u16 DataOffset; __le16 DataOffset;
__u16 DataDisplacement; __le16 DataDisplacement;
__u8 SetupCount; __u8 SetupCount;
__u8 Reserved1; /* zero setup words following */ __u8 Reserved1; /* zero setup words following */
__u16 ByteCount; __u16 ByteCount;
__u8 Pad; __u8 Pad;
__u16 PathConsumed; __le16 PathConsumed;
__u16 NumberOfReferrals; __le16 NumberOfReferrals;
__u16 DFSFlags; __le16 DFSFlags;
__u16 Pad2; __u16 Pad2;
REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */ REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
/* followed by the strings pointed to by the referral structures */ /* followed by the strings pointed to by the referral structures */
......
...@@ -2067,6 +2067,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2067,6 +2067,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
int name_len; int name_len;
unsigned int i; unsigned int i;
char * temp; char * temp;
__u16 params, byte_count;
*number_of_UNC_in_array = 0; *number_of_UNC_in_array = 0;
*targetUNCs = NULL; *targetUNCs = NULL;
...@@ -2103,7 +2104,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2103,7 +2104,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
strncpy(pSMB->RequestFileName, searchName, name_len); strncpy(pSMB->RequestFileName, searchName, name_len);
} }
pSMB->ParameterCount = 2 /* level */ + name_len /*includes null */ ; params = 2 /* level */ + name_len /*includes null */ ;
pSMB->TotalDataCount = 0; pSMB->TotalDataCount = 0;
pSMB->DataCount = 0; pSMB->DataCount = 0;
pSMB->DataOffset = 0; pSMB->DataOffset = 0;
...@@ -2119,12 +2120,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2119,12 +2120,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
pSMB->SetupCount = 1; pSMB->SetupCount = 1;
pSMB->Reserved3 = 0; pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
pSMB->ByteCount = pSMB->ParameterCount + 3 /* pad */ ; byte_count = params + 3 /* pad */ ;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount); pSMB->ParameterCount = cpu_to_le16(params);
pSMB->TotalParameterCount = pSMB->ParameterCount; pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->MaxReferralLevel = cpu_to_le16(3); pSMB->MaxReferralLevel = cpu_to_le16(3);
pSMB->hdr.smb_buf_length += pSMB->ByteCount; pSMB->hdr.smb_buf_length += byte_count;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount); pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
...@@ -2132,20 +2133,21 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2132,20 +2133,21 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
cFYI(1, ("Send error in GetDFSRefer = %d", rc)); cFYI(1, ("Send error in GetDFSRefer = %d", rc));
} else { /* decode response */ } else { /* decode response */
/* BB Add logic to parse referrals here */ /* BB Add logic to parse referrals here */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount); __u16 data_count = le16_to_cpu(pSMBr->DataCount);
cFYI(1, cFYI(1,
("Decoding GetDFSRefer response. BCC: %d Offset %d", ("Decoding GetDFSRefer response. BCC: %d Offset %d",
pSMBr->ByteCount, pSMBr->DataOffset)); pSMBr->ByteCount, data_offset));
if ((pSMBr->ByteCount < 17) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ if ((pSMBr->ByteCount < 17) || (data_offset > 512)) /* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */ rc = -EIO; /* bad smb */
else { else {
referrals = referrals =
(struct dfs_referral_level_3 *) (struct dfs_referral_level_3 *)
(8 /* sizeof start of data block */ + (8 /* sizeof start of data block */ +
pSMBr->DataOffset + data_offset +
(char *) &pSMBr->hdr.Protocol); (char *) &pSMBr->hdr.Protocol);
cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x",pSMBr->NumberOfReferrals,pSMBr->DFSFlags, referrals->ReferralSize,referrals->ServerType,referrals->ReferralFlags,referrals->TimeToLive)); cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x",
le16_to_cpu(pSMBr->NumberOfReferrals),le16_to_cpu(pSMBr->DFSFlags), le16_to_cpu(referrals->ReferralSize),le16_to_cpu(referrals->ServerType),le16_to_cpu(referrals->ReferralFlags),le16_to_cpu(referrals->TimeToLive)));
/* BB This field is actually two bytes in from start of /* BB This field is actually two bytes in from start of
data block so we could do safety check that DataBlock data block so we could do safety check that DataBlock
begins at address of pSMBr->NumberOfReferrals */ begins at address of pSMBr->NumberOfReferrals */
...@@ -2159,19 +2161,19 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2159,19 +2161,19 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
name_len = 0; name_len = 0;
for(i=0;i<*number_of_UNC_in_array;i++) { for(i=0;i<*number_of_UNC_in_array;i++) {
/* make sure that DfsPathOffset not past end */ /* make sure that DfsPathOffset not past end */
referrals->DfsPathOffset = le16_to_cpu(referrals->DfsPathOffset); __u16 offset = le16_to_cpu(referrals->DfsPathOffset);
if(referrals->DfsPathOffset > pSMBr->DataCount) { if (offset > data_count) {
/* if invalid referral, stop here and do /* if invalid referral, stop here and do
not try to copy any more */ not try to copy any more */
*number_of_UNC_in_array = i; *number_of_UNC_in_array = i;
break; break;
} }
temp = ((char *)referrals) + referrals->DfsPathOffset; temp = ((char *)referrals) + offset;
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len += UniStrnlen((wchar_t *)temp,pSMBr->DataCount); name_len += UniStrnlen((wchar_t *)temp,data_count);
} else { } else {
name_len += strnlen(temp,pSMBr->DataCount); name_len += strnlen(temp,data_count);
} }
referrals++; referrals++;
/* BB add check that referral pointer does not fall off end PDU */ /* BB add check that referral pointer does not fall off end PDU */
...@@ -2188,11 +2190,11 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -2188,11 +2190,11 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
referrals = referrals =
(struct dfs_referral_level_3 *) (struct dfs_referral_level_3 *)
(8 /* sizeof data hdr */ + (8 /* sizeof data hdr */ +
pSMBr->DataOffset + data_offset +
(char *) &pSMBr->hdr.Protocol); (char *) &pSMBr->hdr.Protocol);
for(i=0;i<*number_of_UNC_in_array;i++) { for(i=0;i<*number_of_UNC_in_array;i++) {
temp = ((char *)referrals) + referrals->DfsPathOffset; temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
cifs_strfromUCS_le(*targetUNCs, cifs_strfromUCS_le(*targetUNCs,
(wchar_t *) temp, name_len, nls_codepage); (wchar_t *) temp, name_len, nls_codepage);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment