| 
				
			 | 
			
			
				
				@@ -14,6 +14,7 @@ 
			 | 
		
		
	
		
			
			| 
				14
			 | 
			
				14
			 | 
			
			
				
				 #include <gpxe/ip.h> 
			 | 
		
		
	
		
			
			| 
				15
			 | 
			
				15
			 | 
			
			
				
				 #include <gpxe/tcp.h> 
			 | 
		
		
	
		
			
			| 
				16
			 | 
			
				16
			 | 
			
			
				
				 #include <gpxe/hello.h> 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				
				+#include <gpxe/iscsi.h> 
			 | 
		
		
	
		
			
			| 
				17
			 | 
			
				18
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				18
			 | 
			
				19
			 | 
			
			
				
				 typedef int irq_action_t; 
			 | 
		
		
	
		
			
			| 
				19
			 | 
			
				20
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -84,6 +85,23 @@ void netdev_transmit ( const void *data, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				84
			 | 
			
				85
			 | 
			
			
				
				 				      data + ETH_HLEN ); 
			 | 
		
		
	
		
			
			| 
				85
			 | 
			
				86
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				86
			 | 
			
				87
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+ * Utility functions 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+static void hex_dump ( const void *data, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+	unsigned int index; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				
				+	for ( index = 0; index < len; index++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+		if ( ( index % 16 ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				
				+			printf ( "\n%08x :", index ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+		printf ( " %02x", * ( ( unsigned char * ) ( data + index ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+	printf ( "\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				87
			 | 
			
				105
			 | 
			
			
				
				 /***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				88
			 | 
			
				106
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				89
			 | 
			
				107
			 | 
			
			
				
				  * Hijack device interface 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -263,18 +281,20 @@ static void hello_usage ( char **argv ) { 
			 | 
		
		
	
		
			
			| 
				263
			 | 
			
				281
			 | 
			
			
				
				 		  "Usage: %s [global options] hello [hello-specific options]\n" 
			 | 
		
		
	
		
			
			| 
				264
			 | 
			
				282
			 | 
			
			
				
				 		  "\n" 
			 | 
		
		
	
		
			
			| 
				265
			 | 
			
				283
			 | 
			
			
				
				 		  "hello-specific options:\n" 
			 | 
		
		
	
		
			
			| 
				266
			 | 
			
				
			 | 
			
			
				
				-		  "  -h|--host              Host IP address\n" 
			 | 
		
		
	
		
			
			| 
				267
			 | 
			
				
			 | 
			
			
				
				-		  "  -p|--port              Port number\n" 
			 | 
		
		
	
		
			
			| 
				268
			 | 
			
				
			 | 
			
			
				
				-		  "  -m|--message           Message to send\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				284
			 | 
			
			
				
				+		  "  -h|--help              Print this help message\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				285
			 | 
			
			
				
				+		  "  -s|--server ip_addr    Server IP address\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				286
			 | 
			
			
				
				+		  "  -p|--port port         Port number\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				287
			 | 
			
			
				
				+		  "  -m|--message msg       Message to send\n", 
			 | 
		
		
	
		
			
			| 
				269
			 | 
			
				288
			 | 
			
			
				
				 		  argv[0] ); 
			 | 
		
		
	
		
			
			| 
				270
			 | 
			
				289
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				271
			 | 
			
				290
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				272
			 | 
			
				291
			 | 
			
			
				
				 static int hello_parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				273
			 | 
			
				292
			 | 
			
			
				
				 				 struct hello_options *options ) { 
			 | 
		
		
	
		
			
			| 
				274
			 | 
			
				293
			 | 
			
			
				
				 	static struct option long_options[] = { 
			 | 
		
		
	
		
			
			| 
				275
			 | 
			
				
			 | 
			
			
				
				-		{ "host", 1, NULL, 'h' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				294
			 | 
			
			
				
				+		{ "server", 1, NULL, 's' }, 
			 | 
		
		
	
		
			
			| 
				276
			 | 
			
				295
			 | 
			
			
				
				 		{ "port", 1, NULL, 'p' }, 
			 | 
		
		
	
		
			
			| 
				277
			 | 
			
				296
			 | 
			
			
				
				 		{ "message", 1, NULL, 'm' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				297
			 | 
			
			
				
				+		{ "help", 0, NULL, 'h' }, 
			 | 
		
		
	
		
			
			| 
				278
			 | 
			
				298
			 | 
			
			
				
				 		{ }, 
			 | 
		
		
	
		
			
			| 
				279
			 | 
			
				299
			 | 
			
			
				
				 	}; 
			 | 
		
		
	
		
			
			| 
				280
			 | 
			
				300
			 | 
			
			
				
				 	int c; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -290,13 +310,13 @@ static int hello_parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				290
			 | 
			
				310
			 | 
			
			
				
				 	while ( 1 ) { 
			 | 
		
		
	
		
			
			| 
				291
			 | 
			
				311
			 | 
			
			
				
				 		int option_index = 0; 
			 | 
		
		
	
		
			
			| 
				292
			 | 
			
				312
			 | 
			
			
				
				 		 
			 | 
		
		
	
		
			
			| 
				293
			 | 
			
				
			 | 
			
			
				
				-		c = getopt_long ( argc, argv, "h:p:", long_options, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				313
			 | 
			
			
				
				+		c = getopt_long ( argc, argv, "s:p:m:h", long_options, 
			 | 
		
		
	
		
			
			| 
				294
			 | 
			
				314
			 | 
			
			
				
				 				  &option_index ); 
			 | 
		
		
	
		
			
			| 
				295
			 | 
			
				315
			 | 
			
			
				
				 		if ( c < 0 ) 
			 | 
		
		
	
		
			
			| 
				296
			 | 
			
				316
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				297
			 | 
			
				317
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				298
			 | 
			
				318
			 | 
			
			
				
				 		switch ( c ) { 
			 | 
		
		
	
		
			
			| 
				299
			 | 
			
				
			 | 
			
			
				
				-		case 'h': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				319
			 | 
			
			
				
				+		case 's': 
			 | 
		
		
	
		
			
			| 
				300
			 | 
			
				320
			 | 
			
			
				
				 			if ( inet_aton ( optarg, 
			 | 
		
		
	
		
			
			| 
				301
			 | 
			
				321
			 | 
			
			
				
				 					 &options->server.sin_addr ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				302
			 | 
			
				322
			 | 
			
			
				
				 				fprintf ( stderr, "Invalid IP address %s\n", 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -316,6 +336,9 @@ static int hello_parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				316
			 | 
			
				336
			 | 
			
			
				
				 		case 'm': 
			 | 
		
		
	
		
			
			| 
				317
			 | 
			
				337
			 | 
			
			
				
				 			options->message = optarg; 
			 | 
		
		
	
		
			
			| 
				318
			 | 
			
				338
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				339
			 | 
			
			
				
				+		case 'h': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				340
			 | 
			
			
				
				+			hello_usage ( argv ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				341
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				319
			 | 
			
				342
			 | 
			
			
				
				 		case '?': 
			 | 
		
		
	
		
			
			| 
				320
			 | 
			
				343
			 | 
			
			
				
				 			/* Unrecognised option */ 
			 | 
		
		
	
		
			
			| 
				321
			 | 
			
				344
			 | 
			
			
				
				 			return -1; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -376,6 +399,170 @@ static int test_hello ( int argc, char **argv ) { 
			 | 
		
		
	
		
			
			| 
				376
			 | 
			
				399
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				377
			 | 
			
				400
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				378
			 | 
			
				401
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				402
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				403
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				404
			 | 
			
			
				
				+ * iSCSI protocol tester 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				405
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				406
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				407
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				408
			 | 
			
			
				
				+struct iscsi_options { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				409
			 | 
			
			
				
				+	struct sockaddr_in server; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				410
			 | 
			
			
				
				+	const char *initiator; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				411
			 | 
			
			
				
				+	const char *target; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				412
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				413
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				414
			 | 
			
			
				
				+static void iscsi_usage ( char **argv ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				415
			 | 
			
			
				
				+	fprintf ( stderr, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				416
			 | 
			
			
				
				+		  "Usage: %s [global options] iscsi [iscsi-specific options]\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				417
			 | 
			
			
				
				+		  "\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				418
			 | 
			
			
				
				+		  "iscsi-specific options:\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				419
			 | 
			
			
				
				+		  "  -h|--help              Print this help message\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				420
			 | 
			
			
				
				+		  "  -s|--server ip_addr    Server IP address\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				421
			 | 
			
			
				
				+		  "  -p|--port port         Port number\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				422
			 | 
			
			
				
				+		  "  -i|--initiator iqn     iSCSI initiator name\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				423
			 | 
			
			
				
				+		  "  -t|--target iqn        iSCSI target name\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				424
			 | 
			
			
				
				+		  argv[0] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				425
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				426
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				427
			 | 
			
			
				
				+static int iscsi_parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				428
			 | 
			
			
				
				+				 struct iscsi_options *options ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				429
			 | 
			
			
				
				+	static struct option long_options[] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				430
			 | 
			
			
				
				+		{ "server", 1, NULL, 's' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				431
			 | 
			
			
				
				+		{ "port", 1, NULL, 'p' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				432
			 | 
			
			
				
				+		{ "initiator", 1, NULL, 'i' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				433
			 | 
			
			
				
				+		{ "target", 1, NULL, 't' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				434
			 | 
			
			
				
				+		{ "help", 0, NULL, 'h' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				435
			 | 
			
			
				
				+		{ }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				436
			 | 
			
			
				
				+	}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				437
			 | 
			
			
				
				+	int c; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				438
			 | 
			
			
				
				+	char *endptr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				439
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				440
			 | 
			
			
				
				+	/* Set default options */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				441
			 | 
			
			
				
				+	memset ( options, 0, sizeof ( *options ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				442
			 | 
			
			
				
				+	inet_aton ( "192.168.0.1", &options->server.sin_addr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				443
			 | 
			
			
				
				+	options->server.sin_port = htons ( 3260 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				444
			 | 
			
			
				
				+	options->initiator = "iqn.1900-01.localdomain.localhost:initiator"; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				445
			 | 
			
			
				
				+	options->target = "iqn.1900-01.localdomain.localhost:target"; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				446
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				447
			 | 
			
			
				
				+	/* Parse command-line options */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				448
			 | 
			
			
				
				+	while ( 1 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				449
			 | 
			
			
				
				+		int option_index = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				450
			 | 
			
			
				
				+		 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				451
			 | 
			
			
				
				+		c = getopt_long ( argc, argv, "s:p:i:t:h", long_options, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				452
			 | 
			
			
				
				+				  &option_index ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				453
			 | 
			
			
				
				+		if ( c < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				454
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				455
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				456
			 | 
			
			
				
				+		switch ( c ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				457
			 | 
			
			
				
				+		case 's': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				458
			 | 
			
			
				
				+			if ( inet_aton ( optarg, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				459
			 | 
			
			
				
				+					 &options->server.sin_addr ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				460
			 | 
			
			
				
				+				fprintf ( stderr, "Invalid IP address %s\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				461
			 | 
			
			
				
				+					  optarg ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				462
			 | 
			
			
				
				+				return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				463
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				464
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				465
			 | 
			
			
				
				+		case 'p': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				466
			 | 
			
			
				
				+			options->server.sin_port = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				467
			 | 
			
			
				
				+				htons ( strtoul ( optarg, &endptr, 0 ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				468
			 | 
			
			
				
				+			if ( *endptr != '\0' ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				469
			 | 
			
			
				
				+				fprintf ( stderr, "Invalid port %s\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				470
			 | 
			
			
				
				+					  optarg ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				471
			 | 
			
			
				
				+				return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				472
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				473
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				474
			 | 
			
			
				
				+		case 'i': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				475
			 | 
			
			
				
				+			options->initiator = optarg; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				476
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				477
			 | 
			
			
				
				+		case 't': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				478
			 | 
			
			
				
				+			options->target = optarg; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				479
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				480
			 | 
			
			
				
				+		case 'h': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				
				+			iscsi_usage ( argv ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				482
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				483
			 | 
			
			
				
				+		case '?': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				484
			 | 
			
			
				
				+			/* Unrecognised option */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				485
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				486
			 | 
			
			
				
				+		default: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				487
			 | 
			
			
				
				+			fprintf ( stderr, "Unrecognised option '-%c'\n", c ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				488
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				489
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				490
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				491
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				492
			 | 
			
			
				
				+	/* Check there are no remaining arguments */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				493
			 | 
			
			
				
				+	if ( optind != argc ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				494
			 | 
			
			
				
				+		iscsi_usage ( argv ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				495
			 | 
			
			
				
				+		return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				496
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				497
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				498
			 | 
			
			
				
				+	return optind; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				499
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				500
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				501
			 | 
			
			
				
				+struct test_iscsi_buffer { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				502
			 | 
			
			
				
				+	unsigned char data[512]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				503
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				504
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				505
			 | 
			
			
				
				+static void test_iscsi_callback ( void *private, const void *data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				506
			 | 
			
			
				
				+				  unsigned long offset, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				507
			 | 
			
			
				
				+	struct test_iscsi_buffer *buffer = private; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				508
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				509
			 | 
			
			
				
				+	assert ( ( offset + len ) <= sizeof ( buffer->data ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				510
			 | 
			
			
				
				+	memcpy ( buffer->data + offset, data, len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				511
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				512
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				513
			 | 
			
			
				
				+static int test_iscsi_block ( struct iscsi_session *iscsi, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				514
			 | 
			
			
				
				+			      unsigned int block ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				515
			 | 
			
			
				
				+	struct test_iscsi_buffer buffer; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				516
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				517
			 | 
			
			
				
				+	iscsi->block_size = 512; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				518
			 | 
			
			
				
				+	iscsi->block_start = block; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				519
			 | 
			
			
				
				+	iscsi->block_count = 1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				520
			 | 
			
			
				
				+	iscsi->block_read_callback = test_iscsi_callback; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				521
			 | 
			
			
				
				+	iscsi->block_read_private = &buffer; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				522
			 | 
			
			
				
				+	memset ( buffer.data, 0x61, sizeof ( buffer.data ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				523
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				524
			 | 
			
			
				
				+	/* Start up iscsi session */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				525
			 | 
			
			
				
				+	iscsi_wakeup ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				526
			 | 
			
			
				
				+	while ( iscsi_busy ( iscsi ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				527
			 | 
			
			
				
				+		run_tcpip (); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				528
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				529
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				530
			 | 
			
			
				
				+	/* Check for errors */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				531
			 | 
			
			
				
				+	if ( iscsi_error ( iscsi ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				532
			 | 
			
			
				
				+		fprintf ( stderr, "iSCSI error on block %d\n", block ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				533
			 | 
			
			
				
				+		return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				534
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				535
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				536
			 | 
			
			
				
				+	/* Dump out data */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				537
			 | 
			
			
				
				+	hex_dump ( buffer.data, sizeof ( buffer.data ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				538
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				539
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				540
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				541
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				542
			 | 
			
			
				
				+static int test_iscsi ( int argc, char **argv ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				543
			 | 
			
			
				
				+	struct iscsi_options options; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				544
			 | 
			
			
				
				+	struct iscsi_session iscsi; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				545
			 | 
			
			
				
				+	unsigned int block; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				546
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				547
			 | 
			
			
				
				+	/* Parse iscsi-specific options */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				548
			 | 
			
			
				
				+	if ( iscsi_parse_options ( argc, argv, &options ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				549
			 | 
			
			
				
				+		return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				550
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				551
			 | 
			
			
				
				+	/* Construct iscsi session */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				552
			 | 
			
			
				
				+	memset ( &iscsi, 0, sizeof ( iscsi ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				553
			 | 
			
			
				
				+	iscsi.tcp.sin = options.server; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				554
			 | 
			
			
				
				+	iscsi.initiator = options.initiator; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				555
			 | 
			
			
				
				+	iscsi.target = options.target; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				556
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				557
			 | 
			
			
				
				+	/* Read some blocks */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				558
			 | 
			
			
				
				+	for ( block = 0 ; block < 4 ; block += 2 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				559
			 | 
			
			
				
				+		if ( test_iscsi_block ( &iscsi, block ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				560
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				561
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				562
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				563
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				564
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				565
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				379
			 | 
			
				566
			 | 
			
			
				
				 /***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				380
			 | 
			
				567
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				381
			 | 
			
				568
			 | 
			
			
				
				  * Protocol tester 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -389,6 +576,7 @@ struct protocol_test { 
			 | 
		
		
	
		
			
			| 
				389
			 | 
			
				576
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				390
			 | 
			
				577
			 | 
			
			
				
				 static struct protocol_test tests[] = { 
			 | 
		
		
	
		
			
			| 
				391
			 | 
			
				578
			 | 
			
			
				
				 	{ "hello", test_hello }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				579
			 | 
			
			
				
				+	{ "iscsi", test_iscsi }, 
			 | 
		
		
	
		
			
			| 
				392
			 | 
			
				580
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				393
			 | 
			
				581
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				394
			 | 
			
				582
			 | 
			
			
				
				 #define NUM_TESTS ( sizeof ( tests ) / sizeof ( tests[0] ) ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -421,6 +609,8 @@ static struct protocol_test * get_test_from_name ( const char *name ) { 
			 | 
		
		
	
		
			
			| 
				421
			 | 
			
				609
			 | 
			
			
				
				 struct tester_options { 
			 | 
		
		
	
		
			
			| 
				422
			 | 
			
				610
			 | 
			
			
				
				 	char interface[IF_NAMESIZE]; 
			 | 
		
		
	
		
			
			| 
				423
			 | 
			
				611
			 | 
			
			
				
				 	struct in_addr in_addr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				612
			 | 
			
			
				
				+	struct in_addr netmask; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				613
			 | 
			
			
				
				+	struct in_addr gateway; 
			 | 
		
		
	
		
			
			| 
				424
			 | 
			
				614
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				425
			 | 
			
				615
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				426
			 | 
			
				616
			 | 
			
			
				
				 static void usage ( char **argv ) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -430,7 +620,9 @@ static void usage ( char **argv ) { 
			 | 
		
		
	
		
			
			| 
				430
			 | 
			
				620
			 | 
			
			
				
				 		  "Global options:\n" 
			 | 
		
		
	
		
			
			| 
				431
			 | 
			
				621
			 | 
			
			
				
				 		  "  -h|--help              Print this help message\n" 
			 | 
		
		
	
		
			
			| 
				432
			 | 
			
				622
			 | 
			
			
				
				 		  "  -i|--interface intf    Use specified network interface\n" 
			 | 
		
		
	
		
			
			| 
				433
			 | 
			
				
			 | 
			
			
				
				-		  "  -f|--from ip-address   Use specified local IP address\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				623
			 | 
			
			
				
				+		  "  -f|--from ip-addr      Use specified local IP address\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				624
			 | 
			
			
				
				+		  "  -n|--netmask mask      Use specified netmask\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				625
			 | 
			
			
				
				+		  "  -g|--gateway ip-addr   Use specified default gateway\n" 
			 | 
		
		
	
		
			
			| 
				434
			 | 
			
				626
			 | 
			
			
				
				 		  "  -l|--list              List available tests\n" 
			 | 
		
		
	
		
			
			| 
				435
			 | 
			
				627
			 | 
			
			
				
				 		  "\n" 
			 | 
		
		
	
		
			
			| 
				436
			 | 
			
				628
			 | 
			
			
				
				 		  "Use \"%s <test> -h\" to view test-specific options\n", 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -442,6 +634,8 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				442
			 | 
			
				634
			 | 
			
			
				
				 	static struct option long_options[] = { 
			 | 
		
		
	
		
			
			| 
				443
			 | 
			
				635
			 | 
			
			
				
				 		{ "interface", 1, NULL, 'i' }, 
			 | 
		
		
	
		
			
			| 
				444
			 | 
			
				636
			 | 
			
			
				
				 		{ "from", 1, NULL, 'f' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				637
			 | 
			
			
				
				+		{ "netmask", 1, NULL, 'n' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				638
			 | 
			
			
				
				+		{ "gateway", 1, NULL, 'g' }, 
			 | 
		
		
	
		
			
			| 
				445
			 | 
			
				639
			 | 
			
			
				
				 		{ "list", 0, NULL, 'l' }, 
			 | 
		
		
	
		
			
			| 
				446
			 | 
			
				640
			 | 
			
			
				
				 		{ "help", 0, NULL, 'h' }, 
			 | 
		
		
	
		
			
			| 
				447
			 | 
			
				641
			 | 
			
			
				
				 		{ }, 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -457,7 +651,7 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				457
			 | 
			
				651
			 | 
			
			
				
				 	while ( 1 ) { 
			 | 
		
		
	
		
			
			| 
				458
			 | 
			
				652
			 | 
			
			
				
				 		int option_index = 0; 
			 | 
		
		
	
		
			
			| 
				459
			 | 
			
				653
			 | 
			
			
				
				 		 
			 | 
		
		
	
		
			
			| 
				460
			 | 
			
				
			 | 
			
			
				
				-		c = getopt_long ( argc, argv, "+i:f:hl", long_options, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				654
			 | 
			
			
				
				+		c = getopt_long ( argc, argv, "+i:f:n:g:hl", long_options, 
			 | 
		
		
	
		
			
			| 
				461
			 | 
			
				655
			 | 
			
			
				
				 				  &option_index ); 
			 | 
		
		
	
		
			
			| 
				462
			 | 
			
				656
			 | 
			
			
				
				 		if ( c < 0 ) 
			 | 
		
		
	
		
			
			| 
				463
			 | 
			
				657
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -474,6 +668,20 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				474
			 | 
			
				668
			 | 
			
			
				
				 				return -1; 
			 | 
		
		
	
		
			
			| 
				475
			 | 
			
				669
			 | 
			
			
				
				 			} 
			 | 
		
		
	
		
			
			| 
				476
			 | 
			
				670
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				671
			 | 
			
			
				
				+		case 'n': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				672
			 | 
			
			
				
				+			if ( inet_aton ( optarg, &options->netmask ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				673
			 | 
			
			
				
				+				fprintf ( stderr, "Invalid IP address %s\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				674
			 | 
			
			
				
				+					  optarg ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				675
			 | 
			
			
				
				+				return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				676
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				677
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				678
			 | 
			
			
				
				+		case 'g': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				679
			 | 
			
			
				
				+			if ( inet_aton ( optarg, &options->gateway ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				680
			 | 
			
			
				
				+				fprintf ( stderr, "Invalid IP address %s\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				681
			 | 
			
			
				
				+					  optarg ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				682
			 | 
			
			
				
				+				return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				683
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				684
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				477
			 | 
			
				685
			 | 
			
			
				
				 		case 'l': 
			 | 
		
		
	
		
			
			| 
				478
			 | 
			
				686
			 | 
			
			
				
				 			list_tests (); 
			 | 
		
		
	
		
			
			| 
				479
			 | 
			
				687
			 | 
			
			
				
				 			return -1; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -524,6 +732,8 @@ int main ( int argc, char **argv ) { 
			 | 
		
		
	
		
			
			| 
				524
			 | 
			
				732
			 | 
			
			
				
				 	/* Initialise the protocol stack */ 
			 | 
		
		
	
		
			
			| 
				525
			 | 
			
				733
			 | 
			
			
				
				 	init_tcpip(); 
			 | 
		
		
	
		
			
			| 
				526
			 | 
			
				734
			 | 
			
			
				
				 	set_ipaddr ( options.in_addr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				735
			 | 
			
			
				
				+	set_netmask ( options.netmask ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				736
			 | 
			
			
				
				+	set_gateway ( options.gateway ); 
			 | 
		
		
	
		
			
			| 
				527
			 | 
			
				737
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				528
			 | 
			
				738
			 | 
			
			
				
				 	/* Open the hijack device */ 
			 | 
		
		
	
		
			
			| 
				529
			 | 
			
				739
			 | 
			
			
				
				 	hijack_dev.name = options.interface; 
			 |