static void do_get(int client, char *buf) { char *fn, *sn, *data; #ifdef CYGPKG_FS_RAM char _fn[PATH_MAX]; #endif int fd, len, err; struct sockaddr_in srvr_addr; buf += 3; // Skip over command fn = strtok(buf, " ,"); sn = strtok(NULL, " ,"); if ((fn == (char *)NULL) || (sn == (char *)NULL)) { fdprintf(client, "usage: get <file> <server>\n"); return; } // For now, only numeric IP addresses if (!inet_aton(sn, &srvr_addr.sin_addr)) { fdprintf(client, "Can't get host info: %s\n", sn); return; } srvr_addr.sin_port = 0; if ((data = (char *)malloc(0x100000)) == (char *)NULL) { fdprintf(client, "Can't allocate temp buffer\n"); return; } if ((len = tftp_get(fn, &srvr_addr, data, 0x100000, TFTP_OCTET, &err)) > 0) { fdprintf(client, "Read %d bytes\n", len); fd = open(fn, O_RDWR|O_CREAT); if (fd > 0) { err = write(fd, data, len); if (err != len) { fdprintf(client, "Error writing data\n"); } close(fd); } else { fdprintf(client, "Can't create \"%s\"\n", fn); } #ifdef CYGPKG_FS_RAM sprintf(_fn, "/%s", fn); fd = open(_fn, O_RDWR|O_CREAT); if (fd > 0) { err = write(fd, data, len); if (err != len) { fdprintf(client, "Error writing data\n"); } close(fd); } else { fdprintf(client, "Can't create \"%s\"\n", _fn); } #endif } else { fdprintf(client, "Error reading data\n"); } free(data); }
static int tftp_get_v(unsigned int ip, const char *filename, char *buffer) { int r; r = tftp_get(ip, filename, buffer); if(r > 0) printf("I: Successfully downloaded %d bytes from %s over TFTP\n", r, filename); else printf("I: Unable to download %s over TFTP\n", filename); return r; }
static void tftp_test(struct bootp *bp) { int res, err, len; struct sockaddr_in host; #ifdef CYGPKG_NET_INET6 struct sockaddr_in6 ipv6router; char server[64]; #endif memset((char *)&host, 0, sizeof(host)); host.sin_len = sizeof(host); host.sin_family = AF_INET; host.sin_addr = bp->bp_siaddr; host.sin_port = 0; diag_printf("Trying tftp_get %s %16s...\n", GETFILE, inet_ntoa(host.sin_addr)); res = tftp_get( GETFILE, &host, buf, sizeof(buf), TFTP_OCTET, &err); diag_printf("res = %d, err = %d\n", res, err); if (res > 0) { diag_dump_buf(buf, min(res,1024)); } len = res; diag_printf("Trying tftp_put %s %16s, length %d\n", PUTFILE, inet_ntoa(host.sin_addr), len); res = tftp_put( PUTFILE, &host, buf, len, TFTP_OCTET, &err); diag_printf("put - res: %d\n", res); #ifdef CYGPKG_NET_INET6 // Wait for router solicit process to happen. if (!cyg_net_get_ipv6_advrouter(&ipv6router)) { diag_printf("No router advertisement recieved\n"); cyg_test_exit(); } getnameinfo((struct sockaddr *)&ipv6router,sizeof(ipv6router), server, sizeof(server), 0 ,0 ,NI_NUMERICHOST); diag_printf("Trying tftp_get %s using IPv6 from %16s...\n", GETFILE, server); res = tftp_client_get( GETFILE, server, 0, buf, sizeof(buf), TFTP_OCTET, &err); diag_printf("IPv6 res = %d, err = %d\n", res, err); if (res > 0) { diag_dump_buf(buf, min(res,1024)); } len = res; diag_printf("Trying tftp_put %s using IPv6 to %16s, length %d\n", PUTFILE, server, len); res = tftp_client_put( PUTFILE, server, 0, buf, len, TFTP_OCTET, &err); diag_printf("put - res: %d\n", res); #endif }
int main(int argc, char * argv[]) { char * filename = NULL; off_t len = 0; if (argc < 3) { fprintf(stderr, "usage: %s <host> <remote>\n", argv[0]); exit(2); } filename = tftp_get(argv[1], argv[2], &len); if (filename) { printf("read %s:%s -> %s %qd\n", argv[1], argv[2], filename, len); free(filename); exit(0); } else { fprintf(stderr, "tftp %s:%s failed\n", argv[1], argv[2]); exit(1); } return (0); }
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 seq_tftp_get(const char *name, void *buf, size_t bufsize, enum state_t next) { t_next = next; gstate = STATE_WAIT_TFTP; tftp_get(tftp, name, buf, bufsize, tftp_cb, NULL); }