Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe11e4cc authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 03776f45
Loading
Loading
Loading
Loading
+30 −33
Original line number Diff line number Diff line
@@ -427,29 +427,29 @@ read_from_socket(struct TCP_Server_Info *server, char *buf,
}

static bool
check_rfc1002_header(struct TCP_Server_Info *server, char *buf)
is_smb_response(struct TCP_Server_Info *server, unsigned char type)
{
	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) {
	switch (type) {
	case RFC1002_SESSION_MESSAGE:
		/* Regular SMB response */
		return true;
	case RFC1002_SESSION_KEEP_ALIVE:
		cFYI(1, "RFC 1002 session keep alive");
		break;
	case RFC1002_POSITIVE_SESSION_RESPONSE:
		cFYI(1, "RFC 1002 positive session response");
		break;
	case 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);
		cFYI(1, "RFC 1002 negative session response");
		/* give server a second to clean up */
		msleep(1000);
		/*
@@ -458,31 +458,18 @@ check_rfc1002_header(struct TCP_Server_Info *server, char *buf)
		 * is since we do not begin with RFC1001 session
		 * initialize frame).
		 */
		cifs_set_port((struct sockaddr *)
				&server->dstaddr, CIFS_PORT);
		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);
		break;
	default:
		cERROR(1, "RFC 1002 unknown response type 0x%x", type);
		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 struct mid_q_entry *
find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
	      int *length, bool is_large_buf, bool *is_multi_rsp, char **bigbuf)
@@ -683,9 +670,19 @@ cifs_demultiplex_thread(void *p)
		 */
		pdu_length = be32_to_cpu(smb_buffer->smb_buf_length);

		cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
		if (!check_rfc1002_header(server, buf))
		cFYI(1, "RFC1002 header 0x%x", pdu_length);
		if (!is_smb_response(server, buf[0]))
			continue;

		/* check the length */
		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);
			continue;
		}

		/* else length ok */
		if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {