|
|
1.1 root 1: /*
2: * Copyright (C) 2006 Michael Brown <[email protected]>.
3: *
4: * This program is free software; you can redistribute it and/or
5: * modify it under the terms of the GNU General Public License as
6: * published by the Free Software Foundation; either version 2 of the
7: * License, or any later version.
8: *
9: * This program is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with this program; if not, write to the Free Software
16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <stdint.h>
22: #include <stdlib.h>
23: #include <stdio.h>
24: #include <string.h>
25: #include <strings.h>
26: #include <byteswap.h>
27: #include <errno.h>
28: #include <assert.h>
29: #include <ipxe/refcnt.h>
30: #include <ipxe/iobuf.h>
31: #include <ipxe/xfer.h>
32: #include <ipxe/open.h>
33: #include <ipxe/uri.h>
34: #include <ipxe/tcpip.h>
35: #include <ipxe/retry.h>
36: #include <ipxe/features.h>
37: #include <ipxe/bitmap.h>
38: #include <ipxe/settings.h>
39: #include <ipxe/dhcp.h>
40: #include <ipxe/uri.h>
41: #include <ipxe/tftp.h>
42:
43: /** @file
44: *
45: * TFTP protocol
46: *
47: */
48:
49: FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
50:
51: /* TFTP-specific error codes */
52: #define EINVAL_BLKSIZE __einfo_error ( EINFO_EINVAL_BLKSIZE )
53: #define EINFO_EINVAL_BLKSIZE __einfo_uniqify \
54: ( EINFO_EINVAL, 0x01, "Invalid blksize" )
55: #define EINVAL_TSIZE __einfo_error ( EINFO_EINVAL_TSIZE )
56: #define EINFO_EINVAL_TSIZE __einfo_uniqify \
57: ( EINFO_EINVAL, 0x02, "Invalid tsize" )
58: #define EINVAL_MC_NO_PORT __einfo_error ( EINFO_EINVAL_MC_NO_PORT )
59: #define EINFO_EINVAL_MC_NO_PORT __einfo_uniqify \
60: ( EINFO_EINVAL, 0x03, "Missing multicast port" )
61: #define EINVAL_MC_NO_MC __einfo_error ( EINFO_EINVAL_MC_NO_MC )
62: #define EINFO_EINVAL_MC_NO_MC __einfo_uniqify \
63: ( EINFO_EINVAL, 0x04, "Missing multicast mc" )
64: #define EINVAL_MC_INVALID_MC __einfo_error ( EINFO_EINVAL_MC_INVALID_MC )
65: #define EINFO_EINVAL_MC_INVALID_MC __einfo_uniqify \
66: ( EINFO_EINVAL, 0x05, "Missing multicast IP" )
67: #define EINVAL_MC_INVALID_IP __einfo_error ( EINFO_EINVAL_MC_INVALID_IP )
68: #define EINFO_EINVAL_MC_INVALID_IP __einfo_uniqify \
69: ( EINFO_EINVAL, 0x06, "Invalid multicast IP" )
70: #define EINVAL_MC_INVALID_PORT __einfo_error ( EINFO_EINVAL_MC_INVALID_PORT )
71: #define EINFO_EINVAL_MC_INVALID_PORT __einfo_uniqify \
72: ( EINFO_EINVAL, 0x07, "Invalid multicast port" )
73:
74: /**
75: * A TFTP request
76: *
77: * This data structure holds the state for an ongoing TFTP transfer.
78: */
79: struct tftp_request {
80: /** Reference count */
81: struct refcnt refcnt;
82: /** Data transfer interface */
83: struct interface xfer;
84:
85: /** URI being fetched */
86: struct uri *uri;
87: /** Transport layer interface */
88: struct interface socket;
89: /** Multicast transport layer interface */
90: struct interface mc_socket;
91:
92: /** Data block size
93: *
94: * This is the "blksize" option negotiated with the TFTP
95: * server. (If the TFTP server does not support TFTP options,
96: * this will default to 512).
97: */
98: unsigned int blksize;
99: /** File size
100: *
101: * This is the value returned in the "tsize" option from the
102: * TFTP server. If the TFTP server does not support the
103: * "tsize" option, this value will be zero.
104: */
105: unsigned long tsize;
106:
107: /** Server port
108: *
109: * This is the port to which RRQ packets are sent.
110: */
111: unsigned int port;
112: /** Peer address
113: *
114: * The peer address is determined by the first response
115: * received to the TFTP RRQ.
116: */
117: struct sockaddr_tcpip peer;
118: /** Request flags */
119: unsigned int flags;
120: /** MTFTP timeout count */
121: unsigned int mtftp_timeouts;
122:
123: /** Block bitmap */
124: struct bitmap bitmap;
125: /** Maximum known length
126: *
127: * We don't always know the file length in advance. In
128: * particular, if the TFTP server doesn't support the tsize
129: * option, or we are using MTFTP, then we don't know the file
130: * length until we see the end-of-file block (which, in the
131: * case of MTFTP, may not be the last block we see).
132: *
133: * This value is updated whenever we obtain information about
134: * the file length.
135: */
136: size_t filesize;
137: /** Retransmission timer */
138: struct retry_timer timer;
139: };
140:
141: /** TFTP request flags */
142: enum {
143: /** Send ACK packets */
144: TFTP_FL_SEND_ACK = 0x0001,
145: /** Request blksize and tsize options */
146: TFTP_FL_RRQ_SIZES = 0x0002,
147: /** Request multicast option */
148: TFTP_FL_RRQ_MULTICAST = 0x0004,
149: /** Perform MTFTP recovery on timeout */
150: TFTP_FL_MTFTP_RECOVERY = 0x0008,
151: /** Only get filesize and then abort the transfer */
152: TFTP_FL_SIZEONLY = 0x0010,
153: };
154:
155: /** Maximum number of MTFTP open requests before falling back to TFTP */
156: #define MTFTP_MAX_TIMEOUTS 3
157:
158: /**
159: * Free TFTP request
160: *
161: * @v refcnt Reference counter
162: */
163: static void tftp_free ( struct refcnt *refcnt ) {
164: struct tftp_request *tftp =
165: container_of ( refcnt, struct tftp_request, refcnt );
166:
167: uri_put ( tftp->uri );
168: bitmap_free ( &tftp->bitmap );
169: free ( tftp );
170: }
171:
172: /**
173: * Mark TFTP request as complete
174: *
175: * @v tftp TFTP connection
176: * @v rc Return status code
177: */
178: static void tftp_done ( struct tftp_request *tftp, int rc ) {
179:
180: DBGC ( tftp, "TFTP %p finished with status %d (%s)\n",
181: tftp, rc, strerror ( rc ) );
182:
183: /* Stop the retry timer */
184: stop_timer ( &tftp->timer );
185:
186: /* Close all data transfer interfaces */
187: intf_shutdown ( &tftp->socket, rc );
188: intf_shutdown ( &tftp->mc_socket, rc );
189: intf_shutdown ( &tftp->xfer, rc );
190: }
191:
192: /**
193: * Reopen TFTP socket
194: *
195: * @v tftp TFTP connection
196: * @ret rc Return status code
197: */
198: static int tftp_reopen ( struct tftp_request *tftp ) {
199: struct sockaddr_tcpip server;
200: int rc;
201:
202: /* Close socket */
203: intf_restart ( &tftp->socket, 0 );
204:
205: /* Disable ACK sending. */
206: tftp->flags &= ~TFTP_FL_SEND_ACK;
207:
208: /* Reset peer address */
209: memset ( &tftp->peer, 0, sizeof ( tftp->peer ) );
210:
211: /* Open socket */
212: memset ( &server, 0, sizeof ( server ) );
213: server.st_port = htons ( tftp->port );
214: if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM,
215: ( struct sockaddr * ) &server,
216: tftp->uri->host, NULL ) ) != 0 ) {
217: DBGC ( tftp, "TFTP %p could not open socket: %s\n",
218: tftp, strerror ( rc ) );
219: return rc;
220: }
221:
222: return 0;
223: }
224:
225: /**
226: * Reopen TFTP multicast socket
227: *
228: * @v tftp TFTP connection
229: * @v local Local socket address
230: * @ret rc Return status code
231: */
232: static int tftp_reopen_mc ( struct tftp_request *tftp,
233: struct sockaddr *local ) {
234: int rc;
235:
236: /* Close multicast socket */
237: intf_restart ( &tftp->mc_socket, 0 );
238:
239: /* Open multicast socket. We never send via this socket, so
240: * use the local address as the peer address (since the peer
241: * address cannot be NULL).
242: */
243: if ( ( rc = xfer_open_socket ( &tftp->mc_socket, SOCK_DGRAM,
244: local, local ) ) != 0 ) {
245: DBGC ( tftp, "TFTP %p could not open multicast "
246: "socket: %s\n", tftp, strerror ( rc ) );
247: return rc;
248: }
249:
250: return 0;
251: }
252:
253: /**
254: * Presize TFTP receive buffers and block bitmap
255: *
256: * @v tftp TFTP connection
257: * @v filesize Known minimum file size
258: * @ret rc Return status code
259: */
260: static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
261: unsigned int num_blocks;
262: int rc;
263:
264: /* Do nothing if we are already large enough */
265: if ( filesize <= tftp->filesize )
266: return 0;
267:
268: /* Record filesize */
269: tftp->filesize = filesize;
270:
271: /* Notify recipient of file size */
272: xfer_seek ( &tftp->xfer, filesize );
273: xfer_seek ( &tftp->xfer, 0 );
274:
275: /* Calculate expected number of blocks. Note that files whose
276: * length is an exact multiple of the blocksize will have a
277: * trailing zero-length block, which must be included.
278: */
279: num_blocks = ( ( filesize / tftp->blksize ) + 1 );
280: if ( ( rc = bitmap_resize ( &tftp->bitmap, num_blocks ) ) != 0 ) {
281: DBGC ( tftp, "TFTP %p could not resize bitmap to %d blocks: "
282: "%s\n", tftp, num_blocks, strerror ( rc ) );
283: return rc;
284: }
285:
286: return 0;
287: }
288:
289: /**
290: * TFTP requested blocksize
291: *
292: * This is treated as a global configuration parameter.
293: */
294: static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
295:
296: /**
297: * Set TFTP request blocksize
298: *
299: * @v blksize Requested block size
300: */
301: void tftp_set_request_blksize ( unsigned int blksize ) {
302: if ( blksize < TFTP_DEFAULT_BLKSIZE )
303: blksize = TFTP_DEFAULT_BLKSIZE;
304: tftp_request_blksize = blksize;
305: }
306:
307: /**
308: * MTFTP multicast receive address
309: *
310: * This is treated as a global configuration parameter.
311: */
312: static struct sockaddr_in tftp_mtftp_socket = {
313: .sin_family = AF_INET,
314: .sin_addr.s_addr = htonl ( 0xefff0101 ),
315: .sin_port = htons ( 3001 ),
316: };
317:
318: /**
319: * Set MTFTP multicast address
320: *
321: * @v address Multicast IPv4 address
322: */
323: void tftp_set_mtftp_address ( struct in_addr address ) {
324: tftp_mtftp_socket.sin_addr = address;
325: }
326:
327: /**
328: * Set MTFTP multicast port
329: *
330: * @v port Multicast port
331: */
332: void tftp_set_mtftp_port ( unsigned int port ) {
333: tftp_mtftp_socket.sin_port = htons ( port );
334: }
335:
336: /**
337: * Transmit RRQ
338: *
339: * @v tftp TFTP connection
340: * @ret rc Return status code
341: */
342: static int tftp_send_rrq ( struct tftp_request *tftp ) {
343: struct tftp_rrq *rrq;
344: const char *path;
345: size_t len;
346: struct io_buffer *iobuf;
347:
348: /* Strip initial '/' if present. If we were opened via the
349: * URI interface, then there will be an initial '/', since a
350: * full tftp:// URI provides no way to specify a non-absolute
351: * path. However, many TFTP servers (particularly Windows
352: * TFTP servers) complain about having an initial '/', and it
353: * violates user expectations to have a '/' silently added to
354: * the DHCP-specified filename.
355: */
356: path = tftp->uri->path;
357: if ( *path == '/' )
358: path++;
359:
360: DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
361:
362: /* Allocate buffer */
363: len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */
364: + 5 + 1 /* "octet" + NUL */
365: + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */
366: + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */
367: + 9 + 1 + 1 /* "multicast" + NUL + NUL */ );
368: iobuf = xfer_alloc_iob ( &tftp->socket, len );
369: if ( ! iobuf )
370: return -ENOMEM;
371:
372: /* Build request */
373: rrq = iob_put ( iobuf, sizeof ( *rrq ) );
374: rrq->opcode = htons ( TFTP_RRQ );
375: iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ),
376: "%s%coctet", path, 0 ) + 1 );
377: if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
378: iob_put ( iobuf, snprintf ( iobuf->tail,
379: iob_tailroom ( iobuf ),
380: "blksize%c%d%ctsize%c0", 0,
381: tftp_request_blksize, 0, 0 ) + 1 );
382: }
383: if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
384: iob_put ( iobuf, snprintf ( iobuf->tail,
385: iob_tailroom ( iobuf ),
386: "multicast%c", 0 ) + 1 );
387: }
388:
389: /* RRQ always goes to the address specified in the initial
390: * xfer_open() call
391: */
392: return xfer_deliver_iob ( &tftp->socket, iobuf );
393: }
394:
395: /**
396: * Transmit ACK
397: *
398: * @v tftp TFTP connection
399: * @ret rc Return status code
400: */
401: static int tftp_send_ack ( struct tftp_request *tftp ) {
402: struct tftp_ack *ack;
403: struct io_buffer *iobuf;
404: struct xfer_metadata meta = {
405: .dest = ( struct sockaddr * ) &tftp->peer,
406: };
407: unsigned int block;
408:
409: /* Determine next required block number */
410: block = bitmap_first_gap ( &tftp->bitmap );
411: DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block );
412:
413: /* Allocate buffer */
414: iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
415: if ( ! iobuf )
416: return -ENOMEM;
417:
418: /* Build ACK */
419: ack = iob_put ( iobuf, sizeof ( *ack ) );
420: ack->opcode = htons ( TFTP_ACK );
421: ack->block = htons ( block );
422:
423: /* ACK always goes to the peer recorded from the RRQ response */
424: return xfer_deliver ( &tftp->socket, iobuf, &meta );
425: }
426:
427: /**
428: * Transmit ERROR (Abort)
429: *
430: * @v tftp TFTP connection
431: * @v errcode TFTP error code
432: * @v errmsg Error message string
433: * @ret rc Return status code
434: */
435: static int tftp_send_error ( struct tftp_request *tftp, int errcode,
436: const char *errmsg ) {
437: struct tftp_error *err;
438: struct io_buffer *iobuf;
439: struct xfer_metadata meta = {
440: .dest = ( struct sockaddr * ) &tftp->peer,
441: };
442: size_t msglen;
443:
444: DBGC2 ( tftp, "TFTP %p sending ERROR %d: %s\n", tftp, errcode,
445: errmsg );
446:
447: /* Allocate buffer */
448: msglen = sizeof ( *err ) + strlen ( errmsg ) + 1 /* NUL */;
449: iobuf = xfer_alloc_iob ( &tftp->socket, msglen );
450: if ( ! iobuf )
451: return -ENOMEM;
452:
453: /* Build ERROR */
454: err = iob_put ( iobuf, msglen );
455: err->opcode = htons ( TFTP_ERROR );
456: err->errcode = htons ( errcode );
457: strcpy ( err->errmsg, errmsg );
458:
459: /* ERR always goes to the peer recorded from the RRQ response */
460: return xfer_deliver ( &tftp->socket, iobuf, &meta );
461: }
462:
463: /**
464: * Transmit next relevant packet
465: *
466: * @v tftp TFTP connection
467: * @ret rc Return status code
468: */
469: static int tftp_send_packet ( struct tftp_request *tftp ) {
470:
471: /* Update retransmission timer. While name resolution takes place the
472: * window is zero. Avoid unnecessary delay after name resolution
473: * completes by retrying immediately.
474: */
475: stop_timer ( &tftp->timer );
476: if ( xfer_window ( &tftp->socket ) ) {
477: start_timer ( &tftp->timer );
478: } else {
479: start_timer_nodelay ( &tftp->timer );
480: }
481:
482: /* Send RRQ or ACK as appropriate */
483: if ( ! tftp->peer.st_family ) {
484: return tftp_send_rrq ( tftp );
485: } else {
486: if ( tftp->flags & TFTP_FL_SEND_ACK ) {
487: return tftp_send_ack ( tftp );
488: } else {
489: return 0;
490: }
491: }
492: }
493:
494: /**
495: * Handle TFTP retransmission timer expiry
496: *
497: * @v timer Retry timer
498: * @v fail Failure indicator
499: */
500: static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
501: struct tftp_request *tftp =
502: container_of ( timer, struct tftp_request, timer );
503: int rc;
504:
505: /* If we are doing MTFTP, attempt the various recovery strategies */
506: if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) {
507: if ( tftp->peer.st_family ) {
508: /* If we have received any response from the server,
509: * try resending the RRQ to restart the download.
510: */
511: DBGC ( tftp, "TFTP %p attempting reopen\n", tftp );
512: if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
513: goto err;
514: } else {
515: /* Fall back to plain TFTP after several attempts */
516: tftp->mtftp_timeouts++;
517: DBGC ( tftp, "TFTP %p timeout %d waiting for MTFTP "
518: "open\n", tftp, tftp->mtftp_timeouts );
519:
520: if ( tftp->mtftp_timeouts > MTFTP_MAX_TIMEOUTS ) {
521: DBGC ( tftp, "TFTP %p falling back to plain "
522: "TFTP\n", tftp );
523: tftp->flags = TFTP_FL_RRQ_SIZES;
524:
525: /* Close multicast socket */
526: intf_restart ( &tftp->mc_socket, 0 );
527:
528: /* Reset retry timer */
529: start_timer_nodelay ( &tftp->timer );
530:
531: /* The blocksize may change: discard
532: * the block bitmap
533: */
534: bitmap_free ( &tftp->bitmap );
535: memset ( &tftp->bitmap, 0,
536: sizeof ( tftp->bitmap ) );
537:
538: /* Reopen on standard TFTP port */
539: tftp->port = TFTP_PORT;
540: if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
541: goto err;
542: }
543: }
544: } else {
545: /* Not doing MTFTP (or have fallen back to plain
546: * TFTP); fail as per normal.
547: */
548: if ( fail ) {
549: rc = -ETIMEDOUT;
550: goto err;
551: }
552: }
553: tftp_send_packet ( tftp );
554: return;
555:
556: err:
557: tftp_done ( tftp, rc );
558: }
559:
560: /**
561: * Process TFTP "blksize" option
562: *
563: * @v tftp TFTP connection
564: * @v value Option value
565: * @ret rc Return status code
566: */
567: static int tftp_process_blksize ( struct tftp_request *tftp,
568: const char *value ) {
569: char *end;
570:
571: tftp->blksize = strtoul ( value, &end, 10 );
572: if ( *end ) {
573: DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
574: tftp, value );
575: return -EINVAL_BLKSIZE;
576: }
577: DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
578:
579: return 0;
580: }
581:
582: /**
583: * Process TFTP "tsize" option
584: *
585: * @v tftp TFTP connection
586: * @v value Option value
587: * @ret rc Return status code
588: */
589: static int tftp_process_tsize ( struct tftp_request *tftp,
590: const char *value ) {
591: char *end;
592:
593: tftp->tsize = strtoul ( value, &end, 10 );
594: if ( *end ) {
595: DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
596: tftp, value );
597: return -EINVAL_TSIZE;
598: }
599: DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
600:
601: return 0;
602: }
603:
604: /**
605: * Process TFTP "multicast" option
606: *
607: * @v tftp TFTP connection
608: * @v value Option value
609: * @ret rc Return status code
610: */
611: static int tftp_process_multicast ( struct tftp_request *tftp,
612: const char *value ) {
613: union {
614: struct sockaddr sa;
615: struct sockaddr_in sin;
616: } socket;
617: char buf[ strlen ( value ) + 1 ];
618: char *addr;
619: char *port;
620: char *port_end;
621: char *mc;
622: char *mc_end;
623: int rc;
624:
625: /* Split value into "addr,port,mc" fields */
626: memcpy ( buf, value, sizeof ( buf ) );
627: addr = buf;
628: port = strchr ( addr, ',' );
629: if ( ! port ) {
630: DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp );
631: return -EINVAL_MC_NO_PORT;
632: }
633: *(port++) = '\0';
634: mc = strchr ( port, ',' );
635: if ( ! mc ) {
636: DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp );
637: return -EINVAL_MC_NO_MC;
638: }
639: *(mc++) = '\0';
640:
641: /* Parse parameters */
642: if ( strtoul ( mc, &mc_end, 0 ) == 0 )
643: tftp->flags &= ~TFTP_FL_SEND_ACK;
644: if ( *mc_end ) {
645: DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc );
646: return -EINVAL_MC_INVALID_MC;
647: }
648: DBGC ( tftp, "TFTP %p is%s the master client\n",
649: tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) );
650: if ( *addr && *port ) {
651: socket.sin.sin_family = AF_INET;
652: if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) {
653: DBGC ( tftp, "TFTP %p multicast invalid IP address "
654: "%s\n", tftp, addr );
655: return -EINVAL_MC_INVALID_IP;
656: }
657: DBGC ( tftp, "TFTP %p multicast IP address %s\n",
658: tftp, inet_ntoa ( socket.sin.sin_addr ) );
659: socket.sin.sin_port = htons ( strtoul ( port, &port_end, 0 ) );
660: if ( *port_end ) {
661: DBGC ( tftp, "TFTP %p multicast invalid port %s\n",
662: tftp, port );
663: return -EINVAL_MC_INVALID_PORT;
664: }
665: DBGC ( tftp, "TFTP %p multicast port %d\n",
666: tftp, ntohs ( socket.sin.sin_port ) );
667: if ( ( rc = tftp_reopen_mc ( tftp, &socket.sa ) ) != 0 )
668: return rc;
669: }
670:
671: return 0;
672: }
673:
674: /** A TFTP option */
675: struct tftp_option {
676: /** Option name */
677: const char *name;
678: /** Option processor
679: *
680: * @v tftp TFTP connection
681: * @v value Option value
682: * @ret rc Return status code
683: */
684: int ( * process ) ( struct tftp_request *tftp, const char *value );
685: };
686:
687: /** Recognised TFTP options */
688: static struct tftp_option tftp_options[] = {
689: { "blksize", tftp_process_blksize },
690: { "tsize", tftp_process_tsize },
691: { "multicast", tftp_process_multicast },
692: { NULL, NULL }
693: };
694:
695: /**
696: * Process TFTP option
697: *
698: * @v tftp TFTP connection
699: * @v name Option name
700: * @v value Option value
701: * @ret rc Return status code
702: */
703: static int tftp_process_option ( struct tftp_request *tftp,
704: const char *name, const char *value ) {
705: struct tftp_option *option;
706:
707: for ( option = tftp_options ; option->name ; option++ ) {
708: if ( strcasecmp ( name, option->name ) == 0 )
709: return option->process ( tftp, value );
710: }
711:
712: DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
713: tftp, name, value );
714:
715: /* Unknown options should be silently ignored */
716: return 0;
717: }
718:
719: /**
720: * Receive OACK
721: *
722: * @v tftp TFTP connection
723: * @v buf Temporary data buffer
724: * @v len Length of temporary data buffer
725: * @ret rc Return status code
726: */
727: static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
728: struct tftp_oack *oack = buf;
729: char *end = buf + len;
730: char *name;
731: char *value;
732: char *next;
733: int rc = 0;
734:
735: /* Sanity check */
736: if ( len < sizeof ( *oack ) ) {
737: DBGC ( tftp, "TFTP %p received underlength OACK packet "
738: "length %zd\n", tftp, len );
739: rc = -EINVAL;
740: goto done;
741: }
742:
743: /* Process each option in turn */
744: for ( name = oack->data ; name < end ; name = next ) {
745:
746: /* Parse option name and value
747: *
748: * We treat parsing errors as non-fatal, because there
749: * exists at least one TFTP server (IBM Tivoli PXE
750: * Server 5.1.0.3) that has been observed to send
751: * malformed OACKs containing trailing garbage bytes.
752: */
753: value = ( name + strnlen ( name, ( end - name ) ) + 1 );
754: if ( value > end ) {
755: DBGC ( tftp, "TFTP %p received OACK with malformed "
756: "option name:\n", tftp );
757: DBGC_HD ( tftp, oack, len );
758: break;
759: }
760: if ( value == end ) {
761: DBGC ( tftp, "TFTP %p received OACK missing value "
762: "for option \"%s\"\n", tftp, name );
763: DBGC_HD ( tftp, oack, len );
764: break;
765: }
766: next = ( value + strnlen ( value, ( end - value ) ) + 1 );
767: if ( next > end ) {
768: DBGC ( tftp, "TFTP %p received OACK with malformed "
769: "value for option \"%s\":\n", tftp, name );
770: DBGC_HD ( tftp, oack, len );
771: break;
772: }
773:
774: /* Process option */
775: if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
776: goto done;
777: }
778:
779: /* Process tsize information, if available */
780: if ( tftp->tsize ) {
781: if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 )
782: goto done;
783: }
784:
785: /* Abort request if only trying to determine file size */
786: if ( tftp->flags & TFTP_FL_SIZEONLY ) {
787: rc = 0;
788: tftp_send_error ( tftp, 0, "TFTP Aborted" );
789: tftp_done ( tftp, rc );
790: return rc;
791: }
792:
793: /* Request next data block */
794: tftp_send_packet ( tftp );
795:
796: done:
797: if ( rc )
798: tftp_done ( tftp, rc );
799: return rc;
800: }
801:
802: /**
803: * Receive DATA
804: *
805: * @v tftp TFTP connection
806: * @v iobuf I/O buffer
807: * @ret rc Return status code
808: *
809: * Takes ownership of I/O buffer.
810: */
811: static int tftp_rx_data ( struct tftp_request *tftp,
812: struct io_buffer *iobuf ) {
813: struct tftp_data *data = iobuf->data;
814: struct xfer_metadata meta;
815: unsigned int block;
816: off_t offset;
817: size_t data_len;
818: int rc;
819:
820: if ( tftp->flags & TFTP_FL_SIZEONLY ) {
821: /* If we get here then server doesn't support SIZE option */
822: rc = -ENOTSUP;
823: tftp_send_error ( tftp, 0, "TFTP Aborted" );
824: goto done;
825: }
826:
827: /* Sanity check */
828: if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
829: DBGC ( tftp, "TFTP %p received underlength DATA packet "
830: "length %zd\n", tftp, iob_len ( iobuf ) );
831: rc = -EINVAL;
832: goto done;
833: }
834:
835: /* Calculate block number */
836: block = ( ( bitmap_first_gap ( &tftp->bitmap ) + 1 ) & ~0xffff );
837: if ( data->block == 0 && block == 0 ) {
838: DBGC ( tftp, "TFTP %p received data block 0\n", tftp );
839: rc = -EINVAL;
840: goto done;
841: }
842: block += ( ntohs ( data->block ) - 1 );
843:
844: /* Extract data */
845: offset = ( block * tftp->blksize );
846: iob_pull ( iobuf, sizeof ( *data ) );
847: data_len = iob_len ( iobuf );
848: if ( data_len > tftp->blksize ) {
849: DBGC ( tftp, "TFTP %p received overlength DATA packet "
850: "length %zd\n", tftp, data_len );
851: rc = -EINVAL;
852: goto done;
853: }
854:
855: /* Deliver data */
856: memset ( &meta, 0, sizeof ( meta ) );
857: meta.flags = XFER_FL_ABS_OFFSET;
858: meta.offset = offset;
859: if ( ( rc = xfer_deliver ( &tftp->xfer, iob_disown ( iobuf ),
860: &meta ) ) != 0 ) {
861: DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
862: tftp, strerror ( rc ) );
863: goto done;
864: }
865:
866: /* Ensure block bitmap is ready */
867: if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 )
868: goto done;
869:
870: /* Mark block as received */
871: bitmap_set ( &tftp->bitmap, block );
872:
873: /* Acknowledge block */
874: tftp_send_packet ( tftp );
875:
876: /* If all blocks have been received, finish. */
877: if ( bitmap_full ( &tftp->bitmap ) )
878: tftp_done ( tftp, 0 );
879:
880: done:
881: free_iob ( iobuf );
882: if ( rc )
883: tftp_done ( tftp, rc );
884: return rc;
885: }
886:
887: /**
888: * Convert TFTP error code to return status code
889: *
890: * @v errcode TFTP error code
891: * @ret rc Return status code
892: */
893: static int tftp_errcode_to_rc ( unsigned int errcode ) {
894: switch ( errcode ) {
895: case TFTP_ERR_FILE_NOT_FOUND: return -ENOENT;
896: case TFTP_ERR_ACCESS_DENIED: return -EACCES;
897: case TFTP_ERR_ILLEGAL_OP: return -ENOTTY;
898: default: return -ENOTSUP;
899: }
900: }
901:
902: /**
903: * Receive ERROR
904: *
905: * @v tftp TFTP connection
906: * @v buf Temporary data buffer
907: * @v len Length of temporary data buffer
908: * @ret rc Return status code
909: */
910: static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) {
911: struct tftp_error *error = buf;
912: int rc;
913:
914: /* Sanity check */
915: if ( len < sizeof ( *error ) ) {
916: DBGC ( tftp, "TFTP %p received underlength ERROR packet "
917: "length %zd\n", tftp, len );
918: return -EINVAL;
919: }
920:
921: DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
922: "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
923:
924: /* Determine final operation result */
925: rc = tftp_errcode_to_rc ( ntohs ( error->errcode ) );
926:
927: /* Close TFTP request */
928: tftp_done ( tftp, rc );
929:
930: return 0;
931: }
932:
933: /**
934: * Receive new data
935: *
936: * @v tftp TFTP connection
937: * @v iobuf I/O buffer
938: * @v meta Transfer metadata
939: * @ret rc Return status code
940: */
941: static int tftp_rx ( struct tftp_request *tftp,
942: struct io_buffer *iobuf,
943: struct xfer_metadata *meta ) {
944: struct sockaddr_tcpip *st_src;
945: struct tftp_common *common = iobuf->data;
946: size_t len = iob_len ( iobuf );
947: int rc = -EINVAL;
948:
949: /* Sanity checks */
950: if ( len < sizeof ( *common ) ) {
951: DBGC ( tftp, "TFTP %p received underlength packet length "
952: "%zd\n", tftp, len );
953: goto done;
954: }
955: if ( ! meta->src ) {
956: DBGC ( tftp, "TFTP %p received packet without source port\n",
957: tftp );
958: goto done;
959: }
960:
961: /* Filter by TID. Set TID on first response received */
962: st_src = ( struct sockaddr_tcpip * ) meta->src;
963: if ( ! tftp->peer.st_family ) {
964: memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) );
965: DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
966: ntohs ( tftp->peer.st_port ) );
967: } else if ( memcmp ( &tftp->peer, st_src,
968: sizeof ( tftp->peer ) ) != 0 ) {
969: DBGC ( tftp, "TFTP %p received packet from wrong source (got "
970: "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ),
971: ntohs ( tftp->peer.st_port ) );
972: goto done;
973: }
974:
975: switch ( common->opcode ) {
976: case htons ( TFTP_OACK ):
977: rc = tftp_rx_oack ( tftp, iobuf->data, len );
978: break;
979: case htons ( TFTP_DATA ):
980: rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
981: break;
982: case htons ( TFTP_ERROR ):
983: rc = tftp_rx_error ( tftp, iobuf->data, len );
984: break;
985: default:
986: DBGC ( tftp, "TFTP %p received strange packet type %d\n",
987: tftp, ntohs ( common->opcode ) );
988: break;
989: };
990:
991: done:
992: free_iob ( iobuf );
993: return rc;
994: }
995:
996: /**
997: * Receive new data via socket
998: *
999: * @v tftp TFTP connection
1000: * @v iobuf I/O buffer
1001: * @v meta Transfer metadata
1002: * @ret rc Return status code
1003: */
1004: static int tftp_socket_deliver ( struct tftp_request *tftp,
1005: struct io_buffer *iobuf,
1006: struct xfer_metadata *meta ) {
1007:
1008: /* Enable sending ACKs when we receive a unicast packet. This
1009: * covers three cases:
1010: *
1011: * 1. Standard TFTP; we should always send ACKs, and will
1012: * always receive a unicast packet before we need to send the
1013: * first ACK.
1014: *
1015: * 2. RFC2090 multicast TFTP; the only unicast packets we will
1016: * receive are the OACKs; enable sending ACKs here (before
1017: * processing the OACK) and disable it when processing the
1018: * multicast option if we are not the master client.
1019: *
1020: * 3. MTFTP; receiving a unicast datagram indicates that we
1021: * are the "master client" and should send ACKs.
1022: */
1023: tftp->flags |= TFTP_FL_SEND_ACK;
1024:
1025: return tftp_rx ( tftp, iobuf, meta );
1026: }
1027:
1028: /** TFTP socket operations */
1029: static struct interface_operation tftp_socket_operations[] = {
1030: INTF_OP ( xfer_deliver, struct tftp_request *, tftp_socket_deliver ),
1031: };
1032:
1033: /** TFTP socket interface descriptor */
1034: static struct interface_descriptor tftp_socket_desc =
1035: INTF_DESC ( struct tftp_request, socket, tftp_socket_operations );
1036:
1037: /** TFTP multicast socket operations */
1038: static struct interface_operation tftp_mc_socket_operations[] = {
1039: INTF_OP ( xfer_deliver, struct tftp_request *, tftp_rx ),
1040: };
1041:
1042: /** TFTP multicast socket interface descriptor */
1043: static struct interface_descriptor tftp_mc_socket_desc =
1044: INTF_DESC ( struct tftp_request, mc_socket, tftp_mc_socket_operations );
1045:
1046: /**
1047: * Check flow control window
1048: *
1049: * @v tftp TFTP connection
1050: * @ret len Length of window
1051: */
1052: static size_t tftp_xfer_window ( struct tftp_request *tftp ) {
1053:
1054: /* We abuse this data-xfer method to convey the blocksize to
1055: * the caller. This really should be done using some kind of
1056: * stat() method, but we don't yet have the facility to do
1057: * that.
1058: */
1059: return tftp->blksize;
1060: }
1061:
1062: /** TFTP data transfer interface operations */
1063: static struct interface_operation tftp_xfer_operations[] = {
1064: INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ),
1065: INTF_OP ( intf_close, struct tftp_request *, tftp_done ),
1066: };
1067:
1068: /** TFTP data transfer interface descriptor */
1069: static struct interface_descriptor tftp_xfer_desc =
1070: INTF_DESC ( struct tftp_request, xfer, tftp_xfer_operations );
1071:
1072: /**
1073: * Initiate TFTP/TFTM/MTFTP download
1074: *
1075: * @v xfer Data transfer interface
1076: * @v uri Uniform Resource Identifier
1077: * @ret rc Return status code
1078: */
1079: static int tftp_core_open ( struct interface *xfer, struct uri *uri,
1080: unsigned int default_port,
1081: struct sockaddr *multicast,
1082: unsigned int flags ) {
1083: struct tftp_request *tftp;
1084: int rc;
1085:
1086: /* Sanity checks */
1087: if ( ! uri->host )
1088: return -EINVAL;
1089: if ( ! uri->path )
1090: return -EINVAL;
1091:
1092: /* Allocate and populate TFTP structure */
1093: tftp = zalloc ( sizeof ( *tftp ) );
1094: if ( ! tftp )
1095: return -ENOMEM;
1096: ref_init ( &tftp->refcnt, tftp_free );
1097: intf_init ( &tftp->xfer, &tftp_xfer_desc, &tftp->refcnt );
1098: intf_init ( &tftp->socket, &tftp_socket_desc, &tftp->refcnt );
1099: intf_init ( &tftp->mc_socket, &tftp_mc_socket_desc, &tftp->refcnt );
1100: timer_init ( &tftp->timer, tftp_timer_expired, &tftp->refcnt );
1101: tftp->uri = uri_get ( uri );
1102: tftp->blksize = TFTP_DEFAULT_BLKSIZE;
1103: tftp->flags = flags;
1104:
1105: /* Open socket */
1106: tftp->port = uri_port ( tftp->uri, default_port );
1107: if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
1108: goto err;
1109:
1110: /* Open multicast socket */
1111: if ( multicast ) {
1112: if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
1113: goto err;
1114: }
1115:
1116: /* Start timer to initiate RRQ */
1117: start_timer_nodelay ( &tftp->timer );
1118:
1119: /* Attach to parent interface, mortalise self, and return */
1120: intf_plug_plug ( &tftp->xfer, xfer );
1121: ref_put ( &tftp->refcnt );
1122: return 0;
1123:
1124: err:
1125: DBGC ( tftp, "TFTP %p could not create request: %s\n",
1126: tftp, strerror ( rc ) );
1127: tftp_done ( tftp, rc );
1128: ref_put ( &tftp->refcnt );
1129: return rc;
1130: }
1131:
1132: /**
1133: * Initiate TFTP download
1134: *
1135: * @v xfer Data transfer interface
1136: * @v uri Uniform Resource Identifier
1137: * @ret rc Return status code
1138: */
1139: static int tftp_open ( struct interface *xfer, struct uri *uri ) {
1140: return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1141: TFTP_FL_RRQ_SIZES );
1142:
1143: }
1144:
1145: /** TFTP URI opener */
1146: struct uri_opener tftp_uri_opener __uri_opener = {
1147: .scheme = "tftp",
1148: .open = tftp_open,
1149: };
1150:
1151: /**
1152: * Initiate TFTP-size request
1153: *
1154: * @v xfer Data transfer interface
1155: * @v uri Uniform Resource Identifier
1156: * @ret rc Return status code
1157: */
1158: static int tftpsize_open ( struct interface *xfer, struct uri *uri ) {
1159: return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1160: ( TFTP_FL_RRQ_SIZES |
1161: TFTP_FL_SIZEONLY ) );
1162:
1163: }
1164:
1165: /** TFTP URI opener */
1166: struct uri_opener tftpsize_uri_opener __uri_opener = {
1167: .scheme = "tftpsize",
1168: .open = tftpsize_open,
1169: };
1170:
1171: /**
1172: * Initiate TFTM download
1173: *
1174: * @v xfer Data transfer interface
1175: * @v uri Uniform Resource Identifier
1176: * @ret rc Return status code
1177: */
1178: static int tftm_open ( struct interface *xfer, struct uri *uri ) {
1179: return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1180: ( TFTP_FL_RRQ_SIZES |
1181: TFTP_FL_RRQ_MULTICAST ) );
1182:
1183: }
1184:
1185: /** TFTM URI opener */
1186: struct uri_opener tftm_uri_opener __uri_opener = {
1187: .scheme = "tftm",
1188: .open = tftm_open,
1189: };
1190:
1191: /**
1192: * Initiate MTFTP download
1193: *
1194: * @v xfer Data transfer interface
1195: * @v uri Uniform Resource Identifier
1196: * @ret rc Return status code
1197: */
1198: static int mtftp_open ( struct interface *xfer, struct uri *uri ) {
1199: return tftp_core_open ( xfer, uri, MTFTP_PORT,
1200: ( struct sockaddr * ) &tftp_mtftp_socket,
1201: TFTP_FL_MTFTP_RECOVERY );
1202: }
1203:
1204: /** MTFTP URI opener */
1205: struct uri_opener mtftp_uri_opener __uri_opener = {
1206: .scheme = "mtftp",
1207: .open = mtftp_open,
1208: };
1209:
1210: /******************************************************************************
1211: *
1212: * Settings
1213: *
1214: ******************************************************************************
1215: */
1216:
1217: /** TFTP server setting */
1218: struct setting next_server_setting __setting ( SETTING_BOOT ) = {
1219: .name = "next-server",
1220: .description = "TFTP server",
1221: .tag = DHCP_EB_SIADDR,
1222: .type = &setting_type_ipv4,
1223: };
1224:
1225: /**
1226: * Apply TFTP configuration settings
1227: *
1228: * @ret rc Return status code
1229: */
1230: static int tftp_apply_settings ( void ) {
1231: static struct in_addr tftp_server = { 0 };
1232: struct in_addr last_tftp_server;
1233: char uri_string[32];
1234: struct uri *uri;
1235:
1236: /* Retrieve TFTP server setting */
1237: last_tftp_server = tftp_server;
1238: fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
1239:
1240: /* If TFTP server setting has changed, set the current working
1241: * URI to match. Do it only when the TFTP server has changed
1242: * to try to minimise surprises to the user, who probably
1243: * won't expect the CWURI to change just because they updated
1244: * an unrelated setting and triggered all the settings
1245: * applicators.
1246: */
1247: if ( tftp_server.s_addr != last_tftp_server.s_addr ) {
1248: if ( tftp_server.s_addr ) {
1249: snprintf ( uri_string, sizeof ( uri_string ),
1250: "tftp://%s/", inet_ntoa ( tftp_server ) );
1251: uri = parse_uri ( uri_string );
1252: if ( ! uri )
1253: return -ENOMEM;
1254: } else {
1255: uri = NULL;
1256: }
1257: churi ( uri );
1258: uri_put ( uri );
1259: }
1260:
1261: return 0;
1262: }
1263:
1264: /** TFTP settings applicator */
1265: struct settings_applicator tftp_settings_applicator __settings_applicator = {
1266: .apply = tftp_apply_settings,
1267: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.