2 * Copyright 1994, 1995, 2000 Neil Russell.
4 * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
19 #include <linux/stat.h>
20 #include <linux/err.h>
22 #define TFTP_PORT 69 /* Well known TFTP port # */
23 #define TIMEOUT 5 /* Seconds to timeout for a lost pkt */
36 static int tftp_server_port
; /* The UDP port at their end */
37 static unsigned int tftp_block
; /* packet sequence number */
38 static unsigned int tftp_last_block
; /* last packet sequence number received */
39 static int tftp_state
;
40 static uint64_t tftp_timer_start
;
51 #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */
53 static char *tftp_filename
;
54 static struct net_connection
*tftp_con
;
58 #ifdef CONFIG_NET_TFTP_PUSH
61 static inline void do_tftp_push(int push
)
70 static inline void do_tftp_push(int push
)
75 static int tftp_send(void)
80 unsigned char *pkt
= net_udp_get_payload(tftp_con
);
89 if (tftp_state
== STATE_RRQ
)
90 *s
++ = htons(TFTP_RRQ
);
92 *s
++ = htons(TFTP_WRQ
);
93 pkt
= (unsigned char *)s
;
94 pkt
+= sprintf((unsigned char *)pkt
, "%s%coctet%ctimeout%c%d",
95 tftp_filename
, 0, 0, 0, TIMEOUT
) + 1;
103 if (tftp_last_block
== tftp_block
) {
108 tftp_last_block
= tftp_block
;
110 *s
++ = htons(TFTP_DATA
);
111 *s
++ = htons(tftp_block
);
112 len
= read(tftp_fd
, s
, 512);
116 tftp_state
= STATE_DONE
;
121 tftp_state
= STATE_LAST
;
130 *s
++ = htons(TFTP_ACK
);
131 *s
++ = htons(tftp_block
);
132 pkt
= (unsigned char *)s
;
137 tftp_timer_start
= get_time_ns();
138 show_progress(tftp_size
);
139 ret
= net_udp_send(tftp_con
, len
);
144 static void tftp_handler(char *packet
, unsigned len
)
148 char *pkt
= net_eth_to_udp_payload(packet
);
149 struct udphdr
*udp
= net_eth_to_udphdr(packet
);
152 len
= net_eth_to_udplen(packet
);
160 pkt
= (unsigned char *)s
;
162 switch (ntohs(proto
)) {
171 tftp_block
= ntohs(*(uint16_t *)pkt
);
172 if (tftp_block
!= tftp_last_block
) {
173 debug("ack %d != %d\n", tftp_block
, tftp_last_block
);
177 if (tftp_state
== STATE_LAST
) {
178 tftp_state
= STATE_DONE
;
181 tftp_con
->udp
->uh_dport
= udp
->uh_sport
;
182 tftp_state
= STATE_WDATA
;
187 debug("Got OACK: %s %s\n", pkt
, pkt
+ strlen(pkt
) + 1);
188 tftp_server_port
= ntohs(udp
->uh_sport
);
189 tftp_con
->udp
->uh_dport
= udp
->uh_sport
;
192 /* send first block */
193 tftp_state
= STATE_WDATA
;
197 tftp_state
= STATE_OACK
;
208 tftp_block
= ntohs(*(uint16_t *)pkt
);
210 if (tftp_state
== STATE_RRQ
)
211 debug("Server did not acknowledge timeout option!\n");
213 if (tftp_state
== STATE_RRQ
|| tftp_state
== STATE_OACK
) {
214 /* first block received */
215 tftp_state
= STATE_RDATA
;
216 tftp_con
->udp
->uh_dport
= udp
->uh_sport
;
217 tftp_server_port
= ntohs(udp
->uh_sport
);
220 if (tftp_block
!= 1) { /* Assertion */
221 printf("error: First block is not block 1 (%ld)\n",
224 tftp_state
= STATE_DONE
;
229 if (tftp_block
== tftp_last_block
)
230 /* Same block again; ignore it. */
233 tftp_last_block
= tftp_block
;
235 if (!(tftp_block
% 10))
238 ret
= write(tftp_fd
, pkt
+ 2, len
);
242 tftp_state
= STATE_DONE
;
247 * Acknowledge the block just received, which will prompt
248 * the server for the next one.
252 if (len
< TFTP_BLOCK_SIZE
)
253 tftp_state
= STATE_DONE
;
258 debug("\nTFTP error: '%s' (%d)\n",
259 pkt
+ 2, ntohs(*(uint16_t *)pkt
));
260 switch (ntohs(*(uint16_t *)pkt
)) {
261 case 1: tftp_err
= -ENOENT
; break;
262 case 2: tftp_err
= -EACCES
; break;
263 default: tftp_err
= -EINVAL
; break;
265 tftp_state
= STATE_DONE
;
270 static int do_tftpb(struct command
*cmdtp
, int argc
, char *argv
[])
272 char *localfile
, *remotefile
, *file1
, *file2
;
282 while((opt
= getopt(argc
, argv
, "p")) > 0) {
291 return COMMAND_ERROR_USAGE
;
293 file1
= argv
[optind
++];
296 file2
= basename(file1
);
298 file2
= argv
[optind
];
308 flags
= O_WRONLY
| O_CREAT
;
311 tftp_fd
= open(localfile
, flags
);
317 tftp_con
= net_udp_new(net_get_serverip(), TFTP_PORT
, tftp_handler
);
318 if (IS_ERR(tftp_con
)) {
319 tftp_err
= PTR_ERR(tftp_con
);
323 tftp_filename
= remotefile
;
325 printf("TFTP %s server %s ('%s' -> '%s')\n",
326 tftp_push
? "to" : "from",
327 ip_to_string(net_get_serverip(), ip1
),
330 init_progression_bar(tftp_push
? s
.st_size
: 0);
332 tftp_timer_start
= get_time_ns();
333 tftp_state
= tftp_push
? STATE_WRQ
: STATE_RRQ
;
336 tftp_err
= tftp_send();
340 while (tftp_state
!= STATE_DONE
) {
346 if (is_timeout(tftp_timer_start
, SECOND
)) {
352 net_unregister(tftp_con
);
357 printf("\ntftp failed: %s\n", strerror(-tftp_err
));
364 return tftp_err
== 0 ? 0 : 1;
367 static const __maybe_unused
char cmd_tftp_help
[] =
368 "Usage: tftp <remotefile> [localfile]\n"
369 "Load a file from a TFTP server.\n"
370 #ifdef CONFIG_NET_TFTP_PUSH
372 " tftp -p <localfile> [remotefile]\n"
373 "Upload a file to a TFTP server\n"
377 BAREBOX_CMD_START(tftp
)
380 #ifdef CONFIG_NET_TFTP_PUSH
383 "Load file using tftp protocol",
384 BAREBOX_CMD_HELP(cmd_tftp_help
)
388 * @page tftp_command tftp
391 * tftp \<remotefilename\> [\<localfilename\>]
395 * tftp -p \<localfilename\> [\<remotefilename\>]
397 * Load a file from a tftp server or upload a file to a tftp server if
398 * the -p option is given. The second file argument can be skipped in
399 * which case the first filename is used (without the directory part).
401 * \<localfile> can be the local filename or a device file under /dev.
402 * This also works for flash memory. Refer to \b erase, \b unprotect for
405 * Note: This command is available only if enabled in menuconfig.