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

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

unix.superglobalmegacorp.com

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