Added TFTP test code (currently just dumps file to console).
authorMichael Brown <mcb30@etherboot.org>
Wed, 9 Aug 2006 00:09:29 +0000 (00:09 +0000)
committerMichael Brown <mcb30@etherboot.org>
Wed, 9 Aug 2006 00:09:29 +0000 (00:09 +0000)
src/include/gpxe/tftp.h
src/net/udp/tftp.c
src/tests/dhcptest.c
src/tests/tftptest.c [new file with mode: 0644]

index e5c599b..68589b5 100644 (file)
@@ -119,6 +119,12 @@ struct tftp_session {
         * (i.e. that no blocks have yet been received).
         */
        int state;
+       /** Requested data block size
+        *
+        * This is the "blksize" option requested from the TFTP
+        * server.  It may or may not be honoured.
+        */
+       unsigned int request_blksize;
        /** Data block size
         *
         * This is the "blksize" option negotiated with the TFTP
@@ -140,4 +146,8 @@ struct tftp_session {
        struct retry_timer timer;
 };
 
+/* Function prototypes */
+
+extern struct async_operation * tftp_get ( struct tftp_session *tftp );
+
 #endif /* _GPXE_TFTP_H */
index 39839be..2b00cd7 100644 (file)
@@ -207,9 +207,10 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) {
        end = ( buf + len );
        if ( data > end )
                goto overflow;
-       data += snprintf ( data, ( end - data ),
-                          "%s%coctet%cblksize%c%d%ctsize%c0",
-                          tftp->filename, 0, 0, 0, tftp->blksize, 0, 0 ) + 1;
+       data += ( snprintf ( data, ( end - data ),
+                            "%s%coctet%cblksize%c%d%ctsize%c0",
+                            tftp->filename, 0, 0, 0,
+                            tftp->request_blksize, 0, 0 ) + 1 );
        if ( data > end )
                goto overflow;
        rrq->opcode = htons ( TFTP_RRQ );
@@ -456,6 +457,8 @@ struct async_operation * tftp_get ( struct tftp_session *tftp ) {
        tftp->timer.expired = tftp_timer_expired;
        tftp->state = -1;
        tftp->blksize = TFTP_DEFAULT_BLKSIZE;
+       if ( ! tftp->request_blksize )
+               tftp->request_blksize = TFTP_MAX_BLKSIZE;
 
        /* Open UDP connection */
        if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) {
index 4bb2e11..2afe6fa 100644 (file)
@@ -57,6 +57,21 @@ static int test_dhcp_hello ( char *helloname ) {
        return 0;
 }
 
+static int test_dhcp_tftp ( char *tftpname ) {
+       union {
+               struct sockaddr_in sin;
+               struct sockaddr_tcpip st;
+       } target;
+
+       memset ( &target, 0, sizeof ( target ) );
+       target.sin.sin_family = AF_INET;
+       target.sin.sin_port = htons ( 69 );
+       find_global_dhcp_ipv4_option ( DHCP_EB_SIADDR,
+                                      &target.sin.sin_addr );
+
+       return test_tftp ( &target.st, tftpname );
+}
+
 static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
        if ( strncmp ( filename, "aoe:", 4 ) == 0 ) {
                return test_dhcp_aoe_boot ( netdev, &filename[4] );
@@ -65,8 +80,7 @@ static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
        } else if ( strncmp ( filename, "hello:", 6 ) == 0 ) {
                return test_dhcp_hello ( &filename[6] );
        } else {
-               printf ( "Don't know how to boot %s\n", filename );
-               return -EPROTONOSUPPORT;
+               return test_dhcp_tftp ( filename );
        }
 }
 
diff --git a/src/tests/tftptest.c b/src/tests/tftptest.c
new file mode 100644 (file)
index 0000000..ba4c5d0
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stdint.h>
+#include <string.h>
+#include <console.h>
+#include <gpxe/udp.h>
+#include <gpxe/tftp.h>
+#include <gpxe/async.h>
+
+static void test_tftp_callback ( struct tftp_session *tftp __unused,
+                                unsigned int block __unused,
+                                void *data, size_t len ) {
+       unsigned int i;
+       char c;
+
+       for ( i = 0 ; i < len ; i++ ) {
+               c = * ( ( char * ) data + i );
+               if ( c == '\r' ) {
+                       /* Print nothing */
+               } else if ( ( c == '\n' ) || ( c >= 32 ) || ( c <= 126 ) ) {
+                       putchar ( c );
+               } else {
+                       putchar ( '.' );
+               }
+       }       
+}
+
+int test_tftp ( struct sockaddr_tcpip *target, const char *filename ) {
+       struct tftp_session tftp;
+
+       memset ( &tftp, 0, sizeof ( tftp ) );
+       udp_connect ( &tftp.udp, target );
+       tftp.filename = filename;
+       tftp.callback = test_tftp_callback;
+
+       return async_wait ( tftp_get ( &tftp ) );
+}