aboutsummaryrefslogtreecommitdiff
path: root/clients/net-snk/app/netapps/netflash.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/net-snk/app/netapps/netflash.c')
-rw-r--r--clients/net-snk/app/netapps/netflash.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/clients/net-snk/app/netapps/netflash.c b/clients/net-snk/app/netapps/netflash.c
new file mode 100644
index 0000000..6865ecb
--- /dev/null
+++ b/clients/net-snk/app/netapps/netflash.c
@@ -0,0 +1,187 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <netlib/tftp.h>
+#include <netlib/dhcp.h>
+#include <netlib/ethernet.h>
+#include <netlib/ipv4.h>
+#include <rtas.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+
+int netflash(int argc, char * argv[])
+{
+ char buf[256];
+ int rc;
+ int manage_mode = 0;
+ static int len = 0x800000; //max flash size
+ char * buffer = NULL;
+ short arp_failed = 0;
+ filename_ip_t fn_ip;
+ int fd_device;
+ tftp_err_t tftp_err;
+ char * ptr;
+ uint8_t own_mac[6];
+
+ printf("\n Flasher 1.4 \n");
+ memset(&fn_ip, 0, sizeof(filename_ip_t));
+
+ if (argc == 3 && argv[2][0] == '-' && argv[2][1] == 'c' && argv[2][2] == 0)
+ manage_mode = 1;
+ else if (argc == 3 &&
+ argv[2][0] == '-' && argv[2][1] == 'r' && argv[2][2] == 0)
+ manage_mode = 1;
+ else if (argc == 4 &&
+ argv[2][0] == '-' && argv[2][1] == 'f' && argv[2][2] == 0)
+ {
+ manage_mode = 0;
+ buffer = (char *)strtol(argv[1],0,16);
+ if ((long)buffer == -1) {
+ printf(" Bad buffer address. Exiting...\n");
+ return -1;
+ }
+ }
+ else
+ {
+ printf(" Usage: netflash [options] [<filename>]\n");
+ printf(" Options:\n");
+ printf(" -f <filename> flash temporary image\n");
+ printf(" -c commit temporary image\n");
+ printf(" -r reject temporary image\n");
+ printf(" Bad arguments. Exiting...\n\n");
+ return -1;
+ }
+
+ if (manage_mode == 1) {
+ if (argv[2][1] == 99)
+ return rtas_ibm_manage_flash(1);
+ else
+ return rtas_ibm_manage_flash(0);
+ }
+
+ /* Get mac_addr from device */
+ printf(" Reading MAC address from device: ");
+ fd_device = socket(0, 0, 0, (char *) own_mac);
+ if (fd_device == -1) {
+ printf("\nE3000: Could not read MAC address\n");
+ return -100;
+ }
+ else if (fd_device == -2) {
+ printf("\nE3006: Could not initialize network device\n");
+ return -101;
+ }
+
+ printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+ own_mac[0], own_mac[1], own_mac[2],
+ own_mac[3], own_mac[4], own_mac[5]);
+
+ // init ethernet layer
+ set_mac_address(own_mac);
+
+ // identify the BOOTP/DHCP server via broadcasts
+ // don't do this, when using DHCP !!!
+ // fn_ip.server_ip = 0xFFFFFFFF;
+ // memset(fn_ip.server_mac, 0xff, 6);
+
+ /* Get ip address for our mac address */
+ printf(" Requesting IP address via DHCP: ");
+ arp_failed = dhcp(0, &fn_ip, 30);
+
+ if(arp_failed >= 0) {
+ // reinit network stack
+ set_ipv4_address(fn_ip.own_ip);
+ }
+
+ if (arp_failed == -1) {
+ printf("\n DHCP: Could not get ip address\n");
+ return 1;
+ }
+
+ if (arp_failed == -2) {
+ sprintf
+ (buf,"\n ARP request to TFTP server (%d.%d.%d.%d) failed",
+ ((fn_ip.server_ip >> 24) & 0xFF), ((fn_ip.server_ip >> 16) & 0xFF),
+ ((fn_ip.server_ip >> 8) & 0xFF), ( fn_ip.server_ip & 0xFF));
+ return 1;
+ }
+
+ printf("%d.%d.%d.%d\n",
+ ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF),
+ ((fn_ip.own_ip >> 8) & 0xFF), (fn_ip.own_ip & 0xFF));
+
+ /* Load file via TFTP into buffer provided by OpenFirmware */
+
+ for(ptr = argv[3]; *ptr != 0; ++ptr)
+ if(*ptr == '\\')
+ *ptr = '/';
+
+ printf(" Requesting file \"%s\" via TFTP\n",argv[3]);
+
+ strcpy((char *) fn_ip.filename,argv[3]);
+
+ rc = tftp(&fn_ip, (unsigned char*) buffer, len, 20, &tftp_err, 0, 512, 4);
+
+ dhcp_send_release();
+
+ if (rc > 0)
+ {
+ printf (" TFTP: Received %s (%d KBytes)\n", fn_ip.filename, rc/1024);
+ printf (" Now flashing:\n");
+ rc = rtas_ibm_update_flash_64((long long)buffer, rc);
+ return rc;
+ }
+ else if (rc == -1)
+ {
+ printf (" Tftp: Could not load file %s\n", fn_ip.filename);
+ return 1;
+ }
+ else if (rc == -2)
+ {
+ printf (" Tftp: Buffer to small for %s\n", fn_ip.filename);
+ return 1;
+ }
+ else if (rc <= -10 && rc >= -15)
+ {
+ printf("\n ICMP ERROR: Destination unreachable: ");
+ switch(rc) {
+ case -ICMP_NET_UNREACHABLE-10:
+ printf("net unreachable");
+ break;
+ case -ICMP_HOST_UNREACHABLE-10:
+ printf("host unreachable");
+ break;
+ case -ICMP_PROTOCOL_UNREACHABLE-10:
+ printf("protocol unreachable");
+ break;
+ case -ICMP_PORT_UNREACHABLE-10:
+ printf("port unreachable");
+ break;
+ case -ICMP_FRAGMENTATION_NEEDED-10:
+ printf("fragmentation needed and DF set");
+ break;
+ case -ICMP_SOURCE_ROUTE_FAILED-10:
+ printf("source route failed");
+ break;
+ default:
+ printf(" UNKNOWN: this should not happen!");
+ break;
+ }
+ printf("\n");
+ return 1;
+ }
+ else if(rc < 0)
+ printf(" UNKNOWN: rc = %d!", rc);
+
+ return 0;
+}