summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-04-24 15:40:01 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-04-24 15:40:01 -0700
commit5d963127a55c1ad44af5e530aacd3933ffd0b4ca (patch)
treea4e070be1d5acdf2ee7045a00389681830509d85
parent0502b06c879cace4c5a27698f8ec8d8bad8e075a (diff)
downloadsyslinux-4.10-pre4.tar.gz
pxe, tftp: unbreak the TFTP state machinesyslinux-4.10-pre4
Some of the code motion had broken the TFTP state machine, make it work properly again. Furthermore, remove some no longer necessary fields in the pxe inode structure. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/pxe/pxe.h1
-rw-r--r--core/fs/pxe/tftp.c18
2 files changed, 10 insertions, 9 deletions
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 9dec35e2..a685d8eb 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -128,7 +128,6 @@ struct pxe_pvt_inode {
struct netconn *conn; /* lwip network connection */
struct netbuf *buf; /* lwip cached buffer */
uint16_t tftp_remoteport; /* Remote port number */
- uint32_t tftp_remoteip; /* Remote IP address (0 = disconnected) */
uint32_t tftp_filepos; /* bytes downloaded (including buffer) */
uint32_t tftp_blksize; /* Block size for this connection(*) */
uint16_t tftp_bytesleft; /* Unclaimed data bytes */
diff --git a/core/fs/pxe/tftp.c b/core/fs/pxe/tftp.c
index e7a6e01a..5aafd8eb 100644
--- a/core/fs/pxe/tftp.c
+++ b/core/fs/pxe/tftp.c
@@ -30,7 +30,7 @@ static void tftp_error(struct inode *file, uint16_t errnum,
static void tftp_close_file(struct inode *inode)
{
struct pxe_pvt_inode *socket = PVT(inode);
- if (socket->tftp_remoteip) {
+ if (!socket->tftp_goteof) {
tftp_error(inode, 0, "No error, file close");
}
if (socket->conn) {
@@ -258,7 +258,6 @@ void tftp_open(struct url_info *url, struct inode *inode, const char **redir)
printf("netconn_bind error %d\n", err);
return;
}
- socket->tftp_remoteip = url->ip;
buf = rrq_packet_buf;
*(uint16_t *)buf = TFTP_RRQ; /* TFTP opcode */
@@ -283,7 +282,7 @@ sendreq:
nbuf = netbuf_new();
netbuf_ref(nbuf, rrq_packet_buf, rrq_len);
- addr.addr = socket->tftp_remoteip;
+ addr.addr = url->ip;
netconn_sendto(socket->conn, nbuf, &addr, url->port);
netbuf_delete(nbuf);
@@ -299,7 +298,7 @@ wait_pkt:
} else {
/* Make sure the packet actually came from the server */
bool ok_source;
- ok_source = netbuf_fromaddr(nbuf)->addr == socket->tftp_remoteip;
+ ok_source = netbuf_fromaddr(nbuf)->addr == url->ip;
nbuf_len = netbuf_len(nbuf);
if (nbuf_len <= PKTBUF_SIZE)
netbuf_copy(nbuf, packet_buf, nbuf_len);
@@ -311,7 +310,6 @@ wait_pkt:
}
}
- socket->tftp_remoteport = htons(netbuf_fromport(nbuf));
netconn_connect(socket->conn, netbuf_fromaddr(nbuf), netbuf_fromport(nbuf));
/* filesize <- -1 == unknown */
@@ -328,7 +326,7 @@ wait_pkt:
switch (opcode) {
case TFTP_ERROR:
inode->size = 0;
- break; /* ERROR reply; don't try again */
+ goto done; /* ERROR reply; don't try again */
case TFTP_DATA:
/*
@@ -371,7 +369,7 @@ wait_pkt:
socket->tftp_bytesleft = buffersize;
socket->tftp_dataptr = socket->tftp_pktbuf;
memcpy(socket->tftp_pktbuf, data, buffersize);
- break;
+ goto done;
case TFTP_OACK:
/*
@@ -443,11 +441,15 @@ wait_pkt:
*opdata_ptr = opdata;
}
+ if (socket->tftp_blksize < 64 || socket->tftp_blksize > PKTBUF_SIZE)
+ goto err_reply;
+
/* Parsing successful, allocate buffer */
socket->tftp_pktbuf = malloc(socket->tftp_blksize);
if (!socket->tftp_pktbuf)
goto err_reply;
- break;
+ else
+ goto done;
default:
printf("TFTP unknown opcode %d\n", ntohs(opcode));