CIFS: Move RFC1002 check to a separate function
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>
This commit is contained in:
parent
e7015fb1c5
commit
98bac62c9f
@ -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 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;
|
||||
|
||||
/* 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) {
|
||||
if (!check_rfc1002_header(server, buf))
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* else length ok */
|
||||
if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
|
||||
|
Loading…
Reference in New Issue
Block a user