annotate packages/redboot/current/src/net/tftp_client.c @ 1777:c16341b1bac6 default tip

* Added execute permissions to files missed in conversion from CVS
author alexs
date Mon, 12 Oct 2009 02:26:09 +0100
parents 43a89c18d005
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3 // net/tftp_client.c
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
4 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
5 // Stand-alone TFTP support for RedBoot
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
6 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
7 //==========================================================================
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
8 //####ECOSGPLCOPYRIGHTBEGIN####
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
9 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
10 // This file is part of eCos, the Embedded Configurable Operating System.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
12 // Copyright (C) 2002, 2003 Gary Thomas
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
13 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
14 // eCos is free software; you can redistribute it and/or modify it under
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
15 // the terms of the GNU General Public License as published by the Free
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
16 // Software Foundation; either version 2 or (at your option) any later version.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
17 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
21 // for more details.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
22 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
23 // You should have received a copy of the GNU General Public License along
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
26 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
27 // As a special exception, if other files instantiate templates or use macros
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
28 // or inline functions from this file, or you compile this file and link it
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
29 // with other works to produce a work based on this file, this file does not
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
30 // by itself cause the resulting work to be covered by the GNU General Public
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
31 // License. However the source code for this file must still be made available
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
32 // in accordance with section (3) of the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
33 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
34 // This exception does not invalidate any other reasons why a work based on
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
35 // this file might be covered by the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
36 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
210
d2c90368aeef Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents: 208
diff changeset
38 // at http://sources.redhat.com/ecos/ecos-license/
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
39 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
40 //####ECOSGPLCOPYRIGHTEND####
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
41 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
42 //#####DESCRIPTIONBEGIN####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
43 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
44 // Author(s): gthomas
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
45 // Contributors: gthomas
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
46 // Date: 2000-07-14
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
47 // Purpose:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
48 // Description:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
49 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
50 // This code is part of RedBoot (tm).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
51 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
52 //####DESCRIPTIONEND####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
53 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
54 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
55
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
56 // TFTP client support
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
57
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 143
diff changeset
58 #include <redboot.h> // have_net
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
59 #include <net/net.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
60 #include <net/tftp.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
61 #include <net/tftp_support.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
62
161
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
63 // So we remember which ports have been used
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
64 static int get_port = 7700;
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
65
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
66 static struct {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
67 bool open;
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
68 int total_timeouts, packets_received;
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
69 unsigned long last_good_block;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
70 int avail, actual_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
71 struct sockaddr_in local_addr, from_addr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
72 char data[SEGSIZE+sizeof(struct tftphdr)];
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
73 char *bufp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
74 } tftp_stream;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
75
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
76 int
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
77 tftp_stream_open(connection_info_t *info,
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
78 int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
79 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
80 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
81 char *cp, *fp;
143
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
82 char test_buf;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
83
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 143
diff changeset
84 if (!have_net || tftp_stream.open) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
85 *err = TFTP_INVALID; // Already open
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
86 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
87 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
88
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
89 // Create initial request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
90 hdr->th_opcode = htons(RRQ); // Read file
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
91 cp = (char *)&hdr->th_stuff;
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
92 fp = info->filename;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
93 while (*fp) *cp++ = *fp++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
94 *cp++ = '\0';
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
95 // Since this is used for downloading data, OCTET (binary) is the
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
96 // only mode that makes sense.
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
97 fp = "OCTET";
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
98 while (*fp) *cp++ = *fp++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
99 *cp++ = '\0';
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
100
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
101 memset((char *)&tftp_stream.local_addr, 0, sizeof(tftp_stream.local_addr));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
102 tftp_stream.local_addr.sin_family = AF_INET;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
103 tftp_stream.local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
104 tftp_stream.local_addr.sin_port = htons(get_port++);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
105
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
106 if (info->server->sin_port == 0) {
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
107 info->server->sin_port = htons(TFTP_PORT);
1605
43a89c18d005 Add checking (assert) for size of option arrays. Also fix port for TFTP on little endian systems.
gthomas
parents: 1223
diff changeset
108 } else {
43a89c18d005 Add checking (assert) for size of option arrays. Also fix port for TFTP on little endian systems.
gthomas
parents: 1223
diff changeset
109 info->server->sin_port = htons(info->server->sin_port);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
110 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
111
162
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
112 // Send request - note: RFC 1350 (TFTP rev 2) indicates that this should be
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
113 // only as long as required to hold the request, with the nul terminator.
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
114 // Some servers silently go to lunch if the request is not the correct size.
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
115 if (__udp_sendto(tftp_stream.data, cp-(char *)hdr,
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
116 info->server, &tftp_stream.local_addr) < 0) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
117 // Problem sending request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
118 *err = TFTP_NETERR;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
119 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
120 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
121
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
122 tftp_stream.open = true;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
123 tftp_stream.avail = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
124 tftp_stream.actual_len = -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
125 tftp_stream.last_good_block = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
126 tftp_stream.total_timeouts = 0;
197
51b34619b677 Merge from eCos master repository on 2001-11-30-11:22:06-GMT
jlarmour
parents: 174
diff changeset
127 tftp_stream.from_addr.sin_port = 0;
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
128 tftp_stream.packets_received = 0;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
129
143
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
130 // Try and read the first byte [block] since no errors are
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
131 // reported until then.
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
132 if (tftp_stream_read(&test_buf, 1, err) == 1) {
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
133 // Back up [rewind] over this datum
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
134 tftp_stream.bufp--;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
135 tftp_stream.avail++;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
136 return 0; // Open and first read successful
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
137 } else {
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
138 tftp_stream.open = false;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
139 return -1; // Couldn't read
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
140 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
141 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
142
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
143 static int
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
144 tftp_ack(int *err)
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
145 {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
146 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
147 // ACK last packet so server can shut down
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
148 if (tftp_stream.packets_received > 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
149 hdr->th_opcode = htons(ACK);
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
150 hdr->th_block = htons((cyg_uint16)tftp_stream.last_good_block & 0xFFFF);
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
151 if (__udp_sendto(tftp_stream.data, 4 /* FIXME */,
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
152 &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
153 // Problem sending ACK
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
154 *err = TFTP_NETERR;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
155 return -1;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
156 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
157 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
158 return 0;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
159 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
160
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
161 void
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
162 tftp_stream_close(int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
163 {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
164 tftp_ack(err);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
165 tftp_stream.open = false;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
166 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
167
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
168 int
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
169 tftp_stream_read(char *buf,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
170 int len,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
171 int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
172 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
173 int total_bytes = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
174 int size, recv_len, data_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
175 struct timeval timeout;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
176 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
177
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
178 while (total_bytes < len) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
179 // Move any bytes which we've already read/buffered
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
180 if (tftp_stream.avail > 0) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
181 size = tftp_stream.avail;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
182 if (size > (len - total_bytes)) size = len - total_bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
183 memcpy(buf, tftp_stream.bufp, size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
184 buf += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
185 tftp_stream.bufp += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
186 tftp_stream.avail -= size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
187 total_bytes += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
188 } else {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
189 if (tftp_ack(err) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
190 return -1;
174
38892b97b685 Merge from eCos master repository on 2001-07-28-00:17:32-BST
jlarmour
parents: 162
diff changeset
191 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
192 if ((tftp_stream.actual_len >= 0) && (tftp_stream.actual_len < SEGSIZE)) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
193 // Out of data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
194 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
195 }
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
196 timeout.tv_sec = (tftp_stream.last_good_block == 0) ? 10*TFTP_TIMEOUT_PERIOD : TFTP_TIMEOUT_PERIOD;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
197 timeout.tv_usec = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
198 recv_len = sizeof(tftp_stream.data);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
199 if ((data_len = __udp_recvfrom(&tftp_stream.data[0], recv_len, &tftp_stream.from_addr,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
200 &tftp_stream.local_addr, &timeout)) < 0) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
201 // No data, try again
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
202 diag_printf("TFTP timed out %d/%d\n", tftp_stream.total_timeouts+1, TFTP_TIMEOUT_MAX);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
203 if ((++tftp_stream.total_timeouts > TFTP_TIMEOUT_MAX) ||
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
204 (tftp_stream.last_good_block == 0)) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
205 // Timeout - no data received
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
206 *err = TFTP_TIMEOUT;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
207 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
208 }
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
209 // Send out the ACK for the last block - maybe server will retry
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
210 if (tftp_ack(err) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
211 return -1;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
212 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
213 } else {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
214 tftp_stream.packets_received++;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
215 if (ntohs(hdr->th_opcode) == DATA) {
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
216 if (ntohs(hdr->th_block) == (cyg_uint16)((tftp_stream.last_good_block+1) & 0xFFFF)) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
217 // Consume this data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
218 data_len -= 4; /* Sizeof TFTP header */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
219 tftp_stream.avail = tftp_stream.actual_len = data_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
220 tftp_stream.bufp = hdr->th_data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
221 tftp_stream.last_good_block++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
222 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
223 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
224 if (ntohs(hdr->th_opcode) == ERROR) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
225 *err = ntohs(hdr->th_code);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
226 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
227 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
228 // What kind of packet is this?
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
229 *err = TFTP_PROTOCOL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
230 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
231 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
232 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
233 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
234 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
235 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
236 return total_bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
237 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
238
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
239 char *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
240 tftp_error(int err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
241 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
242 char *errmsg = "Unknown error";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
243
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
244 switch (err) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
245 case TFTP_ENOTFOUND:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
246 return "file not found";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
247 case TFTP_EACCESS:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
248 return "access violation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
249 case TFTP_ENOSPACE:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
250 return "disk full or allocation exceeded";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
251 case TFTP_EBADOP:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
252 return "illegal TFTP operation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
253 case TFTP_EBADID:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
254 return "unknown transfer ID";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
255 case TFTP_EEXISTS:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
256 return "file already exists";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
257 case TFTP_ENOUSER:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
258 return "no such user";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
259 case TFTP_TIMEOUT:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
260 return "operation timed out";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
261 case TFTP_NETERR:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
262 return "some sort of network error";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
263 case TFTP_INVALID:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
264 return "invalid parameter";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
265 case TFTP_PROTOCOL:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
266 return "protocol violation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
267 case TFTP_TOOLARGE:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
268 return "file is larger than buffer";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
269 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
270 return errmsg;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
271 }
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
272
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
273 //
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
274 // RedBoot interface
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
275 //
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
276 GETC_IO_FUNCS(tftp_io, tftp_stream_open, tftp_stream_close,
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
277 0, tftp_stream_read, tftp_error);
245
a6660704f7a6 Fix problem with x/y-modem load.
gthomas
parents: 228
diff changeset
278 RedBoot_load(tftp, tftp_io, true, true, 0);
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
279