7 * Copyright (c) 2015 ETH Zurich.
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
15 #ifndef TFTP_INTERNAL_H_
16 #define TFTP_INTERNAL_H_ 1
19 * ------------------------------------------------------------------------------
21 * ------------------------------------------------------------------------------
23 #define TFTP_BLOCKSIZE 512
24 #define TFTP_MAX_MSGSIZE (4 + TFTP_BLOCKSIZE)
25 #define TFTP_TIMEOUT 500
29 * ------------------------------------------------------------------------------
31 * ------------------------------------------------------------------------------
33 //#define TFTP_DEBUG(x...) debug_printf("[tftp] " x)
34 #define TFTP_DEBUG(x...)
35 //#define TFTP_DEBUG_PACKETS(x...) debug_printf("[tftp] " x)
36 #define TFTP_DEBUG_PACKETS(x...)
39 * ------------------------------------------------------------------------------
41 * ------------------------------------------------------------------------------
44 ///< TFTP Operation Codes
45 typedef enum tftp_op {
46 TFTP_OP_INVALID = 0, ///< op code is invalid
47 TFTP_OP_READ_REQ = 1, ///< read request
48 TFTP_OP_WRITE_REQ = 2, ///< write request
49 TFTP_OP_DATA = 3, ///< data response
50 TFTP_OP_ACK = 4, ///< ack response
51 TFTP_OP_ERROR = 5 ///< error response
56 * \brief writes the opcode into the buffer
58 * \param buf buffer where to write the opcode to
59 * \param opcode opcode to be written
61 * \return number of bytes written
63 static inline size_t set_opcode(void *buf, uint16_t opcode)
66 *p = ((opcode >> 8) & 0xff); p++;
69 return sizeof(uint16_t);
73 * \brief obtains the opcode from the buffer
75 * \param buf buffer where to extract the op code
77 * \return tftp op code
79 static inline tpft_op_t get_opcode(void *buf)
82 uint16_t opcode = (*p) << 8; p++;
85 return (tpft_op_t)opcode;
89 * ------------------------------------------------------------------------------
91 * ------------------------------------------------------------------------------
95 typedef enum tpft_st {
96 TFTP_ST_INVALID, ///< state is invalid
97 TFTP_ST_CLOSED, ///< connection is closed
98 TFTP_ST_IDLE, ///< the client is connected and in the idle state
99 TFTP_ST_LAST_ACK_SENT, ///< last ack has been sent
100 TFTP_ST_LAST_DATA_SENT, ///< last data response sent
101 TFTP_ST_ERROR, ///< tftp request resulted in an error
102 TFTP_ST_READ_REQ_SENT, ///< a read request has been sent
103 TFTP_ST_WRITE_REQ_SENT, ///< a write request has been sent
104 TFTP_ST_DATA_SENT, ///< data respnse is being sent
105 TFTP_ST_ACK_SENT, ///< ack has been sent
110 * ------------------------------------------------------------------------------
112 * ------------------------------------------------------------------------------
115 ///< operation mode of the TFTP connection
116 typedef enum tftp_mode {
117 TFTP_MODE_INVALID, ///< invalid operation mode
118 TFTP_MODE_OCTET, ///< use octet moded
119 TFTP_MODE_NETASCII, ///< use netsascii mode
120 TFTP_MODE_MAIL, ///< use mail mode
124 * \brief sets the transfer mode in a buffer
126 * \param buf buffer where to write the transfer mode to
127 * \param mode transfer mode to write
129 * \returns number of bytes written
131 static inline size_t set_mode(void *buf, tftp_mode_t mode)
134 case TFTP_MODE_OCTET:
135 return snprintf(buf, 6, "octet")+1;
137 case TFTP_MODE_NETASCII:
138 return snprintf(buf, 6, "netascii")+1;
141 return snprintf(buf, 5, "mail")+1;
144 assert(!"this should not happen");
150 * \brief parses the transfer mode from the buffer
152 * \param buf buffer to extract the transfer mode from
154 * \return tftp transfer mode
156 static inline tftp_mode_t get_mode(void *buf)
158 if (strncmp(buf, "octet", 5) == 0) {
159 return TFTP_MODE_OCTET;
160 } else if (strncmp(buf, "netascii", 8) == 0) {
161 return TFTP_MODE_NETASCII;
162 } else if (strncmp(buf, "mail", 4) == 0) {
163 return TFTP_MODE_MAIL;
166 return TFTP_MODE_INVALID;
170 * ------------------------------------------------------------------------------
172 * ------------------------------------------------------------------------------
175 ///< possible tftp errors in packages
176 typedef enum tftp_err {
177 TFTP_ERR_NOT_DEFINED = 0, ///< not defined
178 TFTP_ERR_NOT_FOUND = 1, ///< file not found
179 TFTP_ERR_ACCESS_DENIED = 2, ///< access denied
180 TFTP_ERR_DISK_FULL = 3, ///< disk is full
181 TFTP_ERR_UNKNOWN_TID = 4, ///< unkown transfer id
182 TFTP_ERR_ILLEGAL_OP = 5, ///< illegal operation
183 TFTP_ERR_FILE_EXISTS = 6, ///< destination file exist
184 TFTP_ERR_NO_SUCH_USER = 7, ///< no such user
185 TFTP_ERR_INVALID_BUFFER = 0xFFFFFFFF, ///< invalid buffer
189 * \brief extracts the error code from an error package
191 * \param buf buffer to extract the error code from
192 * \param buflen length of the buffer in bytes
194 * \returns tftp error code
196 static inline tftp_err_t get_error(void *buf, size_t buflen) {
198 return TFTP_ERR_INVALID_BUFFER;
202 return (tftp_err_t)((p[2] << 8) + p[3]);
206 * \brief sets the error code in a buffer
208 * \param buf buffer where to write the error code
209 * \param error error code to write
211 * \returns number of bytes written
213 static inline size_t set_error(void *buf, tftp_err_t error)
218 p[2] = ((error >> 8) & 0xff);
219 p[3] = (error & 0xff);
225 * ------------------------------------------------------------------------------
227 * ------------------------------------------------------------------------------
231 * \brief extracts the block number from a buffer
233 * \param buf buffer where to extract the block number
234 * \param buflen length of the buffer
236 * \return block number or TFTP_BLOCKNO_INVALID
238 static inline uint32_t get_block_no(void *buf, size_t buflen)
241 return TFTP_ERR_INVALID_BUFFER;
245 return (data[2] << 8) + data[3];
249 * \brief sets the block number in a buffer
251 * \param buf buffer where to write the block number to
252 * \param blockno block number to write
254 * \return number of bytes written
256 static inline size_t set_block_no(void *buf, uint16_t blockno) {
258 *p = (uint8_t)((blockno >> 8) & 0xff); p++;
259 *p = (uint8_t)(blockno & 0xff);
260 return sizeof(uint16_t);
264 * ------------------------------------------------------------------------------
265 * Sending generic messages
266 * ------------------------------------------------------------------------------
268 errval_t tftp_send_ack(struct net_socket *socket, uint32_t blockno,
269 struct in_addr addr, uint16_t port,
271 #endif /* TFTP_INTERNAL_H_ */