tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: tftp protocol
On Fri, Oct 16, 2009 at 10:56:55PM +0200, Havard Eidnes wrote:
> Actually... I suspect that the BUGS statement is in actual fact
> wrong, if it implies that the protocol spec makes it impossible
> to transfer files larger than 32MiB using tftp with the default
> block size of 512 bytes. I've experienced that same problem,
> when trying to tftp updates for Cisco wireless controllers, which
> also have image files larger than 32MiB.
>
> Cisco's "fix" for this problem is to point to a particular
> implementation of tftp daemon functionality in the form of a
> Windows program (yuk!) (and, yes, the source is available as
> well, but it has Windows-specific code littering the code, if I
> recall correctly). The tftp client in the Cisco case uses the
> default block size of 512 bytes, and with this combination, it
> can actually transfer the wireless controller image file.
>
> The "block numbers" in the tftp protocol are actually not
> designed to do "random access" in the server-side file, it's
> designed to distinguish between duplicate blocks and new blocks
> at the client. If the client and server implements a 0.5 * 2^16
> "block number window", and they allow the block number to wrap
> around the 2^16 mark, it may actually work to transfer files
> larger than 32MiB without increasing the block size above the
> default 512 bytes.
>
> The RFCs specifying the block size extension mention speed as a
> motivation for the extension, not the ability to transfer files
> larger than 32MiB...
>
> I've not actually had the time to sit down to see if a patch
> could be made to the NetBSD tftp daemon (and client) to allow
> such operation.
FWIW, we had to fix a similar issue to tftp a large file from
the windows vista installation. Konstantin Kabassavov came up
with the attached patch; I didn't check it in details.
It also handle '\' vs '/'.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
Index: tftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
retrieving revision 1.31
diff -u -p -u -r1.31 tftpd.c
--- tftpd.c 21 Jul 2008 13:25:47 -0000 1.31
+++ tftpd.c 17 Oct 2009 15:48:33 -0000
@@ -607,7 +607,7 @@ static void
tftp(struct tftphdr *tp, int size)
{
struct formats *pf;
- char *cp;
+ char *cp,*i;
char *filename, *mode;
int first, ecode, alen, etftp=0, r;
@@ -617,6 +617,15 @@ tftp(struct tftphdr *tp, int size)
filename = cp = tp->th_stuff;
again:
+ // KKK
+ i = cp;
+ while (i < buf + size) {
+ if (*i == 0x5c) {
+ *i='/';
+ }
+ i++;
+ }
+
while (cp < buf + size) {
if (*cp == '\0')
break;
@@ -864,10 +873,11 @@ opcode(int code)
void
sendfile(struct formats *pf, int etftp, int acklength)
{
+ volatile unsigned int blocktimes=0;
volatile unsigned int block;
struct tftphdr *dp;
struct tftphdr *ap; /* ack packet */
- int size, n;
+ int size, n,blocktimescandidate=0;
signal(SIGALRM, timer);
ap = (struct tftphdr *)ackbuf;
@@ -918,20 +928,25 @@ send_data:
goto abort;
case ACK:
- if (ap->th_block == 0) {
+ if ((ap->th_block == 0) && (blocktimes == 0) &&
(blocktimescandidate == 0)) {
etftp = 0;
acklength = 0;
dp = r_init();
goto done;
}
- if (ap->th_block == block)
+ if ((ap->th_block + (blocktimes*65536)) ==
block)
goto done;
+ if ((ap->th_block + ((blocktimes+1)*65536)) ==
block){
+ blocktimes++;
+ goto done;
+ }
+
if (debug)
syslog(LOG_DEBUG, "Resync ACK %u != %u",
(unsigned int)ap->th_block, block);
/* Re-synchronize with the other side */
(void) synchnet(peer, tftp_blksize);
- if (ap->th_block == (block -1))
+ if ((ap->th_block + (blocktimes*65536)) ==
(block -1))
goto send_data;
default:
syslog(LOG_INFO, "Received %s in sendfile\n",
@@ -943,6 +958,9 @@ done:
if (debug)
syslog(LOG_DEBUG, "Received ACK for block %u", block);
block++;
+ if (block == 65536)
+ blocktimescandidate = 1;
+
} while (size == tftp_blksize || block == 1);
abort:
(void) fclose(file);
Home |
Main Index |
Thread Index |
Old Index