return 0;
}
-static int test_dhcp_tftp ( char *tftpname ) {
+static int test_dhcp_tftp ( struct net_device *netdev, char *tftpname ) {
union {
struct sockaddr_in sin;
struct sockaddr_tcpip st;
find_global_dhcp_ipv4_option ( DHCP_EB_SIADDR,
&target.sin.sin_addr );
- return test_tftp ( &target.st, tftpname );
+ return test_tftp ( netdev, &target.st, tftpname );
}
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 {
- return test_dhcp_tftp ( filename );
+ return test_dhcp_tftp ( netdev, filename );
}
}
#include <gpxe/udp.h>
#include <gpxe/tftp.h>
#include <gpxe/async.h>
+#include <gpxe/uaccess.h>
+#include "pxe.h"
-static void test_tftp_callback ( struct tftp_session *tftp __unused,
- unsigned int block __unused,
+static void test_tftp_callback ( struct tftp_session *tftp, unsigned int block,
void *data, size_t len ) {
- unsigned int i;
- char c;
+ unsigned long offset = ( ( block - 1 ) * tftp->blksize );
+ userptr_t pxe_buffer = real_to_user ( 0, 0x7c00 );
- 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 ( '.' );
- }
- }
+ copy_to_user ( pxe_buffer, offset, data, len );
}
-int test_tftp ( struct sockaddr_tcpip *target, const char *filename ) {
+int test_tftp ( struct net_device *netdev, struct sockaddr_tcpip *target,
+ const char *filename ) {
struct tftp_session tftp;
+ int rc;
memset ( &tftp, 0, sizeof ( tftp ) );
udp_connect ( &tftp.udp, target );
tftp.filename = filename;
tftp.callback = test_tftp_callback;
- return async_wait ( tftp_get ( &tftp ) );
+ printf ( "Fetching \"%s\" via TFTP\n", filename );
+ if ( ( rc = async_wait ( tftp_get ( &tftp ) ) ) != 0 )
+ return rc;
+
+ printf ( "Attempting PXE boot\n" );
+ pxe_netdev = netdev;
+ rc = pxe_boot();
+ printf ( "PXE NBP returned with status %04x\n", rc );
+ return 0;
}