|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: #include <netlib/tftp.h> ! 14: #include <netlib/ethernet.h> ! 15: #include <netlib/dhcp.h> ! 16: //#include <netlib/dhcpv6.h> ! 17: #include <netlib/ipv4.h> ! 18: //#include <netlib/ipv6.h> ! 19: #include <string.h> ! 20: #include <stdio.h> ! 21: #include <time.h> ! 22: #include <stdlib.h> ! 23: #include <sys/socket.h> ! 24: #include <netapps/args.h> ! 25: #include <libbootmsg/libbootmsg.h> ! 26: #include <of.h> ! 27: ! 28: #define IP_INIT_DEFAULT 2 ! 29: #define IP_INIT_NONE 0 ! 30: #define IP_INIT_BOOTP 1 ! 31: #define IP_INIT_DHCP 2 ! 32: #define IP_INIT_DHCPV6_STATELESS 3 ! 33: #define IP_INIT_IPV6_MANUAL 4 ! 34: ! 35: #define DEFAULT_BOOT_RETRIES 600 ! 36: #define DEFAULT_TFTP_RETRIES 20 ! 37: static int ip_version = 4; ! 38: ! 39: typedef struct { ! 40: char filename[100]; ! 41: int ip_init; ! 42: char siaddr[4]; ! 43: //ip6_addr_t si6addr; ! 44: char ciaddr[4]; ! 45: //ip6_addr_t ci6addr; ! 46: char giaddr[4]; ! 47: //ip6_addr_t gi6addr; ! 48: int bootp_retries; ! 49: int tftp_retries; ! 50: } obp_tftp_args_t; ! 51: ! 52: ! 53: /** ! 54: * Parses a argument string for IPv6 booting, extracts all ! 55: * parameters and fills a structure accordingly ! 56: * ! 57: * @param arg_str string with arguments, seperated with ',' ! 58: * @param argc number of arguments ! 59: * @param obp_tftp_args structure which contains the result ! 60: * @return updated arg_str ! 61: */ ! 62: /* ! 63: static const char * ! 64: parse_ipv6args (const char *arg_str, unsigned int argc, ! 65: obp_tftp_args_t *obp_tftp_args) ! 66: { ! 67: char *ptr = NULL; ! 68: char arg_buf[100]; ! 69: ! 70: // find out siaddr ! 71: if (argc == 0) ! 72: memset(&obp_tftp_args->si6addr.addr, 0, 16); ! 73: else { ! 74: argncpy(arg_str, 0, arg_buf, 100); ! 75: if(parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->si6addr.addr[0]))) { ! 76: arg_str = get_arg_ptr(arg_str, 1); ! 77: --argc; ! 78: } ! 79: else if(arg_buf[0] == 0) { ! 80: memset(&obp_tftp_args->si6addr.addr, 0, 16); ! 81: arg_str = get_arg_ptr(arg_str, 1); ! 82: --argc; ! 83: } ! 84: else ! 85: memset(&obp_tftp_args->si6addr.addr, 0, 16); ! 86: } ! 87: ! 88: // find out filename ! 89: if (argc == 0) ! 90: obp_tftp_args->filename[0] = 0; ! 91: else { ! 92: argncpy(arg_str, 0, obp_tftp_args->filename, 100); ! 93: for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr) ! 94: if(*ptr == '\\') { ! 95: *ptr = '/'; ! 96: } ! 97: arg_str = get_arg_ptr(arg_str, 1); ! 98: --argc; ! 99: } ! 100: ! 101: // find out ciaddr ! 102: if (argc == 0) ! 103: memset(&obp_tftp_args->ci6addr, 0, 16); ! 104: else { ! 105: argncpy(arg_str, 0, arg_buf, 100); ! 106: if (parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->ci6addr.addr)) ) { ! 107: arg_str = get_arg_ptr(arg_str, 1); ! 108: --argc; ! 109: } ! 110: else if(arg_buf[0] == 0) { ! 111: memset(&obp_tftp_args->ci6addr.addr, 0, 16); ! 112: arg_str = get_arg_ptr(arg_str, 1); ! 113: --argc; ! 114: } ! 115: else ! 116: memset(&obp_tftp_args->ci6addr.addr, 0, 16); ! 117: } ! 118: ! 119: // find out giaddr ! 120: if (argc == 0) ! 121: memset(&obp_tftp_args->gi6addr, 0, 16); ! 122: else { ! 123: argncpy(arg_str, 0, arg_buf, 100); ! 124: if (parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->gi6addr.addr)) ) { ! 125: arg_str = get_arg_ptr(arg_str, 1); ! 126: --argc; ! 127: } ! 128: else if(arg_buf[0] == 0) { ! 129: memset(&obp_tftp_args->gi6addr, 0, 16); ! 130: arg_str = get_arg_ptr(arg_str, 1); ! 131: --argc; ! 132: } ! 133: else ! 134: memset(&obp_tftp_args->gi6addr.addr, 0, 16); ! 135: } ! 136: ! 137: return arg_str; ! 138: } ! 139: */ ! 140: ! 141: ! 142: /** ! 143: * Parses a argument string for IPv4 booting, extracts all ! 144: * parameters and fills a structure accordingly ! 145: * ! 146: * @param arg_str string with arguments, seperated with ',' ! 147: * @param argc number of arguments ! 148: * @param obp_tftp_args structure which contains the result ! 149: * @return updated arg_str ! 150: */ ! 151: static const char * ! 152: parse_ipv4args (const char *arg_str, unsigned int argc, ! 153: obp_tftp_args_t *obp_tftp_args) ! 154: { ! 155: char *ptr = NULL; ! 156: char arg_buf[100]; ! 157: ! 158: // find out siaddr ! 159: if(argc==0) { ! 160: memset(obp_tftp_args->siaddr, 0, 4); ! 161: } else { ! 162: argncpy(arg_str, 0, arg_buf, 100); ! 163: if(strtoip(arg_buf, obp_tftp_args->siaddr)) { ! 164: arg_str = get_arg_ptr(arg_str, 1); ! 165: --argc; ! 166: } ! 167: else if(arg_buf[0] == 0) { ! 168: memset(obp_tftp_args->siaddr, 0, 4); ! 169: arg_str = get_arg_ptr(arg_str, 1); ! 170: --argc; ! 171: } ! 172: else ! 173: memset(obp_tftp_args->siaddr, 0, 4); ! 174: } ! 175: ! 176: // find out filename ! 177: if(argc==0) ! 178: obp_tftp_args->filename[0] = 0; ! 179: else { ! 180: argncpy(arg_str, 0, obp_tftp_args->filename, 100); ! 181: for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr) ! 182: if(*ptr == '\\') ! 183: *ptr = '/'; ! 184: arg_str = get_arg_ptr(arg_str, 1); ! 185: --argc; ! 186: } ! 187: ! 188: // find out ciaddr ! 189: if(argc==0) ! 190: memset(obp_tftp_args->ciaddr, 0, 4); ! 191: else { ! 192: argncpy(arg_str, 0, arg_buf, 100); ! 193: if(strtoip(arg_buf, obp_tftp_args->ciaddr)) { ! 194: arg_str = get_arg_ptr(arg_str, 1); ! 195: --argc; ! 196: } ! 197: else if(arg_buf[0] == 0) { ! 198: memset(obp_tftp_args->ciaddr, 0, 4); ! 199: arg_str = get_arg_ptr(arg_str, 1); ! 200: --argc; ! 201: } ! 202: else ! 203: memset(obp_tftp_args->ciaddr, 0, 4); ! 204: } ! 205: ! 206: // find out giaddr ! 207: if(argc==0) ! 208: memset(obp_tftp_args->giaddr, 0, 4); ! 209: else { ! 210: argncpy(arg_str, 0, arg_buf, 100); ! 211: if(strtoip(arg_buf, obp_tftp_args->giaddr)) { ! 212: arg_str = get_arg_ptr(arg_str, 1); ! 213: --argc; ! 214: } ! 215: else if(arg_buf[0] == 0) { ! 216: memset(obp_tftp_args->giaddr, 0, 4); ! 217: arg_str = get_arg_ptr(arg_str, 1); ! 218: --argc; ! 219: } ! 220: else ! 221: memset(obp_tftp_args->giaddr, 0, 4); ! 222: } ! 223: ! 224: return arg_str; ! 225: } ! 226: ! 227: /** ! 228: * Parses a argument string which is given by netload, extracts all ! 229: * parameters and fills a structure according to this ! 230: * ! 231: * Netload-Parameters: ! 232: * [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries ! 233: * ! 234: * @param arg_str string with arguments, seperated with ',' ! 235: * @param obp_tftp_args structure which contains the result ! 236: * @return none ! 237: */ ! 238: static void ! 239: parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) ! 240: { ! 241: unsigned int argc; ! 242: char arg_buf[100]; ! 243: ! 244: argc = get_args_count(arg_str); ! 245: ! 246: // find out if we should use BOOTP or DHCP ! 247: if(argc==0) ! 248: obp_tftp_args->ip_init = IP_INIT_DEFAULT; ! 249: else { ! 250: argncpy(arg_str, 0, arg_buf, 100); ! 251: if (strcasecmp(arg_buf, "bootp") == 0) { ! 252: obp_tftp_args->ip_init = IP_INIT_BOOTP; ! 253: arg_str = get_arg_ptr(arg_str, 1); ! 254: --argc; ! 255: } ! 256: else if(strcasecmp(arg_buf, "dhcp") == 0) { ! 257: obp_tftp_args->ip_init = IP_INIT_DHCP; ! 258: arg_str = get_arg_ptr(arg_str, 1); ! 259: --argc; ! 260: } ! 261: else if(strcasecmp(arg_buf, "ipv6") == 0) { ! 262: obp_tftp_args->ip_init = IP_INIT_DHCPV6_STATELESS; ! 263: arg_str = get_arg_ptr(arg_str, 1); ! 264: --argc; ! 265: ip_version = 6; ! 266: } ! 267: else ! 268: obp_tftp_args->ip_init = IP_INIT_DEFAULT; ! 269: } ! 270: ! 271: if (ip_version == 4) { ! 272: arg_str = parse_ipv4args (arg_str, argc, obp_tftp_args); ! 273: } ! 274: /* ! 275: else if (ip_version == 6) { ! 276: arg_str = parse_ipv6args (arg_str, argc, obp_tftp_args); ! 277: } ! 278: */ ! 279: ! 280: // find out bootp-retries ! 281: if (argc == 0) ! 282: obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; ! 283: else { ! 284: argncpy(arg_str, 0, arg_buf, 100); ! 285: if(arg_buf[0] == 0) ! 286: obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; ! 287: else { ! 288: obp_tftp_args->bootp_retries = strtol(arg_buf, 0, 10); ! 289: if(obp_tftp_args->bootp_retries < 0) ! 290: obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; ! 291: } ! 292: arg_str = get_arg_ptr(arg_str, 1); ! 293: --argc; ! 294: } ! 295: ! 296: // find out tftp-retries ! 297: if (argc == 0) ! 298: obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; ! 299: else { ! 300: argncpy(arg_str, 0, arg_buf, 100); ! 301: if(arg_buf[0] == 0) ! 302: obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; ! 303: else { ! 304: obp_tftp_args->tftp_retries = strtol(arg_buf, 0, 10); ! 305: if(obp_tftp_args->tftp_retries < 0) ! 306: obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; ! 307: } ! 308: arg_str = get_arg_ptr(arg_str, 1); ! 309: --argc; ! 310: } ! 311: } ! 312: ! 313: int ! 314: netboot(int argc, char *argv[]) ! 315: { ! 316: char buf[256]; ! 317: int rc; ! 318: int len = strtol(argv[2], 0, 16); ! 319: char *buffer = (char *) strtol(argv[1], 0, 16); ! 320: char *ret_buffer = (char *) strtol(argv[3], 0, 16); ! 321: filename_ip_t fn_ip; ! 322: int fd_device; ! 323: tftp_err_t tftp_err; ! 324: obp_tftp_args_t obp_tftp_args; ! 325: char null_ip[4] = { 0x00, 0x00, 0x00, 0x00 }; ! 326: /* ! 327: char null_ip6[16] = { 0x00, 0x00, 0x00, 0x00, ! 328: 0x00, 0x00, 0x00, 0x00, ! 329: 0x00, 0x00, 0x00, 0x00, ! 330: 0x00, 0x00, 0x00, 0x00 }; ! 331: */ ! 332: int huge_load = strtol(argv[4], 0, 10); ! 333: int32_t block_size = strtol(argv[5], 0, 10); ! 334: uint8_t own_mac[6]; ! 335: ! 336: printf("\n"); ! 337: printf(" Bootloader 1.6 \n"); ! 338: memset(&fn_ip, 0, sizeof(filename_ip_t)); ! 339: ! 340: /*********************************************************** ! 341: * ! 342: * Initialize network stuff and retrieve boot informations ! 343: * ! 344: ***********************************************************/ ! 345: ! 346: /* Wait for link up and get mac_addr from device */ ! 347: for(rc=0; rc<DEFAULT_BOOT_RETRIES; ++rc) { ! 348: if(rc > 0) { ! 349: set_timer(TICKS_SEC); ! 350: while (get_timer() > 0); ! 351: } ! 352: fd_device = socket(0, 0, 0, (char*) own_mac); ! 353: if(fd_device != -2) ! 354: break; ! 355: if(getchar() == 27) { ! 356: fd_device = -2; ! 357: break; ! 358: } ! 359: } ! 360: ! 361: if (fd_device == -1) { ! 362: strcpy(buf,"E3000: (net) Could not read MAC address"); ! 363: bootmsg_error(0x3000, &buf[7]); ! 364: ! 365: write_mm_log(buf, strlen(buf), 0x91); ! 366: return -100; ! 367: } ! 368: else if (fd_device == -2) { ! 369: strcpy(buf,"E3006: (net) Could not initialize network device"); ! 370: bootmsg_error(0x3006, &buf[7]); ! 371: ! 372: write_mm_log(buf, strlen(buf), 0x91); ! 373: return -101; ! 374: } ! 375: ! 376: printf(" Reading MAC address from device: " ! 377: "%02x:%02x:%02x:%02x:%02x:%02x\n", ! 378: own_mac[0], own_mac[1], own_mac[2], ! 379: own_mac[3], own_mac[4], own_mac[5]); ! 380: ! 381: // init ethernet layer ! 382: set_mac_address(own_mac); ! 383: ! 384: if (argc > 6) { ! 385: parse_args(argv[6], &obp_tftp_args); ! 386: if(obp_tftp_args.bootp_retries - rc < DEFAULT_BOOT_RETRIES) ! 387: obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES; ! 388: else ! 389: obp_tftp_args.bootp_retries -= rc; ! 390: } ! 391: else { ! 392: memset(&obp_tftp_args, 0, sizeof(obp_tftp_args_t)); ! 393: obp_tftp_args.ip_init = IP_INIT_DEFAULT; ! 394: obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES; ! 395: obp_tftp_args.tftp_retries = DEFAULT_TFTP_RETRIES; ! 396: } ! 397: memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); ! 398: ! 399: // reset of error code ! 400: rc = 0; ! 401: ! 402: /* if we still have got all necessary parameters, then we don't ! 403: need to perform an BOOTP/DHCP-Request */ ! 404: if (ip_version == 4) { ! 405: if (memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 ! 406: && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 ! 407: && obp_tftp_args.filename[0] != 0) { ! 408: ! 409: memcpy(&fn_ip.server_ip, &obp_tftp_args.siaddr, 4); ! 410: obp_tftp_args.ip_init = IP_INIT_NONE; ! 411: } ! 412: } ! 413: /* ! 414: else if (ip_version == 6) { ! 415: if (memcmp(&obp_tftp_args.ci6addr, null_ip6, 16) != 0 ! 416: && memcmp(&obp_tftp_args.si6addr, null_ip6, 16) != 0 ! 417: && obp_tftp_args.filename[0] != 0) { ! 418: ! 419: memcpy(&fn_ip.server_ip6.addr[0], ! 420: &obp_tftp_args.si6addr.addr, 16); ! 421: obp_tftp_args.ip_init = IP_INIT_IPV6_MANUAL; ! 422: } ! 423: else { ! 424: obp_tftp_args.ip_init = IP_INIT_DHCPV6_STATELESS; ! 425: } ! 426: } ! 427: */ ! 428: // construction of fn_ip from parameter ! 429: switch(obp_tftp_args.ip_init) { ! 430: case IP_INIT_BOOTP: ! 431: printf(" Requesting IP address via BOOTP: "); ! 432: // if giaddr in not specified, then we have to identify ! 433: // the BOOTP server via broadcasts ! 434: if(memcmp(obp_tftp_args.giaddr, null_ip, 4) == 0) { ! 435: // don't do this, when using DHCP !!! ! 436: fn_ip.server_ip = 0xFFFFFFFF; ! 437: } ! 438: // if giaddr is specified, then we have to use this ! 439: // IP address as proxy to identify the BOOTP server ! 440: else { ! 441: memcpy(&fn_ip.server_ip, obp_tftp_args.giaddr, 4); ! 442: } ! 443: rc = bootp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); ! 444: break; ! 445: case IP_INIT_DHCP: ! 446: printf(" Requesting IP address via DHCP: "); ! 447: rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); ! 448: break; ! 449: /* ! 450: case IP_INIT_DHCPV6_STATELESS: ! 451: set_ipv6_address(0); ! 452: rc = do_dhcpv6 (ret_buffer, &fn_ip, 10, DHCPV6_STATELESS); ! 453: break; ! 454: case IP_INIT_IPV6_MANUAL: ! 455: set_ipv6_address(&obp_tftp_args.ci6addr); ! 456: break; ! 457: */ ! 458: case IP_INIT_NONE: ! 459: default: ! 460: break; ! 461: } ! 462: ! 463: if(rc >= 0 && ip_version == 4) { ! 464: if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 ! 465: && memcmp(obp_tftp_args.ciaddr, &fn_ip.own_ip, 4) != 0) ! 466: memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); ! 467: ! 468: if(memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 ! 469: && memcmp(obp_tftp_args.siaddr, &fn_ip.server_ip, 4) != 0) ! 470: memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4); ! 471: ! 472: // init IPv4 layer ! 473: set_ipv4_address(fn_ip.own_ip); ! 474: } ! 475: /* ! 476: else if (rc >= 0 && ip_version == 6) { ! 477: if(memcmp(&obp_tftp_args.ci6addr.addr, null_ip6, 16) != 0 ! 478: && memcmp(&obp_tftp_args.ci6addr.addr, &fn_ip.own_ip6, 16) != 0) ! 479: memcpy(&fn_ip.own_ip6, &obp_tftp_args.ci6addr.addr, 16); ! 480: ! 481: if(memcmp(&obp_tftp_args.si6addr.addr, null_ip6, 16) != 0 ! 482: && memcmp(&obp_tftp_args.si6addr.addr, &fn_ip.server_ip6.addr, 16) != 0) ! 483: memcpy(&fn_ip.server_ip6.addr, &obp_tftp_args.si6addr.addr, 16); ! 484: } ! 485: */ ! 486: if (rc == -1) { ! 487: strcpy(buf,"E3001: (net) Could not get IP address"); ! 488: bootmsg_error(0x3001, &buf[7]); ! 489: ! 490: write_mm_log(buf, strlen(buf), 0x91); ! 491: return -101; ! 492: } ! 493: ! 494: printf("%d.%d.%d.%d\n", ! 495: ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF), ! 496: ((fn_ip.own_ip >> 8) & 0xFF), ( fn_ip.own_ip & 0xFF)); ! 497: ! 498: if (rc == -2) { ! 499: sprintf(buf, ! 500: "E3002: (net) ARP request to TFTP server " ! 501: "(%d.%d.%d.%d) failed", ! 502: ((fn_ip.server_ip >> 24) & 0xFF), ! 503: ((fn_ip.server_ip >> 16) & 0xFF), ! 504: ((fn_ip.server_ip >> 8) & 0xFF), ! 505: ( fn_ip.server_ip & 0xFF)); ! 506: bootmsg_error(0x3002, &buf[7]); ! 507: ! 508: write_mm_log(buf, strlen(buf), 0x91); ! 509: return -102; ! 510: } ! 511: if (rc == -4 || rc == -3) { ! 512: strcpy(buf,"E3008: (net) Can't obtain TFTP server IP address"); ! 513: bootmsg_error(0x3008, &buf[7]); ! 514: ! 515: write_mm_log(buf, strlen(buf), 0x91); ! 516: return -107; ! 517: } ! 518: ! 519: ! 520: /*********************************************************** ! 521: * ! 522: * Load file via TFTP into buffer provided by OpenFirmware ! 523: * ! 524: ***********************************************************/ ! 525: ! 526: if (obp_tftp_args.filename[0] != 0) { ! 527: strncpy((char *) fn_ip.filename, obp_tftp_args.filename, sizeof(fn_ip.filename)-1); ! 528: fn_ip.filename[sizeof(fn_ip.filename)-1] = 0; ! 529: } ! 530: ! 531: printf(" Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n", ! 532: fn_ip.filename, ! 533: ((fn_ip.server_ip >> 24) & 0xFF), ! 534: ((fn_ip.server_ip >> 16) & 0xFF), ! 535: ((fn_ip.server_ip >> 8) & 0xFF), ! 536: ( fn_ip.server_ip & 0xFF)); ! 537: ! 538: // accept at most 20 bad packets ! 539: // wait at most for 40 packets ! 540: rc = tftp(&fn_ip, (unsigned char *) buffer, ! 541: len, obp_tftp_args.tftp_retries, ! 542: &tftp_err, huge_load, block_size, ip_version); ! 543: ! 544: if(obp_tftp_args.ip_init == IP_INIT_DHCP) ! 545: dhcp_send_release(); ! 546: ! 547: if (rc > 0) { ! 548: printf(" TFTP: Received %s (%d KBytes)\n", fn_ip.filename, ! 549: rc / 1024); ! 550: } else if (rc == -1) { ! 551: bootmsg_error(0x3003, "(net) unknown TFTP error"); ! 552: return -103; ! 553: } else if (rc == -2) { ! 554: sprintf(buf, ! 555: "E3004: (net) TFTP buffer of %d bytes " ! 556: "is too small for %s", ! 557: len, fn_ip.filename); ! 558: bootmsg_error(0x3004, &buf[7]); ! 559: ! 560: write_mm_log(buf, strlen(buf), 0x91); ! 561: return -104; ! 562: } else if (rc == -3) { ! 563: sprintf(buf,"E3009: (net) file not found: %s", ! 564: fn_ip.filename); ! 565: bootmsg_error(0x3009, &buf[7]); ! 566: ! 567: write_mm_log(buf, strlen(buf), 0x91); ! 568: return -108; ! 569: } else if (rc == -4) { ! 570: strcpy(buf,"E3010: (net) TFTP access violation"); ! 571: bootmsg_error(0x3010, &buf[7]); ! 572: ! 573: write_mm_log(buf, strlen(buf), 0x91); ! 574: return -109; ! 575: } else if (rc == -5) { ! 576: strcpy(buf,"E3011: (net) illegal TFTP operation"); ! 577: bootmsg_error(0x3011, &buf[7]); ! 578: ! 579: write_mm_log(buf, strlen(buf), 0x91); ! 580: return -110; ! 581: } else if (rc == -6) { ! 582: strcpy(buf, "E3012: (net) unknown TFTP transfer ID"); ! 583: bootmsg_error(0x3012, &buf[7]); ! 584: ! 585: write_mm_log(buf, strlen(buf), 0x91); ! 586: return -111; ! 587: } else if (rc == -7) { ! 588: strcpy(buf, "E3013: (net) no such TFTP user"); ! 589: bootmsg_error(0x3013, &buf[7]); ! 590: ! 591: write_mm_log(buf, strlen(buf), 0x91); ! 592: return -112; ! 593: } else if (rc == -8) { ! 594: strcpy(buf, "E3017: (net) TFTP blocksize negotiation failed"); ! 595: bootmsg_error(0x3017, &buf[7]); ! 596: ! 597: write_mm_log(buf, strlen(buf), 0x91); ! 598: return -116; ! 599: } else if (rc == -9) { ! 600: strcpy(buf,"E3018: (net) file exceeds maximum TFTP transfer size"); ! 601: bootmsg_error(0x3018, &buf[7]); ! 602: ! 603: write_mm_log(buf, strlen(buf), 0x91); ! 604: return -117; ! 605: } else if (rc <= -10 && rc >= -15) { ! 606: sprintf(buf,"E3005: (net) ICMP ERROR \""); ! 607: switch (rc) { ! 608: case -ICMP_NET_UNREACHABLE - 10: ! 609: sprintf(buf+strlen(buf),"net unreachable"); ! 610: break; ! 611: case -ICMP_HOST_UNREACHABLE - 10: ! 612: sprintf(buf+strlen(buf),"host unreachable"); ! 613: break; ! 614: case -ICMP_PROTOCOL_UNREACHABLE - 10: ! 615: sprintf(buf+strlen(buf),"protocol unreachable"); ! 616: break; ! 617: case -ICMP_PORT_UNREACHABLE - 10: ! 618: sprintf(buf+strlen(buf),"port unreachable"); ! 619: break; ! 620: case -ICMP_FRAGMENTATION_NEEDED - 10: ! 621: sprintf(buf+strlen(buf),"fragmentation needed and DF set"); ! 622: break; ! 623: case -ICMP_SOURCE_ROUTE_FAILED - 10: ! 624: sprintf(buf+strlen(buf),"source route failed"); ! 625: break; ! 626: default: ! 627: sprintf(buf+strlen(buf)," UNKNOWN"); ! 628: break; ! 629: } ! 630: sprintf(buf+strlen(buf),"\""); ! 631: bootmsg_error(0x3005, &buf[7]); ! 632: ! 633: write_mm_log(buf, strlen(buf), 0x91); ! 634: return -105; ! 635: } else if (rc == -40) { ! 636: sprintf(buf, ! 637: "E3014: (net) TFTP error occurred after " ! 638: "%d bad packets received", ! 639: tftp_err.bad_tftp_packets); ! 640: bootmsg_error(0x3014, &buf[7]); ! 641: write_mm_log(buf, strlen(buf), 0x91); ! 642: return -113; ! 643: } else if (rc == -41) { ! 644: sprintf(buf, ! 645: "E3015: (net) TFTP error occurred after " ! 646: "missing %d responses", ! 647: tftp_err.no_packets); ! 648: bootmsg_error(0x3015, &buf[7]); ! 649: write_mm_log(buf, strlen(buf), 0x91); ! 650: return -114; ! 651: } else if (rc == -42) { ! 652: sprintf(buf, ! 653: "E3016: (net) TFTP error missing block %d, " ! 654: "expected block was %d", ! 655: tftp_err.blocks_missed, ! 656: tftp_err.blocks_received); ! 657: bootmsg_error(0x3016, &buf[7]); ! 658: write_mm_log(buf, strlen(buf), 0x91); ! 659: return -115; ! 660: } ! 661: return rc; ! 662: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.