Annotation of qemu/roms/SLOF/clients/net-snk/app/netapps/netboot.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.