aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-11 06:41:32 -0400
committerSteve French <smfrench@gmail.com>2011-10-13 19:44:40 -0400
commitfe11e4ccb8479d92cd2a101d380d332544b84aaa (patch)
tree626e286d6451a26ea07c8fdb89cb23eb1dca0111 /fs/cifs
parent03776f4516bc299b3145595bdd704d40d69adc02 (diff)
cifs: clean up check_rfc1002_header
Rename it for better clarity as to what it does and have the caller pass in just the single type byte. Turn the if statement into a switch and optimize it by placing the most common message type at the top. Move the header length check back into cifs_demultiplex_thread in preparation for adding a new receive phase and normalize the cFYI messages. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c63
1 files changed, 30 insertions, 33 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 82bc0d27e495..97a65af2a08a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -427,29 +427,29 @@ read_from_socket(struct TCP_Server_Info *server, char *buf,
427} 427}
428 428
429static bool 429static bool
430check_rfc1002_header(struct TCP_Server_Info *server, char *buf) 430is_smb_response(struct TCP_Server_Info *server, unsigned char type)
431{ 431{
432 char temp = *buf;
433 unsigned int pdu_length = be32_to_cpu(
434 ((struct smb_hdr *)buf)->smb_buf_length);
435
436 /* 432 /*
437 * The first byte big endian of the length field, 433 * The first byte big endian of the length field,
438 * is actually not part of the length but the type 434 * is actually not part of the length but the type
439 * with the most common, zero, as regular data. 435 * with the most common, zero, as regular data.
440 */ 436 */
441 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { 437 switch (type) {
442 return false; 438 case RFC1002_SESSION_MESSAGE:
443 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 439 /* Regular SMB response */
444 cFYI(1, "Good RFC 1002 session rsp"); 440 return true;
445 return false; 441 case RFC1002_SESSION_KEEP_ALIVE:
446 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 442 cFYI(1, "RFC 1002 session keep alive");
443 break;
444 case RFC1002_POSITIVE_SESSION_RESPONSE:
445 cFYI(1, "RFC 1002 positive session response");
446 break;
447 case RFC1002_NEGATIVE_SESSION_RESPONSE:
447 /* 448 /*
448 * We get this from Windows 98 instead of an error on 449 * We get this from Windows 98 instead of an error on
449 * SMB negprot response. 450 * SMB negprot response.
450 */ 451 */
451 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", 452 cFYI(1, "RFC 1002 negative session response");
452 pdu_length);
453 /* give server a second to clean up */ 453 /* give server a second to clean up */
454 msleep(1000); 454 msleep(1000);
455 /* 455 /*
@@ -458,29 +458,16 @@ check_rfc1002_header(struct TCP_Server_Info *server, char *buf)
458 * is since we do not begin with RFC1001 session 458 * is since we do not begin with RFC1001 session
459 * initialize frame). 459 * initialize frame).
460 */ 460 */
461 cifs_set_port((struct sockaddr *) 461 cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
462 &server->dstaddr, CIFS_PORT);
463 cifs_reconnect(server); 462 cifs_reconnect(server);
464 wake_up(&server->response_q); 463 wake_up(&server->response_q);
465 return false; 464 break;
466 } else if (temp != (char) 0) { 465 default:
467 cERROR(1, "Unknown RFC 1002 frame"); 466 cERROR(1, "RFC 1002 unknown response type 0x%x", type);
468 cifs_dump_mem(" Received Data: ", buf, 4);
469 cifs_reconnect(server);
470 return false;
471 }
472
473 /* else we have an SMB response */
474 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
475 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
476 cERROR(1, "Invalid size SMB length %d pdu_length %d",
477 4, pdu_length+4);
478 cifs_reconnect(server); 467 cifs_reconnect(server);
479 wake_up(&server->response_q);
480 return false;
481 } 468 }
482 469
483 return true; 470 return false;
484} 471}
485 472
486static struct mid_q_entry * 473static struct mid_q_entry *
@@ -683,10 +670,20 @@ cifs_demultiplex_thread(void *p)
683 */ 670 */
684 pdu_length = be32_to_cpu(smb_buffer->smb_buf_length); 671 pdu_length = be32_to_cpu(smb_buffer->smb_buf_length);
685 672
686 cFYI(1, "rfc1002 length 0x%x", pdu_length+4); 673 cFYI(1, "RFC1002 header 0x%x", pdu_length);
687 if (!check_rfc1002_header(server, buf)) 674 if (!is_smb_response(server, buf[0]))
688 continue; 675 continue;
689 676
677 /* check the length */
678 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
679 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
680 cERROR(1, "Invalid size SMB length %d pdu_length %d",
681 4, pdu_length + 4);
682 cifs_reconnect(server);
683 wake_up(&server->response_q);
684 continue;
685 }
686
690 /* else length ok */ 687 /* else length ok */
691 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 688 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
692 isLargeBuf = true; 689 isLargeBuf = true;