Home | History | Annotate | Download | only in gpxe
      1 #ifndef _GPXE_ISCSI_H
      2 #define _GPXE_ISCSI_H
      3 
      4 /** @file
      5  *
      6  * iSCSI protocol
      7  *
      8  */
      9 
     10 FILE_LICENCE ( GPL2_OR_LATER );
     11 
     12 #include <stdint.h>
     13 #include <gpxe/socket.h>
     14 #include <gpxe/scsi.h>
     15 #include <gpxe/chap.h>
     16 #include <gpxe/refcnt.h>
     17 #include <gpxe/xfer.h>
     18 #include <gpxe/process.h>
     19 
     20 /** Default iSCSI port */
     21 #define ISCSI_PORT 3260
     22 
     23 /**
     24  * iSCSI segment lengths
     25  *
     26  * iSCSI uses an icky structure with one one-byte field (a dword
     27  * count) and one three-byte field (a byte count).  This structure,
     28  * and the accompanying macros, relieve some of the pain.
     29  */
     30 union iscsi_segment_lengths {
     31 	struct {
     32 		/** The AHS length (measured in dwords) */
     33 		uint8_t ahs_len;
     34 		/** The data length (measured in bytes), in network
     35 		 * byte order
     36 		 */
     37 		uint8_t data_len[3];
     38 	} bytes;
     39 	/** Ths data length (measured in bytes), in network byte
     40 	 * order, with ahs_len as the first byte.
     41 	 */
     42 	uint32_t ahs_and_data_len;
     43 };
     44 
     45 /** The length of the additional header segment, in dwords */
     46 #define ISCSI_AHS_LEN( segment_lengths ) \
     47 	( (segment_lengths).bytes.ahs_len )
     48 
     49 /** The length of the data segment, in bytes, excluding any padding */
     50 #define ISCSI_DATA_LEN( segment_lengths ) \
     51 	( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff )
     52 
     53 /** The padding of the data segment, in bytes */
     54 #define ISCSI_DATA_PAD_LEN( segment_lengths ) \
     55 	( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 )
     56 
     57 /** Set additional header and data segment lengths */
     58 #define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do {	\
     59 	(segment_lengths).ahs_and_data_len =				\
     60 		htonl ( data_len | ( ahs_len << 24 ) );			\
     61 	} while ( 0 )
     62 
     63 /**
     64  * iSCSI basic header segment common fields
     65  *
     66  */
     67 struct iscsi_bhs_common {
     68 	/** Opcode */
     69 	uint8_t opcode;
     70 	/** Flags */
     71 	uint8_t flags;
     72 	/** Fields specific to the PDU type */
     73 	uint8_t other_a[2];
     74 	/** Segment lengths */
     75 	union iscsi_segment_lengths lengths;
     76 	/** Fields specific to the PDU type */
     77 	uint8_t other_b[8];
     78 	/** Initiator Task Tag */
     79 	uint32_t itt;
     80 	/** Fields specific to the PDU type */
     81 	uint8_t other_c[28];
     82 };
     83 
     84 /** Opcode mask */
     85 #define ISCSI_OPCODE_MASK 0x3f
     86 
     87 /** Immediate delivery */
     88 #define ISCSI_FLAG_IMMEDIATE 0x40
     89 
     90 /** Final PDU of a sequence */
     91 #define ISCSI_FLAG_FINAL 0x80
     92 
     93 /**
     94  * iSCSI basic header segment common request fields
     95  *
     96  */
     97 struct iscsi_bhs_common_response {
     98 	/** Opcode */
     99 	uint8_t opcode;
    100 	/** Flags */
    101 	uint8_t flags;
    102 	/** Fields specific to the PDU type */
    103 	uint8_t other_a[2];
    104 	/** Segment lengths */
    105 	union iscsi_segment_lengths lengths;
    106 	/** Fields specific to the PDU type */
    107 	uint8_t other_b[8];
    108 	/** Initiator Task Tag */
    109 	uint32_t itt;
    110 	/** Fields specific to the PDU type */
    111 	uint8_t other_c[4];
    112 	/** Status sequence number */
    113 	uint32_t statsn;
    114 	/** Expected command sequence number */
    115 	uint32_t expcmdsn;
    116 	/** Fields specific to the PDU type */
    117 	uint8_t other_d[16];
    118 };
    119 
    120 /**
    121  * iSCSI login request basic header segment
    122  *
    123  */
    124 struct iscsi_bhs_login_request {
    125 	/** Opcode */
    126 	uint8_t opcode;
    127 	/** Flags */
    128 	uint8_t flags;
    129 	/** Maximum supported version number */
    130 	uint8_t version_max;
    131 	/** Minimum supported version number */
    132 	uint8_t version_min;
    133 	/** Segment lengths */
    134 	union iscsi_segment_lengths lengths;
    135 	/** Initiator session ID (IANA format) enterprise number and flags */
    136 	uint32_t isid_iana_en;
    137 	/** Initiator session ID (IANA format) qualifier */
    138 	uint16_t isid_iana_qual;
    139 	/** Target session identifying handle */
    140 	uint16_t tsih;
    141 	/** Initiator Task Tag */
    142 	uint32_t itt;
    143 	/** Connection ID */
    144 	uint16_t cid;
    145 	/** Reserved */
    146 	uint16_t reserved_a;
    147 	/** Command sequence number */
    148 	uint32_t cmdsn;
    149 	/** Expected status sequence number */
    150 	uint32_t expstatsn;
    151 	/** Reserved */
    152 	uint8_t reserved_b[16];
    153 };
    154 
    155 /** Login request opcode */
    156 #define ISCSI_OPCODE_LOGIN_REQUEST 0x03
    157 
    158 /** Willingness to transition to next stage */
    159 #define ISCSI_LOGIN_FLAG_TRANSITION 0x80
    160 
    161 /** Key=value pairs continued in subsequent request */
    162 #define ISCSI_LOGIN_FLAG_CONTINUE 0x40
    163 
    164 /* Current stage values and mask */
    165 #define ISCSI_LOGIN_CSG_MASK 0x0c
    166 #define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00
    167 #define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04
    168 #define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c
    169 
    170 /* Next stage values and mask */
    171 #define ISCSI_LOGIN_NSG_MASK 0x03
    172 #define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00
    173 #define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
    174 #define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
    175 
    176 /** ISID IANA format marker */
    177 #define ISCSI_ISID_IANA 0x40000000
    178 
    179 /** Fen Systems Ltd. IANA enterprise number
    180  *
    181  * Permission is hereby granted to use Fen Systems Ltd.'s IANA
    182  * enterprise number with this iSCSI implementation.
    183  */
    184 #define IANA_EN_FEN_SYSTEMS 10019
    185 
    186 /**
    187  * iSCSI login response basic header segment
    188  *
    189  */
    190 struct iscsi_bhs_login_response {
    191 	/** Opcode */
    192 	uint8_t opcode;
    193 	/** Flags */
    194 	uint8_t flags;
    195 	/** Maximum supported version number */
    196 	uint8_t version_max;
    197 	/** Minimum supported version number */
    198 	uint8_t version_min;
    199 	/** Segment lengths */
    200 	union iscsi_segment_lengths lengths;
    201 	/** Initiator session ID (IANA format) enterprise number and flags */
    202 	uint32_t isid_iana_en;
    203 	/** Initiator session ID (IANA format) qualifier */
    204 	uint16_t isid_iana_qual;
    205 	/** Target session identifying handle */
    206 	uint16_t tsih;
    207 	/** Initiator Task Tag */
    208 	uint32_t itt;
    209 	/** Reserved */
    210 	uint32_t reserved_a;
    211 	/** Status sequence number */
    212 	uint32_t statsn;
    213 	/** Expected command sequence number */
    214 	uint32_t expcmdsn;
    215 	/** Maximum command sequence number */
    216 	uint32_t maxcmdsn;
    217 	/** Status class */
    218 	uint8_t status_class;
    219 	/** Status detail */
    220 	uint8_t status_detail;
    221 	/** Reserved */
    222 	uint8_t reserved_b[10];
    223 };
    224 
    225 /** Login response opcode */
    226 #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
    227 
    228 /* Login response status codes */
    229 #define ISCSI_STATUS_SUCCESS			0x00
    230 #define ISCSI_STATUS_REDIRECT			0x01
    231 #define ISCSI_STATUS_INITIATOR_ERROR		0x02
    232 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION	0x01
    233 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION	0x02
    234 #define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND		0x03
    235 #define ISCSI_STATUS_INITIATOR_ERROR_REMOVED		0x04
    236 #define ISCSI_STATUS_TARGET_ERROR		0x03
    237 
    238 /**
    239  * iSCSI SCSI command basic header segment
    240  *
    241  */
    242 struct iscsi_bhs_scsi_command {
    243 	/** Opcode */
    244 	uint8_t opcode;
    245 	/** Flags */
    246 	uint8_t flags;
    247 	/** Reserved */
    248 	uint16_t reserved_a;
    249 	/** Segment lengths */
    250 	union iscsi_segment_lengths lengths;
    251 	/** SCSI Logical Unit Number */
    252 	struct scsi_lun lun;
    253 	/** Initiator Task Tag */
    254 	uint32_t itt;
    255 	/** Expected data transfer length */
    256 	uint32_t exp_len;
    257 	/** Command sequence number */
    258 	uint32_t cmdsn;
    259 	/** Expected status sequence number */
    260 	uint32_t expstatsn;
    261 	/** SCSI Command Descriptor Block (CDB) */
    262 	union scsi_cdb cdb;
    263 };
    264 
    265 /** SCSI command opcode */
    266 #define ISCSI_OPCODE_SCSI_COMMAND 0x01
    267 
    268 /** Command will read data */
    269 #define ISCSI_COMMAND_FLAG_READ 0x40
    270 
    271 /** Command will write data */
    272 #define ISCSI_COMMAND_FLAG_WRITE 0x20
    273 
    274 /* Task attributes */
    275 #define ISCSI_COMMAND_ATTR_UNTAGGED 0x00
    276 #define ISCSI_COMMAND_ATTR_SIMPLE 0x01
    277 #define ISCSI_COMMAND_ATTR_ORDERED 0x02
    278 #define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03
    279 #define ISCSI_COMMAND_ATTR_ACA 0x04
    280 
    281 /**
    282  * iSCSI SCSI response basic header segment
    283  *
    284  */
    285 struct iscsi_bhs_scsi_response {
    286 	/** Opcode */
    287 	uint8_t opcode;
    288 	/** Flags */
    289 	uint8_t flags;
    290 	/** Response code */
    291 	uint8_t response;
    292 	/** SCSI status code */
    293 	uint8_t status;
    294 	/** Segment lengths */
    295 	union iscsi_segment_lengths lengths;
    296 	/** Reserved */
    297 	uint8_t reserved_a[8];
    298 	/** Initiator Task Tag */
    299 	uint32_t itt;
    300 	/** SNACK tag */
    301 	uint32_t snack;
    302 	/** Status sequence number */
    303 	uint32_t statsn;
    304 	/** Expected command sequence number */
    305 	uint32_t expcmdsn;
    306 	/** Maximum command sequence number */
    307 	uint32_t maxcmdsn;
    308 	/** Expected data sequence number */
    309 	uint32_t expdatasn;
    310 	/** Reserved */
    311 	uint8_t reserved_b[8];
    312 };
    313 
    314 /** SCSI response opcode */
    315 #define ISCSI_OPCODE_SCSI_RESPONSE 0x21
    316 
    317 /** SCSI command completed at target */
    318 #define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00
    319 
    320 /** SCSI target failure */
    321 #define ISCSI_RESPONSE_TARGET_FAILURE 0x01
    322 
    323 /** SCSI sense response code offset
    324  *
    325  * The SCSI response may contain unsolicited sense data in the data
    326  * segment.  If it does, this is the offset to the sense response code
    327  * byte, which is the only byte we care about.
    328  */
    329 #define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
    330 
    331 /**
    332  * iSCSI data-in basic header segment
    333  *
    334  */
    335 struct iscsi_bhs_data_in {
    336 	/** Opcode */
    337 	uint8_t opcode;
    338 	/** Flags */
    339 	uint8_t flags;
    340 	/** Reserved */
    341 	uint8_t reserved_a;
    342 	/** SCSI status code */
    343 	uint8_t status;
    344 	/** Segment lengths */
    345 	union iscsi_segment_lengths lengths;
    346 	/** Logical Unit Number */
    347 	struct scsi_lun lun;
    348 	/** Initiator Task Tag */
    349 	uint32_t itt;
    350 	/** Target Transfer Tag */
    351 	uint32_t ttt;
    352 	/** Status sequence number */
    353 	uint32_t statsn;
    354 	/** Expected command sequence number */
    355 	uint32_t expcmdsn;
    356 	/** Maximum command sequence number */
    357 	uint32_t maxcmdsn;
    358 	/** Data sequence number */
    359 	uint32_t datasn;
    360 	/** Buffer offset */
    361 	uint32_t offset;
    362 	/** Residual count */
    363 	uint32_t residual_count;
    364 };
    365 
    366 /** Data-in opcode */
    367 #define ISCSI_OPCODE_DATA_IN 0x25
    368 
    369 /** Data requires acknowledgement */
    370 #define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40
    371 
    372 /** Data overflow occurred */
    373 #define ISCSI_DATA_FLAG_OVERFLOW 0x04
    374 
    375 /** Data underflow occurred */
    376 #define ISCSI_DATA_FLAG_UNDERFLOW 0x02
    377 
    378 /** SCSI status code and overflow/underflow flags are valid */
    379 #define ISCSI_DATA_FLAG_STATUS 0x01
    380 
    381 /**
    382  * iSCSI data-out basic header segment
    383  *
    384  */
    385 struct iscsi_bhs_data_out {
    386 	/** Opcode */
    387 	uint8_t opcode;
    388 	/** Flags */
    389 	uint8_t flags;
    390 	/** Reserved */
    391 	uint16_t reserved_a;
    392 	/** Segment lengths */
    393 	union iscsi_segment_lengths lengths;
    394 	/** Logical Unit Number */
    395 	struct scsi_lun lun;
    396 	/** Initiator Task Tag */
    397 	uint32_t itt;
    398 	/** Target Transfer Tag */
    399 	uint32_t ttt;
    400 	/** Reserved */
    401 	uint32_t reserved_b;
    402 	/** Expected status sequence number */
    403 	uint32_t expstatsn;
    404 	/** Reserved */
    405 	uint32_t reserved_c;
    406 	/** Data sequence number */
    407 	uint32_t datasn;
    408 	/** Buffer offset */
    409 	uint32_t offset;
    410 	/** Reserved */
    411 	uint32_t reserved_d;
    412 };
    413 
    414 /** Data-out opcode */
    415 #define ISCSI_OPCODE_DATA_OUT 0x05
    416 
    417 /**
    418  * iSCSI request to transfer basic header segment
    419  *
    420  */
    421 struct iscsi_bhs_r2t {
    422 	/** Opcode */
    423 	uint8_t opcode;
    424 	/** Flags */
    425 	uint8_t flags;
    426 	/** Reserved */
    427 	uint16_t reserved_a;
    428 	/** Segment lengths */
    429 	union iscsi_segment_lengths lengths;
    430 	/** Logical Unit Number */
    431 	struct scsi_lun lun;
    432 	/** Initiator Task Tag */
    433 	uint32_t itt;
    434 	/** Target Transfer Tag */
    435 	uint32_t ttt;
    436 	/** Status sequence number */
    437 	uint32_t statsn;
    438 	/** Expected command sequence number */
    439 	uint32_t expcmdsn;
    440 	/** Maximum command sequence number */
    441 	uint32_t maxcmdsn;
    442 	/** R2T sequence number */
    443 	uint32_t r2tsn;
    444 	/** Buffer offset */
    445 	uint32_t offset;
    446 	/** Desired data transfer length */
    447 	uint32_t len;
    448 };
    449 
    450 /** R2T opcode */
    451 #define ISCSI_OPCODE_R2T 0x31
    452 
    453 /**
    454  * An iSCSI basic header segment
    455  */
    456 union iscsi_bhs {
    457 	struct iscsi_bhs_common common;
    458 	struct iscsi_bhs_common_response common_response;
    459 	struct iscsi_bhs_login_request login_request;
    460 	struct iscsi_bhs_login_response login_response;
    461 	struct iscsi_bhs_scsi_command scsi_command;
    462 	struct iscsi_bhs_scsi_response scsi_response;
    463 	struct iscsi_bhs_data_in data_in;
    464 	struct iscsi_bhs_data_out data_out;
    465 	struct iscsi_bhs_r2t r2t;
    466 	unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ];
    467 };
    468 
    469 /** State of an iSCSI TX engine */
    470 enum iscsi_tx_state {
    471 	/** Nothing to send */
    472 	ISCSI_TX_IDLE = 0,
    473 	/** Sending the basic header segment */
    474 	ISCSI_TX_BHS,
    475 	/** Sending the additional header segment */
    476 	ISCSI_TX_AHS,
    477 	/** Sending the data segment */
    478 	ISCSI_TX_DATA,
    479 	/** Sending the data segment padding */
    480 	ISCSI_TX_DATA_PADDING,
    481 };
    482 
    483 /** State of an iSCSI RX engine */
    484 enum iscsi_rx_state {
    485 	/** Receiving the basic header segment */
    486 	ISCSI_RX_BHS = 0,
    487 	/** Receiving the additional header segment */
    488 	ISCSI_RX_AHS,
    489 	/** Receiving the data segment */
    490 	ISCSI_RX_DATA,
    491 	/** Receiving the data segment padding */
    492 	ISCSI_RX_DATA_PADDING,
    493 };
    494 
    495 /** An iSCSI session */
    496 struct iscsi_session {
    497 	/** Reference counter */
    498 	struct refcnt refcnt;
    499 
    500 	/** Transport-layer socket */
    501 	struct xfer_interface socket;
    502 
    503 	/** Target address */
    504 	char *target_address;
    505 	/** Target port */
    506 	unsigned int target_port;
    507 	/** Target IQN */
    508 	char *target_iqn;
    509 	/** Logical Unit Number (LUN) */
    510 	struct scsi_lun lun;
    511 	/** Target socket address (recorded only for iBFT) */
    512 	struct sockaddr target_sockaddr;
    513 
    514 	/** Session status
    515 	 *
    516 	 * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
    517 	 * constants.
    518 	 */
    519 	int status;
    520 	/** Retry count
    521 	 *
    522 	 * Number of times that the connection has been retried.
    523 	 * Reset upon a successful connection.
    524 	 */
    525 	int retry_count;
    526 
    527 	/** Initiator username (if any) */
    528 	char *initiator_username;
    529 	/** Initiator password (if any) */
    530 	char *initiator_password;
    531 	/** Target username (if any) */
    532 	char *target_username;
    533 	/** Target password (if any) */
    534 	char *target_password;
    535 	/** CHAP challenge (for target auth only)
    536 	 *
    537 	 * This is a block of random data; the first byte is used as
    538 	 * the CHAP identifier (CHAP_I) and the remainder as the CHAP
    539 	 * challenge (CHAP_C).
    540 	 */
    541 	unsigned char chap_challenge[17];
    542 	/** CHAP response (used for both initiator and target auth) */
    543 	struct chap_response chap;
    544 
    545 	/** Target session identifying handle
    546 	 *
    547 	 * This is assigned by the target when we first log in, and
    548 	 * must be reused on subsequent login attempts.
    549 	 */
    550 	uint16_t tsih;
    551 	/** Initiator task tag
    552 	 *
    553 	 * This is the tag of the current command.  It is incremented
    554 	 * whenever a new command is started.
    555 	 */
    556 	uint32_t itt;
    557 	/** Target transfer tag
    558 	 *
    559 	 * This is the tag attached to a sequence of data-out PDUs in
    560 	 * response to an R2T.
    561 	 */
    562 	uint32_t ttt;
    563 	/**
    564 	 * Transfer offset
    565 	 *
    566 	 * This is the offset for an in-progress sequence of data-out
    567 	 * PDUs in response to an R2T.
    568 	 */
    569 	uint32_t transfer_offset;
    570 	/**
    571 	 * Transfer length
    572 	 *
    573 	 * This is the length for an in-progress sequence of data-out
    574 	 * PDUs in response to an R2T.
    575 	 */
    576 	uint32_t transfer_len;
    577 	/** Command sequence number
    578 	 *
    579 	 * This is the sequence number of the current command, used to
    580 	 * fill out the CmdSN field in iSCSI request PDUs.  It is
    581 	 * updated with the value of the ExpCmdSN field whenever we
    582 	 * receive an iSCSI response PDU containing such a field.
    583 	 */
    584 	uint32_t cmdsn;
    585 	/** Status sequence number
    586 	 *
    587 	 * This is the most recent status sequence number present in
    588 	 * the StatSN field of an iSCSI response PDU containing such a
    589 	 * field.  Whenever we send an iSCSI request PDU, we fill out
    590 	 * the ExpStatSN field with this value plus one.
    591 	 */
    592 	uint32_t statsn;
    593 
    594 	/** Basic header segment for current TX PDU */
    595 	union iscsi_bhs tx_bhs;
    596 	/** State of the TX engine */
    597 	enum iscsi_tx_state tx_state;
    598 	/** TX process */
    599 	struct process process;
    600 
    601 	/** Basic header segment for current RX PDU */
    602 	union iscsi_bhs rx_bhs;
    603 	/** State of the RX engine */
    604 	enum iscsi_rx_state rx_state;
    605 	/** Byte offset within the current RX state */
    606 	size_t rx_offset;
    607 	/** Length of the current RX state */
    608 	size_t rx_len;
    609 	/** Buffer for received data (not always used) */
    610 	void *rx_buffer;
    611 
    612 	/** Current SCSI command
    613 	 *
    614 	 * Set to NULL when command is complete.
    615 	 */
    616 	struct scsi_command *command;
    617 	/** Instant return code
    618 	 *
    619 	 * Set to a non-zero value if all requests should return
    620 	 * immediately.  This can be used to e.g. avoid retrying
    621 	 * logins that are doomed to fail authentication.
    622 	 */
    623 	int instant_rc;
    624 };
    625 
    626 /** iSCSI session is currently in the security negotiation phase */
    627 #define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE		\
    628 	( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION |	\
    629 	  ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION )
    630 
    631 /** iSCSI session is currently in the operational parameter
    632  * negotiation phase
    633  */
    634 #define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE	\
    635 	( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION |	\
    636 	  ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE )
    637 
    638 /** iSCSI session is currently in the full feature phase */
    639 #define ISCSI_STATUS_FULL_FEATURE_PHASE	ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE
    640 
    641 /** Mask for all iSCSI session phases */
    642 #define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK )
    643 
    644 /** iSCSI session needs to send the initial security negotiation strings */
    645 #define ISCSI_STATUS_STRINGS_SECURITY 0x0100
    646 
    647 /** iSCSI session needs to send the CHAP_A string */
    648 #define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200
    649 
    650 /** iSCSI session needs to send the CHAP response */
    651 #define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400
    652 
    653 /** iSCSI session needs to send the mutual CHAP challenge */
    654 #define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE 0x0800
    655 
    656 /** iSCSI session needs to send the operational negotiation strings */
    657 #define ISCSI_STATUS_STRINGS_OPERATIONAL 0x1000
    658 
    659 /** Mask for all iSCSI "needs to send" flags */
    660 #define ISCSI_STATUS_STRINGS_MASK 0xff00
    661 
    662 /** Target has requested forward (initiator) authentication */
    663 #define ISCSI_STATUS_AUTH_FORWARD_REQUIRED 0x00010000
    664 
    665 /** Initiator requires target (reverse) authentication */
    666 #define ISCSI_STATUS_AUTH_REVERSE_REQUIRED 0x00020000
    667 
    668 /** Target authenticated itself correctly */
    669 #define ISCSI_STATUS_AUTH_REVERSE_OK 0x00040000
    670 
    671 /** Maximum number of retries at connecting */
    672 #define ISCSI_MAX_RETRIES 2
    673 
    674 extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
    675 extern void iscsi_detach ( struct scsi_device *scsi );
    676 extern const char * iscsi_initiator_iqn ( void );
    677 
    678 #endif /* _GPXE_ISCSI_H */
    679