diff options
author | Michael Brown | 2007-01-11 16:14:54 +0100 |
---|---|---|
committer | Michael Brown | 2007-01-11 16:14:54 +0100 |
commit | 0010e10ef3d242f0ba92010b63f6222366e5ec05 (patch) | |
tree | 90de66f3fbcbd4e0ca4e3223f57673e554664b46 /src/net/udp/tftp.c | |
parent | Use physical address in debug messages; they make more sense to read. (diff) | |
download | ipxe-0010e10ef3d242f0ba92010b63f6222366e5ec05.tar.gz ipxe-0010e10ef3d242f0ba92010b63f6222366e5ec05.tar.xz ipxe-0010e10ef3d242f0ba92010b63f6222366e5ec05.zip |
Update TFTP to use a struct buffer rather than a callback.
Add debug autocolourisation to TFTP.
Diffstat (limited to 'src/net/udp/tftp.c')
-rw-r--r-- | src/net/udp/tftp.c | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 2b00cd78..6753e838 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -59,10 +59,11 @@ static int tftp_process_blksize ( struct tftp_session *tftp, tftp->blksize = strtoul ( value, &end, 10 ); if ( *end ) { - DBG ( "TFTP %p got invalid blksize \"%s\"\n", tftp, value ); + DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n", + tftp, value ); return -EINVAL; } - DBG ( "TFTP %p blksize=%d\n", tftp, tftp->blksize ); + DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize ); return 0; } @@ -80,10 +81,11 @@ static int tftp_process_tsize ( struct tftp_session *tftp, tftp->tsize = strtoul ( value, &end, 10 ); if ( *end ) { - DBG ( "TFTP %p got invalid tsize \"%s\"\n", tftp, value ); + DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n", + tftp, value ); return -EINVAL; } - DBG ( "TFTP %p tsize=%ld\n", tftp, tftp->tsize ); + DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize ); return 0; } @@ -112,8 +114,8 @@ static int tftp_process_option ( struct tftp_session *tftp, return option->process ( tftp, value ); } - DBG ( "TFTP %p received unknown option \"%s\" = \"%s\"\n", - tftp, name, value ); + DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n", + tftp, name, value ); return -EINVAL; } @@ -201,7 +203,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) { void *data; void *end; - DBG ( "TFTP %p requesting \"%s\"\n", tftp, tftp->filename ); + DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, tftp->filename ); data = rrq->data; end = ( buf + len ); @@ -218,7 +220,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) { return udp_send ( &tftp->udp, buf, ( data - buf ) ); overflow: - DBG ( "TFTP %p RRQ out of space\n", tftp ); + DBGC ( tftp, "TFTP %p RRQ out of space\n", tftp ); return -ENOBUFS; } @@ -239,12 +241,13 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) { /* Sanity check */ if ( len < sizeof ( *oack ) ) { - DBG ( "TFTP %p received underlength OACK packet length %d\n", - tftp, len ); + DBGC ( tftp, "TFTP %p received underlength OACK packet " + "length %d\n", tftp, len ); return -EINVAL; } if ( end[-1] != '\0' ) { - DBG ( "TFTP %p received OACK missing final NUL\n", tftp ); + DBGC ( tftp, "TFTP %p received OACK missing final NUL\n", + tftp ); return -EINVAL; } @@ -253,8 +256,8 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) { while ( name < end ) { value = ( name + strlen ( name ) + 1 ); if ( value == end ) { - DBG ( "TFTP %p received OACK missing value for option " - "\"%s\"\n", tftp, name ); + DBGC ( tftp, "TFTP %p received OACK missing value " + "for option \"%s\"\n", tftp, name ); return -EINVAL; } if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 ) @@ -279,19 +282,28 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) { static int tftp_rx_data ( struct tftp_session *tftp, void *buf, size_t len ) { struct tftp_data *data = buf; unsigned int block; + size_t data_offset; size_t data_len; + int rc; /* Sanity check */ if ( len < sizeof ( *data ) ) { - DBG ( "TFTP %p received underlength DATA packet length %d\n", - tftp, len ); + DBGC ( tftp, "TFTP %p received underlength DATA packet " + "length %d\n", tftp, len ); return -EINVAL; } - /* Pass to callback */ + /* Fill data buffer */ block = ntohs ( data->block ); + data_offset = ( ( block - 1 ) * tftp->blksize ); data_len = ( len - offsetof ( typeof ( *data ), data ) ); - tftp->callback ( tftp, block, data->data, data_len ); + if ( ( rc = fill_buffer ( tftp->buffer, data->data, data_offset, + data_len ) ) != 0 ) { + DBGC ( tftp, "TFTP %p could not fill data buffer: %s\n", + tftp, strerror ( rc ) ); + tftp_done ( tftp, rc ); + return rc; + } /* Mark block as received */ tftp_received ( tftp, block ); @@ -334,13 +346,13 @@ static int tftp_rx_error ( struct tftp_session *tftp, void *buf, size_t len ) { /* Sanity check */ if ( len < sizeof ( *error ) ) { - DBG ( "TFTP %p received underlength ERROR packet length %d\n", - tftp, len ); + DBGC ( tftp, "TFTP %p received underlength ERROR packet " + "length %d\n", tftp, len ); return -EINVAL; } - DBG ( "TFTP %p received ERROR packet with code %d, message \"%s\"\n", - tftp, ntohs ( error->errcode ), error->errmsg ); + DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message " + "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg ); /* Determine final operation result */ err = ntohs ( error->errcode ); @@ -392,30 +404,31 @@ static int tftp_newdata ( struct udp_connection *conn, void *data, size_t len, struct tftp_common *common = data; if ( len < sizeof ( *common ) ) { - DBG ( "TFTP %p received underlength packet length %d\n", - tftp, len ); + DBGC ( tftp, "TFTP %p received underlength packet length %d\n", + tftp, len ); return -EINVAL; } /* Filter by TID. Set TID on first response received */ if ( tftp->tid ) { if ( tftp->tid != st_src->st_port ) { - DBG ( "TFTP %p received packet from wrong port " - "(got %d, wanted %d)\n", tftp, - ntohs ( st_src->st_port ), ntohs ( tftp->tid ) ); + DBGC ( tftp, "TFTP %p received packet from wrong port " + "(got %d, wanted %d)\n", tftp, + ntohs ( st_src->st_port ), ntohs ( tftp->tid )); return -EINVAL; } } else { tftp->tid = st_src->st_port; - DBG ( "TFTP %p using remote port %d\n", tftp, - ntohs ( tftp->tid ) ); + DBGC ( tftp, "TFTP %p using remote port %d\n", tftp, + ntohs ( tftp->tid ) ); udp_connect_port ( &tftp->udp, tftp->tid ); } /* Filter by source address */ if ( memcmp ( st_src, udp_peer ( &tftp->udp ), sizeof ( *st_src ) ) != 0 ) { - DBG ( "TFTP %p received packet from foreign source\n", tftp ); + DBGC ( tftp, "TFTP %p received packet from foreign source\n", + tftp ); return -EINVAL; } @@ -427,8 +440,8 @@ static int tftp_newdata ( struct udp_connection *conn, void *data, size_t len, case htons ( TFTP_ERROR ): return tftp_rx_error ( tftp, data, len ); default: - DBG ( "TFTP %p received strange packet type %d\n", tftp, - ntohs ( common->opcode ) ); + DBGC ( tftp, "TFTP %p received strange packet type %d\n", tftp, + ntohs ( common->opcode ) ); return -EINVAL; }; } @@ -449,16 +462,18 @@ struct async_operation * tftp_get ( struct tftp_session *tftp ) { int rc; assert ( tftp->filename != NULL ); - assert ( tftp->callback != NULL ); + assert ( tftp->buffer != NULL ); assert ( tftp->udp.peer.st_family != 0 ); /* Initialise TFTP session */ - tftp->udp.udp_op = &tftp_udp_operations; - tftp->timer.expired = tftp_timer_expired; - tftp->state = -1; - tftp->blksize = TFTP_DEFAULT_BLKSIZE; if ( ! tftp->request_blksize ) tftp->request_blksize = TFTP_MAX_BLKSIZE; + tftp->blksize = TFTP_DEFAULT_BLKSIZE; + tftp->tsize = 0; + tftp->tid = 0; + tftp->state = -1; + tftp->udp.udp_op = &tftp_udp_operations; + tftp->timer.expired = tftp_timer_expired; /* Open UDP connection */ if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) { |