CIFS: Move RFC1002 check to a separate function
Pavel Shilovsky [Mon, 1 Aug 2011 09:19:42 +0000 (13:19 +0400)]
Reviewed-and-Tested-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

fs/cifs/connect.c

index a2e9fcf..2a53ade 100644 (file)
@@ -416,6 +416,63 @@ read_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg,
        return rc;
 }
 
+static bool
+check_rfc1002_header(struct TCP_Server_Info *server, char *buf)
+{
+       char temp = *buf;
+       unsigned int pdu_length = be32_to_cpu(
+                               ((struct smb_hdr *)buf)->smb_buf_length);
+
+       /*
+        * The first byte big endian of the length field,
+        * is actually not part of the length but the type
+        * with the most common, zero, as regular data.
+        */
+       if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
+               return false;
+       } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
+               cFYI(1, "Good RFC 1002 session rsp");
+               return false;
+       } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
+               /*
+                * We get this from Windows 98 instead of an error on
+                * SMB negprot response.
+                */
+               cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
+                       pdu_length);
+               /* give server a second to clean up */
+               msleep(1000);
+               /*
+                * Always try 445 first on reconnect since we get NACK
+                * on some if we ever connected to port 139 (the NACK
+                * is since we do not begin with RFC1001 session
+                * initialize frame).
+                */
+               cifs_set_port((struct sockaddr *)
+                               &server->dstaddr, CIFS_PORT);
+               cifs_reconnect(server);
+               wake_up(&server->response_q);
+               return false;
+       } else if (temp != (char) 0) {
+               cERROR(1, "Unknown RFC 1002 frame");
+               cifs_dump_mem(" Received Data: ", buf, 4);
+               cifs_reconnect(server);
+               return false;
+       }
+
+       /* else we have an SMB response */
+       if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
+           (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
+               cERROR(1, "Invalid size SMB length %d pdu_length %d",
+                      4, pdu_length+4);
+               cifs_reconnect(server);
+               wake_up(&server->response_q);
+               return false;
+       }
+
+       return true;
+}
+
 static int
 cifs_demultiplex_thread(void *p)
 {
@@ -429,7 +486,6 @@ cifs_demultiplex_thread(void *p)
        struct list_head *tmp, *tmp2;
        struct task_struct *task_to_wake = NULL;
        struct mid_q_entry *mid_entry;
-       char temp;
        bool isLargeBuf = false;
        bool isMultiRsp;
        int rc;
@@ -482,59 +538,21 @@ incomplete_rcv:
                else if (rc == 1)
                        continue;
 
-               /* The right amount was read from socket - 4 bytes */
-               /* so we can now interpret the length field */
-
-               /* the first byte big endian of the length field,
-               is actually not part of the length but the type
-               with the most common, zero, as regular data */
-               temp = *buf;
+               /*
+                * The right amount was read from socket - 4 bytes,
+                * so we can now interpret the length field.
+                */
 
-               /* Note that FC 1001 length is big endian on the wire,
-               but we convert it here so it is always manipulated
-               as host byte order */
+               /*
+                * Note that RFC 1001 length is big endian on the wire,
+                * but we convert it here so it is always manipulated
+                * as host byte order.
+                */
                pdu_length = be32_to_cpu(smb_buffer->smb_buf_length);
 
                cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
-
-               if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
-                       continue;
-               } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
-                       cFYI(1, "Good RFC 1002 session rsp");
-                       continue;
-               } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
-                       /* we get this from Windows 98 instead of
-                          an error on SMB negprot response */
-                       cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
-                               pdu_length);
-                       /* give server a second to clean up  */
-                       msleep(1000);
-                       /* always try 445 first on reconnect since we get NACK
-                        * on some if we ever connected to port 139 (the NACK
-                        * is since we do not begin with RFC1001 session
-                        * initialize frame)
-                        */
-                       cifs_set_port((struct sockaddr *)
-                                       &server->dstaddr, CIFS_PORT);
-                       cifs_reconnect(server);
-                       wake_up(&server->response_q);
-                       continue;
-               } else if (temp != (char) 0) {
-                       cERROR(1, "Unknown RFC 1002 frame");
-                       cifs_dump_mem(" Received Data: ", buf, length);
-                       cifs_reconnect(server);
-                       continue;
-               }
-
-               /* else we have an SMB response */
-               if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
-                           (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
-                       cERROR(1, "Invalid size SMB length %d pdu_length %d",
-                                       length, pdu_length+4);
-                       cifs_reconnect(server);
-                       wake_up(&server->response_q);
+               if (!check_rfc1002_header(server, buf))
                        continue;
-               }
 
                /* else length ok */
                if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {