4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
33 * \brief TFTP protocol implementation
35 * This module implements a TFTP server with a handy KFile interface.
36 * The call to tftp_listen() will block until a client tries to connect,
37 * then it returns a KFile.
38 * If you want to accept the transfer, start reading from the handle and
39 * the transfer will continue. Otherwise, don't access it and immediately
41 * Close the KFile when you're done.
43 * The usage pattern is as follows:
45 * // initialize a TFTP session
47 * // start listening for connections
48 * KFile *f = tftp_listen();
49 * // now you can check the returned file name
50 * // and change behaviour at runtime
51 * if (!strcmp(filename, "firmware.bin"))
53 * else if (!strcmp(filename, "conf.ini"))
54 * // update the configuration
59 * \author Luca Ottaviano <lottaviano@develer.com>
61 * $WIZ$ module_name = "tftp"
62 * $WIZ$ module_configuration = "bertos/cfg/cfg_tftp.h"
63 * $WIZ$ module_depends = "lwip", "kfile"
69 #include <cfg/compiler.h>
70 #include <lwip/sockets.h> // sockaddr_in, socklen_t
73 #define TFTP_RRQ 0x0100 /* TFTP read request packet (already in net endianess). */
74 #define TFTP_WRQ 0x0200 /* TFTP write request packet (already in net endianess). */
75 #define TFTP_DATA 03 /* TFTP data packet. */
76 #define TFTP_ACK 0x0400 /* TFTP acknowledgement packet (already in net endianess). */
77 #define TFTP_PROTOERR 0x0500 /* TFTP acknowledgement packet (already in net endianess). */
79 /* TFTP protocol error codes */
80 #define TFTP_PROTOERR_ACCESS_VIOLATION 0x0200
82 #define TFTP_SERVER_PORT 69
84 /* Return error codes */
85 #define TFTP_ERR_TIMEOUT -2
88 struct PACKED TftpHeader
90 short opcode; ///< packet type */
93 short block; /* block # */
94 short code; /* error code */
95 char stuff[1]; /* request packet stuff */
99 typedef struct PACKED Tftpframe {
100 struct TftpHeader hdr;
101 char data[512]; /* data or error string */
104 struct PACKED ackframe
110 struct PACKED errframe
123 typedef struct TftpSession
125 struct sockaddr_in addr;
128 unsigned short block;
132 size_t bytes_available;
139 int tftp_init(TftpSession *ctx, unsigned short port, mtime_t timeout);
140 KFile *tftp_listen(TftpSession *ctx, char *filename, size_t len, TftpOpenMode *mode);