|
@@ -1,4 +1,5 @@
|
1
|
1
|
#include <string.h>
|
|
2
|
+#include <stdlib.h>
|
2
|
3
|
#include <vsprintf.h>
|
3
|
4
|
#include <byteswap.h>
|
4
|
5
|
#include <gpxe/ip.h>
|
|
@@ -14,31 +15,73 @@ static int test_dhcp_aoe_boot ( struct net_device *netdev,
|
14
|
15
|
return test_aoeboot ( netdev, aoename, drivenum );
|
15
|
16
|
}
|
16
|
17
|
|
17
|
|
-static int test_dhcp_iscsi_boot ( struct net_device *netdev,
|
18
|
|
- char *iscsiname ) {
|
|
18
|
+enum {
|
|
19
|
+ RP_LITERAL = 0,
|
|
20
|
+ RP_SERVERNAME,
|
|
21
|
+ RP_PROTOCOL,
|
|
22
|
+ RP_PORT,
|
|
23
|
+ RP_LUN,
|
|
24
|
+ RP_TARGETNAME,
|
|
25
|
+ NUM_RP_COMPONENTS
|
|
26
|
+};
|
|
27
|
+
|
|
28
|
+static int iscsi_split_root_path ( char *root_path,
|
|
29
|
+ char * components[NUM_RP_COMPONENTS] ) {
|
|
30
|
+ int component = 0;
|
|
31
|
+
|
|
32
|
+ while ( 1 ) {
|
|
33
|
+ components[component++] = root_path;
|
|
34
|
+ if ( component == NUM_RP_COMPONENTS ) {
|
|
35
|
+ return 0;
|
|
36
|
+ }
|
|
37
|
+ for ( ; *root_path != ':' ; root_path++ ) {
|
|
38
|
+ if ( ! *root_path )
|
|
39
|
+ return -EINVAL;
|
|
40
|
+ }
|
|
41
|
+ *(root_path++) = '\0';
|
|
42
|
+ }
|
|
43
|
+}
|
|
44
|
+
|
|
45
|
+static int test_dhcp_iscsi_boot ( struct net_device *netdev ) {
|
|
46
|
+ char root_path[256];
|
|
47
|
+ char *rp_components[NUM_RP_COMPONENTS];
|
19
|
48
|
char initiator_iqn_buf[32];
|
20
|
49
|
char *initiator_iqn = initiator_iqn_buf;
|
21
|
50
|
char username[32];
|
22
|
51
|
char password[32];
|
23
|
|
- char *target_iqn;
|
24
|
52
|
union {
|
25
|
53
|
struct sockaddr_in sin;
|
26
|
54
|
struct sockaddr_tcpip st;
|
27
|
55
|
} target;
|
28
|
56
|
unsigned int drivenum;
|
|
57
|
+ unsigned int lun;
|
29
|
58
|
struct dhcp_option *option;
|
30
|
|
-
|
|
59
|
+ int rc;
|
|
60
|
+
|
31
|
61
|
memset ( &target, 0, sizeof ( target ) );
|
32
|
62
|
target.sin.sin_family = AF_INET;
|
33
|
|
- target.sin.sin_port = htons ( ISCSI_PORT );
|
34
|
|
- target_iqn = strchr ( iscsiname, ':' );
|
35
|
|
- *target_iqn++ = '\0';
|
36
|
|
- if ( ! target_iqn ) {
|
37
|
|
- printf ( "Invalid iSCSI DHCP path\n" );
|
38
|
|
- return -EINVAL;
|
39
|
|
- }
|
40
|
|
- inet_aton ( iscsiname, &target.sin.sin_addr );
|
41
|
63
|
|
|
64
|
+ dhcp_snprintf ( root_path, sizeof ( root_path ),
|
|
65
|
+ find_global_dhcp_option ( DHCP_ROOT_PATH ) );
|
|
66
|
+
|
|
67
|
+ printf ( "Root path \"%s\"\n", root_path );
|
|
68
|
+
|
|
69
|
+ if ( ( rc = iscsi_split_root_path ( root_path, rp_components ) ) != 0 )
|
|
70
|
+ goto bad_root_path;
|
|
71
|
+
|
|
72
|
+ if ( strcmp ( rp_components[RP_LITERAL], "iscsi" ) != 0 )
|
|
73
|
+ goto bad_root_path;
|
|
74
|
+
|
|
75
|
+ if ( inet_aton ( rp_components[RP_SERVERNAME],
|
|
76
|
+ &target.sin.sin_addr ) == 0 )
|
|
77
|
+ goto bad_root_path;
|
|
78
|
+
|
|
79
|
+ target.sin.sin_port = strtoul ( rp_components[RP_PORT], NULL, 0 );
|
|
80
|
+ if ( ! target.st.st_port )
|
|
81
|
+ target.st.st_port = htons ( ISCSI_PORT );
|
|
82
|
+
|
|
83
|
+ lun = strtoul ( rp_components[RP_LUN], NULL, 0 );
|
|
84
|
+
|
42
|
85
|
dhcp_snprintf ( initiator_iqn, sizeof ( initiator_iqn ),
|
43
|
86
|
find_global_dhcp_option ( DHCP_ISCSI_INITIATOR_IQN ) );
|
44
|
87
|
if ( ! *initiator_iqn )
|
|
@@ -50,8 +93,13 @@ static int test_dhcp_iscsi_boot ( struct net_device *netdev,
|
50
|
93
|
|
51
|
94
|
drivenum = find_global_dhcp_num_option ( DHCP_EB_BIOS_DRIVE );
|
52
|
95
|
|
53
|
|
- return test_iscsiboot ( initiator_iqn, &target.st, target_iqn,
|
|
96
|
+ return test_iscsiboot ( initiator_iqn, &target.st,
|
|
97
|
+ rp_components[RP_TARGETNAME], lun,
|
54
|
98
|
username, password, netdev, drivenum );
|
|
99
|
+
|
|
100
|
+ bad_root_path:
|
|
101
|
+ printf ( "Invalid iSCSI root path\n" );
|
|
102
|
+ return -EINVAL;
|
55
|
103
|
}
|
56
|
104
|
|
57
|
105
|
static int test_dhcp_hello ( char *helloname ) {
|
|
@@ -140,8 +188,9 @@ static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
|
140
|
188
|
return test_dhcp_aoe_boot ( netdev, &filename[4] );
|
141
|
189
|
}
|
142
|
190
|
*/
|
143
|
|
- if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
|
144
|
|
- return test_dhcp_iscsi_boot ( netdev, &filename[6] );
|
|
191
|
+ // if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
|
|
192
|
+ if ( ! filename[0] ) {
|
|
193
|
+ return test_dhcp_iscsi_boot ( netdev );
|
145
|
194
|
}
|
146
|
195
|
/*
|
147
|
196
|
if ( strncmp ( filename, "ftp:", 4 ) == 0 ) {
|
|
@@ -198,12 +247,9 @@ int test_dhcp ( struct net_device *netdev ) {
|
198
|
247
|
|
199
|
248
|
dhcp_snprintf ( filename, sizeof ( filename ),
|
200
|
249
|
find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
|
201
|
|
- if ( ! filename[0] ) {
|
202
|
|
- printf ( "No filename specified!\n" );
|
203
|
|
- goto out;
|
204
|
|
- }
|
205
|
250
|
|
206
|
|
- printf ( "Bootfile name %s\n", filename );
|
|
251
|
+ if ( filename[0] )
|
|
252
|
+ printf ( "Bootfile name \"%s\"\n", filename );
|
207
|
253
|
|
208
|
254
|
/* Remove old IP address configuration */
|
209
|
255
|
del_ipv4_address ( netdev );
|