|
|
5544c1 |
From 5579c7740b29be4766ace824af36acb9ab254ecb Mon Sep 17 00:00:00 2001
|
|
|
5544c1 |
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin@reactos.org>
|
|
|
5544c1 |
Date: Thu, 13 Sep 2012 12:39:36 +0200
|
|
|
5544c1 |
Subject: [PATCH] slirp: Handle more than 65535 blocks in TFTP transfers
|
|
|
5544c1 |
MIME-Version: 1.0
|
|
|
5544c1 |
Content-Type: text/plain; charset=UTF-8
|
|
|
5544c1 |
Content-Transfer-Encoding: 8bit
|
|
|
5544c1 |
|
|
|
5544c1 |
RFC 1350 does not mention block count roll-over. However, a lot of TFTP servers
|
|
|
5544c1 |
implement it to be able to transmit big files, so do it also.
|
|
|
5544c1 |
|
|
|
5544c1 |
Current block size is 512 bytes, so TFTP files were limited to 32 MB.
|
|
|
5544c1 |
|
|
|
5544c1 |
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
|
|
|
5544c1 |
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
|
|
|
5544c1 |
(cherry picked from commit 4aa401f39e048e71020cceb59f126ab941095a42)
|
|
|
5544c1 |
|
|
|
5544c1 |
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
5544c1 |
---
|
|
|
5544c1 |
slirp/tftp.c | 24 ++++++++++--------------
|
|
|
5544c1 |
slirp/tftp.h | 1 +
|
|
|
5544c1 |
2 files changed, 11 insertions(+), 14 deletions(-)
|
|
|
5544c1 |
|
|
|
5544c1 |
diff --git a/slirp/tftp.c b/slirp/tftp.c
|
|
|
5544c1 |
index 520dbd6..c6a5df2 100644
|
|
|
5544c1 |
--- a/slirp/tftp.c
|
|
|
5544c1 |
+++ b/slirp/tftp.c
|
|
|
5544c1 |
@@ -97,7 +97,7 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t *tp)
|
|
|
5544c1 |
return -1;
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
-static int tftp_read_data(struct tftp_session *spt, uint16_t block_nr,
|
|
|
5544c1 |
+static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr,
|
|
|
5544c1 |
uint8_t *buf, int len)
|
|
|
5544c1 |
{
|
|
|
5544c1 |
int bytes_read = 0;
|
|
|
5544c1 |
@@ -197,19 +197,14 @@ out:
|
|
|
5544c1 |
tftp_session_terminate(spt);
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
-static int tftp_send_data(struct tftp_session *spt,
|
|
|
5544c1 |
- uint16_t block_nr,
|
|
|
5544c1 |
- struct tftp_t *recv_tp)
|
|
|
5544c1 |
+static int tftp_send_next_block(struct tftp_session *spt,
|
|
|
5544c1 |
+ struct tftp_t *recv_tp)
|
|
|
5544c1 |
{
|
|
|
5544c1 |
struct sockaddr_in saddr, daddr;
|
|
|
5544c1 |
struct mbuf *m;
|
|
|
5544c1 |
struct tftp_t *tp;
|
|
|
5544c1 |
int nobytes;
|
|
|
5544c1 |
|
|
|
5544c1 |
- if (block_nr < 1) {
|
|
|
5544c1 |
- return -1;
|
|
|
5544c1 |
- }
|
|
|
5544c1 |
-
|
|
|
5544c1 |
m = m_get(spt->slirp);
|
|
|
5544c1 |
|
|
|
5544c1 |
if (!m) {
|
|
|
5544c1 |
@@ -223,7 +218,7 @@ static int tftp_send_data(struct tftp_session *spt,
|
|
|
5544c1 |
m->m_data += sizeof(struct udpiphdr);
|
|
|
5544c1 |
|
|
|
5544c1 |
tp->tp_op = htons(TFTP_DATA);
|
|
|
5544c1 |
- tp->x.tp_data.tp_block_nr = htons(block_nr);
|
|
|
5544c1 |
+ tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff);
|
|
|
5544c1 |
|
|
|
5544c1 |
saddr.sin_addr = recv_tp->ip.ip_dst;
|
|
|
5544c1 |
saddr.sin_port = recv_tp->udp.uh_dport;
|
|
|
5544c1 |
@@ -231,7 +226,7 @@ static int tftp_send_data(struct tftp_session *spt,
|
|
|
5544c1 |
daddr.sin_addr = spt->client_ip;
|
|
|
5544c1 |
daddr.sin_port = spt->client_port;
|
|
|
5544c1 |
|
|
|
5544c1 |
- nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
|
|
|
5544c1 |
+ nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512);
|
|
|
5544c1 |
|
|
|
5544c1 |
if (nobytes < 0) {
|
|
|
5544c1 |
m_free(m);
|
|
|
5544c1 |
@@ -255,6 +250,7 @@ static int tftp_send_data(struct tftp_session *spt,
|
|
|
5544c1 |
tftp_session_terminate(spt);
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
+ spt->block_nr++;
|
|
|
5544c1 |
return 0;
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
@@ -373,7 +369,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
|
|
|
5544c1 |
}
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
- tftp_send_data(spt, 1, tp);
|
|
|
5544c1 |
+ spt->block_nr = 0;
|
|
|
5544c1 |
+ tftp_send_next_block(spt, tp);
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
|
|
|
5544c1 |
@@ -386,9 +383,8 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
|
|
|
5544c1 |
return;
|
|
|
5544c1 |
}
|
|
|
5544c1 |
|
|
|
5544c1 |
- if (tftp_send_data(&slirp->tftp_sessions[s],
|
|
|
5544c1 |
- ntohs(tp->x.tp_data.tp_block_nr) + 1,
|
|
|
5544c1 |
- tp) < 0) {
|
|
|
5544c1 |
+ if (tftp_send_next_block(&slirp->tftp_sessions[s],
|
|
|
5544c1 |
+ tp) < 0) {
|
|
|
5544c1 |
return;
|
|
|
5544c1 |
}
|
|
|
5544c1 |
}
|
|
|
5544c1 |
diff --git a/slirp/tftp.h b/slirp/tftp.h
|
|
|
5544c1 |
index 9c364ea..51704e4 100644
|
|
|
5544c1 |
--- a/slirp/tftp.h
|
|
|
5544c1 |
+++ b/slirp/tftp.h
|
|
|
5544c1 |
@@ -37,6 +37,7 @@ struct tftp_session {
|
|
|
5544c1 |
|
|
|
5544c1 |
struct in_addr client_ip;
|
|
|
5544c1 |
uint16_t client_port;
|
|
|
5544c1 |
+ uint32_t block_nr;
|
|
|
5544c1 |
|
|
|
5544c1 |
int timestamp;
|
|
|
5544c1 |
};
|
|
|
5544c1 |
--
|
|
|
5544c1 |
1.7.12.1
|
|
|
5544c1 |
|