int download_using_TFTP(char * name) { // Use TFTP to get the bootfile. Function returns a non-negative value on success // (which is the length of the downloaded file) or negative for error. See // tftp_init() and tftp_tick() for error code documentation. // Rather than use this function, you could also use the tftp_exec() function // but you have to provide a string host name to tftp_exec() whereas we have a // binary IP address. int status; struct tftp_state ts; #define MAX_FILESIZE 3000 // Max bytes to download load_bootfile = 0; // Don't do it more than once ts.state = 0; // Tell it to read (download) ts.buf_addr = xalloc(MAX_FILESIZE); // Where to put the data (in a real program, // you would want to save this address somewhere). ts.buf_len = MAX_FILESIZE; // Max file size to download. ts.my_tid = 0; // Tell it to use default TFTP port number ts.sock = &mysock; // Give it a socket to work with ts.rem_ip = bootfile_host; // IP address of server ts.mode = TFTP_MODE_OCTET; // Binary transfer mode strcpy(ts.file, my_bootfile); // Name of file (from DHCP server) if (status = tftp_init(&ts)) { printf("TFTP initialization failed.\n"); return status; } else { while ((status = tftp_tick(&ts)) == 1); // Loop until complete or error if (!status) return ts.buf_used; // Return length of downloaded file } return status; }
err_t casper_tftp_init() { casper_tftp_context.open = casper_tftp_open; casper_tftp_context.close = casper_tftp_close; casper_tftp_context.read = casper_tftp_read_error; casper_tftp_context.write = casper_tftp_write_error; return tftp_init(&casper_tftp_context); }
PROCESS_THREAD(shell_tftpupdate_process, ev, data) { char *s; int err; PROCESS_BEGIN(); // Make sure we got some arguments if ((data == NULL) || (strlen(data) == 0)) { tftpupdate_usage(); PROCESS_EXIT(); } // Find the space between the server and the filename s = strchr(data, ' '); // Check we got <server><SPACE><filename> if (s == NULL) { tftpupdate_usage(); PROCESS_EXIT(); } // Clean up after a previous run if (tftpupdate) { shell_output_P(&tftpupdate_command, PSTR("Previous run failed to clean up after itself! Clobbering.\n")); tftpupdate_cleanup(); } // Allocate our memory block if necessary tftpupdate = malloc(sizeof(*tftpupdate)); if (tftpupdate == NULL) { shell_output_P(&tftpupdate_command, PSTR("Out of memory!\n")); PROCESS_EXIT(); } tftpupdate->s.conn = NULL; // Copy out the server name int len = s - (char *)data; if (len >= sizeof(tftpupdate->res.name)) { len = sizeof(tftpupdate->res.name) - 1; } strncpy(tftpupdate->res.name, data, len); tftpupdate->res.name[len] = '\0'; // Copy out the filename strncpy(tftpupdate->filename, s + 1, sizeof(tftpupdate->filename) - 1); tftpupdate->filename[sizeof(tftpupdate->filename) - 1] = '\0'; // Check there is something in the filename if (strlen(tftpupdate->filename) == 0) { tftpupdate_usage(); tftpupdate_cleanup(); PROCESS_EXIT(); } // Tell the user what's going on shell_output_P(&tftpupdate_command, PSTR("Looking up '%s'...\n"), tftpupdate->res.name); // Start the lookup resolv_helper_lookup(&tftpupdate->res); while (1) { PROCESS_WAIT_EVENT(); resolv_helper_appcall(&tftpupdate->res, ev, data); if (tftpupdate->res.state == RESOLV_HELPER_STATE_ASKING) { continue; } else if (tftpupdate->res.state == RESOLV_HELPER_STATE_DONE) { break; } else if (tftpupdate->res.state == RESOLV_HELPER_STATE_ERROR) { shell_output_P(&tftpupdate_command, PSTR("Error during DNS lookup.\n")); tftpupdate_cleanup(); PROCESS_EXIT(); } else { shell_output_P(&tftpupdate_command, PSTR("Error during DNS lookup. (unknown state)\n")); tftpupdate_cleanup(); PROCESS_EXIT(); } } // Tell the user what's going on shell_output_P(&tftpupdate_command, PSTR("Preparing to write to flash...\n")); // Start the flash write err = flashmgt_sec_write_start(); if (err) { shell_output_P(&tftpupdate_command, PSTR("Could not set up flash write (%d).\n"), err); tftpupdate_cleanup(); PROCESS_EXIT(); } // More user info shell_output_P(&tftpupdate_command, PSTR("Requesting '%s' from %u.%u.%u.%u...\n"), tftpupdate->filename, uip_ipaddr_to_quad(&tftpupdate->res.ipaddr)); // Start the TFTP transfer tftpupdate->s.addr = tftpupdate->res.ipaddr; tftpupdate->s.iofunc = tftpupdate_iofunc; tftp_init(&tftpupdate->s); tftp_get(&tftpupdate->s, tftpupdate->filename); while (1) { PROCESS_WAIT_EVENT(); if (ev == tcpip_event) { tftp_appcall(&tftpupdate->s); if (tftpupdate->s.state == TFTP_STATE_CLOSE) { shell_output_P(&tftpupdate_command, PSTR("\rTransfer complete (%lu bytes read).\n"), tftpupdate->s.size); // Send final ACK PROCESS_WAIT_EVENT(); break; } else if (tftpupdate->s.state == TFTP_STATE_ERR) { shell_output_P(&tftpupdate_command, PSTR("\rAborting due to error.\n")); // Abort the flash write flashmgt_sec_write_abort(); // Make sure error message is sent PROCESS_WAIT_EVENT(); tftpupdate_cleanup(); PROCESS_EXIT(); } else if (tftpupdate->s.state == TFTP_STATE_TIMEOUT) { shell_output_P(&tftpupdate_command, PSTR("\rTransfer timed out.\n")); // Abort the flash write flashmgt_sec_write_abort(); // Make sure error message is sent PROCESS_WAIT_EVENT(); tftpupdate_cleanup(); PROCESS_EXIT(); } } } // Tell the user what's going on shell_output_P(&tftpupdate_command, PSTR("Completing update process...\n")); // Finish the flash write process err = flashmgt_sec_write_finish(); if (err) { shell_output_P(&tftpupdate_command, PSTR("Could not apply firmware update (%d)\n"), err); } else { shell_output_P(&tftpupdate_command, PSTR("New firmware image is in flash. " "Please reboot to apply the upgrade.\n"), err); } tftpupdate_cleanup(); PROCESS_END(); }
void netmain_init(void) { int e; int i; char * msg; #ifdef IP_V6 ip6_addr host; #endif printf("\n%s\n", name); printf("Copyright 1997-2006 by InterNiche Technologies. All rights reserved. \n"); #ifndef SUPERLOOP /* call this to do pre-task setup including intialization of port_prep */ msg = pre_task_setup(); if (msg) panic(msg); #endif #ifdef INCLUDE_NVPARMS /* system uses InterNiche NV system */ e = get_nv_params(); /* get flash parameters into data structs */ if (e) { printf("fatal error (%d) reading NV parameters.\n", e); panic("nv"); } /* set static iface IP info up from stored parameters. These may be overwritten from command line parms or DHCP later. */ for (i = 0; i < STATIC_NETS; i++) { netstatic[i].n_ipaddr = inet_nvparms.ifs[i].ipaddr; netstatic[i].snmask = inet_nvparms.ifs[i].subnet; netstatic[i].n_defgw = inet_nvparms.ifs[i].gateway; #ifdef IP_MULTICAST /* Create a dummy entry for the Ethernet interface mcastlist */ /* If this entry is set to NULL, multicast is not supported */ /* on this interface */ netstatic[i].n_mcastlist = mcastlist; #endif /* IP_MULTICAST */ #ifdef IP_V6 IP6CPY(&host, &inet_nvparms.ifs[i].ipv6addr); if ( (host.addr[0] == 0xFE) && (host.addr[1] == 0xC0)) { netstatic[i].v6addrs[IPA_SITE] = ip6_mkaddr(&netstatic[i], IPA_SITE, &host); } else if ( (host.addr[0] == 0xFE) && (host.addr[1] == 0x80) ) { printf ("[IPV6 init]error : bad IPV6 address\n"); } else if (host.addr[0] != 0) { netstatic[i].v6addrs[IPA_GLOBAL] = ip6_mkaddr(&netstatic[i], IPA_GLOBAL, &host ); } #endif } #ifdef DNS_CLIENT /* set DNS client's server list from nvparms information */ MEMCPY(dns_servers, inet_nvparms.dns_servers, sizeof(dns_servers)); #ifdef DNS_CLIENT_UPDT MEMCPY(soa_mname, inet_nvparms.dns_zone_name, sizeof(soa_mname)); #endif /* DNS_CLIENT_UPDT */ #endif /* DNS_CLIENT */ #ifdef USE_COMPORT comportcfg.comport = comport_nvparms.comport; comportcfg.LineProtocol = comport_nvparms.LineProtocol; #endif /* USE_COMPORT */ #endif /* INCLUDE_NVPARMS */ #ifndef INCLUDE_NVPARMS #ifdef USE_COMPORT comportcfg.comport = 0x01; comportcfg.LineProtocol = PPP; /* Default to PPP */ #endif /* USE_COMPORT */ #endif /* INCLUDE_NVPARMS */ msg = ip_startup(); if (msg) { printf("inet startup error: %s\n", msg); panic("IP"); } #if defined(MEMDEV_SIZE) && defined(VFS_FILES) init_memdev(); /* init the mem and null test devices */ #endif #ifdef IP_MULTICAST #ifdef INCLUDE_TCP /* call the IP multicast test program */ u_mctest_init(); #endif #endif /* clear debugging flags. Port can optionally turn them * back on in post_task_setup(); * NDEBUG = UPCTRACE | IPTRACE | TPTRACE ; */ NDEBUG = 0; /* print IP address of the first interface - for user's benefit */ printf("IP address of %s : %s\n" , ((NET)(netlist.q_head))->name, print_ipad(((NET)(netlist.q_head))->n_ipaddr)); #ifndef SUPERLOOP /* call this per-target routine after basic tasks & net are up */ msg = post_task_setup(); if (msg) panic(msg); #endif #ifdef PING_APP ping_init(); #endif /* PING_APP */ #ifdef RAWIPTEST raw_test_init(); #endif /* RAWIPTEST */ #if defined(TFTP_CLIENT) || defined(TFTP_SERVER) tftp_init(); #endif /* TFTP */ #ifdef TESTMENU install_menu(testmenu); #endif /* TESTMENU */ #ifdef USE_AUTOIP Upnp_init(); /* start Auto IP before DHCP client */ #endif /* USE_AUTOIP */ #ifdef DHCP_CLIENT if( POWERUP_CONFIG_DHCP_ENABLED ) dhc_setup(); /* kick off any DHCP clients */ #endif /* DHCP_CLIENT */ #ifdef DHCP_SERVER #ifdef INCLUDE_NVPARMS if(dhserve_nvparms.ServeDHCP) #endif { e = dhcp_init(); if(e) { dprintf("Error %d starting DHCP server.\n",e); } else { exit_hook(dhcpsrv_cleanup); dprintf("Started DHCP server\n"); } } #endif /* DHCP_SERVER */ #ifdef IN_MENUS printf(prompt); #endif #ifdef UDPSTEST e=udp_echo_init(); if ( e == SUCCESS ) { exit_hook(udp_echo_cleanup); } else dprintf("Error %d starting UDP Echo server.\n",e); #endif #ifdef RIP_SUPPORT e=rip_init(); if ( e == SUCCESS ) { exit_hook(rip_cleanup); } else dprintf("Error %d starting RIP server.\n",e); #endif #ifdef INICHE_SYSLOG e =syslog_init(); if (e == SUCCESS) exit_hook(closelog); else dprintf("Error %d initializing syslog client.\n",e); #endif #ifdef FTP_CLIENT fc_callback=ftpc_callback; #endif /* The following initializations take place when SUPERLOOP is enabled. * Otherwise they would be done in the respective task. */ #ifdef SUPERLOOP #ifdef INCLUDE_SNMP e = snmp_init(); if (e == SUCCESS) exit_hook(snmp_cleanup); else dprintf("Error %d initializing SNMP agent.\n",e); #endif /* INCLUDE_SNMP */ #ifdef WEBPORT e = http_init(); /* start up http server */ if (e) dprintf("Error %d starting HTTP server.\n",e); #endif /* WEBPORT */ #ifdef FTP_SERVER e = ftps_init(); if ( e == SUCCESS ) { exit_hook(ftps_cleanup); } else dprintf("Error %d starting FTP server.\n",e); #endif /* FTP_SERVER */ #ifdef TELNET_SVR e=tel_init(); if ( e == SUCCESS ) { exit_hook(tel_cleanup); } else dprintf("Error %d starting TELNET server.\n",e); #endif #ifdef TCP_ECHOTEST e=tcp_echo_init(); if ( e == SUCCESS ) { exit_hook(tcp_echo_cleanup); } else dprintf("Error %d starting TCP Echo server.\n",e); #endif #ifdef TCP_CIPHERTEST e=tcp_cipher_init(); if ( e == SUCCESS ) { exit_hook(tcp_cipher_cleanup); } else dprintf("Error %d starting TCP cipher server.\n",e); #endif #ifdef USE_CRYPTOENG e = ce_init(); if(e != 0) { dprintf("ce_init() failed\n"); panic("prep_modules"); } #endif #ifdef SMTP_ALERTS smtp_init (); #endif #endif /* SUPERLOOP */ USE_ARG(e); /* Avoid compiler warnings */ USE_ARG(i); } /* end of netmain_init() */
int main() { struct tftp_state ts; int status; word bflen; status = sock_init(); if (status) { printf("Could not init packet driver.\n"); exit(3); } // Wait for the interface to come up while (ifpending(IF_DEFAULT) == IF_COMING_UP) { tcp_tick(NULL); } /*########## DOWNLOAD ##########*/ ts.state = 0; // 0 = read ts.buf_len = TFTP_DL_SIZE; // max length to download ts.buf_addr = xalloc(TFTP_DL_SIZE); // allocate a buffer ts.my_tid = 0; // zero to use default TFTP UDP port number ts.sock = &tsock; // point to socket to use ts.rem_ip = resolve(TFTP_SERVER); // resolve server IP address ts.mode = TFTP_MODE_OCTET; // send/receive binary data strcpy(ts.file, TFTP_DL_FILENAME); // set file name on server printf("Downloading %s...\n", ts.file); // This uses the non-blocking TFTP functions, but in a blocking // manner. It would be easier to use tftp_exec(), but this // doesn't return the server error message. tftp_init(&ts); while ((status = tftp_tick(&ts)) > 0); // Loop until complete if (!status) printf("Download completed\n"); else if (status == -3) printf("ERROR: Download timed out.\n"); else if (status == -5) printf("Download completed, but truncated\n"); else { printf("Download failed: code %d\n", status); if (status == -1) printf(" Message from server: %s\n", ts.file); } /*########## UPLOAD ##########*/ ts.state = 1; // 0 = write ts.buf_len = ts.buf_used; // length to upload (use same buffer as downloaded) ts.my_tid = 0; // zero to use default TFTP UDP port number ts.sock = &tsock; // point to socket to use ts.rem_ip = resolve(TFTP_SERVER); // resolve server IP address ts.mode = TFTP_MODE_OCTET; // send/receive binary data strcpy(ts.file, TFTP_UL_FILENAME); // set file name on server printf("Uploading as %s...\n", ts.file); tftp_init(&ts); while ((status = tftp_tick(&ts)) > 0); // Loop until complete if (!status) printf("Upload completed\n"); else { printf("Upload failed: code %d\n", status); if (status == -1) printf(" Message from server: %s\n", ts.file); else if (status == -3) printf("ERROR: Download timed out.\n"); else if (status == -2) { printf(" Server did not ack last packet...\n"); printf(" Acked %u\n", ts.buf_used); if (ts.buf_len - ts.buf_used <= 512) printf(" Some bug-ridden servers don't ack the last packet sent :-(\n"); } } printf("All done.\n"); return 0; }
static void upd_flash(tftp *tftp) { char str[17]; int tftp_block; u32 waddr; u32 sector, last_sector; int len; tftp_init(tftp); tftp->filename = upd_mem; waddr = 0; last_sector= 0xFFFFFFFF; while(1) { tftp_run(tftp); if ( (tftp->state == 2) || (tftp->state == 3)) { if (tftp->lastblock != tftp_block) { tftp_block = tftp->lastblock; strcpy(str, "Load flash "); b2ds(&str[11], tftp_block); oled_pos(0, 0); oled_puts(str); sector = (tftp_block << 9) & 0xFFFF0000; if (sector != last_sector) { flash_erase(sector); last_sector = sector; } uart_puts(str); uart_putc('\r'); len = 0; if (tftp->length > 4) { u8 *dat; dat = (u8 *)&tftp->data[4]; len = tftp->length - 4; if (len > 256) { flash_write(waddr, dat, 256); len -= 256; /* Update remaining data length */ dat += 256; /* Move the source pointer */ waddr += 256; /* Update the dest address */ /* Wait for the write transfer ends */ while(flash_status() & 1) ; } flash_write(waddr, dat, len); /* Wait for the write transfer ends */ while(flash_status() & 1) ; /* Update write address for next packet */ waddr += len; } } tftp_ack(tftp); } if (tftp->state == 3) { uart_crlf(); break; } if (tftp->state == 98) { uart_puts("TFTP timeout, restart\r\n"); oled_pos(0, 0); oled_puts("TFTP: timeout!"); tftp->timestamp = 0x3000; tftp->state = 0; } if (tftp->state == 99) { uart_puts("upd_firmware() TFTP error 99\r\n"); break; } } }