From 932277c9a5f90d906296a319c0c3e5f36bf2e8b1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 2 Feb 2009 15:14:27 -0800 Subject: [PATCH] tftpd: implement the "rollover" option Implement the "rollover" option, to set the rollover block number to anything other than zero. Apparently some idiots have gotten the idea that block numbers should roll over to one, rather than zero. --- tftpd/tftpd.8.in | 4 ++++ tftpd/tftpd.c | 26 ++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tftpd/tftpd.8.in b/tftpd/tftpd.8.in index a469ac8..f42d874 100644 --- a/tftpd/tftpd.8.in +++ b/tftpd/tftpd.8.in @@ -218,6 +218,10 @@ Set the time before the server retransmits a packet, in seconds. .TP \fButimeout\fP (nonstandard) Set the time before the server retransmits a packet, in microseconds. +.TP +\fBrollover\fP (nonstandard) +Set the block number to resume at after a block number rollover. The +default and recommended value is zero. .PP The .B \-\-refuse diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c index 3c96844..f98d52b 100644 --- a/tftpd/tftpd.c +++ b/tftpd/tftpd.c @@ -81,6 +81,7 @@ static unsigned long rexmtval = TIMEOUT; /* Basic timeout value */ static unsigned long maxtimeout = TIMEOUT_LIMIT * TIMEOUT; static int timeout_quit = 0; static sigjmp_buf timeoutbuf; +static uint16_t rollover_val = 0; #define PKTSIZE MAX_SEGSIZE+4 static char buf[PKTSIZE]; @@ -119,6 +120,7 @@ static int set_blksize2(char *, char **); static int set_tsize(char *, char **); static int set_timeout(char *, char **); static int set_utimeout(char *, char **); +static int set_rollover(char *, char **); struct options { const char *o_opt; @@ -129,6 +131,7 @@ struct options { {"tsize", set_tsize}, {"timeout", set_timeout}, {"utimeout", set_utimeout}, + {"rollover", set_rollover}, {NULL, NULL} }; @@ -1160,6 +1163,23 @@ static int set_blksize2(char *val, char **ret) return (1); } +/* + * Set the block number rollover value + */ +static int set_rollover(char *val, char **ret) +{ + uintmax_t ro; + char *vend; + + ro = strtoumax(val, &vend, 10); + if (ro > 65535 || *vend) + return 0; + + rollover_val = (uint16_t)ro; + *ret = val; + return 1; +} + /* * Return a file size (c.f. RFC2349) * For netascii mode, we don't know the size ahead of time; @@ -1542,7 +1562,8 @@ static void tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen) } } - block++; + if (!++block) + block = rollover_val; } while (size == segsize); abort: (void)fclose(file); @@ -1575,7 +1596,8 @@ static void tftp_recvfile(struct formats *pf, struct tftphdr *oap, int oacklen) ap->th_block = htons((u_short) block); acksize = 4; } - block++; + if (!++block) + block = rollover_val; (void)sigsetjmp(timeoutbuf, 1); send_ack: r_timeout = timeout;