diff options
author | 2006-07-20 09:42:44 +0000 | |
---|---|---|
committer | 2006-07-20 09:42:44 +0000 | |
commit | 3e7729ddb4bf5659c12057e895b089f5a8979d8b (patch) | |
tree | 8665bfb7cc82c32352481edf392a202f70319871 | |
parent | update for the new ADMtek PCI ids. (diff) | |
download | wireguard-openbsd-3e7729ddb4bf5659c12057e895b089f5a8979d8b.tar.xz wireguard-openbsd-3e7729ddb4bf5659c12057e895b089f5a8979d8b.zip |
Add blksize option support for tftpd according to RFC 2348.
Note:
While testing the new option, we noticed that our stable tftpd has
a problem if any option is set (e.g. tsize) and you try to put a file.
This has nothing todo with our new blksize option. We fix this as
next.
ok claudio@
-rw-r--r-- | include/arpa/tftp.h | 4 | ||||
-rw-r--r-- | libexec/tftpd/tftpd.c | 80 | ||||
-rw-r--r-- | usr.bin/tftp/tftp.c | 8 | ||||
-rw-r--r-- | usr.bin/tftp/tftpsubs.c | 21 | ||||
-rw-r--r-- | usr.bin/tftp/tftpsubs.h | 6 |
5 files changed, 77 insertions, 42 deletions
diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h index 62808559899..0f6fe83ae25 100644 --- a/include/arpa/tftp.h +++ b/include/arpa/tftp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tftp.h,v 1.5 2004/01/27 02:25:30 deraadt Exp $ */ +/* $OpenBSD: tftp.h,v 1.6 2006/07/20 09:42:44 mglocker Exp $ */ /* $NetBSD: tftp.h,v 1.3 1994/10/26 00:56:48 cgd Exp $ */ /* @@ -39,6 +39,8 @@ * Trivial File Transfer Protocol (IEN-133) */ #define SEGSIZE 512 /* data segment size */ +#define SEGSIZE_MIN 8 /* minimal data segment size */ +#define SEGSIZE_MAX 65464 /* maximal data segment size */ /* * Packet types. diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 1adb8ce9c3e..a351ce6bb4b 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tftpd.c,v 1.46 2006/07/14 22:57:46 mglocker Exp $ */ +/* $OpenBSD: tftpd.c,v 1.47 2006/07/20 09:42:44 mglocker Exp $ */ /* * Copyright (c) 1983 Regents of the University of California. @@ -37,7 +37,7 @@ char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)tftpd.c 5.13 (Berkeley) 2/26/91";*/ -static char rcsid[] = "$OpenBSD: tftpd.c,v 1.46 2006/07/14 22:57:46 mglocker Exp $"; +static char rcsid[] = "$OpenBSD: tftpd.c,v 1.47 2006/07/20 09:42:44 mglocker Exp $"; #endif /* not lint */ /* @@ -70,12 +70,11 @@ static char rcsid[] = "$OpenBSD: tftpd.c,v 1.46 2006/07/14 22:57:46 mglocker Exp #define TIMEOUT 5 #define MAX_TIMEOUTS 5 -#define PKTSIZE SEGSIZE + 4 struct formats; -int readit(FILE *, struct tftphdr **, int); -void read_ahead(FILE *, int); +int readit(FILE *, struct tftphdr **, int, int); +void read_ahead(FILE *, int, int); int writeit(FILE *, struct tftphdr **, int, int); int write_behind(FILE *, int); int synchnet(int); @@ -94,13 +93,15 @@ struct sockaddr_storage s_in; int peer; int rexmtval = TIMEOUT; int max_rexmtval = 2 * TIMEOUT; -char buf[PKTSIZE]; -char ackbuf[PKTSIZE]; +char *buf; +char *ackbuf; struct sockaddr_storage from; int ndirs; char **dirs; int secure; int cancreate; +unsigned int segment_size = SEGSIZE; +unsigned int packet_size = SEGSIZE + 4; struct formats { const char *f_mode; @@ -121,12 +122,14 @@ struct options { } options[] = { { "tsize", NULL, 0 }, /* OPT_TSIZE */ { "timeout", NULL, 0 }, /* OPT_TIMEOUT */ + { "blksize", NULL, 0 }, /* OPT_BLKSIZE */ { NULL, NULL, 0 } }; enum opt_enum { OPT_TSIZE = 0, - OPT_TIMEOUT + OPT_TIMEOUT, + OPT_BLKSIZE }; struct errmsg { @@ -254,9 +257,18 @@ main(int argc, char *argv[]) break; } + if ((buf = malloc(packet_size)) == NULL) { + syslog(LOG_ERR, "malloc: %m"); + exit(1); + } + if ((ackbuf = malloc(packet_size)) == NULL) { + syslog(LOG_ERR, "malloc: %m"); + exit(1); + } + bzero(&msg, sizeof(msg)); iov.iov_base = buf; - iov.iov_len = sizeof(buf); + iov.iov_len = packet_size; msg.msg_name = &from; msg.msg_namelen = sizeof(from); msg.msg_iov = &iov; @@ -300,7 +312,7 @@ main(int argc, char *argv[]) */ bzero(&msg, sizeof(msg)); iov.iov_base = buf; - iov.iov_len = sizeof(buf); + iov.iov_len = packet_size; msg.msg_name = &from; msg.msg_namelen = sizeof(from); msg.msg_iov = &iov; @@ -374,8 +386,9 @@ tftp(struct tftphdr *tp, int size) char *cp; int i, first = 1, has_options = 0, ecode; struct formats *pf; - char *filename, *mode = NULL, *option, *ccp; + char *filename, *mode = NULL, *option, *ccp, *newp = NULL; char fnbuf[MAXPATHLEN], nicebuf[MAXPATHLEN]; + const char *errstr; cp = tp->th_stuff; again: @@ -448,6 +461,27 @@ option_fail: options[OPT_TIMEOUT].o_request = NULL; } + if (options[OPT_BLKSIZE].o_request) { + segment_size = strtonum(options[OPT_BLKSIZE].o_request, + SEGSIZE_MIN, SEGSIZE_MAX, &errstr); + if (errstr) { + nak(EBADOP); + exit(1); + } + packet_size = segment_size + 4; + if ((newp = realloc(buf, packet_size)) == NULL) { + syslog(LOG_ERR, "realloc: %m"); + exit(1); + } + buf = newp; + if ((newp = realloc(ackbuf, packet_size)) == NULL) { + syslog(LOG_ERR, "realloc: %m"); + exit(1); + } + ackbuf = newp; + options[OPT_BLKSIZE].o_reply = segment_size; + } + (void)strnvis(nicebuf, filename, MAXPATHLEN, VIS_SAFE|VIS_OCTAL); ecode = (*pf->f_validate)(filename, tp->th_opcode); if (has_options) @@ -573,7 +607,7 @@ sendfile(struct formats *pf) do { /* read data from file */ - size = readit(file, &dp, pf->f_convert); + size = readit(file, &dp, pf->f_convert, segment_size); if (size < 0) { nak(errno + 100); goto abort; @@ -591,7 +625,7 @@ sendfile(struct formats *pf) syslog(LOG_ERR, "send: %m"); goto abort; } - read_ahead(file, pf->f_convert); + read_ahead(file, pf->f_convert, segment_size); } error = 0; @@ -609,7 +643,7 @@ sendfile(struct formats *pf) syslog(LOG_ERR, "poll: %m"); goto abort; } - n = recv(peer, ackbuf, sizeof(ackbuf), 0); + n = recv(peer, ackbuf, packet_size, 0); if (n == -1) { error = 1; if (errno == EINTR) @@ -634,7 +668,7 @@ sendfile(struct formats *pf) } block++; - } while (size == SEGSIZE); + } while (size == segment_size); abort: fclose(file); @@ -690,7 +724,7 @@ recvfile(struct formats *pf) syslog(LOG_ERR, "poll: %m"); goto abort; } - n = recv(peer, dp, PKTSIZE, 0); + n = recv(peer, dp, packet_size, 0); if (n == -1) { error = 1; if (errno == EINTR) @@ -723,7 +757,7 @@ recvfile(struct formats *pf) nak(ENOSPACE); goto abort; } - } while (size == SEGSIZE); + } while (size == segment_size); /* close data file */ write_behind(file, pf->f_convert); @@ -740,7 +774,7 @@ recvfile(struct formats *pf) nfds = poll(pfd, 1, TIMEOUT * 1000); if (nfds < 1) exit(1); - n = recv(peer, buf, sizeof(buf), 0); + n = recv(peer, buf, packet_size, 0); /* * If read some data and got a data block then my last ack was lost * resend final ack. @@ -775,9 +809,9 @@ nak(int error) pe->e_msg = strerror(error - 100); tp->th_code = EUNDEF; /* set 'undef' errorcode */ } - length = strlcpy(tp->th_msg, pe->e_msg, sizeof(buf)) + 5; - if (length > sizeof(buf)) - length = sizeof(buf); + length = strlcpy(tp->th_msg, pe->e_msg, packet_size) + 5; + if (length > packet_size) + length = packet_size; if (send(peer, buf, length, 0) != length) syslog(LOG_ERR, "nak: %m"); } @@ -795,7 +829,7 @@ oack(void) tp = (struct tftphdr *)buf; bp = buf + 2; - size = sizeof(buf) - 2; + size = packet_size - 2; tp->th_opcode = htons((u_short)OACK); for (i = 0; options[i].o_type != NULL; i++) { if (options[i].o_request) { @@ -843,7 +877,7 @@ oack(void) syslog(LOG_ERR, "poll: %m"); exit(1); } - n = recv(peer, ackbuf, sizeof(ackbuf), 0); + n = recv(peer, ackbuf, packet_size, 0); if (n == -1) { error = 1; if (errno == EINTR) diff --git a/usr.bin/tftp/tftp.c b/usr.bin/tftp/tftp.c index 6a4c8fc3e3e..38b575708bc 100644 --- a/usr.bin/tftp/tftp.c +++ b/usr.bin/tftp/tftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tftp.c,v 1.17 2006/07/12 16:58:51 mglocker Exp $ */ +/* $OpenBSD: tftp.c,v 1.18 2006/07/20 09:42:44 mglocker Exp $ */ /* $NetBSD: tftp.c,v 1.5 1995/04/29 05:55:25 cgd Exp $ */ /* @@ -35,7 +35,7 @@ static char sccsid[] = "@(#)tftp.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$OpenBSD: tftp.c,v 1.17 2006/07/12 16:58:51 mglocker Exp $"; + "$OpenBSD: tftp.c,v 1.18 2006/07/20 09:42:44 mglocker Exp $"; #endif /* not lint */ /* @@ -127,7 +127,7 @@ sendfile(int fd, char *name, char *mode) if (!block) size = makerequest(WRQ, name, dp, mode) - 4; else { - size = readit(file, &dp, convert); + size = readit(file, &dp, convert, SEGSIZE); if (size < 0) { nak(errno + 100); break; @@ -152,7 +152,7 @@ sendfile(int fd, char *name, char *mode) warn("sendto"); goto abort; } - read_ahead(file, convert); + read_ahead(file, convert, SEGSIZE); } error = 0; diff --git a/usr.bin/tftp/tftpsubs.c b/usr.bin/tftp/tftpsubs.c index f8a00a79301..15896a78655 100644 --- a/usr.bin/tftp/tftpsubs.c +++ b/usr.bin/tftp/tftpsubs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tftpsubs.c,v 1.10 2006/07/12 16:58:51 mglocker Exp $ */ +/* $OpenBSD: tftpsubs.c,v 1.11 2006/07/20 09:42:44 mglocker Exp $ */ /* $NetBSD: tftpsubs.c,v 1.3 1994/12/08 09:51:31 jtc Exp $ */ /* @@ -35,7 +35,7 @@ static char sccsid[] = "@(#)tftpsubs.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$OpenBSD: tftpsubs.c,v 1.10 2006/07/12 16:58:51 mglocker Exp $"; + "$OpenBSD: tftpsubs.c,v 1.11 2006/07/20 09:42:44 mglocker Exp $"; #endif /* not lint */ /* @@ -62,7 +62,6 @@ static const char rcsid[] = #include "tftpsubs.h" -#define PKTSIZE SEGSIZE + 4 /* should be moved to tftp.h */ /* values for bf.counter */ #define BF_ALLOC -3 /* alloc'd but not yet filled */ #define BF_FREE -2 /* free */ @@ -71,8 +70,8 @@ static const char rcsid[] = static struct tftphdr *rw_init(int); struct bf { - int counter; /* size of data in buffer, or flag */ - char buf[PKTSIZE]; /* room for data packet */ + int counter; /* size of data in buffer, or flag */ + char buf[SEGSIZE_MAX + 4]; /* room for data packet */ } bfs[2]; static int nextone; /* index of next buffer to use */ @@ -115,7 +114,7 @@ rw_init(int x) * Free it and return next buffer filled with data. */ int -readit(FILE *file, struct tftphdr **dpp, int convert) +readit(FILE *file, struct tftphdr **dpp, int convert, int segment_size) { struct bf *b; @@ -124,7 +123,7 @@ readit(FILE *file, struct tftphdr **dpp, int convert) b = &bfs[current]; /* look at new buffer */ if (b->counter == BF_FREE) /* if it's empty */ - read_ahead(file, convert); /* fill it */ + read_ahead(file, convert, segment_size); /* fill it */ /* assert(b->counter != BF_FREE); */ /* check */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ @@ -136,7 +135,7 @@ readit(FILE *file, struct tftphdr **dpp, int convert) * Conversions are lf -> cr, lf and cr -> cr, nul. */ void -read_ahead(FILE *file, int convert) +read_ahead(FILE *file, int convert, int segment_size) { int i; char *p; @@ -152,12 +151,12 @@ read_ahead(FILE *file, int convert) dp = (struct tftphdr *)b->buf; if (convert == 0) { - b->counter = read(fileno(file), dp->th_data, SEGSIZE); + b->counter = read(fileno(file), dp->th_data, segment_size); return; } p = dp->th_data; - for (i = 0; i < SEGSIZE; i++) { + for (i = 0; i < segment_size; i++) { if (newline) { if (prevchar == '\n') c = '\n'; /* lf to cr, lf */ @@ -266,7 +265,7 @@ int synchnet(int f) { int i, j = 0; - char rbuf[PKTSIZE]; + char rbuf[SEGSIZE_MIN]; struct sockaddr_in from; socklen_t fromlen; diff --git a/usr.bin/tftp/tftpsubs.h b/usr.bin/tftp/tftpsubs.h index bd6f55adf13..3e14b1f0997 100644 --- a/usr.bin/tftp/tftpsubs.h +++ b/usr.bin/tftp/tftpsubs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tftpsubs.h,v 1.5 2006/07/12 16:58:51 mglocker Exp $ */ +/* $OpenBSD: tftpsubs.h,v 1.6 2006/07/20 09:42:44 mglocker Exp $ */ /* $NetBSD: tftpsubs.h,v 1.2 1994/12/08 09:51:32 jtc Exp $ */ /* @@ -37,8 +37,8 @@ * server. */ struct tftphdr *r_init(void); -void read_ahead(FILE *, int); -int readit(FILE *, struct tftphdr **, int); +void read_ahead(FILE *, int, int); +int readit(FILE *, struct tftphdr **, int, int); int synchnet(int); |