aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
authorTim Gardner <tim.gardner@canonical.com>2013-11-02 13:50:34 -0400
committerSteve French <smfrench@gmail.com>2013-11-02 13:51:53 -0400
commit3d378d3fd82a759d59c60d89b4559bf325d7e668 (patch)
tree1fc4634672bc18c7af79f1029d42e99869beb2c4 /fs/cifs/misc.c
parent944d6f1a5b8f42a780a65378e5f52bea3ae0ce07 (diff)
cifs: Make big endian multiplex ID sequences monotonic on the wire
The multiplex identifier (MID) in the SMB header is only ever used by the client, in conjunction with PID, to match responses from the server. As such, the endianess of the MID is not important. However, When tracing packet sequences on the wire, protocol analyzers such as wireshark display MID as little endian. It is much more informative for the on-the-wire MID sequences to match debug information emitted by the CIFS driver. Therefore, one should write and read MID in the SMB header assuming it is always little endian. Observed from wireshark during the protocol negotiation and session setup: Multiplex ID: 256 Multiplex ID: 256 Multiplex ID: 512 Multiplex ID: 512 Multiplex ID: 768 Multiplex ID: 768 After this patch on-the-wire MID values begin at 1 and increase monotonically. Introduce get_next_mid64() for the internal consumers that use the full 64 bit multiplex identifier. Introduce the helpers get_mid() and compare_mid() to make the endian translation clear. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Tim Gardner <timg@tpi.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 298e31e3bdc6..2f9f3790679d 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -295,7 +295,8 @@ check_smb_hdr(struct smb_hdr *smb)
295 if (smb->Command == SMB_COM_LOCKING_ANDX) 295 if (smb->Command == SMB_COM_LOCKING_ANDX)
296 return 0; 296 return 0;
297 297
298 cifs_dbg(VFS, "Server sent request, not response. mid=%u\n", smb->Mid); 298 cifs_dbg(VFS, "Server sent request, not response. mid=%u\n",
299 get_mid(smb));
299 return 1; 300 return 1;
300} 301}
301 302
@@ -351,6 +352,7 @@ checkSMB(char *buf, unsigned int total_read)
351 } 352 }
352 353
353 if (4 + rfclen != clc_len) { 354 if (4 + rfclen != clc_len) {
355 __u16 mid = get_mid(smb);
354 /* check if bcc wrapped around for large read responses */ 356 /* check if bcc wrapped around for large read responses */
355 if ((rfclen > 64 * 1024) && (rfclen > clc_len)) { 357 if ((rfclen > 64 * 1024) && (rfclen > clc_len)) {
356 /* check if lengths match mod 64K */ 358 /* check if lengths match mod 64K */
@@ -358,11 +360,11 @@ checkSMB(char *buf, unsigned int total_read)
358 return 0; /* bcc wrapped */ 360 return 0; /* bcc wrapped */
359 } 361 }
360 cifs_dbg(FYI, "Calculated size %u vs length %u mismatch for mid=%u\n", 362 cifs_dbg(FYI, "Calculated size %u vs length %u mismatch for mid=%u\n",
361 clc_len, 4 + rfclen, smb->Mid); 363 clc_len, 4 + rfclen, mid);
362 364
363 if (4 + rfclen < clc_len) { 365 if (4 + rfclen < clc_len) {
364 cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n", 366 cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
365 rfclen, smb->Mid); 367 rfclen, mid);
366 return -EIO; 368 return -EIO;
367 } else if (rfclen > clc_len + 512) { 369 } else if (rfclen > clc_len + 512) {
368 /* 370 /*
@@ -375,7 +377,7 @@ checkSMB(char *buf, unsigned int total_read)
375 * data to 512 bytes. 377 * data to 512 bytes.
376 */ 378 */
377 cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n", 379 cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n",
378 rfclen, smb->Mid); 380 rfclen, mid);
379 return -EIO; 381 return -EIO;
380 } 382 }
381 } 383 }