|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.