Browse Source

Add tftp_ack() and tftp_error()

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
7d63b39e3d
1 changed files with 73 additions and 7 deletions
  1. 73
    7
      src/proto/tftpcore.c

+ 73
- 7
src/proto/tftpcore.c View File

25
  * (i.e. comes from the TFTP server, has the correct destination port,
25
  * (i.e. comes from the TFTP server, has the correct destination port,
26
  * and is addressed either to our IP address or to our multicast
26
  * and is addressed either to our IP address or to our multicast
27
  * listening address).
27
  * listening address).
28
+ *
29
+ * Invoke await_tftp() using code such as
30
+ *
31
+ * @code
32
+ *
33
+ * if ( await_reply ( await_tftp, 0, &tftp_state, timeout ) ) {
34
+ *	...
35
+ * }
36
+ *
37
+ * @endcode
28
  */
38
  */
29
-static int await_tftp ( int ival __unused, void *ptr,
30
-			unsigned short ptype __unused, struct iphdr *ip,
31
-			struct udphdr *udp, struct tcphdr *tcp __unused ) {
39
+int await_tftp ( int ival __unused, void *ptr, unsigned short ptype __unused,
40
+		 struct iphdr *ip, struct udphdr *udp,
41
+		 struct tcphdr *tcp __unused ) {
32
 	struct tftp_state *state = ptr;
42
 	struct tftp_state *state = ptr;
33
 
43
 
34
 	/* Must have valid UDP (and, therefore, also IP) headers */
44
 	/* Must have valid UDP (and, therefore, also IP) headers */
55
 /**
65
 /**
56
  * Issue a TFTP open request (RRQ)
66
  * Issue a TFTP open request (RRQ)
57
  *
67
  *
58
- * @v filename				File name
59
  * @v state				TFTP transfer state
68
  * @v state				TFTP transfer state
60
  * @v tftp_state::server::sin_addr	TFTP server IP address
69
  * @v tftp_state::server::sin_addr	TFTP server IP address
61
  * @v tftp_state::server::sin_port	TFTP server UDP port, or 0
70
  * @v tftp_state::server::sin_port	TFTP server UDP port, or 0
62
  * @v tftp_state::client::sin_addr	Client multicast IP address, or 0.0.0.0
71
  * @v tftp_state::client::sin_addr	Client multicast IP address, or 0.0.0.0
63
  * @v tftp_state::client::sin_port	Client UDP port, or 0
72
  * @v tftp_state::client::sin_port	Client UDP port, or 0
64
  * @v tftp_state::blksize		Requested blksize, or 0
73
  * @v tftp_state::blksize		Requested blksize, or 0
74
+ * @v filename				File name
65
  * @ret True				Received a non-error response
75
  * @ret True				Received a non-error response
66
  * @ret False				Received error response / no response
76
  * @ret False				Received error response / no response
67
  * @ret tftp_state::client::sin_port	Client UDP port
77
  * @ret tftp_state::client::sin_port	Client UDP port
120
  * leave_group() at appropriate times.
130
  * leave_group() at appropriate times.
121
  *
131
  *
122
  */
132
  */
123
-int tftp_open ( const char *filename, struct tftp_state *state,
133
+int tftp_open ( struct tftp_state *state, const char *filename,
124
 		union tftp_any **tftp ) {
134
 		union tftp_any **tftp ) {
125
 	static unsigned short lport = 2000; /* local port */
135
 	static unsigned short lport = 2000; /* local port */
126
 	int fixed_lport;
136
 	int fixed_lport;
165
 			state->client.sin_port = ++lport;
175
 			state->client.sin_port = ++lport;
166
 		
176
 		
167
 		/* Send the RRQ */
177
 		/* Send the RRQ */
178
+		DBG ( "TFTPCORE: requesting %@:%d/%s from port %d\n",
179
+		      state->server.sin_addr.s_addr, state->server.sin_port,
180
+		      rrq.data, state->client.sin_port );
168
 		if ( ! udp_transmit ( state->server.sin_addr.s_addr,
181
 		if ( ! udp_transmit ( state->server.sin_addr.s_addr,
169
 				      state->client.sin_port,
182
 				      state->client.sin_port,
170
 				      state->server.sin_port,
183
 				      state->server.sin_port,
185
 /**
198
 /**
186
  * Process a TFTP OACK packet
199
  * Process a TFTP OACK packet
187
  *
200
  *
188
- * @v oack				The TFTP OACK packet
189
  * @v state				TFTP transfer state
201
  * @v state				TFTP transfer state
202
+ * @v oack				The TFTP OACK packet
190
  * @ret True				Options were processed successfully
203
  * @ret True				Options were processed successfully
191
  * @ret False				Options were not processed successfully
204
  * @ret False				Options were not processed successfully
192
  * @ret tftp_state::blksize		Negotiated blksize
205
  * @ret tftp_state::blksize		Negotiated blksize
213
  * #TFTP_DEFAULT_BLKSIZE before returning, you probably don't need to
226
  * #TFTP_DEFAULT_BLKSIZE before returning, you probably don't need to
214
  * worry about this.
227
  * worry about this.
215
  */
228
  */
216
-int tftp_process_opts ( struct tftp_oack *oack, struct tftp_state *state ) {
229
+int tftp_process_opts ( struct tftp_state *state, struct tftp_oack *oack ) {
217
 	const char *p;
230
 	const char *p;
218
 	const char *end;
231
 	const char *end;
219
 
232
 
297
 
310
 
298
 	return 1;
311
 	return 1;
299
 }
312
 }
313
+
314
+/**
315
+ * Acknowledge a TFTP packet
316
+ *
317
+ * @v state				TFTP transfer state
318
+ * @v tftp_state::server::sin_addr	TFTP server IP address
319
+ * @v tftp_state::server::sin_port	TFTP server UDP port
320
+ * @v tftp_state::client::sin_port	Client UDP port
321
+ * @v tftp_state::block			Most recently received block number
322
+ * @ret True				Acknowledgement packet was sent
323
+ * @ret False				Acknowledgement packet was not sent
324
+ * 
325
+ * Send a TFTP ACK packet for the most recently received block.
326
+ *
327
+ * This sends only a single ACK packet; it does not wait for the
328
+ * server's response.
329
+ */
330
+int tftp_ack ( struct tftp_state *state ) {
331
+	struct tftp_ack ack;
332
+
333
+	ack.opcode = htons ( TFTP_ACK );
334
+	ack.block = htons ( state->block );
335
+	return udp_transmit ( state->server.sin_addr.s_addr,
336
+			      state->client.sin_port, state->server.sin_port,
337
+			      sizeof ( ack ), &ack );
338
+}
339
+
340
+/**
341
+ * Send a TFTP error
342
+ *
343
+ * @v state				TFTP transfer state
344
+ * @v tftp_state::server::sin_addr	TFTP server IP address
345
+ * @v tftp_state::server::sin_port	TFTP server UDP port
346
+ * @v tftp_state::client::sin_port	Client UDP port
347
+ * @v err				TFTP error code
348
+ * @v errmsg				Descriptive error string
349
+ * @ret True				Error packet was sent
350
+ * @ret False				Error packet was not sent
351
+ *
352
+ * Send a TFTP ERROR packet back to the server to terminate the
353
+ * transfer.
354
+ */
355
+int tftp_error ( struct tftp_state *state, int err, const char *errmsg ) {
356
+	struct tftp_error error;
357
+
358
+	DBG ( "TFTPCORE: aborting with error %d (%s)\n", err, errmsg );
359
+	error.opcode = htons ( TFTP_ERROR );
360
+	error.errcode = htons ( err );
361
+	strncpy ( error.errmsg, errmsg, sizeof ( error.errmsg ) );
362
+	return udp_transmit ( state->server.sin_addr.s_addr,
363
+			      state->client.sin_port, state->server.sin_port,
364
+			      sizeof ( error ), &error );
365
+}

Loading…
Cancel
Save