uboot/net/tftp.c
<<
>>
Prefs
   1/*
   2 * Copyright 1994, 1995, 2000 Neil Russell.
   3 * (See License)
   4 * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
   5 * Copyright 2011 Comelit Group SpA,
   6 *                Luca Ceresoli <luca.ceresoli@comelit.it>
   7 */
   8#include <common.h>
   9#include <command.h>
  10#include <display_options.h>
  11#include <efi_loader.h>
  12#include <env.h>
  13#include <image.h>
  14#include <lmb.h>
  15#include <log.h>
  16#include <mapmem.h>
  17#include <net.h>
  18#include <net6.h>
  19#include <asm/global_data.h>
  20#include <net/tftp.h>
  21#include "bootp.h"
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25/* Well known TFTP port # */
  26#define WELL_KNOWN_PORT 69
  27/* Millisecs to timeout for lost pkt */
  28#define TIMEOUT         5000UL
  29/* Number of "loading" hashes per line (for checking the image size) */
  30#define HASHES_PER_LINE 65
  31
  32/*
  33 *      TFTP operations.
  34 */
  35#define TFTP_RRQ        1
  36#define TFTP_WRQ        2
  37#define TFTP_DATA       3
  38#define TFTP_ACK        4
  39#define TFTP_ERROR      5
  40#define TFTP_OACK       6
  41
  42static ulong timeout_ms = TIMEOUT;
  43static int timeout_count_max = (CONFIG_NET_RETRY_COUNT * 2);
  44static ulong time_start;   /* Record time we started tftp */
  45static struct in6_addr tftp_remote_ip6;
  46
  47/*
  48 * These globals govern the timeout behavior when attempting a connection to a
  49 * TFTP server. tftp_timeout_ms specifies the number of milliseconds to
  50 * wait for the server to respond to initial connection. Second global,
  51 * tftp_timeout_count_max, gives the number of such connection retries.
  52 * tftp_timeout_count_max must be non-negative and tftp_timeout_ms must be
  53 * positive. The globals are meant to be set (and restored) by code needing
  54 * non-standard timeout behavior when initiating a TFTP transfer.
  55 */
  56ulong tftp_timeout_ms = TIMEOUT;
  57int tftp_timeout_count_max = (CONFIG_NET_RETRY_COUNT * 2);
  58
  59enum {
  60        TFTP_ERR_UNDEFINED           = 0,
  61        TFTP_ERR_FILE_NOT_FOUND      = 1,
  62        TFTP_ERR_ACCESS_DENIED       = 2,
  63        TFTP_ERR_DISK_FULL           = 3,
  64        TFTP_ERR_UNEXPECTED_OPCODE   = 4,
  65        TFTP_ERR_UNKNOWN_TRANSFER_ID  = 5,
  66        TFTP_ERR_FILE_ALREADY_EXISTS = 6,
  67        TFTP_ERR_OPTION_NEGOTIATION = 8,
  68};
  69
  70static struct in_addr tftp_remote_ip;
  71/* The UDP port at their end */
  72static int      tftp_remote_port;
  73/* The UDP port at our end */
  74static int      tftp_our_port;
  75static int      timeout_count;
  76/* packet sequence number */
  77static ulong    tftp_cur_block;
  78/* last packet sequence number received */
  79static ulong    tftp_prev_block;
  80/* count of sequence number wraparounds */
  81static ulong    tftp_block_wrap;
  82/* memory offset due to wrapping */
  83static ulong    tftp_block_wrap_offset;
  84static int      tftp_state;
  85static ulong    tftp_load_addr;
  86#ifdef CONFIG_LMB
  87static ulong    tftp_load_size;
  88#endif
  89#ifdef CONFIG_TFTP_TSIZE
  90/* The file size reported by the server */
  91static int      tftp_tsize;
  92/* The number of hashes we printed */
  93static short    tftp_tsize_num_hash;
  94#endif
  95/* The window size negotiated */
  96static ushort   tftp_windowsize;
  97/* Next block to send ack to */
  98static ushort   tftp_next_ack;
  99/* Last nack block we send */
 100static ushort   tftp_last_nack;
 101#ifdef CONFIG_CMD_TFTPPUT
 102/* 1 if writing, else 0 */
 103static int      tftp_put_active;
 104/* 1 if we have sent the last block */
 105static int      tftp_put_final_block_sent;
 106#else
 107#define tftp_put_active 0
 108#endif
 109
 110#define STATE_SEND_RRQ  1
 111#define STATE_DATA      2
 112#define STATE_TOO_LARGE 3
 113#define STATE_BAD_MAGIC 4
 114#define STATE_OACK      5
 115#define STATE_RECV_WRQ  6
 116#define STATE_SEND_WRQ  7
 117#define STATE_INVALID_OPTION    8
 118
 119/* default TFTP block size */
 120#define TFTP_BLOCK_SIZE         512
 121#define TFTP_MTU_BLOCKSIZE6 (CONFIG_TFTP_BLOCKSIZE - 20)
 122/* sequence number is 16 bit */
 123#define TFTP_SEQUENCE_SIZE      ((ulong)(1<<16))
 124
 125#define DEFAULT_NAME_LEN        (8 + 4 + 1)
 126static char default_filename[DEFAULT_NAME_LEN];
 127
 128#ifndef CONFIG_TFTP_FILE_NAME_MAX_LEN
 129#define MAX_LEN 128
 130#else
 131#define MAX_LEN CONFIG_TFTP_FILE_NAME_MAX_LEN
 132#endif
 133
 134static char tftp_filename[MAX_LEN];
 135
 136/* 512 is poor choice for ethernet, MTU is typically 1500.
 137 * Minus eth.hdrs thats 1468.  Can get 2x better throughput with
 138 * almost-MTU block sizes.  At least try... fall back to 512 if need be.
 139 * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file)
 140 */
 141
 142/* When windowsize is defined to 1,
 143 * tftp behaves the same way as it was
 144 * never declared
 145 */
 146#ifdef CONFIG_TFTP_WINDOWSIZE
 147#define TFTP_WINDOWSIZE CONFIG_TFTP_WINDOWSIZE
 148#else
 149#define TFTP_WINDOWSIZE 1
 150#endif
 151
 152static unsigned short tftp_block_size = TFTP_BLOCK_SIZE;
 153static unsigned short tftp_block_size_option = CONFIG_TFTP_BLOCKSIZE;
 154static unsigned short tftp_window_size_option = TFTP_WINDOWSIZE;
 155
 156static inline int store_block(int block, uchar *src, unsigned int len)
 157{
 158        ulong offset = block * tftp_block_size + tftp_block_wrap_offset -
 159                        tftp_block_size;
 160        ulong newsize = offset + len;
 161        ulong store_addr = tftp_load_addr + offset;
 162        void *ptr;
 163
 164#ifdef CONFIG_LMB
 165        ulong end_addr = tftp_load_addr + tftp_load_size;
 166
 167        if (!end_addr)
 168                end_addr = ULONG_MAX;
 169
 170        if (store_addr < tftp_load_addr ||
 171            store_addr + len > end_addr) {
 172                puts("\nTFTP error: ");
 173                puts("trying to overwrite reserved memory...\n");
 174                return -1;
 175        }
 176#endif
 177        ptr = map_sysmem(store_addr, len);
 178        memcpy(ptr, src, len);
 179        unmap_sysmem(ptr);
 180
 181        if (net_boot_file_size < newsize)
 182                net_boot_file_size = newsize;
 183
 184        return 0;
 185}
 186
 187/* Clear our state ready for a new transfer */
 188static void new_transfer(void)
 189{
 190        tftp_prev_block = 0;
 191        tftp_block_wrap = 0;
 192        tftp_block_wrap_offset = 0;
 193#ifdef CONFIG_CMD_TFTPPUT
 194        tftp_put_final_block_sent = 0;
 195#endif
 196}
 197
 198#ifdef CONFIG_CMD_TFTPPUT
 199/**
 200 * Load the next block from memory to be sent over tftp.
 201 *
 202 * @param block Block number to send
 203 * @param dst   Destination buffer for data
 204 * @param len   Number of bytes in block (this one and every other)
 205 * Return: number of bytes loaded
 206 */
 207static int load_block(unsigned block, uchar *dst, unsigned len)
 208{
 209        /* We may want to get the final block from the previous set */
 210        ulong offset = block * tftp_block_size + tftp_block_wrap_offset -
 211                       tftp_block_size;
 212        ulong tosend = len;
 213
 214        tosend = min(net_boot_file_size - offset, tosend);
 215        (void)memcpy(dst, (void *)(image_save_addr + offset), tosend);
 216        debug("%s: block=%u, offset=%lu, len=%u, tosend=%lu\n", __func__,
 217              block, offset, len, tosend);
 218        return tosend;
 219}
 220#endif
 221
 222static void tftp_send(void);
 223static void tftp_timeout_handler(void);
 224
 225/**********************************************************************/
 226
 227static void show_block_marker(void)
 228{
 229        ulong pos;
 230
 231#ifdef CONFIG_TFTP_TSIZE
 232        if (tftp_tsize) {
 233                pos = tftp_cur_block * tftp_block_size +
 234                        tftp_block_wrap_offset;
 235                if (pos > tftp_tsize)
 236                        pos = tftp_tsize;
 237
 238                while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) {
 239                        putc('#');
 240                        tftp_tsize_num_hash++;
 241                }
 242        } else
 243#endif
 244        {
 245                pos = (tftp_cur_block - 1) +
 246                        (tftp_block_wrap * TFTP_SEQUENCE_SIZE);
 247                if ((pos % 10) == 0)
 248                        putc('#');
 249                else if (((pos + 1) % (10 * HASHES_PER_LINE)) == 0)
 250                        puts("\n\t ");
 251        }
 252}
 253
 254/**
 255 * restart the current transfer due to an error
 256 *
 257 * @param msg   Message to print for user
 258 */
 259static void restart(const char *msg)
 260{
 261        printf("\n%s; starting again\n", msg);
 262        net_start_again();
 263}
 264
 265/*
 266 * Check if the block number has wrapped, and update progress
 267 *
 268 * TODO: The egregious use of global variables in this file should be tidied.
 269 */
 270static void update_block_number(void)
 271{
 272        /*
 273         * RFC1350 specifies that the first data packet will
 274         * have sequence number 1. If we receive a sequence
 275         * number of 0 this means that there was a wrap
 276         * around of the (16 bit) counter.
 277         */
 278        if (tftp_cur_block == 0 && tftp_prev_block != 0) {
 279                tftp_block_wrap++;
 280                tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE;
 281                timeout_count = 0; /* we've done well, reset the timeout */
 282        }
 283        show_block_marker();
 284}
 285
 286/* The TFTP get or put is complete */
 287static void tftp_complete(void)
 288{
 289#ifdef CONFIG_TFTP_TSIZE
 290        /* Print hash marks for the last packet received */
 291        while (tftp_tsize && tftp_tsize_num_hash < 49) {
 292                putc('#');
 293                tftp_tsize_num_hash++;
 294        }
 295        puts("  ");
 296        print_size(tftp_tsize, "");
 297#endif
 298        time_start = get_timer(time_start);
 299        if (time_start > 0) {
 300                puts("\n\t ");  /* Line up with "Loading: " */
 301                print_size(net_boot_file_size /
 302                        time_start * 1000, "/s");
 303        }
 304        puts("\ndone\n");
 305        if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
 306                if (!tftp_put_active)
 307                        efi_set_bootdev("Net", "", tftp_filename,
 308                                        map_sysmem(tftp_load_addr, 0),
 309                                        net_boot_file_size);
 310        }
 311        net_set_state(NETLOOP_SUCCESS);
 312}
 313
 314static void tftp_send(void)
 315{
 316        uchar *pkt;
 317        uchar *xp;
 318        int len = 0;
 319        ushort *s;
 320        bool err_pkt = false;
 321
 322        /*
 323         *      We will always be sending some sort of packet, so
 324         *      cobble together the packet headers now.
 325         */
 326        if (IS_ENABLED(CONFIG_IPV6) && use_ip6)
 327                pkt = net_tx_packet + net_eth_hdr_size() +
 328                      IP6_HDR_SIZE + UDP_HDR_SIZE;
 329        else
 330                pkt = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
 331
 332        switch (tftp_state) {
 333        case STATE_SEND_RRQ:
 334        case STATE_SEND_WRQ:
 335                xp = pkt;
 336                s = (ushort *)pkt;
 337#ifdef CONFIG_CMD_TFTPPUT
 338                *s++ = htons(tftp_state == STATE_SEND_RRQ ? TFTP_RRQ :
 339                        TFTP_WRQ);
 340#else
 341                *s++ = htons(TFTP_RRQ);
 342#endif
 343                pkt = (uchar *)s;
 344                strcpy((char *)pkt, tftp_filename);
 345                pkt += strlen(tftp_filename) + 1;
 346                strcpy((char *)pkt, "octet");
 347                pkt += 5 /*strlen("octet")*/ + 1;
 348                strcpy((char *)pkt, "timeout");
 349                pkt += 7 /*strlen("timeout")*/ + 1;
 350                sprintf((char *)pkt, "%lu", timeout_ms / 1000);
 351                debug("send option \"timeout %s\"\n", (char *)pkt);
 352                pkt += strlen((char *)pkt) + 1;
 353#ifdef CONFIG_TFTP_TSIZE
 354                pkt += sprintf((char *)pkt, "tsize%c%u%c",
 355                                0, net_boot_file_size, 0);
 356#endif
 357                /* try for more effic. blk size */
 358                pkt += sprintf((char *)pkt, "blksize%c%d%c",
 359                                0, tftp_block_size_option, 0);
 360
 361                /* try for more effic. window size.
 362                 * Implemented only for tftp get.
 363                 * Don't bother sending if it's 1
 364                 */
 365                if (tftp_state == STATE_SEND_RRQ && tftp_window_size_option > 1)
 366                        pkt += sprintf((char *)pkt, "windowsize%c%d%c",
 367                                        0, tftp_window_size_option, 0);
 368                len = pkt - xp;
 369                break;
 370
 371        case STATE_OACK:
 372
 373        case STATE_RECV_WRQ:
 374        case STATE_DATA:
 375                xp = pkt;
 376                s = (ushort *)pkt;
 377                s[0] = htons(TFTP_ACK);
 378                s[1] = htons(tftp_cur_block);
 379                pkt = (uchar *)(s + 2);
 380#ifdef CONFIG_CMD_TFTPPUT
 381                if (tftp_put_active) {
 382                        int toload = tftp_block_size;
 383                        int loaded = load_block(tftp_cur_block, pkt, toload);
 384
 385                        s[0] = htons(TFTP_DATA);
 386                        pkt += loaded;
 387                        tftp_put_final_block_sent = (loaded < toload);
 388                }
 389#endif
 390                len = pkt - xp;
 391                break;
 392
 393        case STATE_TOO_LARGE:
 394                xp = pkt;
 395                s = (ushort *)pkt;
 396                *s++ = htons(TFTP_ERROR);
 397                        *s++ = htons(3);
 398
 399                pkt = (uchar *)s;
 400                strcpy((char *)pkt, "File too large");
 401                pkt += 14 /*strlen("File too large")*/ + 1;
 402                len = pkt - xp;
 403                err_pkt = true;
 404                break;
 405
 406        case STATE_BAD_MAGIC:
 407                xp = pkt;
 408                s = (ushort *)pkt;
 409                *s++ = htons(TFTP_ERROR);
 410                *s++ = htons(2);
 411                pkt = (uchar *)s;
 412                strcpy((char *)pkt, "File has bad magic");
 413                pkt += 18 /*strlen("File has bad magic")*/ + 1;
 414                len = pkt - xp;
 415                err_pkt = true;
 416                break;
 417
 418        case STATE_INVALID_OPTION:
 419                xp = pkt;
 420                s = (ushort *)pkt;
 421                *s++ = htons(TFTP_ERROR);
 422                *s++ = htons(TFTP_ERR_OPTION_NEGOTIATION);
 423                pkt = (uchar *)s;
 424                strcpy((char *)pkt, "Option Negotiation Failed");
 425                /* strlen("Option Negotiation Failed") + NULL*/
 426                pkt += 25 + 1;
 427                len = pkt - xp;
 428                err_pkt = true;
 429                break;
 430        }
 431
 432        if (IS_ENABLED(CONFIG_IPV6) && use_ip6)
 433                net_send_udp_packet6(net_server_ethaddr,
 434                                     &tftp_remote_ip6,
 435                                     tftp_remote_port,
 436                                     tftp_our_port, len);
 437        else
 438                net_send_udp_packet(net_server_ethaddr, tftp_remote_ip,
 439                                    tftp_remote_port, tftp_our_port, len);
 440
 441        if (err_pkt)
 442                net_set_state(NETLOOP_FAIL);
 443}
 444
 445#ifdef CONFIG_CMD_TFTPPUT
 446static void icmp_handler(unsigned type, unsigned code, unsigned dest,
 447                         struct in_addr sip, unsigned src, uchar *pkt,
 448                         unsigned len)
 449{
 450        if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
 451                /* Oh dear the other end has gone away */
 452                restart("TFTP server died");
 453        }
 454}
 455#endif
 456
 457static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
 458                         unsigned src, unsigned len)
 459{
 460        __be16 proto;
 461        __be16 *s;
 462        int i;
 463        u16 timeout_val_rcvd;
 464
 465        if (dest != tftp_our_port) {
 466                        return;
 467        }
 468        if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port &&
 469            tftp_state != STATE_RECV_WRQ && tftp_state != STATE_SEND_WRQ)
 470                return;
 471
 472        if (len < 2)
 473                return;
 474        len -= 2;
 475        /* warning: don't use increment (++) in ntohs() macros!! */
 476        s = (__be16 *)pkt;
 477        proto = *s++;
 478        pkt = (uchar *)s;
 479        switch (ntohs(proto)) {
 480        case TFTP_RRQ:
 481                break;
 482
 483        case TFTP_ACK:
 484#ifdef CONFIG_CMD_TFTPPUT
 485                if (tftp_put_active) {
 486                        if (tftp_put_final_block_sent) {
 487                                tftp_complete();
 488                        } else {
 489                                /*
 490                                 * Move to the next block. We want our block
 491                                 * count to wrap just like the other end!
 492                                 */
 493                                int block = ntohs(*s);
 494                                int ack_ok = (tftp_cur_block == block);
 495
 496                                tftp_prev_block = tftp_cur_block;
 497                                tftp_cur_block = (unsigned short)(block + 1);
 498                                update_block_number();
 499                                if (ack_ok)
 500                                        tftp_send(); /* Send next data block */
 501                        }
 502                }
 503#endif
 504                break;
 505
 506        default:
 507                break;
 508
 509#ifdef CONFIG_CMD_TFTPSRV
 510        case TFTP_WRQ:
 511                debug("Got WRQ\n");
 512                tftp_remote_ip = sip;
 513                tftp_remote_port = src;
 514                tftp_our_port = 1024 + (get_timer(0) % 3072);
 515                new_transfer();
 516                tftp_send(); /* Send ACK(0) */
 517                break;
 518#endif
 519
 520        case TFTP_OACK:
 521                debug("Got OACK: ");
 522                for (i = 0; i < len; i++) {
 523                        if (pkt[i] == '\0')
 524                                debug(" ");
 525                        else
 526                                debug("%c", pkt[i]);
 527                }
 528                debug("\n");
 529                tftp_state = STATE_OACK;
 530                tftp_remote_port = src;
 531                /*
 532                 * Check for 'blksize' option.
 533                 * Careful: "i" is signed, "len" is unsigned, thus
 534                 * something like "len-8" may give a *huge* number
 535                 */
 536                for (i = 0; i+8 < len; i++) {
 537                        if (strcasecmp((char *)pkt + i, "blksize") == 0) {
 538                                tftp_block_size = (unsigned short)
 539                                        dectoul((char *)pkt + i + 8, NULL);
 540                                debug("Blocksize oack: %s, %d\n",
 541                                      (char *)pkt + i + 8, tftp_block_size);
 542                                if (tftp_block_size > tftp_block_size_option) {
 543                                        printf("Invalid blk size(=%d)\n",
 544                                               tftp_block_size);
 545                                        tftp_state = STATE_INVALID_OPTION;
 546                                }
 547                        }
 548                        if (strcasecmp((char *)pkt + i, "timeout") == 0) {
 549                                timeout_val_rcvd = (unsigned short)
 550                                        dectoul((char *)pkt + i + 8, NULL);
 551                                debug("Timeout oack: %s, %d\n",
 552                                      (char *)pkt + i + 8, timeout_val_rcvd);
 553                                if (timeout_val_rcvd != (timeout_ms / 1000)) {
 554                                        printf("Invalid timeout val(=%d s)\n",
 555                                               timeout_val_rcvd);
 556                                        tftp_state = STATE_INVALID_OPTION;
 557                                }
 558                        }
 559#ifdef CONFIG_TFTP_TSIZE
 560                        if (strcasecmp((char *)pkt + i, "tsize") == 0) {
 561                                tftp_tsize = dectoul((char *)pkt + i + 6,
 562                                                     NULL);
 563                                debug("size = %s, %d\n",
 564                                      (char *)pkt + i + 6, tftp_tsize);
 565                        }
 566#endif
 567                        if (strcasecmp((char *)pkt + i,  "windowsize") == 0) {
 568                                tftp_windowsize =
 569                                        dectoul((char *)pkt + i + 11, NULL);
 570                                debug("windowsize = %s, %d\n",
 571                                      (char *)pkt + i + 11, tftp_windowsize);
 572                        }
 573                }
 574
 575                tftp_next_ack = tftp_windowsize;
 576
 577#ifdef CONFIG_CMD_TFTPPUT
 578                if (tftp_put_active && tftp_state == STATE_OACK) {
 579                        /* Get ready to send the first block */
 580                        tftp_state = STATE_DATA;
 581                        tftp_cur_block++;
 582                }
 583#endif
 584                tftp_send(); /* Send ACK or first data block */
 585                break;
 586        case TFTP_DATA:
 587                if (len < 2)
 588                        return;
 589                len -= 2;
 590
 591                if (ntohs(*(__be16 *)pkt) != (ushort)(tftp_cur_block + 1)) {
 592                        debug("Received unexpected block: %d, expected: %d\n",
 593                              ntohs(*(__be16 *)pkt),
 594                              (ushort)(tftp_cur_block + 1));
 595                        /*
 596                         * Only ACK if the block count received is greater than
 597                         * the expected block count, otherwise skip ACK.
 598                         * (required to properly handle the server retransmitting
 599                         *  the window)
 600                         */
 601                        if ((ushort)(tftp_cur_block + 1) - (short)(ntohs(*(__be16 *)pkt)) > 0)
 602                                break;
 603                        /*
 604                         * If one packet is dropped most likely
 605                         * all other buffers in the window
 606                         * that will arrive will cause a sending NACK.
 607                         * This just overwellms the server, let's just send one.
 608                         */
 609                        if (tftp_last_nack != tftp_cur_block) {
 610                                tftp_send();
 611                                tftp_last_nack = tftp_cur_block;
 612                                tftp_next_ack = (ushort)(tftp_cur_block +
 613                                                         tftp_windowsize);
 614                        }
 615                        break;
 616                }
 617
 618                tftp_cur_block++;
 619                tftp_cur_block %= TFTP_SEQUENCE_SIZE;
 620
 621                if (tftp_state == STATE_SEND_RRQ) {
 622                        debug("Server did not acknowledge any options!\n");
 623                        tftp_next_ack = tftp_windowsize;
 624                }
 625
 626                if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK ||
 627                    tftp_state == STATE_RECV_WRQ) {
 628                        /* first block received */
 629                        tftp_state = STATE_DATA;
 630                        tftp_remote_port = src;
 631                        new_transfer();
 632
 633                        if (tftp_cur_block != 1) {      /* Assertion */
 634                                puts("\nTFTP error: ");
 635                                printf("First block is not block 1 (%ld)\n",
 636                                       tftp_cur_block);
 637                                puts("Starting again\n\n");
 638                                net_start_again();
 639                                break;
 640                        }
 641                }
 642
 643                if (tftp_cur_block == tftp_prev_block) {
 644                        /* Same block again; ignore it. */
 645                        break;
 646                }
 647
 648                update_block_number();
 649                tftp_prev_block = tftp_cur_block;
 650                timeout_count_max = tftp_timeout_count_max;
 651                net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
 652
 653                if (store_block(tftp_cur_block, pkt + 2, len)) {
 654                        eth_halt();
 655                        net_set_state(NETLOOP_FAIL);
 656                        break;
 657                }
 658
 659                if (len < tftp_block_size) {
 660                        tftp_send();
 661                        tftp_complete();
 662                        break;
 663                }
 664
 665                /*
 666                 *      Acknowledge the block just received, which will prompt
 667                 *      the remote for the next one.
 668                 */
 669                if (tftp_cur_block == tftp_next_ack) {
 670                        tftp_send();
 671                        tftp_next_ack += tftp_windowsize;
 672                }
 673                break;
 674
 675        case TFTP_ERROR:
 676                printf("\nTFTP error: '%s' (%d)\n",
 677                       pkt + 2, ntohs(*(__be16 *)pkt));
 678
 679                switch (ntohs(*(__be16 *)pkt)) {
 680                case TFTP_ERR_FILE_NOT_FOUND:
 681                case TFTP_ERR_ACCESS_DENIED:
 682                        puts("Not retrying...\n");
 683                        eth_halt();
 684                        net_set_state(NETLOOP_FAIL);
 685                        break;
 686                case TFTP_ERR_UNDEFINED:
 687                case TFTP_ERR_DISK_FULL:
 688                case TFTP_ERR_UNEXPECTED_OPCODE:
 689                case TFTP_ERR_UNKNOWN_TRANSFER_ID:
 690                case TFTP_ERR_FILE_ALREADY_EXISTS:
 691                default:
 692                        puts("Starting again\n\n");
 693                        net_start_again();
 694                        break;
 695                }
 696                break;
 697        }
 698}
 699
 700
 701static void tftp_timeout_handler(void)
 702{
 703        if (++timeout_count > timeout_count_max) {
 704                restart("Retry count exceeded");
 705        } else {
 706                puts("T ");
 707                net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
 708                if (tftp_state != STATE_RECV_WRQ)
 709                        tftp_send();
 710        }
 711}
 712
 713/* Initialize tftp_load_addr and tftp_load_size from image_load_addr and lmb */
 714static int tftp_init_load_addr(void)
 715{
 716#ifdef CONFIG_LMB
 717        struct lmb lmb;
 718        phys_size_t max_size;
 719
 720        lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
 721
 722        max_size = lmb_get_free_size(&lmb, image_load_addr);
 723        if (!max_size)
 724                return -1;
 725
 726        tftp_load_size = max_size;
 727#endif
 728        tftp_load_addr = image_load_addr;
 729        return 0;
 730}
 731
 732static int saved_tftp_block_size_option;
 733static void sanitize_tftp_block_size_option(enum proto_t protocol)
 734{
 735        int cap, max_defrag;
 736
 737        switch (protocol) {
 738        case TFTPGET:
 739                max_defrag = config_opt_enabled(CONFIG_IP_DEFRAG, CONFIG_NET_MAXDEFRAG, 0);
 740                if (max_defrag) {
 741                        /* Account for IP, UDP and TFTP headers. */
 742                        cap = max_defrag - (20 + 8 + 4);
 743                        /* RFC2348 sets a hard upper limit. */
 744                        cap = min(cap, 65464);
 745                        break;
 746                }
 747                /*
 748                 * If not CONFIG_IP_DEFRAG, cap at the same value as
 749                 * for tftp put, namely normal MTU minus protocol
 750                 * overhead.
 751                 */
 752                fallthrough;
 753        case TFTPPUT:
 754        default:
 755                /*
 756                 * U-Boot does not support IP fragmentation on TX, so
 757                 * this must be small enough that it fits normal MTU
 758                 * (and small enough that it fits net_tx_packet which
 759                 * has room for PKTSIZE_ALIGN bytes).
 760                 */
 761                cap = 1468;
 762        }
 763        if (tftp_block_size_option > cap) {
 764                printf("Capping tftp block size option to %d (was %d)\n",
 765                       cap, tftp_block_size_option);
 766                saved_tftp_block_size_option = tftp_block_size_option;
 767                tftp_block_size_option = cap;
 768        }
 769}
 770
 771void tftp_start(enum proto_t protocol)
 772{
 773        __maybe_unused char *ep;             /* Environment pointer */
 774
 775        if (saved_tftp_block_size_option) {
 776                tftp_block_size_option = saved_tftp_block_size_option;
 777                saved_tftp_block_size_option = 0;
 778        }
 779
 780        if (IS_ENABLED(CONFIG_NET_TFTP_VARS)) {
 781
 782                /*
 783                 * Allow the user to choose TFTP blocksize and timeout.
 784                 * TFTP protocol has a minimal timeout of 1 second.
 785                 */
 786
 787                ep = env_get("tftpblocksize");
 788                if (ep != NULL)
 789                        tftp_block_size_option = simple_strtol(ep, NULL, 10);
 790
 791                ep = env_get("tftpwindowsize");
 792                if (ep != NULL)
 793                        tftp_window_size_option = simple_strtol(ep, NULL, 10);
 794
 795                ep = env_get("tftptimeout");
 796                if (ep != NULL)
 797                        timeout_ms = simple_strtol(ep, NULL, 10);
 798
 799                if (timeout_ms < 1000) {
 800                        printf("TFTP timeout (%ld ms) too low, set min = 1000 ms\n",
 801                               timeout_ms);
 802                        timeout_ms = 1000;
 803                }
 804
 805                ep = env_get("tftptimeoutcountmax");
 806                if (ep != NULL)
 807                        tftp_timeout_count_max = simple_strtol(ep, NULL, 10);
 808
 809                if (tftp_timeout_count_max < 0) {
 810                        printf("TFTP timeout count max (%d ms) negative, set to 0\n",
 811                               tftp_timeout_count_max);
 812                        tftp_timeout_count_max = 0;
 813                }
 814        }
 815
 816        sanitize_tftp_block_size_option(protocol);
 817
 818        debug("TFTP blocksize = %i, TFTP windowsize = %d timeout = %ld ms\n",
 819              tftp_block_size_option, tftp_window_size_option, timeout_ms);
 820
 821        if (IS_ENABLED(CONFIG_IPV6))
 822                tftp_remote_ip6 = net_server_ip6;
 823
 824        tftp_remote_ip = net_server_ip;
 825        if (!net_parse_bootfile(&tftp_remote_ip, tftp_filename, MAX_LEN)) {
 826                sprintf(default_filename, "%02X%02X%02X%02X.img",
 827                        net_ip.s_addr & 0xFF,
 828                        (net_ip.s_addr >>  8) & 0xFF,
 829                        (net_ip.s_addr >> 16) & 0xFF,
 830                        (net_ip.s_addr >> 24) & 0xFF);
 831
 832                strncpy(tftp_filename, default_filename, DEFAULT_NAME_LEN);
 833                tftp_filename[DEFAULT_NAME_LEN - 1] = 0;
 834
 835                printf("*** Warning: no boot file name; using '%s'\n",
 836                       tftp_filename);
 837        }
 838
 839        if (IS_ENABLED(CONFIG_IPV6)) {
 840                if (use_ip6) {
 841                        char *s, *e;
 842                        size_t len;
 843
 844                        s = strchr(net_boot_file_name, '[');
 845                        e = strchr(net_boot_file_name, ']');
 846                        len = e - s;
 847                        if (s && e) {
 848                                string_to_ip6(s + 1, len - 1, &tftp_remote_ip6);
 849                                strlcpy(tftp_filename, e + 2, MAX_LEN);
 850                        } else {
 851                                strlcpy(tftp_filename, net_boot_file_name, MAX_LEN);
 852                                tftp_filename[MAX_LEN - 1] = 0;
 853                        }
 854                }
 855        }
 856
 857        printf("Using %s device\n", eth_get_name());
 858
 859        if (IS_ENABLED(CONFIG_IPV6) && use_ip6) {
 860                printf("TFTP from server %pI6c; our IP address is %pI6c",
 861                       &tftp_remote_ip6, &net_ip6);
 862
 863                if (tftp_block_size_option > TFTP_MTU_BLOCKSIZE6)
 864                        tftp_block_size_option = TFTP_MTU_BLOCKSIZE6;
 865        } else {
 866                printf("TFTP %s server %pI4; our IP address is %pI4",
 867#ifdef CONFIG_CMD_TFTPPUT
 868               protocol == TFTPPUT ? "to" : "from",
 869#else
 870               "from",
 871#endif
 872               &tftp_remote_ip, &net_ip);
 873        }
 874
 875        /* Check if we need to send across this subnet */
 876        if (IS_ENABLED(CONFIG_IPV6) && use_ip6) {
 877                if (!ip6_addr_in_subnet(&net_ip6, &tftp_remote_ip6,
 878                                        net_prefix_length))
 879                        printf("; sending through gateway %pI6c",
 880                               &net_gateway6);
 881        } else if (net_gateway.s_addr && net_netmask.s_addr) {
 882                struct in_addr our_net;
 883                struct in_addr remote_net;
 884
 885                our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
 886                remote_net.s_addr = tftp_remote_ip.s_addr & net_netmask.s_addr;
 887                if (our_net.s_addr != remote_net.s_addr)
 888                        printf("; sending through gateway %pI4", &net_gateway);
 889        }
 890        putc('\n');
 891
 892        printf("Filename '%s'.", tftp_filename);
 893
 894        if (net_boot_file_expected_size_in_blocks) {
 895                printf(" Size is 0x%x Bytes = ",
 896                       net_boot_file_expected_size_in_blocks << 9);
 897                print_size(net_boot_file_expected_size_in_blocks << 9, "");
 898        }
 899
 900        putc('\n');
 901#ifdef CONFIG_CMD_TFTPPUT
 902        tftp_put_active = (protocol == TFTPPUT);
 903        if (tftp_put_active) {
 904                printf("Save address: 0x%lx\n", image_save_addr);
 905                printf("Save size:    0x%lx\n", image_save_size);
 906                net_boot_file_size = image_save_size;
 907                puts("Saving: *\b");
 908                tftp_state = STATE_SEND_WRQ;
 909                new_transfer();
 910        } else
 911#endif
 912        {
 913                if (tftp_init_load_addr()) {
 914                        eth_halt();
 915                        net_set_state(NETLOOP_FAIL);
 916                        puts("\nTFTP error: ");
 917                        puts("trying to overwrite reserved memory...\n");
 918                        return;
 919                }
 920                printf("Load address: 0x%lx\n", tftp_load_addr);
 921                puts("Loading: *\b");
 922                tftp_state = STATE_SEND_RRQ;
 923        }
 924
 925        time_start = get_timer(0);
 926        timeout_count_max = tftp_timeout_count_max;
 927
 928        net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
 929        net_set_udp_handler(tftp_handler);
 930#ifdef CONFIG_CMD_TFTPPUT
 931        net_set_icmp_handler(icmp_handler);
 932#endif
 933        tftp_remote_port = WELL_KNOWN_PORT;
 934        timeout_count = 0;
 935        /* Use a pseudo-random port unless a specific port is set */
 936        tftp_our_port = 1024 + (get_timer(0) % 3072);
 937
 938#ifdef CONFIG_TFTP_PORT
 939        ep = env_get("tftpdstp");
 940        if (ep != NULL)
 941                tftp_remote_port = simple_strtol(ep, NULL, 10);
 942        ep = env_get("tftpsrcp");
 943        if (ep != NULL)
 944                tftp_our_port = simple_strtol(ep, NULL, 10);
 945#endif
 946        tftp_cur_block = 0;
 947        tftp_windowsize = 1;
 948        tftp_last_nack = 0;
 949        /* zero out server ether in case the server ip has changed */
 950        memset(net_server_ethaddr, 0, 6);
 951        /* Revert tftp_block_size to dflt */
 952        tftp_block_size = TFTP_BLOCK_SIZE;
 953#ifdef CONFIG_TFTP_TSIZE
 954        tftp_tsize = 0;
 955        tftp_tsize_num_hash = 0;
 956#endif
 957
 958        tftp_send();
 959}
 960
 961#ifdef CONFIG_CMD_TFTPSRV
 962void tftp_start_server(void)
 963{
 964        tftp_filename[0] = 0;
 965
 966        if (tftp_init_load_addr()) {
 967                eth_halt();
 968                net_set_state(NETLOOP_FAIL);
 969                puts("\nTFTP error: trying to overwrite reserved memory...\n");
 970                return;
 971        }
 972        printf("Using %s device\n", eth_get_name());
 973        printf("Listening for TFTP transfer on %pI4\n", &net_ip);
 974        printf("Load address: 0x%lx\n", tftp_load_addr);
 975
 976        puts("Loading: *\b");
 977
 978        timeout_count_max = tftp_timeout_count_max;
 979        timeout_count = 0;
 980        timeout_ms = TIMEOUT;
 981        net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
 982
 983        /* Revert tftp_block_size to dflt */
 984        tftp_block_size = TFTP_BLOCK_SIZE;
 985        tftp_cur_block = 0;
 986        tftp_our_port = WELL_KNOWN_PORT;
 987        tftp_windowsize = 1;
 988        tftp_next_ack = tftp_windowsize;
 989
 990#ifdef CONFIG_TFTP_TSIZE
 991        tftp_tsize = 0;
 992        tftp_tsize_num_hash = 0;
 993#endif
 994
 995        tftp_state = STATE_RECV_WRQ;
 996        net_set_udp_handler(tftp_handler);
 997
 998        /* zero out server ether in case the server ip has changed */
 999        memset(net_server_ethaddr, 0, 6);
1000}
1001#endif /* CONFIG_CMD_TFTPSRV */
1002