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