uboot/common/cmd_net.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * Boot support
  26 */
  27#include <common.h>
  28#include <command.h>
  29#include <net.h>
  30
  31extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
  32
  33static int netboot_common (proto_t, cmd_tbl_t *, int , char *[]);
  34
  35int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  36{
  37        return netboot_common (BOOTP, cmdtp, argc, argv);
  38}
  39
  40U_BOOT_CMD(
  41        bootp,  3,      1,      do_bootp,
  42        "boot image via network using BOOTP/TFTP protocol",
  43        "[loadAddress] [[hostIPaddr:]bootfilename]"
  44);
  45
  46int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  47{
  48        return netboot_common (TFTP, cmdtp, argc, argv);
  49}
  50
  51U_BOOT_CMD(
  52        tftpboot,       3,      1,      do_tftpb,
  53        "boot image via network using TFTP protocol",
  54        "[loadAddress] [[hostIPaddr:]bootfilename]"
  55);
  56
  57int do_rarpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  58{
  59        return netboot_common (RARP, cmdtp, argc, argv);
  60}
  61
  62U_BOOT_CMD(
  63        rarpboot,       3,      1,      do_rarpb,
  64        "boot image via network using RARP/TFTP protocol",
  65        "[loadAddress] [[hostIPaddr:]bootfilename]"
  66);
  67
  68#if defined(CONFIG_CMD_DHCP)
  69int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  70{
  71        return netboot_common(DHCP, cmdtp, argc, argv);
  72}
  73
  74U_BOOT_CMD(
  75        dhcp,   3,      1,      do_dhcp,
  76        "boot image via network using DHCP/TFTP protocol",
  77        "[loadAddress] [[hostIPaddr:]bootfilename]"
  78);
  79#endif
  80
  81#if defined(CONFIG_CMD_NFS)
  82int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  83{
  84        return netboot_common(NFS, cmdtp, argc, argv);
  85}
  86
  87U_BOOT_CMD(
  88        nfs,    3,      1,      do_nfs,
  89        "boot image via network using NFS protocol",
  90        "[loadAddress] [[hostIPaddr:]bootfilename]"
  91);
  92#endif
  93
  94static void netboot_update_env (void)
  95{
  96        char tmp[22];
  97
  98        if (NetOurGatewayIP) {
  99                ip_to_string (NetOurGatewayIP, tmp);
 100                setenv ("gatewayip", tmp);
 101        }
 102
 103        if (NetOurSubnetMask) {
 104                ip_to_string (NetOurSubnetMask, tmp);
 105                setenv ("netmask", tmp);
 106        }
 107
 108        if (NetOurHostName[0])
 109                setenv ("hostname", NetOurHostName);
 110
 111        if (NetOurRootPath[0])
 112                setenv ("rootpath", NetOurRootPath);
 113
 114        if (NetOurIP) {
 115                ip_to_string (NetOurIP, tmp);
 116                setenv ("ipaddr", tmp);
 117        }
 118
 119        if (NetServerIP) {
 120                ip_to_string (NetServerIP, tmp);
 121                setenv ("serverip", tmp);
 122        }
 123
 124        if (NetOurDNSIP) {
 125                ip_to_string (NetOurDNSIP, tmp);
 126                setenv ("dnsip", tmp);
 127        }
 128#if defined(CONFIG_BOOTP_DNS2)
 129        if (NetOurDNS2IP) {
 130                ip_to_string (NetOurDNS2IP, tmp);
 131                setenv ("dnsip2", tmp);
 132        }
 133#endif
 134        if (NetOurNISDomain[0])
 135                setenv ("domain", NetOurNISDomain);
 136
 137#if defined(CONFIG_CMD_SNTP) \
 138    && defined(CONFIG_BOOTP_TIMEOFFSET)
 139        if (NetTimeOffset) {
 140                sprintf (tmp, "%d", NetTimeOffset);
 141                setenv ("timeoffset", tmp);
 142        }
 143#endif
 144#if defined(CONFIG_CMD_SNTP) \
 145    && defined(CONFIG_BOOTP_NTPSERVER)
 146        if (NetNtpServerIP) {
 147                ip_to_string (NetNtpServerIP, tmp);
 148                setenv ("ntpserverip", tmp);
 149        }
 150#endif
 151}
 152
 153static int
 154netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
 155{
 156        char *s;
 157        char *end;
 158        int   rcode = 0;
 159        int   size;
 160        ulong addr;
 161
 162        /* pre-set load_addr */
 163        if ((s = getenv("loadaddr")) != NULL) {
 164                load_addr = simple_strtoul(s, NULL, 16);
 165        }
 166
 167        switch (argc) {
 168        case 1:
 169                break;
 170
 171        case 2: /*
 172                 * Only one arg - accept two forms:
 173                 * Just load address, or just boot file name. The latter
 174                 * form must be written in a format which can not be
 175                 * mis-interpreted as a valid number.
 176                 */
 177                addr = simple_strtoul(argv[1], &end, 16);
 178                if (end == (argv[1] + strlen(argv[1])))
 179                        load_addr = addr;
 180                else
 181                        copy_filename(BootFile, argv[1], sizeof(BootFile));
 182                break;
 183
 184        case 3: load_addr = simple_strtoul(argv[1], NULL, 16);
 185                copy_filename (BootFile, argv[2], sizeof(BootFile));
 186
 187                break;
 188
 189        default: cmd_usage(cmdtp);
 190                show_boot_progress (-80);
 191                return 1;
 192        }
 193
 194        show_boot_progress (80);
 195        if ((size = NetLoop(proto)) < 0) {
 196                show_boot_progress (-81);
 197                return 1;
 198        }
 199
 200        show_boot_progress (81);
 201        /* NetLoop ok, update environment */
 202        netboot_update_env();
 203
 204        /* done if no file was loaded (no errors though) */
 205        if (size == 0) {
 206                show_boot_progress (-82);
 207                return 0;
 208        }
 209
 210        /* flush cache */
 211        flush_cache(load_addr, size);
 212
 213        /* Loading ok, check if we should attempt an auto-start */
 214        if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
 215                char *local_args[2];
 216                local_args[0] = argv[0];
 217                local_args[1] = NULL;
 218
 219                printf ("Automatic boot of image at addr 0x%08lX ...\n",
 220                        load_addr);
 221                show_boot_progress (82);
 222                rcode = do_bootm (cmdtp, 0, 1, local_args);
 223        }
 224
 225        if (rcode < 0)
 226                show_boot_progress (-83);
 227        else
 228                show_boot_progress (84);
 229        return rcode;
 230}
 231
 232#if defined(CONFIG_CMD_PING)
 233int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 234{
 235        if (argc < 2)
 236                return -1;
 237
 238        NetPingIP = string_to_ip(argv[1]);
 239        if (NetPingIP == 0) {
 240                cmd_usage(cmdtp);
 241                return -1;
 242        }
 243
 244        if (NetLoop(PING) < 0) {
 245                printf("ping failed; host %s is not alive\n", argv[1]);
 246                return 1;
 247        }
 248
 249        printf("host %s is alive\n", argv[1]);
 250
 251        return 0;
 252}
 253
 254U_BOOT_CMD(
 255        ping,   2,      1,      do_ping,
 256        "send ICMP ECHO_REQUEST to network host",
 257        "pingAddress"
 258);
 259#endif
 260
 261#if defined(CONFIG_CMD_CDP)
 262
 263static void cdp_update_env(void)
 264{
 265        char tmp[16];
 266
 267        if (CDPApplianceVLAN != htons(-1)) {
 268                printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
 269                VLAN_to_string(CDPApplianceVLAN, tmp);
 270                setenv("vlan", tmp);
 271                NetOurVLAN = CDPApplianceVLAN;
 272        }
 273
 274        if (CDPNativeVLAN != htons(-1)) {
 275                printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
 276                VLAN_to_string(CDPNativeVLAN, tmp);
 277                setenv("nvlan", tmp);
 278                NetOurNativeVLAN = CDPNativeVLAN;
 279        }
 280
 281}
 282
 283int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 284{
 285        int r;
 286
 287        r = NetLoop(CDP);
 288        if (r < 0) {
 289                printf("cdp failed; perhaps not a CISCO switch?\n");
 290                return 1;
 291        }
 292
 293        cdp_update_env();
 294
 295        return 0;
 296}
 297
 298U_BOOT_CMD(
 299        cdp,    1,      1,      do_cdp,
 300        "Perform CDP network configuration",
 301);
 302#endif
 303
 304#if defined(CONFIG_CMD_SNTP)
 305int do_sntp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 306{
 307        char *toff;
 308
 309        if (argc < 2) {
 310                NetNtpServerIP = getenv_IPaddr ("ntpserverip");
 311                if (NetNtpServerIP == 0) {
 312                        printf ("ntpserverip not set\n");
 313                        return (1);
 314                }
 315        } else {
 316                NetNtpServerIP = string_to_ip(argv[1]);
 317                if (NetNtpServerIP == 0) {
 318                        printf ("Bad NTP server IP address\n");
 319                        return (1);
 320                }
 321        }
 322
 323        toff = getenv ("timeoffset");
 324        if (toff == NULL) NetTimeOffset = 0;
 325        else NetTimeOffset = simple_strtol (toff, NULL, 10);
 326
 327        if (NetLoop(SNTP) < 0) {
 328                printf("SNTP failed: host %s not responding\n", argv[1]);
 329                return 1;
 330        }
 331
 332        return 0;
 333}
 334
 335U_BOOT_CMD(
 336        sntp,   2,      1,      do_sntp,
 337        "synchronize RTC via network",
 338        "[NTP server IP]\n"
 339);
 340#endif
 341
 342#if defined(CONFIG_CMD_DNS)
 343int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 344{
 345        if (argc == 1) {
 346                cmd_usage(cmdtp);
 347                return -1;
 348        }
 349
 350        /*
 351         * We should check for a valid hostname:
 352         * - Each label must be between 1 and 63 characters long
 353         * - the entire hostname has a maximum of 255 characters
 354         * - only the ASCII letters 'a' through 'z' (case-insensitive),
 355         *   the digits '0' through '9', and the hyphen
 356         * - cannot begin or end with a hyphen
 357         * - no other symbols, punctuation characters, or blank spaces are
 358         *   permitted
 359         * but hey - this is a minimalist implmentation, so only check length
 360         * and let the name server deal with things.
 361         */
 362        if (strlen(argv[1]) >= 255) {
 363                printf("dns error: hostname too long\n");
 364                return 1;
 365        }
 366
 367        NetDNSResolve = argv[1];
 368
 369        if (argc == 3)
 370                NetDNSenvvar = argv[2];
 371        else
 372                NetDNSenvvar = NULL;
 373
 374        if (NetLoop(DNS) < 0) {
 375                printf("dns lookup of %s failed, check setup\n", argv[1]);
 376                return 1;
 377        }
 378
 379        return 0;
 380}
 381
 382U_BOOT_CMD(
 383        dns,    3,      1,      do_dns,
 384        "lookup the IP of a hostname",
 385        "hostname [envvar]"
 386);
 387
 388#endif  /* CONFIG_CMD_DNS */
 389