📄 tftp.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/router/tftp.c,v 1.2 2001/11/09 21:06:51 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1994-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: tftp.c,v $ * Revision 1.2 2001/11/09 21:06:51 josh * demo router path modification * * Revision 1.1.1.1 2001/11/05 17:49:10 tneale * Tornado shuffle * * Revision 2.10 2001/01/19 22:24:39 paul * Update copyright. * * Revision 2.9 2000/03/17 00:14:19 meister * Update copyright message * * Revision 2.8 1999/04/15 21:43:41 wes * Fix SNARK_ATTACHE_34_DNS_COMPAT to continue working.. * * Revision 2.7 1998/10/28 18:51:16 josh * marging in courier-sep98 branch * * Revision 2.6 1998/10/16 20:50:40 wes * Clean up namespace of of TFTP error symbols; s/ERR_/TFTP_ERR_/ * * Revision 2.5 1998/09/25 16:56:57 wes * Include udp.h so previous change will work.. * * Revision 2.4 1998/09/25 16:55:54 wes * Consistently use udp_free instead of pkt_free * * Revision 2.3 1998/09/18 19:55:14 meister * timer call renaming; tm_ --> etc_tm_ * * Revision 2.2.8.1 1998/09/12 19:27:36 sra * Minor kludges to make this development snapshot of snark compile with * the released versions of the Attache, Envoy, and Emissary products. * These changes will need to be un-done when this branch is merged back * into the main code base. * * Revision 2.2 1998/04/13 21:32:48 wes * Actually implement 'tftp mode oldapi' ... * * Revision 2.1 1998/04/09 22:00:25 wes * Start splitting main.c into app-specific files; add netime client * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*/#include <stdio.h>#include <stdlib.h>#include <wrn/wm/attache/config.h>#include <wrn/wm/attache/mib.h>#include <wrn/wm/attache/timer.h>#include <wrn/wm/attache/packet.h>#include <wrn/wm/attache/net.h>#include <wrn/wm/attache/route.h>#include <wrn/wm/attache/ip.h>#include <wrn/wm/attache/udp.h>#include <wrn/wm/attache/glue.h>#include "cmds.h"#if INSTALL_ATTACHE_TFTP#include <wrn/wm/attache/tftpc.h>#endif#if INSTALL_ATTACHE_DNS#include <wrn/wm/attache/dns.h>#endif#include <wrn/wm/demo/snarklib.h>#include <wrn/wm/demo/read_ini.h>#if INSTALL_ATTACHE_DNS && INSTALL_ATTACHE_TFTP/* structure to hold error strings for tftp_error_print() */struct tftp_err_lookup { int err_code; char * err_string; };/* error strings for TFTP */struct tftp_err_lookup tftp_err_strings[] ={ { TFTP_ERR_NOFILE, "TFTP error: File not found."}, { TFTP_ERR_ACCESS, "TFTP error: Access violation."}, { TFTP_ERR_DISKFULL, "TFTP error: Disk full or allocation exceeded."}, { TFTP_ERR_ILLEGALOP, "TFTP error: Illegal TFTP operation."}, { TFTP_ERR_BADTID, "TFTP error: Unknown transfer ID."}, { TFTP_ERR_EXISTS, "TFTP error: File already exists."}, { TFTP_ERR_NOUSER, "TFTP error: No such user."}, { TFTP_ERR_RESOURCES, "TFTP error: Resources not available."}, { TFTP_ERR_USEMSG, "TFTP error: Aborted by client request."}, { TFTP_ERR_TIMEOUT, "TFTP error: Timed out."}};#define TFTP_ERR_STRINGS (sizeof(tftp_err_strings)/sizeof(*tftp_err_strings))/* structure to keep track of current tftp "connections" */struct tftp_state{ ipaddr_t host; char * file_name_ptr; int direction; FILE * fp; struct sty *sty; struct tftp_state * next; tftp_cnxn_t *cnxn; packet *delay_pkt; struct timer delack_tm; int delay_block; int defer_exit;};static struct tftp_state * tftp_state_head = 0;static int tftp_start_xfer (int argc, char ** argv, struct sty * sty);static void tftp_dns_err(struct dns_query *query, enum dns_error error, void *cookie);static void tftp_dns_won(struct dns_query *query, char *dname, int n, ipaddr_t addrs[], void *cookie);static boolean_t tftp_error_print (struct sty * sty, struct tftp_err_lookup table[], int table_size, int err_val);static int tftp_read_handler (tftp_rval_t code, packet *pkt, void *cookie, tftp_error_t errnum, tftp_cnxn_t * tftp_cnxn);static void tftp_read_delack_handler(struct timer *tm, void *cookie);#if INSTALL_ATTACHE_TFTP_SENDFILE static int tftp_write_handler (tftp_rval_t code, packet *pkt, void *cookie, tftp_error_t errnum, tftp_cnxn_t * tftp_cnxn);#endifstatic int tftp_parse_parm(char * cmd, char * cmd_list[], int num_choices);static boolean_t tftp_exit(struct tftp_state * );/* string for TFTP second-level commands */static char * tftp_cmds[] = { "get", "send", "mode" };#define TFTP_CMDS (sizeof(tftp_cmds)/sizeof(*tftp_cmds))/* string for TFTP mode third-level commands */static char * tftp_modes[] = { "delack", "nodelack", "oldapi", "newapi"};#define TFTP_MODES (sizeof(tftp_modes)/sizeof(*tftp_modes))int newapi = 1;int delack = 0;/* cmd_tftp() * * function that gets called when a "tftp" command is typed at the command line */boolean_t cmd_tftp (struct sty *sty, enum help_level help, int argc, char **argv){ switch (help) { case help_none: if (tftp_start_xfer(argc,argv,sty) == 1) return 0; break; case help_short: sty_puts(sty, "tftp tftp get/send host filename\n"); break; case help_long: sty_puts(sty, "\The \"tftp\" command attempts to send or retrieve a file \via the TFTP protocol.\n \The filename is the full path of the remote file; \n \the local file will always be assumed to be in the current directory.\n"); break; } return 1;}#if INSTALL_SNARK_ATTACHE_34_DNS_COMPATstatic void tftp_dns_won_compat (struct dns_query *query, char *dname, int n, inaddr_t addrs[], void *cookie){ snark_attache_dns_34_compat(tftp_dns_won, query, dname, n, addrs, cookie);}#endif /* INSTALL_SNARK_ATTACHE_34_DNS_COMPAT *//* tftp_start_xfer() * * Begin a TFTP operation: passed a set of parameters where: * it is known there are exactly four, * the first is known to be "tftp", * the second presumably "get" or "send", * the third a host to get the file from, * and the fourth is a filename to get. * * Returns 0 on error, 1 otherwise. */static int tftp_start_xfer(int argc, char ** argv, struct sty * sty){ int mode; struct tftp_state * session; /* get a session block */ if ((session = (struct tftp_state *) GLUE_ALLOC(sizeof(*session))) == 0) { sty_puts(sty, "%% Couldn't allocate state block\n"); return 0; } session->direction = tftp_parse_parm(argv[1], tftp_cmds, TFTP_CMDS); switch (session->direction) { case 1: /* get */ if (argc < 4) { sty_puts(sty, "insufficient arguments\n"); sty_puts(sty, "usage: tftp get/send host filename\n"); GLUE_FREE(session); return 0; } break; case 2: /* send */#if INSTALL_ATTACHE_TFTP_SENDFILE if (argc < 4) { sty_puts(sty, "insufficient arguments\n"); sty_puts(sty, "usage: tftp get/send host filename\n"); GLUE_FREE(session); return 0; } break;#else sty_puts(sty, "tftp send not installed\n"); GLUE_FREE(session); return 0;#endif case 3: mode = tftp_parse_parm(argv[2], tftp_modes, TFTP_MODES); switch(mode) { case 1: delack = 1; break; case 2: delack = 0; break; case 3:#if INSTALL_SNARK_ATTACHE_34_TFTP_COMPAT newapi = 0;#else sty_puts(sty, "tftp old api support not included\n");#endif break; case 4: newapi = 1; break; default: sty_puts(sty, "tftp mode delack/nodelack/oldapi/newapi\n"); } GLUE_FREE(session); return 0; break; default: sty_puts(sty, "tftp tftp get/send host filename\n"); GLUE_FREE(session); return 0; } /* get some memory to stash the filename */ if ((session->file_name_ptr = GLUE_ALLOC(strlen(argv[3]) + 1)) == 0) { sty_puts(sty, "%% Couldn't allocate scratch space for filename\n"); GLUE_FREE(session); return 0; } strcpy(session->file_name_ptr, argv[3]); /* Fill the state block with whatever we need now. */ session->sty = sty; session->fp = NULL; /* and friends, Obie was making sure ... */ session->delay_pkt = NULL; session->delay_block = 0; session->defer_exit = 0; etc_tm_init(&session->delack_tm); session->delack_tm.handler = tftp_read_delack_handler; session->delack_tm.cookie = session; /* Go to the DNS for the IP address of our target */ DNS_NAME_TO_IPADDR(argv[2], tftp_dns_won, tftp_dns_err, &domain_config, 0, session); return 1;}/* tftp_dns_err() * * DNS callback if it didn't get an IP address * * prints an error and kills the "session" state block */static void tftp_dns_err(struct dns_query *query, enum dns_error error, void *cookie){ struct tftp_state * session = cookie;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -