1 /* vi: set sw=4 ts=4: */
2 /* -------------------------------------------------------------------------
5 * A simple tftp client/server for busybox.
6 * Tries to follow RFC1350.
7 * Only "octet" mode supported.
8 * Optional blocksize negotiation (RFC2347 + RFC2348)
10 * Copyright (C) 2001 Magnus Damm <damm@opensource.se>
12 * Parts of the code based on:
14 * atftp: Copyright (C) 2000 Jean-Pierre Lefebvre <helix@step.polymtl.ca>
15 * and Remi Lefebvre <remi@debian.org>
17 * utftp: Copyright (C) 1999 Uwe Ohse <uwe@ohse.de>
19 * tftpd added by Denys Vlasenko & Vladimir Dronnikov
21 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
22 * ------------------------------------------------------------------------- */
26 #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT
28 #define TFTP_BLKSIZE_DEFAULT 512 /* according to RFC 1350, don't change */
29 #define TFTP_TIMEOUT_MS 50
30 #define TFTP_MAXTIMEOUT_MS 2000
31 #define TFTP_NUM_RETRIES 12 /* number of backed-off retries */
33 /* opcodes we support */
41 /* error codes sent over network (we use only 0, 3 and 8) */
42 /* generic (error message is included in the packet) */
46 /* disk full or allocation exceeded */
51 #define ERR_BAD_USER 7
54 /* masks coming from getopt32 */
56 TFTP_OPT_GET = (1 << 0),
57 TFTP_OPT_PUT = (1 << 1),
58 /* pseudo option: if set, it's tftpd */
59 TFTPD_OPT = (1 << 7) * ENABLE_TFTPD,
60 TFTPD_OPT_r = (1 << 8) * ENABLE_TFTPD,
61 TFTPD_OPT_c = (1 << 9) * ENABLE_TFTPD,
62 TFTPD_OPT_u = (1 << 10) * ENABLE_TFTPD,
65 #if ENABLE_FEATURE_TFTP_GET && !ENABLE_FEATURE_TFTP_PUT
66 #define USE_GETPUT(...)
67 #define CMD_GET(cmd) 1
68 #define CMD_PUT(cmd) 0
69 #elif !ENABLE_FEATURE_TFTP_GET && ENABLE_FEATURE_TFTP_PUT
70 #define USE_GETPUT(...)
71 #define CMD_GET(cmd) 0
72 #define CMD_PUT(cmd) 1
74 #define USE_GETPUT(...) __VA_ARGS__
75 #define CMD_GET(cmd) ((cmd) & TFTP_OPT_GET)
76 #define CMD_PUT(cmd) ((cmd) & TFTP_OPT_PUT)
78 /* NB: in the code below
79 * CMD_GET(cmd) and CMD_PUT(cmd) are mutually exclusive
84 /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */
85 uint8_t error_pkt[4 + 32];
87 /* used in tftpd_main(), a bit big for stack: */
88 char block_buf[TFTP_BLKSIZE_DEFAULT];
90 #define G (*(struct globals*)&bb_common_bufsiz1)
91 #define block_buf (G.block_buf )
92 #define user_opt (G.user_opt )
93 #define error_pkt (G.error_pkt )
98 #define error_pkt_reason (error_pkt[3])
99 #define error_pkt_str (error_pkt + 4)
102 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
104 static int tftp_blksize_check(const char *blksize_str, int maxsize)
106 /* Check if the blksize is valid:
107 * RFC2348 says between 8 and 65464,
108 * but our implementation makes it impossible
109 * to use blksizes smaller than 22 octets. */
110 unsigned blksize = bb_strtou(blksize_str, NULL, 10);
112 || (blksize < 24) || (blksize > maxsize)
114 bb_error_msg("bad blocksize '%s'", blksize_str);
117 #if ENABLE_DEBUG_TFTP
118 bb_error_msg("using blksize %u", blksize);
123 static char *tftp_get_blksize(char *buf, int len)
125 #define option "blksize"
131 * "opt_name<NUL>opt_val<NUL>opt_name2<NUL>opt_val2<NUL>..." */
134 /* Make sure options are terminated correctly */
135 for (k = 0; k < len; k++) {
136 if (buf[k] == '\0') {
142 if (opt_val == 0) { /* it's "name" part */
143 if (strcasecmp(buf, option) == 0) {
146 } else if (opt_found) {
162 static int tftp_protocol(
163 len_and_sockaddr *our_lsa,
164 len_and_sockaddr *peer_lsa,
165 const char *local_file,
166 USE_TFTP(const char *remote_file,)
170 #define remote_file NULL
172 struct pollfd pfd[1];
173 #define socket_fd (pfd[0].fd)
176 USE_FEATURE_TFTP_BLOCKSIZE(smallint want_option_ack = 0;)
177 smallint finished = 0;
181 int open_mode, local_fd;
182 int retries, waittime_ms;
183 int io_bufsize = blksize + 4;
184 char *cp = cp; /* for compiler */
185 /* Can't use RESERVE_CONFIG_BUFFER here since the allocation
186 * size varies meaning BUFFERS_GO_ON_STACK would fail */
187 /* We must keep the transmit and receive buffers seperate */
188 /* In case we rcv a garbage pkt and we need to rexmit the last pkt */
189 char *xbuf = xmalloc(io_bufsize);
190 char *rbuf = xmalloc(io_bufsize);
192 socket_fd = xsocket(peer_lsa->u.sa.sa_family, SOCK_DGRAM, 0);
193 setsockopt_reuseaddr(socket_fd);
197 if (!ENABLE_TFTP || our_lsa) {
200 /* Create a socket which is:
201 * 1. bound to IP:port peer sent 1st datagram to,
202 * 2. connected to peer's IP:port
203 * This way we will answer from the IP:port peer
204 * expects, will not get any other packets on
205 * the socket, and also plain read/write will work. */
206 xbind(socket_fd, &our_lsa->u.sa, our_lsa->len);
207 xconnect(socket_fd, &peer_lsa->u.sa, peer_lsa->len);
209 /* Is there an error already? Send pkt and bail out */
210 if (error_pkt_reason || error_pkt_str[0])
213 if (CMD_GET(option_mask32)) {
214 /* it's upload - we must ACK 1st packet (with filename)
215 * as if it's "block 0" */
219 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
220 if (blksize != TFTP_BLKSIZE_DEFAULT) {
221 /* Create and send OACK packet */
222 /* For the download case, block_nr is still 1 -
223 * we expect 1st ACK from peer to be for (block_nr-1),
224 * that is, for "block 0" which is our OACK pkt */
227 /* to be continued, see below */
231 struct passwd *pw = getpwnam(user_opt);
233 bb_error_msg_and_die("unknown user '%s'", user_opt);
234 change_identity(pw); /* initgroups, setgid, setuid */
238 /* Open local file (must be after changing user) */
239 if (CMD_PUT(option_mask32)) {
240 open_mode = O_RDONLY;
242 open_mode = O_WRONLY | O_TRUNC | O_CREAT;
244 if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) {
245 /* tftpd without -c */
246 open_mode = O_WRONLY | O_TRUNC;
250 if (!(option_mask32 & TFTPD_OPT)) {
251 local_fd = CMD_GET(option_mask32) ? STDOUT_FILENO : STDIN_FILENO;
252 if (NOT_LONE_DASH(local_file))
253 local_fd = xopen(local_file, open_mode);
255 local_fd = open_or_warn(local_file, open_mode);
257 /*error_pkt_reason = ERR_NOFILE/ERR_ACCESS?*/
258 strcpy(error_pkt_str, "can't open file");
263 if (!ENABLE_TFTP || our_lsa) {
264 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
265 if (blksize != TFTP_BLKSIZE_DEFAULT) {
266 /* Create and send OACK packet. continued */
267 goto add_blksize_opt;
273 /* We can't (and don't really need to) bind the socket:
274 * we don't know from which local IP datagrams will be sent,
275 * but kernel will pick the same IP every time (unless routing
276 * table is changed), thus peer will see dgrams consistently
277 * coming from the same IP.
278 * We would like to connect the socket, but since peer's
279 * UDP code can be less perfect than ours, _peer's_ IP:port
280 * in replies may differ from IP:port we used to send
281 * our first packet. We can connect() only when we get
286 if (CMD_GET(option_mask32)) {
290 /* add filename and mode */
291 /* fill in packet if the filename fits into xbuf */
292 len = strlen(remote_file) + 1;
293 if (2 + len + sizeof("octet") >= io_bufsize) {
294 bb_error_msg("remote filename is too long");
297 strcpy(cp, remote_file);
299 /* add "mode" part of the package */
301 cp += sizeof("octet");
303 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
304 if (blksize != TFTP_BLKSIZE_DEFAULT) {
305 /* rfc2348 says that 65464 is a max allowed value */
306 if ((&xbuf[io_bufsize - 1] - cp) < sizeof("blksize NNNNN")) {
307 bb_error_msg("remote filename is too long");
312 /* add "blksize", <nul>, blksize, <nul> */
313 strcpy(cp, "blksize");
314 cp += sizeof("blksize");
315 cp += snprintf(cp, 6, "%d", blksize) + 1;
318 /* First packet is built, so skip packet generation */
322 /* Using mostly goto's - continue/break will be less clear
323 * in where we actually jump to */
325 /* Build ACK or DATA */
327 *((uint16_t*)cp) = htons(block_nr);
331 if (CMD_PUT(option_mask32)) {
333 len = full_read(local_fd, cp, blksize);
335 goto send_read_err_pkt;
337 if (len != blksize) {
344 *((uint16_t*)xbuf) = htons(opcode); /* fill in opcode part */
345 send_len = cp - xbuf;
346 /* NB: send_len value is preserved in code below
347 * for potential resend */
349 retries = TFTP_NUM_RETRIES; /* re-initialize */
350 waittime_ms = TFTP_TIMEOUT_MS;
353 #if ENABLE_DEBUG_TFTP
354 fprintf(stderr, "sending %u bytes\n", send_len);
355 for (cp = xbuf; cp < &xbuf[send_len]; cp++)
356 fprintf(stderr, "%02x ", (unsigned char) *cp);
357 fprintf(stderr, "\n");
359 xsendto(socket_fd, xbuf, send_len, &peer_lsa->u.sa, peer_lsa->len);
360 /* Was it final ACK? then exit */
361 if (finished && (opcode == TFTP_ACK))
366 /*pfd[0].fd = socket_fd;*/
367 pfd[0].events = POLLIN;
368 switch (safe_poll(pfd, 1, waittime_ms)) {
370 /*bb_perror_msg("poll"); - done in safe_poll */
375 bb_error_msg("timeout");
376 goto ret; /* no err packet sent */
379 /* exponential backoff with limit */
380 waittime_ms += waittime_ms/2;
381 if (waittime_ms > TFTP_MAXTIMEOUT_MS) {
382 waittime_ms = TFTP_MAXTIMEOUT_MS;
385 goto send_again; /* resend last sent pkt */
388 /* tftp (not tftpd!) receiving 1st packet */
389 our_lsa = ((void*)(ptrdiff_t)-1); /* not NULL */
390 len = recvfrom(socket_fd, rbuf, io_bufsize, 0,
391 &peer_lsa->u.sa, &peer_lsa->len);
392 /* Our first dgram went to port 69
393 * but reply may come from different one.
394 * Remember and use this new port (and IP) */
396 xconnect(socket_fd, &peer_lsa->u.sa, peer_lsa->len);
398 /* tftpd, or not the very first packet:
399 * socket is connect()ed, can just read from it. */
400 /* Don't full_read()!
401 * This is not TCP, one read == one pkt! */
402 len = safe_read(socket_fd, rbuf, io_bufsize);
405 goto send_read_err_pkt;
407 if (len < 4) { /* too small? */
412 /* Process recv'ed packet */
413 opcode = ntohs( ((uint16_t*)rbuf)[0] );
414 recv_blk = ntohs( ((uint16_t*)rbuf)[1] );
415 #if ENABLE_DEBUG_TFTP
416 fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, recv_blk);
419 if (opcode == TFTP_ERROR) {
420 static const char errcode_str[] =
426 "unknown transfer id\0"
427 "file already exists\0"
431 const char *msg = "";
433 if (len > 4 && rbuf[4] != '\0') {
435 rbuf[io_bufsize - 1] = '\0'; /* paranoia */
436 } else if (recv_blk <= 8) {
437 msg = nth_string(errcode_str, recv_blk);
439 bb_error_msg("server error: (%u) %s", recv_blk, msg);
443 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
444 if (want_option_ack) {
446 if (opcode == TFTP_OACK) {
447 /* server seems to support options */
450 res = tftp_get_blksize(&rbuf[2], len - 2);
452 blksize = tftp_blksize_check(res, blksize);
454 error_pkt_reason = ERR_BAD_OPT;
457 io_bufsize = blksize + 4;
458 /* Send ACK for OACK ("block" no: 0) */
463 * "An option not acknowledged by the server
464 * must be ignored by the client and server
465 * as if it were never requested." */
467 bb_error_msg("server only supports blocksize of 512");
468 blksize = TFTP_BLKSIZE_DEFAULT;
469 io_bufsize = TFTP_BLKSIZE_DEFAULT + 4;
472 /* block_nr is already advanced to next block# we expect
473 * to get / block# we are about to send next time */
475 if (CMD_GET(option_mask32) && (opcode == TFTP_DATA)) {
476 if (recv_blk == block_nr) {
477 int sz = full_write(local_fd, &rbuf[4], len - 4);
479 strcpy(error_pkt_str, bb_msg_write_error);
480 error_pkt_reason = ERR_WRITE;
486 continue; /* send ACK */
488 if (recv_blk == (block_nr - 1)) {
489 /* Server lost our TFTP_ACK. Resend it */
495 if (CMD_PUT(option_mask32) && (opcode == TFTP_ACK)) {
496 /* did peer ACK our last DATA pkt? */
497 if (recv_blk == (uint16_t) (block_nr - 1)) {
500 continue; /* send next block */
503 /* Awww... recv'd packet is not recognized! */
505 /* why recv_again? - rfc1123 says:
506 * "The sender (i.e., the side originating the DATA packets)
507 * must never resend the current DATA packet on receipt
508 * of a duplicate ACK".
509 * DATA pkts are resent ONLY on timeout.
510 * Thus "goto send_again" will ba a bad mistake above.
512 * http://en.wikipedia.org/wiki/Sorcerer's_Apprentice_Syndrome
514 } /* end of "while (1)" */
516 if (ENABLE_FEATURE_CLEAN_UP) {
522 return finished == 0; /* returns 1 on failure */
525 strcpy(error_pkt_str, bb_msg_read_error);
527 if (error_pkt_str[0])
528 bb_error_msg(error_pkt_str);
529 error_pkt[1] = TFTP_ERROR;
530 xsendto(socket_fd, error_pkt, 4 + 1 + strlen(error_pkt_str),
531 &peer_lsa->u.sa, peer_lsa->len);
537 int tftp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
538 int tftp_main(int argc ATTRIBUTE_UNUSED, char **argv)
540 len_and_sockaddr *peer_lsa;
541 const char *local_file = NULL;
542 const char *remote_file = NULL;
543 const char *blksize_str = "512";
551 /* -p or -g is mandatory, and they are mutually exclusive */
552 opt_complementary = "" USE_FEATURE_TFTP_GET("g:") USE_FEATURE_TFTP_PUT("p:")
553 USE_GETPUT("g--p:p--g:");
555 USE_GETPUT(opt =) getopt32(argv,
556 USE_FEATURE_TFTP_GET("g") USE_FEATURE_TFTP_PUT("p")
557 "l:r:" USE_FEATURE_TFTP_BLOCKSIZE("b:"),
558 &local_file, &remote_file
559 USE_FEATURE_TFTP_BLOCKSIZE(, &blksize_str));
562 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
563 /* Check if the blksize is valid:
564 * RFC2348 says between 8 and 65464 */
565 blksize = tftp_blksize_check(blksize_str, 65564);
567 //bb_error_msg("bad block size");
573 local_file = remote_file;
575 remote_file = local_file;
576 /* Error if filename or host is not known */
577 if (!remote_file || !argv[0])
580 port = bb_lookup_port(argv[1], "udp", 69);
581 peer_lsa = xhost2sockaddr(argv[0], port);
583 #if ENABLE_DEBUG_TFTP
584 fprintf(stderr, "using server '%s', remote_file '%s', local_file '%s'\n",
585 xmalloc_sockaddr2dotted(&peer_lsa->u.sa),
586 remote_file, local_file);
589 result = tftp_protocol(
590 NULL /* our_lsa*/, peer_lsa,
591 local_file, remote_file,
594 if (result != EXIT_SUCCESS && NOT_LONE_DASH(local_file) && CMD_GET(opt)) {
600 #endif /* ENABLE_TFTP */
604 /* TODO: libbb candidate? */
605 static len_and_sockaddr *get_sock_lsa(int s)
607 len_and_sockaddr *lsa;
610 if (getsockname(s, NULL, &len) != 0)
612 lsa = xzalloc(LSA_LEN_SIZE + len);
614 getsockname(s, &lsa->u.sa, &lsa->len);
618 int tftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
619 int tftpd_main(int argc ATTRIBUTE_UNUSED, char **argv)
621 len_and_sockaddr *our_lsa;
622 len_and_sockaddr *peer_lsa;
623 char *local_file, *mode;
624 const char *error_msg;
625 int opt, result, opcode;
626 int blksize = TFTP_BLKSIZE_DEFAULT;
630 our_lsa = get_sock_lsa(STDIN_FILENO);
632 bb_perror_msg_and_die("stdin is not a socket");
633 peer_lsa = xzalloc(LSA_LEN_SIZE + our_lsa->len);
634 peer_lsa->len = our_lsa->len;
636 /* Shifting to not collide with TFTP_OPTs */
637 opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu:", &user_opt) << 8);
642 result = recv_from_to(STDIN_FILENO, block_buf, sizeof(block_buf),
644 &peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len);
646 error_msg = "malformed packet";
647 opcode = ntohs(*(uint16_t*)block_buf);
648 if (result < 4 || result >= sizeof(block_buf)
649 || block_buf[result-1] != '\0'
650 || (USE_FEATURE_TFTP_GET(opcode != TFTP_RRQ) /* not download */
652 USE_FEATURE_TFTP_GET(opcode != TFTP_WRQ) /* not upload */
657 local_file = block_buf + 2;
658 if (local_file[0] == '.' || strstr(local_file, "/.")) {
659 error_msg = "dot in file name";
662 mode = local_file + strlen(local_file) + 1;
663 if (mode >= block_buf + result || strcmp(mode, "octet") != 0) {
666 #if ENABLE_FEATURE_TFTP_BLOCKSIZE
669 char *opt_str = mode + sizeof("octet");
670 int opt_len = block_buf + result - opt_str;
672 res = tftp_get_blksize(opt_str, opt_len);
674 blksize = tftp_blksize_check(res, 65564);
676 error_pkt_reason = ERR_BAD_OPT;
677 /* will just send error pkt */
685 if (!ENABLE_FEATURE_TFTP_PUT || opcode == TFTP_WRQ) {
686 if (opt & TFTPD_OPT_r) {
687 /* This would mean "disk full" - not true */
688 /*error_pkt_reason = ERR_WRITE;*/
689 error_msg = bb_msg_write_error;
692 USE_GETPUT(option_mask32 |= TFTP_OPT_GET;) /* will receive file's data */
694 USE_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */
697 close(STDIN_FILENO); /* close old, possibly wildcard socket */
698 /* tftp_protocol() will create new one, bound to particular local IP */
700 /* NB: if error_pkt_str or error_pkt_reason is set up,
701 * tftp_protocol() just sends one error pkt and returns */
703 result = tftp_protocol(
705 local_file, USE_TFTP(NULL /*remote_file*/,)
711 strcpy(error_pkt_str, error_msg);
715 #endif /* ENABLE_TFTPD */
717 #endif /* ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT */