1 /* 2 * Copyright (C) 2006 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <stddef.h> 22 #include <string.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <errno.h> 26 #include <assert.h> 27 #include <byteswap.h> 28 #include <gpxe/vsprintf.h> 29 #include <gpxe/socket.h> 30 #include <gpxe/xfer.h> 31 #include <gpxe/open.h> 32 #include <gpxe/scsi.h> 33 #include <gpxe/process.h> 34 #include <gpxe/uaccess.h> 35 #include <gpxe/tcpip.h> 36 #include <gpxe/settings.h> 37 #include <gpxe/features.h> 38 #include <gpxe/iscsi.h> 39 40 /** @file 41 * 42 * iSCSI protocol 43 * 44 */ 45 46 FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 ); 47 48 /** iSCSI initiator name (explicitly specified) */ 49 static char *iscsi_explicit_initiator_iqn; 50 51 /** Default iSCSI initiator name (constructed from hostname) */ 52 static char *iscsi_default_initiator_iqn; 53 54 /** iSCSI initiator username */ 55 static char *iscsi_initiator_username; 56 57 /** iSCSI initiator password */ 58 static char *iscsi_initiator_password; 59 60 /** iSCSI target username */ 61 static char *iscsi_target_username; 62 63 /** iSCSI target password */ 64 static char *iscsi_target_password; 65 66 static void iscsi_start_tx ( struct iscsi_session *iscsi ); 67 static void iscsi_start_login ( struct iscsi_session *iscsi ); 68 static void iscsi_start_data_out ( struct iscsi_session *iscsi, 69 unsigned int datasn ); 70 71 /** 72 * Finish receiving PDU data into buffer 73 * 74 * @v iscsi iSCSI session 75 */ 76 static void iscsi_rx_buffered_data_done ( struct iscsi_session *iscsi ) { 77 free ( iscsi->rx_buffer ); 78 iscsi->rx_buffer = NULL; 79 } 80 81 /** 82 * Free iSCSI session 83 * 84 * @v refcnt Reference counter 85 */ 86 static void iscsi_free ( struct refcnt *refcnt ) { 87 struct iscsi_session *iscsi = 88 container_of ( refcnt, struct iscsi_session, refcnt ); 89 90 free ( iscsi->target_address ); 91 free ( iscsi->target_iqn ); 92 free ( iscsi->initiator_username ); 93 free ( iscsi->initiator_password ); 94 free ( iscsi->target_username ); 95 free ( iscsi->target_password ); 96 chap_finish ( &iscsi->chap ); 97 iscsi_rx_buffered_data_done ( iscsi ); 98 free ( iscsi ); 99 } 100 101 /** 102 * Open iSCSI transport-layer connection 103 * 104 * @v iscsi iSCSI session 105 * @ret rc Return status code 106 */ 107 static int iscsi_open_connection ( struct iscsi_session *iscsi ) { 108 struct sockaddr_tcpip target; 109 int rc; 110 111 assert ( iscsi->tx_state == ISCSI_TX_IDLE ); 112 assert ( iscsi->rx_state == ISCSI_RX_BHS ); 113 assert ( iscsi->rx_offset == 0 ); 114 115 /* Open socket */ 116 memset ( &target, 0, sizeof ( target ) ); 117 target.st_port = htons ( iscsi->target_port ); 118 if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM, 119 ( struct sockaddr * ) &target, 120 iscsi->target_address, 121 NULL ) ) != 0 ) { 122 DBGC ( iscsi, "iSCSI %p could not open socket: %s\n", 123 iscsi, strerror ( rc ) ); 124 return rc; 125 } 126 127 /* Enter security negotiation phase */ 128 iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE | 129 ISCSI_STATUS_STRINGS_SECURITY ); 130 if ( iscsi->target_username ) 131 iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_REQUIRED; 132 133 /* Assign fresh initiator task tag */ 134 iscsi->itt++; 135 136 /* Initiate login */ 137 iscsi_start_login ( iscsi ); 138 139 return 0; 140 } 141 142 /** 143 * Close iSCSI transport-layer connection 144 * 145 * @v iscsi iSCSI session 146 * @v rc Reason for close 147 * 148 * Closes the transport-layer connection and resets the session state 149 * ready to attempt a fresh login. 150 */ 151 static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { 152 153 /* Close all data transfer interfaces */ 154 xfer_close ( &iscsi->socket, rc ); 155 156 /* Clear connection status */ 157 iscsi->status = 0; 158 159 /* Reset TX and RX state machines */ 160 iscsi->tx_state = ISCSI_TX_IDLE; 161 iscsi->rx_state = ISCSI_RX_BHS; 162 iscsi->rx_offset = 0; 163 164 /* Free any temporary dynamically allocated memory */ 165 chap_finish ( &iscsi->chap ); 166 iscsi_rx_buffered_data_done ( iscsi ); 167 } 168 169 /** 170 * Mark iSCSI SCSI operation as complete 171 * 172 * @v iscsi iSCSI session 173 * @v rc Return status code 174 * 175 * Note that iscsi_scsi_done() will not close the connection, and must 176 * therefore be called only when the internal state machines are in an 177 * appropriate state, otherwise bad things may happen on the next call 178 * to iscsi_issue(). The general rule is to call iscsi_scsi_done() 179 * only at the end of receiving a PDU; at this point the TX and RX 180 * engines should both be idle. 181 */ 182 static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc ) { 183 184 assert ( iscsi->tx_state == ISCSI_TX_IDLE ); 185 assert ( iscsi->command != NULL ); 186 187 iscsi->command->rc = rc; 188 iscsi->command = NULL; 189 } 190 191 /**************************************************************************** 192 * 193 * iSCSI SCSI command issuing 194 * 195 */ 196 197 /** 198 * Build iSCSI SCSI command BHS 199 * 200 * @v iscsi iSCSI session 201 * 202 * We don't currently support bidirectional commands (i.e. with both 203 * Data-In and Data-Out segments); these would require providing code 204 * to generate an AHS, and there doesn't seem to be any need for it at 205 * the moment. 206 */ 207 static void iscsi_start_command ( struct iscsi_session *iscsi ) { 208 struct iscsi_bhs_scsi_command *command = &iscsi->tx_bhs.scsi_command; 209 210 assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) ); 211 212 /* Construct BHS and initiate transmission */ 213 iscsi_start_tx ( iscsi ); 214 command->opcode = ISCSI_OPCODE_SCSI_COMMAND; 215 command->flags = ( ISCSI_FLAG_FINAL | 216 ISCSI_COMMAND_ATTR_SIMPLE ); 217 if ( iscsi->command->data_in ) 218 command->flags |= ISCSI_COMMAND_FLAG_READ; 219 if ( iscsi->command->data_out ) 220 command->flags |= ISCSI_COMMAND_FLAG_WRITE; 221 /* lengths left as zero */ 222 command->lun = iscsi->lun; 223 command->itt = htonl ( ++iscsi->itt ); 224 command->exp_len = htonl ( iscsi->command->data_in_len | 225 iscsi->command->data_out_len ); 226 command->cmdsn = htonl ( iscsi->cmdsn ); 227 command->expstatsn = htonl ( iscsi->statsn + 1 ); 228 memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb )); 229 DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n", 230 iscsi, SCSI_CDB_DATA ( command->cdb ), 231 ( iscsi->command->data_in ? "in" : "out" ), 232 ( iscsi->command->data_in ? 233 iscsi->command->data_in_len : 234 iscsi->command->data_out_len ) ); 235 } 236 237 /** 238 * Receive data segment of an iSCSI SCSI response PDU 239 * 240 * @v iscsi iSCSI session 241 * @v data Received data 242 * @v len Length of received data 243 * @v remaining Data remaining after this data 244 * @ret rc Return status code 245 */ 246 static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi, 247 const void *data, size_t len, 248 size_t remaining ) { 249 struct iscsi_bhs_scsi_response *response 250 = &iscsi->rx_bhs.scsi_response; 251 int sense_offset; 252 253 /* Capture the sense response code as it floats past, if present */ 254 sense_offset = ISCSI_SENSE_RESPONSE_CODE_OFFSET - iscsi->rx_offset; 255 if ( ( sense_offset >= 0 ) && len ) { 256 iscsi->command->sense_response = 257 * ( ( char * ) data + sense_offset ); 258 } 259 260 /* Wait for whole SCSI response to arrive */ 261 if ( remaining ) 262 return 0; 263 264 /* Record SCSI status code */ 265 iscsi->command->status = response->status; 266 267 /* Check for errors */ 268 if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE ) 269 return -EIO; 270 271 /* Mark as completed */ 272 iscsi_scsi_done ( iscsi, 0 ); 273 return 0; 274 } 275 276 /** 277 * Receive data segment of an iSCSI data-in PDU 278 * 279 * @v iscsi iSCSI session 280 * @v data Received data 281 * @v len Length of received data 282 * @v remaining Data remaining after this data 283 * @ret rc Return status code 284 */ 285 static int iscsi_rx_data_in ( struct iscsi_session *iscsi, 286 const void *data, size_t len, 287 size_t remaining ) { 288 struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in; 289 unsigned long offset; 290 291 /* Copy data to data-in buffer */ 292 offset = ntohl ( data_in->offset ) + iscsi->rx_offset; 293 assert ( iscsi->command != NULL ); 294 assert ( iscsi->command->data_in ); 295 assert ( ( offset + len ) <= iscsi->command->data_in_len ); 296 copy_to_user ( iscsi->command->data_in, offset, data, len ); 297 298 /* Wait for whole SCSI response to arrive */ 299 if ( remaining ) 300 return 0; 301 302 /* Mark as completed if status is present */ 303 if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) { 304 assert ( ( offset + len ) == iscsi->command->data_in_len ); 305 assert ( data_in->flags & ISCSI_FLAG_FINAL ); 306 iscsi->command->status = data_in->status; 307 /* iSCSI cannot return an error status via a data-in */ 308 iscsi_scsi_done ( iscsi, 0 ); 309 } 310 311 return 0; 312 } 313 314 /** 315 * Receive data segment of an iSCSI R2T PDU 316 * 317 * @v iscsi iSCSI session 318 * @v data Received data 319 * @v len Length of received data 320 * @v remaining Data remaining after this data 321 * @ret rc Return status code 322 */ 323 static int iscsi_rx_r2t ( struct iscsi_session *iscsi, 324 const void *data __unused, size_t len __unused, 325 size_t remaining __unused ) { 326 struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t; 327 328 /* Record transfer parameters and trigger first data-out */ 329 iscsi->ttt = ntohl ( r2t->ttt ); 330 iscsi->transfer_offset = ntohl ( r2t->offset ); 331 iscsi->transfer_len = ntohl ( r2t->len ); 332 iscsi_start_data_out ( iscsi, 0 ); 333 334 return 0; 335 } 336 337 /** 338 * Build iSCSI data-out BHS 339 * 340 * @v iscsi iSCSI session 341 * @v datasn Data sequence number within the transfer 342 * 343 */ 344 static void iscsi_start_data_out ( struct iscsi_session *iscsi, 345 unsigned int datasn ) { 346 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 347 unsigned long offset; 348 unsigned long remaining; 349 unsigned long len; 350 351 /* We always send 512-byte Data-Out PDUs; this removes the 352 * need to worry about the target's MaxRecvDataSegmentLength. 353 */ 354 offset = datasn * 512; 355 remaining = iscsi->transfer_len - offset; 356 len = remaining; 357 if ( len > 512 ) 358 len = 512; 359 360 /* Construct BHS and initiate transmission */ 361 iscsi_start_tx ( iscsi ); 362 data_out->opcode = ISCSI_OPCODE_DATA_OUT; 363 if ( len == remaining ) 364 data_out->flags = ( ISCSI_FLAG_FINAL ); 365 ISCSI_SET_LENGTHS ( data_out->lengths, 0, len ); 366 data_out->lun = iscsi->lun; 367 data_out->itt = htonl ( iscsi->itt ); 368 data_out->ttt = htonl ( iscsi->ttt ); 369 data_out->expstatsn = htonl ( iscsi->statsn + 1 ); 370 data_out->datasn = htonl ( datasn ); 371 data_out->offset = htonl ( iscsi->transfer_offset + offset ); 372 DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n", 373 iscsi, datasn, len ); 374 } 375 376 /** 377 * Complete iSCSI data-out PDU transmission 378 * 379 * @v iscsi iSCSI session 380 * 381 */ 382 static void iscsi_data_out_done ( struct iscsi_session *iscsi ) { 383 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 384 385 /* If we haven't reached the end of the sequence, start 386 * sending the next data-out PDU. 387 */ 388 if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) ) 389 iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 ); 390 } 391 392 /** 393 * Send iSCSI data-out data segment 394 * 395 * @v iscsi iSCSI session 396 * @ret rc Return status code 397 */ 398 static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) { 399 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 400 struct io_buffer *iobuf; 401 unsigned long offset; 402 size_t len; 403 404 offset = ntohl ( data_out->offset ); 405 len = ISCSI_DATA_LEN ( data_out->lengths ); 406 407 assert ( iscsi->command != NULL ); 408 assert ( iscsi->command->data_out ); 409 assert ( ( offset + len ) <= iscsi->command->data_out_len ); 410 411 iobuf = xfer_alloc_iob ( &iscsi->socket, len ); 412 if ( ! iobuf ) 413 return -ENOMEM; 414 415 copy_from_user ( iob_put ( iobuf, len ), 416 iscsi->command->data_out, offset, len ); 417 418 return xfer_deliver_iob ( &iscsi->socket, iobuf ); 419 } 420 421 /**************************************************************************** 422 * 423 * iSCSI login 424 * 425 */ 426 427 /** 428 * Build iSCSI login request strings 429 * 430 * @v iscsi iSCSI session 431 * 432 * These are the initial set of strings sent in the first login 433 * request PDU. We want the following settings: 434 * 435 * HeaderDigest=None 436 * DataDigest=None 437 * MaxConnections is irrelevant; we make only one connection anyway 438 * InitialR2T=Yes [1] 439 * ImmediateData is irrelevant; we never send immediate data 440 * MaxRecvDataSegmentLength=8192 (default; we don't care) [3] 441 * MaxBurstLength=262144 (default; we don't care) [3] 442 * FirstBurstLength=262144 (default; we don't care) 443 * DefaultTime2Wait=0 [2] 444 * DefaultTime2Retain=0 [2] 445 * MaxOutstandingR2T=1 446 * DataPDUInOrder=Yes 447 * DataSequenceInOrder=Yes 448 * ErrorRecoveryLevel=0 449 * 450 * [1] InitialR2T has an OR resolution function, so the target may 451 * force us to use it. We therefore simplify our logic by always 452 * using it. 453 * 454 * [2] These ensure that we can safely start a new task once we have 455 * reconnected after a failure, without having to manually tidy up 456 * after the old one. 457 * 458 * [3] We are quite happy to use the RFC-defined default values for 459 * these parameters, but some targets (notably OpenSolaris) 460 * incorrectly assume a default value of zero, so we explicitly 461 * specify the default values. 462 */ 463 static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi, 464 void *data, size_t len ) { 465 unsigned int used = 0; 466 unsigned int i; 467 const char *auth_method; 468 469 if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) { 470 /* Default to allowing no authentication */ 471 auth_method = "None"; 472 /* If we have a credential to supply, permit CHAP */ 473 if ( iscsi->initiator_username ) 474 auth_method = "CHAP,None"; 475 /* If we have a credential to check, force CHAP */ 476 if ( iscsi->target_username ) 477 auth_method = "CHAP"; 478 used += ssnprintf ( data + used, len - used, 479 "InitiatorName=%s%c" 480 "TargetName=%s%c" 481 "SessionType=Normal%c" 482 "AuthMethod=%s%c", 483 iscsi_initiator_iqn(), 0, 484 iscsi->target_iqn, 0, 0, 485 auth_method, 0 ); 486 } 487 488 if ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_ALGORITHM ) { 489 used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 ); 490 } 491 492 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) { 493 assert ( iscsi->initiator_username != NULL ); 494 used += ssnprintf ( data + used, len - used, 495 "CHAP_N=%s%cCHAP_R=0x", 496 iscsi->initiator_username, 0 ); 497 for ( i = 0 ; i < iscsi->chap.response_len ; i++ ) { 498 used += ssnprintf ( data + used, len - used, "%02x", 499 iscsi->chap.response[i] ); 500 } 501 used += ssnprintf ( data + used, len - used, "%c", 0 ); 502 } 503 504 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) { 505 used += ssnprintf ( data + used, len - used, 506 "CHAP_I=%d%cCHAP_C=0x", 507 iscsi->chap_challenge[0], 0 ); 508 for ( i = 1 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) { 509 used += ssnprintf ( data + used, len - used, "%02x", 510 iscsi->chap_challenge[i] ); 511 } 512 used += ssnprintf ( data + used, len - used, "%c", 0 ); 513 } 514 515 if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) { 516 used += ssnprintf ( data + used, len - used, 517 "HeaderDigest=None%c" 518 "DataDigest=None%c" 519 "InitialR2T=Yes%c" 520 "MaxRecvDataSegmentLength=8192%c" 521 "MaxBurstLength=262144%c" 522 "DefaultTime2Wait=0%c" 523 "DefaultTime2Retain=0%c" 524 "MaxOutstandingR2T=1%c" 525 "DataPDUInOrder=Yes%c" 526 "DataSequenceInOrder=Yes%c" 527 "ErrorRecoveryLevel=0%c", 528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); 529 } 530 531 return used; 532 } 533 534 /** 535 * Build iSCSI login request BHS 536 * 537 * @v iscsi iSCSI session 538 */ 539 static void iscsi_start_login ( struct iscsi_session *iscsi ) { 540 struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; 541 int len; 542 543 /* Construct BHS and initiate transmission */ 544 iscsi_start_tx ( iscsi ); 545 request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST | 546 ISCSI_FLAG_IMMEDIATE ); 547 request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) | 548 ISCSI_LOGIN_FLAG_TRANSITION ); 549 /* version_max and version_min left as zero */ 550 len = iscsi_build_login_request_strings ( iscsi, NULL, 0 ); 551 ISCSI_SET_LENGTHS ( request->lengths, 0, len ); 552 request->isid_iana_en = htonl ( ISCSI_ISID_IANA | 553 IANA_EN_FEN_SYSTEMS ); 554 /* isid_iana_qual left as zero */ 555 request->tsih = htons ( iscsi->tsih ); 556 request->itt = htonl ( iscsi->itt ); 557 /* cid left as zero */ 558 request->cmdsn = htonl ( iscsi->cmdsn ); 559 request->expstatsn = htonl ( iscsi->statsn + 1 ); 560 } 561 562 /** 563 * Complete iSCSI login request PDU transmission 564 * 565 * @v iscsi iSCSI session 566 * 567 */ 568 static void iscsi_login_request_done ( struct iscsi_session *iscsi ) { 569 570 /* Clear any "strings to send" flags */ 571 iscsi->status &= ~ISCSI_STATUS_STRINGS_MASK; 572 573 /* Free any dynamically allocated storage used for login */ 574 chap_finish ( &iscsi->chap ); 575 } 576 577 /** 578 * Transmit data segment of an iSCSI login request PDU 579 * 580 * @v iscsi iSCSI session 581 * @ret rc Return status code 582 * 583 * For login requests, the data segment consists of the login strings. 584 */ 585 static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) { 586 struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; 587 struct io_buffer *iobuf; 588 size_t len; 589 590 len = ISCSI_DATA_LEN ( request->lengths ); 591 iobuf = xfer_alloc_iob ( &iscsi->socket, len ); 592 if ( ! iobuf ) 593 return -ENOMEM; 594 iob_put ( iobuf, len ); 595 iscsi_build_login_request_strings ( iscsi, iobuf->data, len ); 596 return xfer_deliver_iob ( &iscsi->socket, iobuf ); 597 } 598 599 /** 600 * Handle iSCSI TargetAddress text value 601 * 602 * @v iscsi iSCSI session 603 * @v value TargetAddress value 604 * @ret rc Return status code 605 */ 606 static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi, 607 const char *value ) { 608 char *separator; 609 610 DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value ); 611 612 /* Replace target address */ 613 free ( iscsi->target_address ); 614 iscsi->target_address = strdup ( value ); 615 if ( ! iscsi->target_address ) 616 return -ENOMEM; 617 618 /* Replace target port */ 619 iscsi->target_port = htons ( ISCSI_PORT ); 620 separator = strchr ( iscsi->target_address, ':' ); 621 if ( separator ) { 622 *separator = '\0'; 623 iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 ); 624 } 625 626 return 0; 627 } 628 629 /** 630 * Handle iSCSI AuthMethod text value 631 * 632 * @v iscsi iSCSI session 633 * @v value AuthMethod value 634 * @ret rc Return status code 635 */ 636 static int iscsi_handle_authmethod_value ( struct iscsi_session *iscsi, 637 const char *value ) { 638 639 /* If server requests CHAP, send the CHAP_A string */ 640 if ( strcmp ( value, "CHAP" ) == 0 ) { 641 DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n", 642 iscsi ); 643 iscsi->status |= ( ISCSI_STATUS_STRINGS_CHAP_ALGORITHM | 644 ISCSI_STATUS_AUTH_FORWARD_REQUIRED ); 645 } 646 647 return 0; 648 } 649 650 /** 651 * Handle iSCSI CHAP_A text value 652 * 653 * @v iscsi iSCSI session 654 * @v value CHAP_A value 655 * @ret rc Return status code 656 */ 657 static int iscsi_handle_chap_a_value ( struct iscsi_session *iscsi, 658 const char *value ) { 659 660 /* We only ever offer "5" (i.e. MD5) as an algorithm, so if 661 * the server responds with anything else it is a protocol 662 * violation. 663 */ 664 if ( strcmp ( value, "5" ) != 0 ) { 665 DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n", 666 iscsi, value ); 667 return -EPROTO; 668 } 669 670 return 0; 671 } 672 673 /** 674 * Handle iSCSI CHAP_I text value 675 * 676 * @v iscsi iSCSI session 677 * @v value CHAP_I value 678 * @ret rc Return status code 679 */ 680 static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi, 681 const char *value ) { 682 unsigned int identifier; 683 char *endp; 684 int rc; 685 686 /* The CHAP identifier is an integer value */ 687 identifier = strtoul ( value, &endp, 0 ); 688 if ( *endp != '\0' ) { 689 DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n", 690 iscsi, value ); 691 return -EPROTO; 692 } 693 694 /* Prepare for CHAP with MD5 */ 695 chap_finish ( &iscsi->chap ); 696 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { 697 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", 698 iscsi, strerror ( rc ) ); 699 return rc; 700 } 701 702 /* Identifier and secret are the first two components of the 703 * challenge. 704 */ 705 chap_set_identifier ( &iscsi->chap, identifier ); 706 if ( iscsi->initiator_password ) { 707 chap_update ( &iscsi->chap, iscsi->initiator_password, 708 strlen ( iscsi->initiator_password ) ); 709 } 710 711 return 0; 712 } 713 714 /** 715 * Handle iSCSI CHAP_C text value 716 * 717 * @v iscsi iSCSI session 718 * @v value CHAP_C value 719 * @ret rc Return status code 720 */ 721 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi, 722 const char *value ) { 723 char buf[3]; 724 char *endp; 725 uint8_t byte; 726 unsigned int i; 727 728 /* Check and strip leading "0x" */ 729 if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) { 730 DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge \"%s\"\n", 731 iscsi, value ); 732 return -EPROTO; 733 } 734 value += 2; 735 736 /* Process challenge an octet at a time */ 737 for ( ; ( value[0] && value[1] ) ; value += 2 ) { 738 memcpy ( buf, value, 2 ); 739 buf[2] = 0; 740 byte = strtoul ( buf, &endp, 16 ); 741 if ( *endp != '\0' ) { 742 DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge " 743 "byte \"%s\"\n", iscsi, buf ); 744 return -EPROTO; 745 } 746 chap_update ( &iscsi->chap, &byte, sizeof ( byte ) ); 747 } 748 749 /* Build CHAP response */ 750 DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi ); 751 chap_respond ( &iscsi->chap ); 752 iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_RESPONSE; 753 754 /* Send CHAP challenge, if applicable */ 755 if ( iscsi->target_username ) { 756 iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_CHALLENGE; 757 /* Generate CHAP challenge data */ 758 for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) { 759 iscsi->chap_challenge[i] = random(); 760 } 761 } 762 763 return 0; 764 } 765 766 /** 767 * Handle iSCSI CHAP_N text value 768 * 769 * @v iscsi iSCSI session 770 * @v value CHAP_N value 771 * @ret rc Return status code 772 */ 773 static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi, 774 const char *value ) { 775 776 /* The target username isn't actually involved at any point in 777 * the authentication process; it merely serves to identify 778 * which password the target is using to generate the CHAP 779 * response. We unnecessarily verify that the username is as 780 * expected, in order to provide mildly helpful diagnostics if 781 * the target is supplying the wrong username/password 782 * combination. 783 */ 784 if ( iscsi->target_username && 785 ( strcmp ( iscsi->target_username, value ) != 0 ) ) { 786 DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect " 787 "(wanted \"%s\")\n", 788 iscsi, value, iscsi->target_username ); 789 return -EACCES; 790 } 791 792 return 0; 793 } 794 795 /** 796 * Handle iSCSI CHAP_R text value 797 * 798 * @v iscsi iSCSI session 799 * @v value CHAP_R value 800 * @ret rc Return status code 801 */ 802 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi, 803 const char *value ) { 804 char buf[3]; 805 char *endp; 806 uint8_t byte; 807 unsigned int i; 808 int rc; 809 810 /* Generate CHAP response for verification */ 811 chap_finish ( &iscsi->chap ); 812 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { 813 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", 814 iscsi, strerror ( rc ) ); 815 return rc; 816 } 817 chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] ); 818 if ( iscsi->target_password ) { 819 chap_update ( &iscsi->chap, iscsi->target_password, 820 strlen ( iscsi->target_password ) ); 821 } 822 chap_update ( &iscsi->chap, &iscsi->chap_challenge[1], 823 ( sizeof ( iscsi->chap_challenge ) - 1 ) ); 824 chap_respond ( &iscsi->chap ); 825 826 /* Check and strip leading "0x" */ 827 if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) { 828 DBGC ( iscsi, "iSCSI %p saw invalid CHAP response \"%s\"\n", 829 iscsi, value ); 830 return -EPROTO; 831 } 832 value += 2; 833 834 /* Check CHAP response length */ 835 if ( strlen ( value ) != ( 2 * iscsi->chap.response_len ) ) { 836 DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n", 837 iscsi ); 838 return -EPROTO; 839 } 840 841 /* Process response an octet at a time */ 842 for ( i = 0 ; ( value[0] && value[1] ) ; value += 2, i++ ) { 843 memcpy ( buf, value, 2 ); 844 buf[2] = 0; 845 byte = strtoul ( buf, &endp, 16 ); 846 if ( *endp != '\0' ) { 847 DBGC ( iscsi, "iSCSI %p saw invalid CHAP response " 848 "byte \"%s\"\n", iscsi, buf ); 849 return -EPROTO; 850 } 851 if ( byte != iscsi->chap.response[i] ) { 852 DBGC ( iscsi, "iSCSI %p saw incorrect CHAP " 853 "response\n", iscsi ); 854 return -EACCES; 855 } 856 } 857 assert ( i == iscsi->chap.response_len ); 858 859 /* Mark session as authenticated */ 860 iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK; 861 862 return 0; 863 } 864 865 /** An iSCSI text string that we want to handle */ 866 struct iscsi_string_type { 867 /** String key 868 * 869 * This is the portion up to and including the "=" sign, 870 * e.g. "InitiatorName=", "CHAP_A=", etc. 871 */ 872 const char *key; 873 /** Handle iSCSI string value 874 * 875 * @v iscsi iSCSI session 876 * @v value iSCSI string value 877 * @ret rc Return status code 878 */ 879 int ( * handle ) ( struct iscsi_session *iscsi, const char *value ); 880 }; 881 882 /** iSCSI text strings that we want to handle */ 883 static struct iscsi_string_type iscsi_string_types[] = { 884 { "TargetAddress=", iscsi_handle_targetaddress_value }, 885 { "AuthMethod=", iscsi_handle_authmethod_value }, 886 { "CHAP_A=", iscsi_handle_chap_a_value }, 887 { "CHAP_I=", iscsi_handle_chap_i_value }, 888 { "CHAP_C=", iscsi_handle_chap_c_value }, 889 { "CHAP_N=", iscsi_handle_chap_n_value }, 890 { "CHAP_R=", iscsi_handle_chap_r_value }, 891 { NULL, NULL } 892 }; 893 894 /** 895 * Handle iSCSI string 896 * 897 * @v iscsi iSCSI session 898 * @v string iSCSI string (in "key=value" format) 899 * @ret rc Return status code 900 */ 901 static int iscsi_handle_string ( struct iscsi_session *iscsi, 902 const char *string ) { 903 struct iscsi_string_type *type; 904 size_t key_len; 905 int rc; 906 907 for ( type = iscsi_string_types ; type->key ; type++ ) { 908 key_len = strlen ( type->key ); 909 if ( strncmp ( string, type->key, key_len ) != 0 ) 910 continue; 911 DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string ); 912 if ( ( rc = type->handle ( iscsi, 913 ( string + key_len ) ) ) != 0 ) { 914 DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n", 915 iscsi, string, strerror ( rc ) ); 916 return rc; 917 } 918 return 0; 919 } 920 DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string ); 921 return 0; 922 } 923 924 /** 925 * Handle iSCSI strings 926 * 927 * @v iscsi iSCSI session 928 * @v string iSCSI string buffer 929 * @v len Length of string buffer 930 * @ret rc Return status code 931 */ 932 static int iscsi_handle_strings ( struct iscsi_session *iscsi, 933 const char *strings, size_t len ) { 934 size_t string_len; 935 int rc; 936 937 /* Handle each string in turn, taking care not to overrun the 938 * data buffer in case of badly-terminated data. 939 */ 940 while ( 1 ) { 941 string_len = ( strnlen ( strings, len ) + 1 ); 942 if ( string_len > len ) 943 break; 944 if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 ) 945 return rc; 946 strings += string_len; 947 len -= string_len; 948 } 949 return 0; 950 } 951 952 /** 953 * Receive PDU data into buffer 954 * 955 * @v iscsi iSCSI session 956 * @v data Data to receive 957 * @v len Length of data 958 * @ret rc Return status code 959 * 960 * This can be used when the RX PDU type handler wishes to buffer up 961 * all received data and process the PDU as a single unit. The caller 962 * is repsonsible for calling iscsi_rx_buffered_data_done() after 963 * processing the data. 964 */ 965 static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi, 966 const void *data, size_t len ) { 967 968 /* Allocate buffer on first call */ 969 if ( ! iscsi->rx_buffer ) { 970 iscsi->rx_buffer = malloc ( iscsi->rx_len ); 971 if ( ! iscsi->rx_buffer ) 972 return -ENOMEM; 973 } 974 975 /* Copy data to buffer */ 976 assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len ); 977 memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len ); 978 979 return 0; 980 } 981 982 /** 983 * Convert iSCSI response status to return status code 984 * 985 * @v status_class iSCSI status class 986 * @v status_detail iSCSI status detail 987 * @ret rc Return status code 988 */ 989 static int iscsi_status_to_rc ( unsigned int status_class, 990 unsigned int status_detail ) { 991 switch ( status_class ) { 992 case ISCSI_STATUS_INITIATOR_ERROR : 993 switch ( status_detail ) { 994 case ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION : 995 return -EACCES; 996 case ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION : 997 return -EPERM; 998 case ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND : 999 case ISCSI_STATUS_INITIATOR_ERROR_REMOVED : 1000 return -ENODEV; 1001 default : 1002 return -ENOTSUP; 1003 } 1004 case ISCSI_STATUS_TARGET_ERROR : 1005 return -EIO; 1006 default : 1007 return -EINVAL; 1008 } 1009 } 1010 1011 /** 1012 * Receive data segment of an iSCSI login response PDU 1013 * 1014 * @v iscsi iSCSI session 1015 * @v data Received data 1016 * @v len Length of received data 1017 * @v remaining Data remaining after this data 1018 * @ret rc Return status code 1019 */ 1020 static int iscsi_rx_login_response ( struct iscsi_session *iscsi, 1021 const void *data, size_t len, 1022 size_t remaining ) { 1023 struct iscsi_bhs_login_response *response 1024 = &iscsi->rx_bhs.login_response; 1025 int rc; 1026 1027 /* Buffer up the PDU data */ 1028 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) { 1029 DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n", 1030 iscsi, strerror ( rc ) ); 1031 return rc; 1032 } 1033 if ( remaining ) 1034 return 0; 1035 1036 /* Process string data and discard string buffer */ 1037 if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer, 1038 iscsi->rx_len ) ) != 0 ) 1039 return rc; 1040 iscsi_rx_buffered_data_done ( iscsi ); 1041 1042 /* Check for login redirection */ 1043 if ( response->status_class == ISCSI_STATUS_REDIRECT ) { 1044 DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi ); 1045 iscsi_close_connection ( iscsi, 0 ); 1046 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { 1047 DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ", 1048 iscsi, strerror ( rc ) ); 1049 return rc; 1050 } 1051 return 0; 1052 } 1053 1054 /* Check for fatal errors */ 1055 if ( response->status_class != 0 ) { 1056 DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n", 1057 response->status_class, response->status_detail ); 1058 rc = iscsi_status_to_rc ( response->status_class, 1059 response->status_detail ); 1060 iscsi->instant_rc = rc; 1061 return rc; 1062 } 1063 1064 /* Handle login transitions */ 1065 if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) { 1066 iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK | 1067 ISCSI_STATUS_STRINGS_MASK ); 1068 switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) { 1069 case ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION: 1070 iscsi->status |= 1071 ( ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE | 1072 ISCSI_STATUS_STRINGS_OPERATIONAL ); 1073 break; 1074 case ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE: 1075 iscsi->status |= ISCSI_STATUS_FULL_FEATURE_PHASE; 1076 break; 1077 default: 1078 DBGC ( iscsi, "iSCSI %p got invalid response flags " 1079 "%02x\n", iscsi, response->flags ); 1080 return -EIO; 1081 } 1082 } 1083 1084 /* Send next login request PDU if we haven't reached the full 1085 * feature phase yet. 1086 */ 1087 if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) != 1088 ISCSI_STATUS_FULL_FEATURE_PHASE ) { 1089 iscsi_start_login ( iscsi ); 1090 return 0; 1091 } 1092 1093 /* Check that target authentication was successful (if required) */ 1094 if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) && 1095 ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) { 1096 DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass " 1097 "authentication\n", iscsi ); 1098 return -EPROTO; 1099 } 1100 1101 /* Reset retry count */ 1102 iscsi->retry_count = 0; 1103 1104 /* Record TSIH for future reference */ 1105 iscsi->tsih = ntohl ( response->tsih ); 1106 1107 /* Send the actual SCSI command */ 1108 iscsi_start_command ( iscsi ); 1109 1110 return 0; 1111 } 1112 1113 /**************************************************************************** 1114 * 1115 * iSCSI to socket interface 1116 * 1117 */ 1118 1119 /** 1120 * Start up a new TX PDU 1121 * 1122 * @v iscsi iSCSI session 1123 * 1124 * This initiates the process of sending a new PDU. Only one PDU may 1125 * be in transit at any one time. 1126 */ 1127 static void iscsi_start_tx ( struct iscsi_session *iscsi ) { 1128 assert ( iscsi->tx_state == ISCSI_TX_IDLE ); 1129 1130 /* Initialise TX BHS */ 1131 memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) ); 1132 1133 /* Flag TX engine to start transmitting */ 1134 iscsi->tx_state = ISCSI_TX_BHS; 1135 } 1136 1137 /** 1138 * Transmit nothing 1139 * 1140 * @v iscsi iSCSI session 1141 * @ret rc Return status code 1142 */ 1143 static int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused ) { 1144 return 0; 1145 } 1146 1147 /** 1148 * Transmit basic header segment of an iSCSI PDU 1149 * 1150 * @v iscsi iSCSI session 1151 * @ret rc Return status code 1152 */ 1153 static int iscsi_tx_bhs ( struct iscsi_session *iscsi ) { 1154 return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs, 1155 sizeof ( iscsi->tx_bhs ) ); 1156 } 1157 1158 /** 1159 * Transmit data segment of an iSCSI PDU 1160 * 1161 * @v iscsi iSCSI session 1162 * @ret rc Return status code 1163 * 1164 * Handle transmission of part of a PDU data segment. iscsi::tx_bhs 1165 * will be valid when this is called. 1166 */ 1167 static int iscsi_tx_data ( struct iscsi_session *iscsi ) { 1168 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 1169 1170 switch ( common->opcode & ISCSI_OPCODE_MASK ) { 1171 case ISCSI_OPCODE_DATA_OUT: 1172 return iscsi_tx_data_out ( iscsi ); 1173 case ISCSI_OPCODE_LOGIN_REQUEST: 1174 return iscsi_tx_login_request ( iscsi ); 1175 default: 1176 /* Nothing to send in other states */ 1177 return 0; 1178 } 1179 } 1180 1181 /** 1182 * Transmit data padding of an iSCSI PDU 1183 * 1184 * @v iscsi iSCSI session 1185 * @ret rc Return status code 1186 * 1187 * Handle transmission of any data padding in a PDU data segment. 1188 * iscsi::tx_bhs will be valid when this is called. 1189 */ 1190 static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) { 1191 static const char pad[] = { '\0', '\0', '\0' }; 1192 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 1193 size_t pad_len; 1194 1195 pad_len = ISCSI_DATA_PAD_LEN ( common->lengths ); 1196 if ( ! pad_len ) 1197 return 0; 1198 1199 return xfer_deliver_raw ( &iscsi->socket, pad, pad_len ); 1200 } 1201 1202 /** 1203 * Complete iSCSI PDU transmission 1204 * 1205 * @v iscsi iSCSI session 1206 * 1207 * Called when a PDU has been completely transmitted and the TX state 1208 * machine is about to enter the idle state. iscsi::tx_bhs will be 1209 * valid for the just-completed PDU when this is called. 1210 */ 1211 static void iscsi_tx_done ( struct iscsi_session *iscsi ) { 1212 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 1213 1214 switch ( common->opcode & ISCSI_OPCODE_MASK ) { 1215 case ISCSI_OPCODE_DATA_OUT: 1216 iscsi_data_out_done ( iscsi ); 1217 case ISCSI_OPCODE_LOGIN_REQUEST: 1218 iscsi_login_request_done ( iscsi ); 1219 default: 1220 /* No action */ 1221 break; 1222 } 1223 } 1224 1225 /** 1226 * Transmit iSCSI PDU 1227 * 1228 * @v iscsi iSCSI session 1229 * @v buf Temporary data buffer 1230 * @v len Length of temporary data buffer 1231 * 1232 * Constructs data to be sent for the current TX state 1233 */ 1234 static void iscsi_tx_step ( struct process *process ) { 1235 struct iscsi_session *iscsi = 1236 container_of ( process, struct iscsi_session, process ); 1237 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 1238 int ( * tx ) ( struct iscsi_session *iscsi ); 1239 enum iscsi_tx_state next_state; 1240 size_t tx_len; 1241 int rc; 1242 1243 /* Select fragment to transmit */ 1244 while ( 1 ) { 1245 switch ( iscsi->tx_state ) { 1246 case ISCSI_TX_IDLE: 1247 /* Stop processing */ 1248 return; 1249 case ISCSI_TX_BHS: 1250 tx = iscsi_tx_bhs; 1251 tx_len = sizeof ( iscsi->tx_bhs ); 1252 next_state = ISCSI_TX_AHS; 1253 break; 1254 case ISCSI_TX_AHS: 1255 tx = iscsi_tx_nothing; 1256 tx_len = 0; 1257 next_state = ISCSI_TX_DATA; 1258 break; 1259 case ISCSI_TX_DATA: 1260 tx = iscsi_tx_data; 1261 tx_len = ISCSI_DATA_LEN ( common->lengths ); 1262 next_state = ISCSI_TX_DATA_PADDING; 1263 break; 1264 case ISCSI_TX_DATA_PADDING: 1265 tx = iscsi_tx_data_padding; 1266 tx_len = ISCSI_DATA_PAD_LEN ( common->lengths ); 1267 next_state = ISCSI_TX_IDLE; 1268 break; 1269 default: 1270 assert ( 0 ); 1271 return; 1272 } 1273 1274 /* Check for window availability, if needed */ 1275 if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) { 1276 /* Cannot transmit at this point; stop processing */ 1277 return; 1278 } 1279 1280 /* Transmit data */ 1281 if ( ( rc = tx ( iscsi ) ) != 0 ) { 1282 DBGC ( iscsi, "iSCSI %p could not transmit: %s\n", 1283 iscsi, strerror ( rc ) ); 1284 return; 1285 } 1286 1287 /* Move to next state */ 1288 iscsi->tx_state = next_state; 1289 if ( next_state == ISCSI_TX_IDLE ) 1290 iscsi_tx_done ( iscsi ); 1291 } 1292 } 1293 1294 /** 1295 * Receive basic header segment of an iSCSI PDU 1296 * 1297 * @v iscsi iSCSI session 1298 * @v data Received data 1299 * @v len Length of received data 1300 * @v remaining Data remaining after this data 1301 * @ret rc Return status code 1302 * 1303 * This fills in iscsi::rx_bhs with the data from the BHS portion of 1304 * the received PDU. 1305 */ 1306 static int iscsi_rx_bhs ( struct iscsi_session *iscsi, const void *data, 1307 size_t len, size_t remaining __unused ) { 1308 memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len ); 1309 if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) { 1310 DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n", 1311 iscsi, iscsi->rx_bhs.common.opcode, 1312 ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) ); 1313 } 1314 return 0; 1315 } 1316 1317 /** 1318 * Discard portion of an iSCSI PDU. 1319 * 1320 * @v iscsi iSCSI session 1321 * @v data Received data 1322 * @v len Length of received data 1323 * @v remaining Data remaining after this data 1324 * @ret rc Return status code 1325 * 1326 * This discards data from a portion of a received PDU. 1327 */ 1328 static int iscsi_rx_discard ( struct iscsi_session *iscsi __unused, 1329 const void *data __unused, size_t len __unused, 1330 size_t remaining __unused ) { 1331 /* Do nothing */ 1332 return 0; 1333 } 1334 1335 /** 1336 * Receive data segment of an iSCSI PDU 1337 * 1338 * @v iscsi iSCSI session 1339 * @v data Received data 1340 * @v len Length of received data 1341 * @v remaining Data remaining after this data 1342 * @ret rc Return status code 1343 * 1344 * Handle processing of part of a PDU data segment. iscsi::rx_bhs 1345 * will be valid when this is called. 1346 */ 1347 static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, 1348 size_t len, size_t remaining ) { 1349 struct iscsi_bhs_common_response *response 1350 = &iscsi->rx_bhs.common_response; 1351 1352 /* Update cmdsn and statsn */ 1353 iscsi->cmdsn = ntohl ( response->expcmdsn ); 1354 iscsi->statsn = ntohl ( response->statsn ); 1355 1356 switch ( response->opcode & ISCSI_OPCODE_MASK ) { 1357 case ISCSI_OPCODE_LOGIN_RESPONSE: 1358 return iscsi_rx_login_response ( iscsi, data, len, remaining ); 1359 case ISCSI_OPCODE_SCSI_RESPONSE: 1360 return iscsi_rx_scsi_response ( iscsi, data, len, remaining ); 1361 case ISCSI_OPCODE_DATA_IN: 1362 return iscsi_rx_data_in ( iscsi, data, len, remaining ); 1363 case ISCSI_OPCODE_R2T: 1364 return iscsi_rx_r2t ( iscsi, data, len, remaining ); 1365 default: 1366 if ( remaining ) 1367 return 0; 1368 DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi, 1369 response->opcode ); 1370 return -ENOTSUP; 1371 } 1372 } 1373 1374 /** 1375 * Receive new data 1376 * 1377 * @v socket Transport layer interface 1378 * @v data Received data 1379 * @v len Length of received data 1380 * @ret rc Return status code 1381 * 1382 * This handles received PDUs. The receive strategy is to fill in 1383 * iscsi::rx_bhs with the contents of the BHS portion of the PDU, 1384 * throw away any AHS portion, and then process each part of the data 1385 * portion as it arrives. The data processing routine therefore 1386 * always has a full copy of the BHS available, even for portions of 1387 * the data in different packets to the BHS. 1388 */ 1389 static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, 1390 const void *data, size_t len ) { 1391 struct iscsi_session *iscsi = 1392 container_of ( socket, struct iscsi_session, socket ); 1393 struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; 1394 int ( * rx ) ( struct iscsi_session *iscsi, const void *data, 1395 size_t len, size_t remaining ); 1396 enum iscsi_rx_state next_state; 1397 size_t frag_len; 1398 size_t remaining; 1399 int rc; 1400 1401 while ( 1 ) { 1402 switch ( iscsi->rx_state ) { 1403 case ISCSI_RX_BHS: 1404 rx = iscsi_rx_bhs; 1405 iscsi->rx_len = sizeof ( iscsi->rx_bhs ); 1406 next_state = ISCSI_RX_AHS; 1407 break; 1408 case ISCSI_RX_AHS: 1409 rx = iscsi_rx_discard; 1410 iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths ); 1411 next_state = ISCSI_RX_DATA; 1412 break; 1413 case ISCSI_RX_DATA: 1414 rx = iscsi_rx_data; 1415 iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths ); 1416 next_state = ISCSI_RX_DATA_PADDING; 1417 break; 1418 case ISCSI_RX_DATA_PADDING: 1419 rx = iscsi_rx_discard; 1420 iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths ); 1421 next_state = ISCSI_RX_BHS; 1422 break; 1423 default: 1424 assert ( 0 ); 1425 return -EINVAL; 1426 } 1427 1428 frag_len = iscsi->rx_len - iscsi->rx_offset; 1429 if ( frag_len > len ) 1430 frag_len = len; 1431 remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; 1432 if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) { 1433 DBGC ( iscsi, "iSCSI %p could not process received " 1434 "data: %s\n", iscsi, strerror ( rc ) ); 1435 iscsi_close_connection ( iscsi, rc ); 1436 iscsi_scsi_done ( iscsi, rc ); 1437 return rc; 1438 } 1439 1440 iscsi->rx_offset += frag_len; 1441 data += frag_len; 1442 len -= frag_len; 1443 1444 /* If all the data for this state has not yet been 1445 * received, stay in this state for now. 1446 */ 1447 if ( iscsi->rx_offset != iscsi->rx_len ) 1448 return 0; 1449 1450 iscsi->rx_state = next_state; 1451 iscsi->rx_offset = 0; 1452 } 1453 1454 return 0; 1455 } 1456 1457 /** 1458 * Handle stream connection closure 1459 * 1460 * @v socket Transport layer interface 1461 * @v rc Reason for close 1462 * 1463 */ 1464 static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { 1465 struct iscsi_session *iscsi = 1466 container_of ( socket, struct iscsi_session, socket ); 1467 1468 /* Even a graceful close counts as an error for iSCSI */ 1469 if ( ! rc ) 1470 rc = -ECONNRESET; 1471 1472 /* Close session cleanly */ 1473 iscsi_close_connection ( iscsi, rc ); 1474 1475 /* Retry connection if within the retry limit, otherwise fail */ 1476 if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) { 1477 DBGC ( iscsi, "iSCSI %p retrying connection (retry #%d)\n", 1478 iscsi, iscsi->retry_count ); 1479 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { 1480 DBGC ( iscsi, "iSCSI %p could not reconnect: %s\n", 1481 iscsi, strerror ( rc ) ); 1482 iscsi_scsi_done ( iscsi, rc ); 1483 } 1484 } else { 1485 DBGC ( iscsi, "iSCSI %p retry count exceeded\n", iscsi ); 1486 iscsi->instant_rc = rc; 1487 iscsi_scsi_done ( iscsi, rc ); 1488 } 1489 } 1490 1491 /** 1492 * Handle redirection event 1493 * 1494 * @v socket Transport layer interface 1495 * @v type Location type 1496 * @v args Remaining arguments depend upon location type 1497 * @ret rc Return status code 1498 */ 1499 static int iscsi_vredirect ( struct xfer_interface *socket, int type, 1500 va_list args ) { 1501 struct iscsi_session *iscsi = 1502 container_of ( socket, struct iscsi_session, socket ); 1503 va_list tmp; 1504 struct sockaddr *peer; 1505 1506 /* Intercept redirects to a LOCATION_SOCKET and record the IP 1507 * address for the iBFT. This is a bit of a hack, but avoids 1508 * inventing an ioctl()-style call to retrieve the socket 1509 * address from a data-xfer interface. 1510 */ 1511 if ( type == LOCATION_SOCKET ) { 1512 va_copy ( tmp, args ); 1513 ( void ) va_arg ( tmp, int ); /* Discard "semantics" */ 1514 peer = va_arg ( tmp, struct sockaddr * ); 1515 memcpy ( &iscsi->target_sockaddr, peer, 1516 sizeof ( iscsi->target_sockaddr ) ); 1517 va_end ( tmp ); 1518 } 1519 1520 return xfer_vreopen ( socket, type, args ); 1521 } 1522 1523 1524 /** iSCSI socket operations */ 1525 static struct xfer_interface_operations iscsi_socket_operations = { 1526 .close = iscsi_socket_close, 1527 .vredirect = iscsi_vredirect, 1528 .window = unlimited_xfer_window, 1529 .alloc_iob = default_xfer_alloc_iob, 1530 .deliver_iob = xfer_deliver_as_raw, 1531 .deliver_raw = iscsi_socket_deliver_raw, 1532 }; 1533 1534 1535 /**************************************************************************** 1536 * 1537 * iSCSI command issuing 1538 * 1539 */ 1540 1541 /** 1542 * Issue SCSI command 1543 * 1544 * @v scsi SCSI device 1545 * @v command SCSI command 1546 * @ret rc Return status code 1547 */ 1548 static int iscsi_command ( struct scsi_device *scsi, 1549 struct scsi_command *command ) { 1550 struct iscsi_session *iscsi = 1551 container_of ( scsi->backend, struct iscsi_session, refcnt ); 1552 int rc; 1553 1554 /* Abort immediately if we have a recorded permanent failure */ 1555 if ( iscsi->instant_rc ) 1556 return iscsi->instant_rc; 1557 1558 /* Record SCSI command */ 1559 iscsi->command = command; 1560 1561 /* Issue command or open connection as appropriate */ 1562 if ( iscsi->status ) { 1563 iscsi_start_command ( iscsi ); 1564 } else { 1565 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { 1566 iscsi->command = NULL; 1567 return rc; 1568 } 1569 } 1570 1571 return 0; 1572 } 1573 1574 /** 1575 * Shut down iSCSI interface 1576 * 1577 * @v scsi SCSI device 1578 */ 1579 void iscsi_detach ( struct scsi_device *scsi ) { 1580 struct iscsi_session *iscsi = 1581 container_of ( scsi->backend, struct iscsi_session, refcnt ); 1582 1583 xfer_nullify ( &iscsi->socket ); 1584 iscsi_close_connection ( iscsi, 0 ); 1585 process_del ( &iscsi->process ); 1586 scsi->command = scsi_detached_command; 1587 ref_put ( scsi->backend ); 1588 scsi->backend = NULL; 1589 } 1590 1591 /**************************************************************************** 1592 * 1593 * Instantiator 1594 * 1595 */ 1596 1597 /** iSCSI root path components (as per RFC4173) */ 1598 enum iscsi_root_path_component { 1599 RP_LITERAL = 0, 1600 RP_SERVERNAME, 1601 RP_PROTOCOL, 1602 RP_PORT, 1603 RP_LUN, 1604 RP_TARGETNAME, 1605 NUM_RP_COMPONENTS 1606 }; 1607 1608 /** 1609 * Parse iSCSI root path 1610 * 1611 * @v iscsi iSCSI session 1612 * @v root_path iSCSI root path (as per RFC4173) 1613 * @ret rc Return status code 1614 */ 1615 static int iscsi_parse_root_path ( struct iscsi_session *iscsi, 1616 const char *root_path ) { 1617 char rp_copy[ strlen ( root_path ) + 1 ]; 1618 char *rp_comp[NUM_RP_COMPONENTS]; 1619 char *rp = rp_copy; 1620 int i = 0; 1621 int rc; 1622 1623 /* Split root path into component parts */ 1624 strcpy ( rp_copy, root_path ); 1625 while ( 1 ) { 1626 rp_comp[i++] = rp; 1627 if ( i == NUM_RP_COMPONENTS ) 1628 break; 1629 for ( ; *rp != ':' ; rp++ ) { 1630 if ( ! *rp ) { 1631 DBGC ( iscsi, "iSCSI %p root path \"%s\" " 1632 "too short\n", iscsi, root_path ); 1633 return -EINVAL; 1634 } 1635 } 1636 *(rp++) = '\0'; 1637 } 1638 1639 /* Use root path components to configure iSCSI session */ 1640 iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] ); 1641 if ( ! iscsi->target_address ) 1642 return -ENOMEM; 1643 iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 ); 1644 if ( ! iscsi->target_port ) 1645 iscsi->target_port = ISCSI_PORT; 1646 if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) { 1647 DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n", 1648 iscsi, rp_comp[RP_LUN] ); 1649 return rc; 1650 } 1651 iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] ); 1652 if ( ! iscsi->target_iqn ) 1653 return -ENOMEM; 1654 1655 return 0; 1656 } 1657 1658 /** 1659 * Set iSCSI authentication details 1660 * 1661 * @v iscsi iSCSI session 1662 * @v initiator_username Initiator username, if any 1663 * @v initiator_password Initiator password, if any 1664 * @v target_username Target username, if any 1665 * @v target_password Target password, if any 1666 * @ret rc Return status code 1667 */ 1668 static int iscsi_set_auth ( struct iscsi_session *iscsi, 1669 const char *initiator_username, 1670 const char *initiator_password, 1671 const char *target_username, 1672 const char *target_password ) { 1673 1674 /* Check for initiator or target credentials */ 1675 if ( initiator_username || initiator_password || 1676 target_username || target_password ) { 1677 1678 /* We must have at least an initiator username+password */ 1679 if ( ! ( initiator_username && initiator_password ) ) 1680 goto invalid_auth; 1681 1682 /* Store initiator credentials */ 1683 iscsi->initiator_username = strdup ( initiator_username ); 1684 if ( ! iscsi->initiator_username ) 1685 return -ENOMEM; 1686 iscsi->initiator_password = strdup ( initiator_password ); 1687 if ( ! iscsi->initiator_password ) 1688 return -ENOMEM; 1689 1690 /* Check for target credentials */ 1691 if ( target_username || target_password ) { 1692 1693 /* We must have target username+password */ 1694 if ( ! ( target_username && target_password ) ) 1695 goto invalid_auth; 1696 1697 /* Store target credentials */ 1698 iscsi->target_username = strdup ( target_username ); 1699 if ( ! iscsi->target_username ) 1700 return -ENOMEM; 1701 iscsi->target_password = strdup ( target_password ); 1702 if ( ! iscsi->target_password ) 1703 return -ENOMEM; 1704 } 1705 } 1706 1707 return 0; 1708 1709 invalid_auth: 1710 DBGC ( iscsi, "iSCSI %p invalid credentials: initiator " 1711 "%sname,%spw, target %sname,%spw\n", iscsi, 1712 ( initiator_username ? "" : "no " ), 1713 ( initiator_password ? "" : "no " ), 1714 ( target_username ? "" : "no " ), 1715 ( target_password ? "" : "no " ) ); 1716 return -EINVAL; 1717 } 1718 1719 /** 1720 * Attach iSCSI interface 1721 * 1722 * @v scsi SCSI device 1723 * @v root_path iSCSI root path (as per RFC4173) 1724 * @ret rc Return status code 1725 */ 1726 int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { 1727 struct iscsi_session *iscsi; 1728 int rc; 1729 1730 /* Allocate and initialise structure */ 1731 iscsi = zalloc ( sizeof ( *iscsi ) ); 1732 if ( ! iscsi ) 1733 return -ENOMEM; 1734 iscsi->refcnt.free = iscsi_free; 1735 xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt ); 1736 process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt ); 1737 1738 /* Parse root path */ 1739 if ( ( rc = iscsi_parse_root_path ( iscsi, root_path ) ) != 0 ) 1740 goto err; 1741 /* Set fields not specified by root path */ 1742 if ( ( rc = iscsi_set_auth ( iscsi, 1743 iscsi_initiator_username, 1744 iscsi_initiator_password, 1745 iscsi_target_username, 1746 iscsi_target_password ) ) != 0 ) 1747 goto err; 1748 1749 /* Sanity checks */ 1750 if ( ! iscsi->target_address ) { 1751 DBGC ( iscsi, "iSCSI %p does not yet support discovery\n", 1752 iscsi ); 1753 rc = -ENOTSUP; 1754 goto err; 1755 } 1756 if ( ! iscsi->target_iqn ) { 1757 DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n", 1758 iscsi, root_path ); 1759 rc = -EINVAL; 1760 goto err; 1761 } 1762 1763 /* Attach parent interface, mortalise self, and return */ 1764 scsi->backend = ref_get ( &iscsi->refcnt ); 1765 scsi->command = iscsi_command; 1766 ref_put ( &iscsi->refcnt ); 1767 return 0; 1768 1769 err: 1770 ref_put ( &iscsi->refcnt ); 1771 return rc; 1772 } 1773 1774 /**************************************************************************** 1775 * 1776 * Settings 1777 * 1778 */ 1779 1780 /** iSCSI initiator IQN setting */ 1781 struct setting initiator_iqn_setting __setting = { 1782 .name = "initiator-iqn", 1783 .description = "iSCSI initiator name", 1784 .tag = DHCP_ISCSI_INITIATOR_IQN, 1785 .type = &setting_type_string, 1786 }; 1787 1788 /** iSCSI reverse username setting */ 1789 struct setting reverse_username_setting __setting = { 1790 .name = "reverse-username", 1791 .description = "Reverse user name", 1792 .tag = DHCP_EB_REVERSE_USERNAME, 1793 .type = &setting_type_string, 1794 }; 1795 1796 /** iSCSI reverse password setting */ 1797 struct setting reverse_password_setting __setting = { 1798 .name = "reverse-password", 1799 .description = "Reverse password", 1800 .tag = DHCP_EB_REVERSE_PASSWORD, 1801 .type = &setting_type_string, 1802 }; 1803 1804 /** An iSCSI string setting */ 1805 struct iscsi_string_setting { 1806 /** Setting */ 1807 struct setting *setting; 1808 /** String to update */ 1809 char **string; 1810 /** String prefix */ 1811 const char *prefix; 1812 }; 1813 1814 /** iSCSI string settings */ 1815 static struct iscsi_string_setting iscsi_string_settings[] = { 1816 { 1817 .setting = &initiator_iqn_setting, 1818 .string = &iscsi_explicit_initiator_iqn, 1819 .prefix = "", 1820 }, 1821 { 1822 .setting = &username_setting, 1823 .string = &iscsi_initiator_username, 1824 .prefix = "", 1825 }, 1826 { 1827 .setting = &password_setting, 1828 .string = &iscsi_initiator_password, 1829 .prefix = "", 1830 }, 1831 { 1832 .setting = &reverse_username_setting, 1833 .string = &iscsi_target_username, 1834 .prefix = "", 1835 }, 1836 { 1837 .setting = &reverse_password_setting, 1838 .string = &iscsi_target_password, 1839 .prefix = "", 1840 }, 1841 { 1842 .setting = &hostname_setting, 1843 .string = &iscsi_default_initiator_iqn, 1844 .prefix = "iqn.2000-01.org.etherboot:", 1845 }, 1846 }; 1847 1848 /** 1849 * Apply iSCSI setting 1850 * 1851 * @v setting iSCSI string setting 1852 * @ret rc Return status code 1853 */ 1854 static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){ 1855 size_t prefix_len; 1856 int setting_len; 1857 size_t len; 1858 int check_len; 1859 char *p; 1860 1861 /* Free old string */ 1862 free ( *setting->string ); 1863 *setting->string = NULL; 1864 1865 /* Allocate new string */ 1866 prefix_len = strlen ( setting->prefix ); 1867 setting_len = fetch_setting_len ( NULL, setting->setting ); 1868 if ( setting_len < 0 ) { 1869 /* Missing settings are not errors; leave strings as NULL */ 1870 return 0; 1871 } 1872 len = ( prefix_len + setting_len + 1 ); 1873 p = *setting->string = malloc ( len ); 1874 if ( ! p ) 1875 return -ENOMEM; 1876 1877 /* Fill new string */ 1878 strcpy ( p, setting->prefix ); 1879 check_len = fetch_string_setting ( NULL, setting->setting, 1880 ( p + prefix_len ), 1881 ( len - prefix_len ) ); 1882 assert ( check_len == setting_len ); 1883 1884 return 0; 1885 } 1886 1887 /** 1888 * Apply iSCSI settings 1889 * 1890 * @ret rc Return status code 1891 */ 1892 static int apply_iscsi_settings ( void ) { 1893 struct iscsi_string_setting *setting; 1894 unsigned int i; 1895 int rc; 1896 1897 for ( i = 0 ; i < ( sizeof ( iscsi_string_settings ) / 1898 sizeof ( iscsi_string_settings[0] ) ) ; i++ ) { 1899 setting = &iscsi_string_settings[i]; 1900 if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) { 1901 DBG ( "iSCSI could not apply setting %s\n", 1902 setting->setting->name ); 1903 return rc; 1904 } 1905 } 1906 1907 return 0; 1908 } 1909 1910 /** iSCSI settings applicator */ 1911 struct settings_applicator iscsi_settings_applicator __settings_applicator = { 1912 .apply = apply_iscsi_settings, 1913 }; 1914 1915 /**************************************************************************** 1916 * 1917 * Initiator name 1918 * 1919 */ 1920 1921 /** 1922 * Get iSCSI initiator IQN 1923 * 1924 * @v iscsi iSCSI session 1925 * @ret rc Return status code 1926 */ 1927 const char * iscsi_initiator_iqn ( void ) { 1928 1929 if ( iscsi_explicit_initiator_iqn ) 1930 return iscsi_explicit_initiator_iqn; 1931 if ( iscsi_default_initiator_iqn ) 1932 return iscsi_default_initiator_iqn; 1933 return "iqn.2000-09.org.etherboot:UNKNOWN"; 1934 } 1935