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 {
typedef struct smb_com_transaction2_get_dfs_refer_req {
struct smb_hdr hdr; /* wct = 15 */
__u16 TotalParameterCount;
__u16 TotalDataCount;
__u16 MaxParameterCount;
__u16 MaxDataCount;
__le16 TotalParameterCount;
__le16 TotalDataCount;
__le16 MaxParameterCount;
__le16 MaxDataCount;
__u8 MaxSetupCount;
__u8 Reserved;
__u16 Flags;
__u32 Timeout;
__le16 Flags;
__le32 Timeout;
__u16 Reserved2;
__u16 ParameterCount;
__u16 ParameterOffset;
__u16 DataCount;
__u16 DataOffset;
__le16 ParameterCount;
__le16 ParameterOffset;
__le16 DataCount;
__le16 DataOffset;
__u8 SetupCount;
__u8 Reserved3;
__u16 SubCommand; /* one setup word */
__u16 ByteCount;
__le16 SubCommand; /* one setup word */
__le16 ByteCount;
__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];
} TRANSACTION2_GET_DFS_REFER_REQ;
typedef struct dfs_referral_level_3 {
__u16 VersionNumber;
__u16 ReferralSize;
__u16 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 */
__u16 TimeToLive;
__u16 Proximity;
__u16 DfsPathOffset;
__u16 DfsAlternatePathOffset;
__u16 NetworkAddressOffset;
__le16 VersionNumber;
__le16 ReferralSize;
__le16 ServerType; /* 0x0001 = CIFS server */
__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 */
__le16 TimeToLive;
__le16 Proximity;
__le16 DfsPathOffset;
__le16 DfsAlternatePathOffset;
__le16 NetworkAddressOffset;
} REFERRAL3;
typedef struct smb_com_transaction_get_dfs_refer_rsp {
struct smb_hdr hdr; /* wct = 10 */
__u16 TotalParameterCount;
__u16 TotalDataCount;
__le16 TotalParameterCount;
__le16 TotalDataCount;
__u16 Reserved;
__u16 ParameterCount;
__u16 ParameterOffset;
__u16 ParameterDisplacement;
__u16 DataCount;
__u16 DataOffset;
__u16 DataDisplacement;
__le16 ParameterCount;
__le16 ParameterOffset;
__le16 ParameterDisplacement;
__le16 DataCount;
__le16 DataOffset;
__le16 DataDisplacement;
__u8 SetupCount;
__u8 Reserved1; /* zero setup words following */
__u16 ByteCount;
__u8 Pad;
__u16 PathConsumed;
__u16 NumberOfReferrals;
__u16 DFSFlags;
__le16 PathConsumed;
__le16 NumberOfReferrals;
__le16 DFSFlags;
__u16 Pad2;
REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
/* followed by the strings pointed to by the referral structures */
......
......@@ -2067,6 +2067,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
int name_len;
unsigned int i;
char * temp;
__u16 params, byte_count;
*number_of_UNC_in_array = 0;
*targetUNCs = NULL;
......@@ -2103,7 +2104,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
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->DataCount = 0;
pSMB->DataOffset = 0;
......@@ -2119,12 +2120,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
pSMB->ByteCount = pSMB->ParameterCount + 3 /* pad */ ;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
byte_count = params + 3 /* pad */ ;
pSMB->ParameterCount = cpu_to_le16(params);
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->MaxReferralLevel = cpu_to_le16(3);
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
pSMB->hdr.smb_buf_length += byte_count;
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
......@@ -2132,20 +2133,21 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
cFYI(1, ("Send error in GetDFSRefer = %d", rc));
} else { /* decode response */
/* BB Add logic to parse referrals here */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
__u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
__u16 data_count = le16_to_cpu(pSMBr->DataCount);
cFYI(1,
("Decoding GetDFSRefer response. BCC: %d Offset %d",
pSMBr->ByteCount, pSMBr->DataOffset));
if ((pSMBr->ByteCount < 17) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
pSMBr->ByteCount, data_offset));
if ((pSMBr->ByteCount < 17) || (data_offset > 512)) /* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */
else {
referrals =
(struct dfs_referral_level_3 *)
(8 /* sizeof start of data block */ +
pSMBr->DataOffset +
data_offset +
(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
data block so we could do safety check that DataBlock
begins at address of pSMBr->NumberOfReferrals */
......@@ -2159,19 +2161,19 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
name_len = 0;
for(i=0;i<*number_of_UNC_in_array;i++) {
/* make sure that DfsPathOffset not past end */
referrals->DfsPathOffset = le16_to_cpu(referrals->DfsPathOffset);
if(referrals->DfsPathOffset > pSMBr->DataCount) {
__u16 offset = le16_to_cpu(referrals->DfsPathOffset);
if (offset > data_count) {
/* if invalid referral, stop here and do
not try to copy any more */
*number_of_UNC_in_array = i;
break;
}
temp = ((char *)referrals) + referrals->DfsPathOffset;
temp = ((char *)referrals) + offset;
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len += UniStrnlen((wchar_t *)temp,pSMBr->DataCount);
name_len += UniStrnlen((wchar_t *)temp,data_count);
} else {
name_len += strnlen(temp,pSMBr->DataCount);
name_len += strnlen(temp,data_count);
}
referrals++;
/* BB add check that referral pointer does not fall off end PDU */
......@@ -2188,11 +2190,11 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
referrals =
(struct dfs_referral_level_3 *)
(8 /* sizeof data hdr */ +
pSMBr->DataOffset +
data_offset +
(char *) &pSMBr->hdr.Protocol);
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) {
cifs_strfromUCS_le(*targetUNCs,
(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