summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2009-02-02 15:14:27 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2009-02-02 15:14:27 -0800
commit932277c9a5f90d906296a319c0c3e5f36bf2e8b1 (patch)
treee4b6bf022f0db16b1ce11fdfa23d0a46b0bf51c9
parentfcdd859a7513319f68a5ba1261c0f66ef3a28723 (diff)
downloadtftp-hpa-932277c9a5f90d906296a319c0c3e5f36bf2e8b1.tar.gz
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.
-rw-r--r--tftpd/tftpd.8.in4
-rw-r--r--tftpd/tftpd.c26
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}
};
@@ -1161,6 +1164,23 @@ static int set_blksize2(char *val, char **ret)
}
/*
+ * 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;
* so reject the option.
@@ -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;