Blame 0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch

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