Add IScsiDxe driver to NetworkPkg in order to support iSCSI over IPv6 stack and iSCSI MPIO.

Signed-off-by: tye1
Reviewed-by: hhuan13
Reviewed-by: eric_tian


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12149 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
tye1 2011-08-17 02:38:08 +00:00
parent ab0eecec6e
commit 4c5a5e0cfe
26 changed files with 14300 additions and 1 deletions

View File

@ -0,0 +1,181 @@
/** @file
UEFI Component Name(2) protocol implementation for iSCSI.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName = {
IScsiComponentNameGetDriverName,
IScsiComponentNameGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IScsiComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IScsiComponentNameGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable[] = {
{
"eng;en",
L"iSCSI Driver"
},
{
NULL,
NULL
}
};
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param[out] DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
IScsiComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mIScsiDriverNameTable,
DriverName,
(BOOLEAN) (This == &gIScsiComponentName)
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] ControllerHandle The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param[in] ChildHandle The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param[out] ControllerName A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language, from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
IScsiComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,67 @@
/** @file
Implementation for EFI_AUTHENTICATION_INFO_PROTOCOL. Currently it is a
dummy support.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
EFI_AUTHENTICATION_INFO_PROTOCOL gIScsiAuthenticationInfo = {
IScsiGetAuthenticationInfo,
IScsiSetAuthenticationInfo
};
/**
Retrieves the authentication information associated with a particular controller handle.
@param[in] This Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL.
@param[in] ControllerHandle Handle to the Controller.
@param[out] Buffer Pointer to the authentication information. This function is
responsible for allocating the buffer and it is the caller's
responsibility to free buffer when the caller is finished with buffer.
@retval EFI_DEVICE_ERROR The authentication information could not be
retrieved due to a hardware error.
**/
EFI_STATUS
EFIAPI
IScsiGetAuthenticationInfo (
IN EFI_AUTHENTICATION_INFO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
OUT VOID **Buffer
)
{
return EFI_DEVICE_ERROR;
}
/**
Set the authentication information for a given controller handle.
@param[in] This Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL.
@param[in] ControllerHandle Handle to the Controller.
@param[in] Buffer Pointer to the authentication information.
@retval EFI_UNSUPPORTED If the platform policies do not allow setting of
the authentication information.
**/
EFI_STATUS
EFIAPI
IScsiSetAuthenticationInfo (
IN EFI_AUTHENTICATION_INFO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN VOID *Buffer
)
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,474 @@
/** @file
This file is for Challenge-Handshake Authentication Protocol (CHAP) Configuration.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
/**
Initator caculates its own expected hash value.
@param[in] ChapIdentifier iSCSI CHAP identifier sent by authenticator.
@param[in] ChapSecret iSCSI CHAP secret of the authenticator.
@param[in] SecretLength The length of iSCSI CHAP secret.
@param[in] ChapChallenge The challenge message sent by authenticator.
@param[in] ChallengeLength The length of iSCSI CHAP challenge message.
@param[out] ChapResponse The calculation of the expected hash value.
@retval EFI_SUCCESS The expected hash value was caculatedly successfully.
@retval EFI_PROTOCOL_ERROR The length of the secret should be at least the
length of the hash value for the hashing algorithm chosen.
@retval EFI_PROTOCOL_ERROR MD5 hash operation fail.
@retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete MD5.
**/
EFI_STATUS
IScsiCHAPCalculateResponse (
IN UINT32 ChapIdentifier,
IN CHAR8 *ChapSecret,
IN UINT32 SecretLength,
IN UINT8 *ChapChallenge,
IN UINT32 ChallengeLength,
OUT UINT8 *ChapResponse
)
{
UINTN Md5ContextSize;
VOID *Md5Ctx;
CHAR8 IdByte[1];
EFI_STATUS Status;
if (SecretLength < ISCSI_CHAP_SECRET_MIN_LEN) {
return EFI_PROTOCOL_ERROR;
}
Md5ContextSize = Md5GetContextSize ();
Md5Ctx = AllocatePool (Md5ContextSize);
if (Md5Ctx == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = EFI_PROTOCOL_ERROR;
if (!Md5Init (Md5Ctx)) {
goto Exit;
}
//
// Hash Identifier - Only calculate 1 byte data (RFC1994)
//
IdByte[0] = (CHAR8) ChapIdentifier;
if (!Md5Update (Md5Ctx, IdByte, 1)) {
goto Exit;
}
//
// Hash Secret
//
if (!Md5Update (Md5Ctx, ChapSecret, SecretLength)) {
goto Exit;
}
//
// Hash Challenge received from Target
//
if (!Md5Update (Md5Ctx, ChapChallenge, ChallengeLength)) {
goto Exit;
}
if (Md5Final (Md5Ctx, ChapResponse)) {
Status = EFI_SUCCESS;
}
Exit:
FreePool (Md5Ctx);
return Status;
}
/**
The initator checks the CHAP response replied by target against its own
calculation of the expected hash value.
@param[in] AuthData iSCSI CHAP authentication data.
@param[in] TargetResponse The response from target.
@retval EFI_SUCCESS The response from target passed authentication.
@retval EFI_SECURITY_VIOLATION The response from target was not expected value.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiCHAPAuthTarget (
IN ISCSI_CHAP_AUTH_DATA *AuthData,
IN UINT8 *TargetResponse
)
{
EFI_STATUS Status;
UINT32 SecretSize;
UINT8 VerifyRsp[ISCSI_CHAP_RSP_LEN];
Status = EFI_SUCCESS;
SecretSize = (UINT32) AsciiStrLen (AuthData->AuthConfig->ReverseCHAPSecret);
Status = IScsiCHAPCalculateResponse (
AuthData->OutIdentifier,
AuthData->AuthConfig->ReverseCHAPSecret,
SecretSize,
AuthData->OutChallenge,
AuthData->OutChallengeLength,
VerifyRsp
);
if (CompareMem (VerifyRsp, TargetResponse, ISCSI_CHAP_RSP_LEN) != 0) {
Status = EFI_SECURITY_VIOLATION;
}
return Status;
}
/**
This function checks the received iSCSI Login Response during the security
negotiation stage.
@param[in] Conn The iSCSI connection.
@retval EFI_SUCCESS The Login Response passed the CHAP validation.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiCHAPOnRspReceived (
IN ISCSI_CONNECTION *Conn
)
{
EFI_STATUS Status;
ISCSI_SESSION *Session;
ISCSI_CHAP_AUTH_DATA *AuthData;
CHAR8 *Value;
UINT8 *Data;
UINT32 Len;
LIST_ENTRY *KeyValueList;
UINTN Algorithm;
CHAR8 *Identifier;
CHAR8 *Challenge;
CHAR8 *Name;
CHAR8 *Response;
UINT8 TargetRsp[ISCSI_CHAP_RSP_LEN];
UINT32 RspLen;
UINTN Result;
ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
ASSERT (Conn->RspQue.BufNum != 0);
Session = Conn->Session;
AuthData = &Session->AuthData.CHAP;
Len = Conn->RspQue.BufSize;
Data = AllocateZeroPool (Len);
if (Data == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Copy the data in case the data spans over multiple PDUs.
//
NetbufQueCopy (&Conn->RspQue, 0, Len, Data);
//
// Build the key-value list from the data segment of the Login Response.
//
KeyValueList = IScsiBuildKeyValueList ((CHAR8 *) Data, Len);
if (KeyValueList == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Status = EFI_PROTOCOL_ERROR;
switch (Conn->AuthStep) {
case ISCSI_AUTH_INITIAL:
//
// The first Login Response.
//
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
if (Value == NULL) {
goto ON_EXIT;
}
Result = IScsiNetNtoi (Value);
if (Result > 0xFFFF) {
goto ON_EXIT;
}
Session->TargetPortalGroupTag = (UINT16) Result;
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_AUTH_METHOD);
if (Value == NULL) {
goto ON_EXIT;
}
//
// Initiator mandates CHAP authentication but target replies without "CHAP", or
// initiator suggets "None" but target replies with some kind of auth method.
//
if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) {
if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) != 0) {
goto ON_EXIT;
}
} else if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
if (AsciiStrCmp (Value, ISCSI_AUTH_METHOD_CHAP) != 0) {
goto ON_EXIT;
}
} else {
goto ON_EXIT;
}
//
// Transit to CHAP step one.
//
Conn->AuthStep = ISCSI_CHAP_STEP_ONE;
Status = EFI_SUCCESS;
break;
case ISCSI_CHAP_STEP_TWO:
//
// The Target replies with CHAP_A=<A> CHAP_I=<I> CHAP_C=<C>
//
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_ALGORITHM);
if (Value == NULL) {
goto ON_EXIT;
}
Algorithm = IScsiNetNtoi (Value);
if (Algorithm != ISCSI_CHAP_ALGORITHM_MD5) {
//
// Unsupported algorithm is chosen by target.
//
goto ON_EXIT;
}
Identifier = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_IDENTIFIER);
if (Identifier == NULL) {
goto ON_EXIT;
}
Challenge = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_CHALLENGE);
if (Challenge == NULL) {
goto ON_EXIT;
}
//
// Process the CHAP identifier and CHAP Challenge from Target.
// Calculate Response value.
//
Result = IScsiNetNtoi (Identifier);
if (Result > 0xFF) {
goto ON_EXIT;
}
AuthData->InIdentifier = (UINT32) Result;
AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
IScsiHexToBin ((UINT8 *) AuthData->InChallenge, &AuthData->InChallengeLength, Challenge);
Status = IScsiCHAPCalculateResponse (
AuthData->InIdentifier,
AuthData->AuthConfig->CHAPSecret,
(UINT32) AsciiStrLen (AuthData->AuthConfig->CHAPSecret),
AuthData->InChallenge,
AuthData->InChallengeLength,
AuthData->CHAPResponse
);
//
// Transit to next step.
//
Conn->AuthStep = ISCSI_CHAP_STEP_THREE;
break;
case ISCSI_CHAP_STEP_THREE:
//
// One way CHAP authentication and the target would like to
// authenticate us.
//
Status = EFI_SUCCESS;
break;
case ISCSI_CHAP_STEP_FOUR:
ASSERT (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL);
//
// The forth step, CHAP_N=<N> CHAP_R=<R> is received from Target.
//
Name = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_NAME);
if (Name == NULL) {
goto ON_EXIT;
}
Response = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_RESPONSE);
if (Response == NULL) {
goto ON_EXIT;
}
RspLen = ISCSI_CHAP_RSP_LEN;
IScsiHexToBin (TargetRsp, &RspLen, Response);
//
// Check the CHAP Name and Response replied by Target.
//
Status = IScsiCHAPAuthTarget (AuthData, TargetRsp);
break;
default:
break;
}
ON_EXIT:
if (KeyValueList != NULL) {
IScsiFreeKeyValueList (KeyValueList);
}
FreePool (Data);
return Status;
}
/**
This function fills the CHAP authentication information into the login PDU
during the security negotiation stage in the iSCSI connection login.
@param[in] Conn The iSCSI connection.
@param[in, out] Pdu The PDU to send out.
@retval EFI_SUCCESS All check passed and the phase-related CHAP
authentication info is filled into the iSCSI PDU.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred.
**/
EFI_STATUS
IScsiCHAPToSendReq (
IN ISCSI_CONNECTION *Conn,
IN OUT NET_BUF *Pdu
)
{
EFI_STATUS Status;
ISCSI_SESSION *Session;
ISCSI_LOGIN_REQUEST *LoginReq;
ISCSI_CHAP_AUTH_DATA *AuthData;
CHAR8 *Value;
CHAR8 ValueStr[256];
CHAR8 *Response;
UINT32 RspLen;
CHAR8 *Challenge;
UINT32 ChallengeLen;
ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
Session = Conn->Session;
AuthData = &Session->AuthData.CHAP;
LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufGetByte (Pdu, 0, 0);
Status = EFI_SUCCESS;
RspLen = 2 * ISCSI_CHAP_RSP_LEN + 3;
Response = AllocateZeroPool (RspLen);
if (Response == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ChallengeLen = 2 * ISCSI_CHAP_RSP_LEN + 3;
Challenge = AllocateZeroPool (ChallengeLen);
if (Challenge == NULL) {
FreePool (Response);
return EFI_OUT_OF_RESOURCES;
}
switch (Conn->AuthStep) {
case ISCSI_AUTH_INITIAL:
//
// It's the initial Login Request. Fill in the key=value pairs mandatory
// for the initial Login Request.
//
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_INITIATOR_NAME, mPrivate->InitiatorName);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_SESSION_TYPE, "Normal");
IScsiAddKeyValuePair (
Pdu,
ISCSI_KEY_TARGET_NAME,
Session->ConfigData->SessionConfigData.TargetName
);
if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) {
Value = ISCSI_KEY_VALUE_NONE;
ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
} else {
Value = ISCSI_AUTH_METHOD_CHAP;
}
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_AUTH_METHOD, Value);
break;
case ISCSI_CHAP_STEP_ONE:
//
// First step, send the Login Request with CHAP_A=<A1,A2...> key-value pair.
//
AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", ISCSI_CHAP_ALGORITHM_MD5);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_ALGORITHM, ValueStr);
Conn->AuthStep = ISCSI_CHAP_STEP_TWO;
break;
case ISCSI_CHAP_STEP_THREE:
//
// Third step, send the Login Request with CHAP_N=<N> CHAP_R=<R> or
// CHAP_N=<N> CHAP_R=<R> CHAP_I=<I> CHAP_C=<C> if target authentication is
// required too.
//
// CHAP_N=<N>
//
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_NAME, (CHAR8 *) &AuthData->AuthConfig->CHAPName);
//
// CHAP_R=<R>
//
IScsiBinToHex ((UINT8 *) AuthData->CHAPResponse, ISCSI_CHAP_RSP_LEN, Response, &RspLen);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_RESPONSE, Response);
if (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) {
//
// CHAP_I=<I>
//
IScsiGenRandom ((UINT8 *) &AuthData->OutIdentifier, 1);
AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr);
//
// CHAP_C=<C>
//
IScsiGenRandom ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN);
AuthData->OutChallengeLength = ISCSI_CHAP_RSP_LEN;
IScsiBinToHex ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN, Challenge, &ChallengeLen);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_CHALLENGE, Challenge);
Conn->AuthStep = ISCSI_CHAP_STEP_FOUR;
}
//
// Set the stage transition flag.
//
ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
break;
default:
Status = EFI_PROTOCOL_ERROR;
break;
}
FreePool (Response);
FreePool (Challenge);
return Status;
}

View File

@ -0,0 +1,113 @@
/** @file
The header file of CHAP configuration.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_CHAP_H_
#define _ISCSI_CHAP_H_
#define ISCSI_CHAP_AUTH_INFO_GUID \
{ \
0x786ec0ac, 0x65ae, 0x4d1b, { 0xb1, 0x37, 0xd, 0x11, 0xa, 0x48, 0x37, 0x97 }\
}
#define ISCSI_AUTH_METHOD_CHAP "CHAP"
#define ISCSI_KEY_CHAP_ALGORITHM "CHAP_A"
#define ISCSI_KEY_CHAP_IDENTIFIER "CHAP_I"
#define ISCSI_KEY_CHAP_CHALLENGE "CHAP_C"
#define ISCSI_KEY_CHAP_NAME "CHAP_N"
#define ISCSI_KEY_CHAP_RESPONSE "CHAP_R"
#define ISCSI_CHAP_ALGORITHM_MD5 5
#define ISCSI_CHAP_AUTH_MAX_LEN 1024
///
/// MD5_HASHSIZE
///
#define ISCSI_CHAP_RSP_LEN 16
#define ISCSI_CHAP_STEP_ONE 1
#define ISCSI_CHAP_STEP_TWO 2
#define ISCSI_CHAP_STEP_THREE 3
#define ISCSI_CHAP_STEP_FOUR 4
#pragma pack(1)
typedef struct _ISCSI_CHAP_AUTH_CONFIG_NVDATA {
UINT8 CHAPType;
CHAR8 CHAPName[ISCSI_CHAP_NAME_STORAGE];
CHAR8 CHAPSecret[ISCSI_CHAP_SECRET_STORAGE];
CHAR8 ReverseCHAPName[ISCSI_CHAP_NAME_STORAGE];
CHAR8 ReverseCHAPSecret[ISCSI_CHAP_SECRET_STORAGE];
} ISCSI_CHAP_AUTH_CONFIG_NVDATA;
#pragma pack()
///
/// ISCSI CHAP Authentication Data
///
typedef struct _ISCSI_CHAP_AUTH_DATA {
ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
UINT32 InIdentifier;
UINT8 InChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
UINT32 InChallengeLength;
//
// Calculated CHAP Response (CHAP_R) value.
//
UINT8 CHAPResponse[ISCSI_CHAP_RSP_LEN];
//
// Auth-data to be sent out for mutual authentication.
//
UINT32 OutIdentifier;
UINT8 OutChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
UINT32 OutChallengeLength;
} ISCSI_CHAP_AUTH_DATA;
/**
This function checks the received iSCSI Login Response during the security
negotiation stage.
@param[in] Conn The iSCSI connection.
@retval EFI_SUCCESS The Login Response passed the CHAP validation.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiCHAPOnRspReceived (
IN ISCSI_CONNECTION *Conn
);
/**
This function fills the CHAP authentication information into the login PDU
during the security negotiation stage in the iSCSI connection login.
@param[in] Conn The iSCSI connection.
@param[in, out] Pdu The PDU to send out.
@retval EFI_SUCCESS All check passed and the phase-related CHAP
authentication info is filled into the iSCSI PDU.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred.
**/
EFI_STATUS
IScsiCHAPToSendReq (
IN ISCSI_CONNECTION *Conn,
IN OUT NET_BUF *Pdu
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/** @file
The header file of functions for configuring or getting the parameters
relating to iSCSI.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_CONFIG_H_
#define _ISCSI_CONFIG_H_
#include "IScsiConfigNVDataStruc.h"
typedef struct _ISCSI_FORM_CALLBACK_INFO ISCSI_FORM_CALLBACK_INFO;
extern UINT8 IScsiConfigVfrBin[];
extern UINT8 IScsiDxeStrings[];
extern ISCSI_FORM_CALLBACK_INFO *mCallbackInfo;
extern EFI_GUID mVendorGuid;
#define VAR_OFFSET(Field) \
((UINT16) ((UINTN) &(((ISCSI_CONFIG_IFR_NVDATA *) 0)->Field)))
#define QUESTION_ID(Field) \
((UINT16) (VAR_OFFSET (Field) + CONFIG_OPTION_OFFSET))
#define DYNAMIC_ONE_OF_VAR_OFFSET VAR_OFFSET (Enabled)
#define DYNAMIC_ORDERED_LIST_QUESTION_ID QUESTION_ID (DynamicOrderedList)
#define DYNAMIC_ORDERED_LIST_VAR_OFFSET VAR_OFFSET (DynamicOrderedList)
#define ATTEMPT_DEL_QUESTION_ID QUESTION_ID (DeleteAttemptList)
#define ATTEMPT_DEL_VAR_OFFSET VAR_OFFSET (DeleteAttemptList)
//
// sizeof (EFI_MAC_ADDRESS) * 3
//
#define ISCSI_MAX_MAC_STRING_LEN 96
#define ISCSI_INITATOR_NAME_VAR_NAME L"I_NAME"
#define ISCSI_CONFIG_VAR_ATTR (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE)
#define ISCSI_FORM_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('I', 'f', 'c', 'i')
#define ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK(Callback) \
CR ( \
Callback, \
ISCSI_FORM_CALLBACK_INFO, \
ConfigAccess, \
ISCSI_FORM_CALLBACK_INFO_SIGNATURE \
)
#pragma pack(1)
struct _ISCSI_ATTEMPT_CONFIG_NVDATA {
LIST_ENTRY Link;
UINT8 NicIndex;
UINT8 AttemptConfigIndex;
BOOLEAN DhcpSuccess;
BOOLEAN ValidiBFTPath;
BOOLEAN ValidPath;
UINT8 AutoConfigureMode;
EFI_STRING_ID AttemptTitleToken;
EFI_STRING_ID AttemptTitleHelpToken;
CHAR8 AttemptName[ATTEMPT_NAME_MAX_SIZE];
CHAR8 MacString[ISCSI_MAX_MAC_STRING_LEN];
EFI_IP_ADDRESS PrimaryDns;
EFI_IP_ADDRESS SecondaryDns;
EFI_IP_ADDRESS DhcpServer;
ISCSI_SESSION_CONFIG_NVDATA SessionConfigData;
UINT8 AuthenticationType;
union {
ISCSI_CHAP_AUTH_CONFIG_NVDATA CHAP;
} AuthConfigData;
};
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
#pragma pack()
struct _ISCSI_FORM_CALLBACK_INFO {
UINT32 Signature;
EFI_HANDLE DriverHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
UINT16 *KeyList;
VOID *FormBuffer;
EFI_HII_HANDLE RegisteredHandle;
ISCSI_ATTEMPT_CONFIG_NVDATA *Current;
};
/**
Initialize the iSCSI configuration form.
@param[in] DriverBindingHandle The iSCSI driverbinding handle.
@retval EFI_SUCCESS The iSCSI configuration form is initialized.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
EFI_STATUS
IScsiConfigFormInit (
IN EFI_HANDLE DriverBindingHandle
);
/**
Unload the iSCSI configuration form, this includes: delete all the iSCSI
configuration entries, uninstall the form callback protocol, and
free the resources used.
@param[in] DriverBindingHandle The iSCSI driverbinding handle.
@retval EFI_SUCCESS The iSCSI configuration form is unloaded.
@retval Others Failed to unload the form.
**/
EFI_STATUS
IScsiConfigFormUnload (
IN EFI_HANDLE DriverBindingHandle
);
/**
Update the MAIN form to display the configured attempts.
**/
VOID
IScsiConfigUpdateAttempt (
VOID
);
/**
Get the attempt config data from global structure by the ConfigIndex.
@param[in] AttemptConfigIndex The unique index indicates the attempt.
@return Pointer to the attempt config data.
@retval NULL The attempt configuration data can not be found.
**/
ISCSI_ATTEMPT_CONFIG_NVDATA *
IScsiConfigGetAttemptByConfigIndex (
IN UINT8 AttemptConfigIndex
);
#endif

View File

@ -0,0 +1,194 @@
/** @file
Define NVData structures used by the iSCSI configuration component.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_NVDATASTRUC_H_
#define _ISCSI_NVDATASTRUC_H_
#define ISCSI_CONFIG_GUID \
{ \
0x6456ed61, 0x3579, 0x41c9, { 0x8a, 0x26, 0x0a, 0x0b, 0xd6, 0x2b, 0x78, 0xfc } \
}
#define VAR_EQ_TEST_NAME 0x100
#define CONFIGURATION_VARSTORE_ID 0x6666
#define FORMID_MAIN_FORM 1
#define FORMID_MAC_FORM 2
#define FORMID_ATTEMPT_FORM 3
#define FORMID_ORDER_FORM 4
#define FORMID_DELETE_FORM 5
#define ISCSI_NAME_IFR_MIN_SIZE 4
#define ISCSI_NAME_IFR_MAX_SIZE 223
#define ISCSI_NAME_MAX_SIZE 224
#define ATTEMPT_NAME_MAX_SIZE 96
#define ATTEMPT_NAME_SIZE 10
#define CONNECT_MIN_RETRY 0
#define CONNECT_MAX_RETRY 16
#define CONNECT_MIN_TIMEOUT 100
#define CONNECT_MAX_TIMEOUT 20000
#define CONNECT_DEFAULT_TIMEOUT 1000
#define ISCSI_MAX_ATTEMPTS_NUM 255
#define ISCSI_DISABLED 0
#define ISCSI_ENABLED 1
#define ISCSI_ENABLED_FOR_MPIO 2
#define IP_MODE_IP4 0
#define IP_MODE_IP6 1
#define IP_MODE_AUTOCONFIG 2
#define ISCSI_AUTH_TYPE_NONE 0
#define ISCSI_AUTH_TYPE_CHAP 1
#define ISCSI_AUTH_TYPE_KRB 2
#define IP4_MIN_SIZE 7
#define IP4_MAX_SIZE 15
#define IP4_STR_MAX_SIZE 16
//
// Macros used for an IPv4 or an IPv6 address.
//
#define IP_MIN_SIZE 2
#define IP_MAX_SIZE 39
#define IP_STR_MAX_SIZE 40
#define LUN_MIN_SIZE 1
#define LUN_MAX_SIZE 20
#define ISCSI_CHAP_UNI 1
#define ISCSI_CHAP_MUTUAL 2
#define TARGET_PORT_MIN_NUM 0
#define TARGET_PORT_MAX_NUM 65535
#define LABEL_END 0xffff
#define KEY_INITIATOR_NAME 0x101
#define KEY_DHCP_ENABLE 0x102
#define KEY_LOCAL_IP 0x103
#define KEY_SUBNET_MASK 0x104
#define KEY_GATE_WAY 0x105
#define KEY_TARGET_IP 0x106
#define KEY_CHAP_NAME 0x107
#define KEY_CHAP_SECRET 0x108
#define KEY_REVERSE_CHAP_NAME 0x109
#define KEY_REVERSE_CHAP_SECRET 0x10a
#define KEY_SAVE_CHANGES 0x10b
#define KEY_TARGET_NAME 0x10c
#define KEY_BOOT_LUN 0x10d
#define KEY_ADD_ATTEMPT 0x10e
#define KEY_SAVE_ATTEMPT_CONFIG 0x10f
#define KEY_ORDER_ATTEMPT_CONFIG 0x110
#define KEY_SAVE_ORDER_CHANGES 0x111
#define KEY_IGNORE_ORDER_CHANGES 0x112
#define KEY_ATTEMPT_NAME 0x113
#define KEY_SAVE_DELETE_ATTEMPT 0x114
#define KEY_IGNORE_DELETE_ATTEMPT 0x115
#define KEY_DELETE_ATTEMPT 0x116
#define KEY_KERBEROS_USER_NAME 0x117
#define KEY_KERBEROS_USER_SECRET 0x118
#define KEY_KERBEROS_KDC_NAME 0x119
#define KEY_KERBEROS_KDC_REALM 0x11a
#define KEY_KERBEROS_KDC_IP_ADDR 0x11b
#define KEY_IP_MODE 0x11c
#define KEY_AUTH_TYPE 0x11d
#define KEY_CONFIG_ISID 0x11e
#define ATTEMPT_ENTRY_LABEL 0x9000
#define KEY_ATTEMPT_ENTRY_BASE 0xa000
#define KEY_DE_ATTEMPT_ENTRY_BASE 0xb000
#define KEY_DEVICE_ENTRY_BASE 0x1000
#define KEY_MAC_ENTRY_BASE 0x2000
#define MAC_ENTRY_LABEL 0x3000
#define ORDER_ENTRY_LABEL 0x4000
#define DELETE_ENTRY_LABEL 0x5000
#define CONFIG_OPTION_OFFSET 0x9000
#define ISCSI_LUN_STR_MAX_LEN 21
#define ISCSI_CHAP_SECRET_MIN_LEN 12
#define ISCSI_CHAP_SECRET_MAX_LEN 16
//
// ISCSI_CHAP_SECRET_STORAGE = ISCSI_CHAP_SECRET_MAX_LEN + sizeof (NULL-Terminator)
//
#define ISCSI_CHAP_SECRET_STORAGE 17
#define ISCSI_CHAP_NAME_MAX_LEN 126
#define ISCSI_CHAP_NAME_STORAGE 127
#define KERBEROS_SECRET_MIN_LEN 12
#define KERBEROS_SECRET_MAX_LEN 16
#define KERBEROS_SECRET_STORAGE 17
#define KERBEROS_NAME_MAX_LEN 96
#define KERBEROS_KDC_PORT_MIN_NUM 0
#define KERBEROS_KDC_PORT_MAX_NUM 65535
#define ISID_CONFIGURABLE_MIN_LEN 6
#define ISID_CONFIGURABLE_MAX_LEN 12
#define ISID_CONFIGURABLE_STORAGE 13
#pragma pack(1)
typedef struct _ISCSI_CONFIG_IFR_NVDATA {
CHAR16 InitiatorName[ISCSI_NAME_MAX_SIZE];
CHAR16 AttemptName[ATTEMPT_NAME_MAX_SIZE];
UINT8 Enabled;
UINT8 IpMode;
UINT8 ConnectRetryCount;
UINT8 Padding1;
UINT16 ConnectTimeout; // Timeout value in milliseconds.
UINT8 InitiatorInfoFromDhcp;
UINT8 TargetInfoFromDhcp;
CHAR16 LocalIp[IP4_STR_MAX_SIZE];
CHAR16 SubnetMask[IP4_STR_MAX_SIZE];
CHAR16 Gateway[IP4_STR_MAX_SIZE];
CHAR16 TargetName[ISCSI_NAME_MAX_SIZE];
CHAR16 TargetIp[IP_STR_MAX_SIZE];
UINT16 TargetPort;
CHAR16 BootLun[ISCSI_LUN_STR_MAX_LEN];
UINT8 AuthenticationType;
UINT8 CHAPType;
CHAR16 CHAPName[ISCSI_CHAP_NAME_STORAGE];
CHAR16 CHAPSecret[ISCSI_CHAP_SECRET_STORAGE];
CHAR16 ReverseCHAPName[ISCSI_CHAP_NAME_STORAGE];
CHAR16 ReverseCHAPSecret[ISCSI_CHAP_SECRET_STORAGE];
BOOLEAN MutualRequired;
UINT8 Padding2;
CHAR16 KerberosUserName[KERBEROS_NAME_MAX_LEN];
CHAR16 KerberosUserSecret[KERBEROS_SECRET_STORAGE];
CHAR16 KerberosKDCName[KERBEROS_NAME_MAX_LEN];
CHAR16 KerberosKDCRealm[KERBEROS_NAME_MAX_LEN];
CHAR16 KerberosKDCIp[IP_STR_MAX_SIZE];
UINT16 KerberosKDCPort;
UINT8 DynamicOrderedList[ISCSI_MAX_ATTEMPTS_NUM];
UINT8 DeleteAttemptList[ISCSI_MAX_ATTEMPTS_NUM];
CHAR16 IsId[ISID_CONFIGURABLE_STORAGE];
} ISCSI_CONFIG_IFR_NVDATA;
#pragma pack()
#endif

Binary file not shown.

View File

@ -0,0 +1,429 @@
/** @file
VFR file used by the iSCSI configuration component.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiConfigNVDataStruc.h"
#define EFI_NETWORK_DEVICE_CLASS 0x04
formset
guid = ISCSI_CONFIG_GUID,
title = STRING_TOKEN(STR_ISCSI_CONFIG_FORM_TITLE),
help = STRING_TOKEN(STR_ISCSI_CONFIG_FORM_HELP),
class = EFI_NETWORK_DEVICE_CLASS,
subclass = 0x03,
varstore ISCSI_CONFIG_IFR_NVDATA,
varid = CONFIGURATION_VARSTORE_ID,
name = ISCSI_CONFIG_IFR_NVDATA,
guid = ISCSI_CONFIG_GUID;
form formid = FORMID_MAIN_FORM,
title = STRING_TOKEN(STR_ISCSI_MAIN_FORM_TITLE);
string varid = ISCSI_CONFIG_IFR_NVDATA.InitiatorName,
prompt = STRING_TOKEN(STR_ISCSI_CONFIG_INIT_NAME),
help = STRING_TOKEN(STR_ISCSI_CONFIG_INIT_NAME_HELP),
flags = INTERACTIVE,
key = KEY_INITIATOR_NAME,
minsize = ISCSI_NAME_IFR_MIN_SIZE,
maxsize = ISCSI_NAME_IFR_MAX_SIZE,
endstring;
subtitle text = STRING_TOKEN(STR_NULL);
goto FORMID_MAC_FORM,
prompt = STRING_TOKEN(STR_ADD_ATTEMPT_ENTRY),
help = STRING_TOKEN(STR_ADD_ATTEMPT_ENTRY),
flags = INTERACTIVE,
key = KEY_ADD_ATTEMPT;
label ATTEMPT_ENTRY_LABEL;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_NULL);
goto FORMID_DELETE_FORM,
prompt = STRING_TOKEN (STR_DEL_ATTEMPT_ENTRY),
help = STRING_TOKEN (STR_DEL_ATTEMPT_ENTRY_HELP),
flags = INTERACTIVE,
key = KEY_DELETE_ATTEMPT;
subtitle text = STRING_TOKEN(STR_NULL);
goto FORMID_ORDER_FORM,
prompt = STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),
help = STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),
flags = INTERACTIVE,
key = KEY_ORDER_ATTEMPT_CONFIG;
subtitle text = STRING_TOKEN(STR_NULL);
endform;
form formid = FORMID_MAC_FORM,
title = STRING_TOKEN(STR_ISCSI_MAC_FORM_TITLE);
label MAC_ENTRY_LABEL;
label LABEL_END;
endform;
form formid = FORMID_ORDER_FORM,
title = STRING_TOKEN(STR_ORDER_ATTEMPT_ENTRY);
label ORDER_ENTRY_LABEL;
label LABEL_END;
goto FORMID_MAIN_FORM,
prompt = STRING_TOKEN (STR_SAVE_AND_EXIT),
help = STRING_TOKEN (STR_SAVE_AND_EXIT),
flags = INTERACTIVE,
key = KEY_SAVE_ORDER_CHANGES;
goto FORMID_MAIN_FORM,
prompt = STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
help = STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
flags = INTERACTIVE,
key = KEY_IGNORE_ORDER_CHANGES;
endform;
form formid = FORMID_DELETE_FORM,
title = STRING_TOKEN(STR_DEL_ATTEMPT_ENTRY);
label DELETE_ENTRY_LABEL;
label LABEL_END;
goto FORMID_MAIN_FORM,
prompt = STRING_TOKEN (STR_SAVE_AND_EXIT),
help = STRING_TOKEN (STR_SAVE_AND_EXIT),
flags = INTERACTIVE,
key = KEY_SAVE_DELETE_ATTEMPT;
goto FORMID_MAIN_FORM,
prompt = STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
help = STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
flags = INTERACTIVE,
key = KEY_IGNORE_DELETE_ATTEMPT;
endform;
form formid = FORMID_ATTEMPT_FORM,
title = STRING_TOKEN(STR_ISCSI_ATTEMPT_FORM_TITLE);
string varid = ISCSI_CONFIG_IFR_NVDATA.AttemptName,
prompt = STRING_TOKEN(STR_ISCSI_ATTEMPT_NAME),
help = STRING_TOKEN(STR_ISCSI_ATTEMPT_NAME_HELP),
flags = INTERACTIVE,
key = KEY_ATTEMPT_NAME,
minsize = 0,
maxsize = ATTEMPT_NAME_MAX_SIZE,
endstring;
subtitle text = STRING_TOKEN(STR_NULL);
oneof varid = ISCSI_CONFIG_IFR_NVDATA.Enabled,
prompt = STRING_TOKEN(STR_ISCSI_MODE_PROMPT),
help = STRING_TOKEN(STR_ISCSI_MODE_HELP),
option text = STRING_TOKEN(STR_ISCSI_MODE_DISABLED), value = ISCSI_DISABLED, flags = DEFAULT;
option text = STRING_TOKEN(STR_ISCSI_MODE_ENABLED), value = ISCSI_ENABLED, flags = 0;
option text = STRING_TOKEN(STR_ISCSI_MODE_ENABLED_FOR_MPIO), value = ISCSI_ENABLED_FOR_MPIO, flags = 0;
endoneof;
subtitle text = STRING_TOKEN(STR_NULL);
oneof varid = ISCSI_CONFIG_IFR_NVDATA.IpMode,
questionid = KEY_IP_MODE,
prompt = STRING_TOKEN(STR_IP_MODE_PROMPT),
help = STRING_TOKEN(STR_IP_MODE_HELP),
option text = STRING_TOKEN(STR_IP_MODE_IP4), value = IP_MODE_IP4, flags = INTERACTIVE;
option text = STRING_TOKEN(STR_IP_MODE_IP6), value = IP_MODE_IP6, flags = INTERACTIVE;
option text = STRING_TOKEN(STR_IP_MODE_AUTOCONFIG), value = IP_MODE_AUTOCONFIG, flags = INTERACTIVE;
endoneof;
subtitle text = STRING_TOKEN(STR_NULL);
numeric varid = ISCSI_CONFIG_IFR_NVDATA.ConnectRetryCount,
prompt = STRING_TOKEN(STR_ISCSI_CONFIG_RETRY),
help = STRING_TOKEN(STR_ISCSI_CONFIG_RETRY_HELP),
flags = 0,
minimum = CONNECT_MIN_RETRY,
maximum = CONNECT_MAX_RETRY,
step = 0,
endnumeric;
numeric varid = ISCSI_CONFIG_IFR_NVDATA.ConnectTimeout,
prompt = STRING_TOKEN(STR_ISCSI_CONFIG_TIMEOUT),
help = STRING_TOKEN(STR_ISCSI_CONFIG_TIMEOUT_HELP),
flags = 0,
minimum = CONNECT_MIN_TIMEOUT,
maximum = CONNECT_MAX_TIMEOUT,
step = 0,
default = CONNECT_DEFAULT_TIMEOUT,
endnumeric;
subtitle text = STRING_TOKEN(STR_NULL);
string varid = ISCSI_CONFIG_IFR_NVDATA.IsId,
prompt = STRING_TOKEN(STR_ISCSI_CONFIG_ISID),
help = STRING_TOKEN(STR_ISCSI_CONFIG_ISID_HELP),
flags = INTERACTIVE,
key = KEY_CONFIG_ISID,
minsize = ISID_CONFIGURABLE_MIN_LEN,
maxsize = ISID_CONFIGURABLE_MAX_LEN,
endstring;
subtitle text = STRING_TOKEN(STR_NULL);
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG;
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp,
prompt = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP),
help = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP),
flags = INTERACTIVE,
key = KEY_DHCP_ENABLE,
endcheckbox;
endif;
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp == 0x01 OR
ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_IP6 OR
ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG;
string varid = ISCSI_CONFIG_IFR_NVDATA.LocalIp,
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_IP_ADDRESS),
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
flags = INTERACTIVE,
key = KEY_LOCAL_IP,
minsize = IP4_MIN_SIZE,
maxsize = IP4_MAX_SIZE,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.SubnetMask,
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_MASK),
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
flags = INTERACTIVE,
key = KEY_SUBNET_MASK,
minsize = IP4_MIN_SIZE,
maxsize = IP4_MAX_SIZE,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.Gateway,
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_GATEWAY),
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
flags = INTERACTIVE,
key = KEY_GATE_WAY,
minsize = IP4_MIN_SIZE,
maxsize = IP4_MAX_SIZE,
endstring;
endif;
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG;
subtitle text = STRING_TOKEN(STR_NULL);
endif;
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG OR
ideqval ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp == 0x00;
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.TargetInfoFromDhcp,
prompt = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP_ON_TARGET),
help = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP_ON_TARGET),
flags = 0,
endcheckbox;
endif;
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG OR
ideqval ISCSI_CONFIG_IFR_NVDATA.TargetInfoFromDhcp == 0x01;
string varid = ISCSI_CONFIG_IFR_NVDATA.TargetName,
prompt = STRING_TOKEN(STR_ISCSI_TARGET_NAME),
help = STRING_TOKEN(STR_ISCSI_TARGET_NAME_HELP),
flags = INTERACTIVE,
key = KEY_TARGET_NAME,
minsize = ISCSI_NAME_IFR_MIN_SIZE,
maxsize = ISCSI_NAME_IFR_MAX_SIZE,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.TargetIp,
prompt = STRING_TOKEN(STR_ISCSI_TARGET_IP_ADDRESS),
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
flags = INTERACTIVE,
key = KEY_TARGET_IP,
minsize = IP_MIN_SIZE,
maxsize = IP_MAX_SIZE,
endstring;
numeric varid = ISCSI_CONFIG_IFR_NVDATA.TargetPort,
prompt = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
help = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
flags = 0,
minimum = TARGET_PORT_MIN_NUM,
maximum = TARGET_PORT_MAX_NUM,
step = 0,
endnumeric;
string varid = ISCSI_CONFIG_IFR_NVDATA.BootLun,
prompt = STRING_TOKEN(STR_ISCSI_BOOT_LUN),
help = STRING_TOKEN(STR_ISCSI_BOOT_LUN_HELP),
flags = INTERACTIVE,
key = KEY_BOOT_LUN,
minsize = LUN_MIN_SIZE,
maxsize = LUN_MAX_SIZE,
endstring;
endif;
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.IpMode == IP_MODE_AUTOCONFIG;
subtitle text = STRING_TOKEN(STR_NULL);
endif;
oneof varid = ISCSI_CONFIG_IFR_NVDATA.AuthenticationType,
questionid = KEY_AUTH_TYPE,
prompt = STRING_TOKEN(STR_AUTHEN_TYPE_PROMPT),
help = STRING_TOKEN(STR_AUTHEN_TYPE_HELP),
option text = STRING_TOKEN(STR_AUTHEN_TYPE_CHAP), value = ISCSI_AUTH_TYPE_CHAP, flags = 0;
option text = STRING_TOKEN(STR_AUTHEN_TYPE_NONE), value = ISCSI_AUTH_TYPE_NONE, flags = DEFAULT;
endoneof;
suppressif NOT ideqval ISCSI_CONFIG_IFR_NVDATA.AuthenticationType == ISCSI_AUTH_TYPE_CHAP;
oneof varid = ISCSI_CONFIG_IFR_NVDATA.CHAPType,
prompt = STRING_TOKEN(STR_CHAP_TYPE_PROMPT),
help = STRING_TOKEN(STR_CHAP_TYPE_HELP),
option text = STRING_TOKEN(STR_CHAP_TYPE_UNI), value = ISCSI_CHAP_UNI, flags = 0;
option text = STRING_TOKEN(STR_CHAP_TYPE_MUTUAL), value = ISCSI_CHAP_MUTUAL, flags = DEFAULT;
endoneof;
endif;
suppressif NOT ideqval ISCSI_CONFIG_IFR_NVDATA.AuthenticationType == ISCSI_AUTH_TYPE_CHAP;
string varid = ISCSI_CONFIG_IFR_NVDATA.CHAPName,
prompt = STRING_TOKEN(STR_ISCSI_CHAP_NAME),
help = STRING_TOKEN(STR_ISCSI_CHAP_NAME),
flags = INTERACTIVE,
key = KEY_CHAP_NAME,
minsize = 0,
maxsize = ISCSI_CHAP_NAME_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.CHAPSecret,
prompt = STRING_TOKEN(STR_ISCSI_CHAP_SECRET),
help = STRING_TOKEN(STR_ISCSI_CHAP_SECRET_HELP),
flags = INTERACTIVE,
key = KEY_CHAP_SECRET,
minsize = ISCSI_CHAP_SECRET_MIN_LEN,
maxsize = ISCSI_CHAP_SECRET_MAX_LEN,
endstring;
endif;
suppressif NOT ideqval ISCSI_CONFIG_IFR_NVDATA.AuthenticationType == ISCSI_AUTH_TYPE_CHAP OR
NOT ideqval ISCSI_CONFIG_IFR_NVDATA.CHAPType == ISCSI_CHAP_MUTUAL;
string varid = ISCSI_CONFIG_IFR_NVDATA.ReverseCHAPName,
prompt = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_NAME),
help = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_NAME),
flags = INTERACTIVE,
key = KEY_REVERSE_CHAP_NAME,
minsize = 0,
maxsize = ISCSI_CHAP_NAME_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.ReverseCHAPSecret,
prompt = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_SECRET),
help = STRING_TOKEN(STR_ISCSI_CHAP_SECRET_HELP),
flags = INTERACTIVE,
key = KEY_REVERSE_CHAP_SECRET,
minsize = ISCSI_CHAP_SECRET_MIN_LEN,
maxsize = ISCSI_CHAP_SECRET_MAX_LEN,
endstring;
endif;
suppressif NOT ideqval ISCSI_CONFIG_IFR_NVDATA.AuthenticationType == ISCSI_AUTH_TYPE_KRB;
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.MutualRequired,
prompt = STRING_TOKEN(STR_ISCSI_MUTUAL_REQUIRED),
help = STRING_TOKEN(STR_ISCSI_MUTUAL_REQUIRED_HELP),
flags = 0,
endcheckbox;
string varid = ISCSI_CONFIG_IFR_NVDATA.KerberosUserName,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_USER_NAME),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_USER_NAME),
flags = INTERACTIVE,
key = KEY_KERBEROS_USER_NAME,
minsize = 0,
maxsize = KERBEROS_NAME_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.KerberosUserSecret,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_USER_SECRET),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_USER_SECRET),
flags = INTERACTIVE,
key = KEY_KERBEROS_USER_SECRET,
minsize = KERBEROS_SECRET_MIN_LEN,
maxsize = KERBEROS_SECRET_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.KerberosKDCName,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_NAME),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_NAME),
flags = INTERACTIVE,
key = KEY_KERBEROS_KDC_NAME,
minsize = 0,
maxsize = KERBEROS_NAME_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.KerberosKDCRealm,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_REALM),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_REALM),
flags = INTERACTIVE,
key = KEY_KERBEROS_KDC_REALM,
minsize = 0,
maxsize = KERBEROS_NAME_MAX_LEN,
endstring;
string varid = ISCSI_CONFIG_IFR_NVDATA.KerberosKDCIp,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_IP),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_IP),
flags = INTERACTIVE,
key = KEY_KERBEROS_KDC_IP_ADDR,
minsize = IP_MIN_SIZE,
maxsize = IP_MAX_SIZE,
endstring;
numeric varid = ISCSI_CONFIG_IFR_NVDATA.KerberosKDCPort,
prompt = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_PORT),
help = STRING_TOKEN(STR_ISCSI_KERBEROS_KDC_PORT),
flags = 0,
minimum = KERBEROS_KDC_PORT_MIN_NUM,
maximum = KERBEROS_KDC_PORT_MAX_NUM,
step = 0,
endnumeric;
endif;
subtitle text = STRING_TOKEN(STR_NULL);
goto FORMID_ATTEMPT_FORM,
prompt = STRING_TOKEN (STR_SAVE_CHANGES),
help = STRING_TOKEN (STR_SAVE_CHANGES),
flags = INTERACTIVE,
key = KEY_SAVE_ATTEMPT_CONFIG;
goto FORMID_MAIN_FORM,
prompt = STRING_TOKEN (STR_RETURN_MAIN_FORM),
help = STRING_TOKEN (STR_RETURN_MAIN_FORM),
flags = 0;
endform;
endformset;

View File

@ -0,0 +1,498 @@
/** @file
iSCSI DHCP4 related configuration routines.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
/**
Extract the Root Path option and get the required target information.
@param[in] RootPath The RootPath.
@param[in] Length Length of the RootPath option payload.
@param[in, out] ConfigData The iSCSI attempt configuration data read
from a nonvolatile device.
@retval EFI_SUCCESS All required information is extracted from the RootPath option.
@retval EFI_NOT_FOUND The RootPath is not an iSCSI RootPath.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_INVALID_PARAMETER The RootPath is malformatted.
**/
EFI_STATUS
IScsiDhcpExtractRootPath (
IN CHAR8 *RootPath,
IN UINT8 Length,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
)
{
EFI_STATUS Status;
UINT8 IScsiRootPathIdLen;
CHAR8 *TmpStr;
ISCSI_ROOT_PATH_FIELD Fields[RP_FIELD_IDX_MAX];
ISCSI_ROOT_PATH_FIELD *Field;
UINT32 FieldIndex;
UINT8 Index;
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
EFI_IP_ADDRESS Ip;
UINT8 IpMode;
ConfigNvData = &ConfigData->SessionConfigData;
//
// "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
//
IScsiRootPathIdLen = (UINT8) AsciiStrLen (ISCSI_ROOT_PATH_ID);
if ((Length <= IScsiRootPathIdLen) || (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
return EFI_NOT_FOUND;
}
//
// Skip the iSCSI RootPath ID "iscsi:".
//
RootPath += IScsiRootPathIdLen;
Length = (UINT8) (Length - IScsiRootPathIdLen);
TmpStr = (CHAR8 *) AllocatePool (Length + 1);
if (TmpStr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (TmpStr, RootPath, Length);
TmpStr[Length] = '\0';
Index = 0;
FieldIndex = RP_FIELD_IDX_SERVERNAME;
ZeroMem (&Fields[0], sizeof (Fields));
//
// Extract the fields in the Root Path option string.
//
for (FieldIndex = RP_FIELD_IDX_SERVERNAME; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {
if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
Fields[FieldIndex].Str = &TmpStr[Index];
}
while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
Index++;
}
if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
if (FieldIndex != RP_FIELD_IDX_TARGETNAME) {
TmpStr[Index] = '\0';
Index++;
}
if (Fields[FieldIndex].Str != NULL) {
Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
}
}
}
if (FieldIndex != RP_FIELD_IDX_MAX) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
(Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||
(Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)
) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Get the IP address of the target.
//
Field = &Fields[RP_FIELD_IDX_SERVERNAME];
if (ConfigNvData->IpMode < IP_MODE_AUTOCONFIG) {
IpMode = ConfigNvData->IpMode;
} else {
IpMode = ConfigData->AutoConfigureMode;
}
Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// Check the protocol type.
//
Field = &Fields[RP_FIELD_IDX_PROTOCOL];
if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Get the port of the iSCSI target.
//
Field = &Fields[RP_FIELD_IDX_PORT];
if (Field->Str != NULL) {
ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
} else {
ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
}
//
// Get the LUN.
//
Field = &Fields[RP_FIELD_IDX_LUN];
if (Field->Str != NULL) {
Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
} else {
ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
}
//
// Get the target iSCSI Name.
//
Field = &Fields[RP_FIELD_IDX_TARGETNAME];
if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Validate the iSCSI name.
//
Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
AsciiStrCpy (ConfigNvData->TargetName, Field->Str);
ON_EXIT:
FreePool (TmpStr);
return Status;
}
/**
The callback function registerd to the DHCP4 instance that is used to select
the qualified DHCP OFFER.
@param[in] This The DHCP4 protocol.
@param[in] Context The context set when configuring the DHCP4 protocol.
@param[in] CurrentState The current state of the DHCP4 protocol.
@param[in] Dhcp4Event The event occurs in the current state.
@param[in] Packet The DHCP packet that is to be sent or was already received.
@param[out] NewPacket The packet used to replace the above Packet.
@retval EFI_SUCCESS Either the DHCP OFFER is qualified or we're not intereseted
in the Dhcp4Event.
@retval EFI_NOT_READY The DHCP OFFER packet doesn't match our requirements.
@retval Others Other errors as indicated.
**/
EFI_STATUS
EFIAPI
IScsiDhcpSelectOffer (
IN EFI_DHCP4_PROTOCOL *This,
IN VOID *Context,
IN EFI_DHCP4_STATE CurrentState,
IN EFI_DHCP4_EVENT Dhcp4Event,
IN EFI_DHCP4_PACKET *Packet, OPTIONAL
OUT EFI_DHCP4_PACKET **NewPacket OPTIONAL
)
{
EFI_STATUS Status;
UINT32 OptionCount;
EFI_DHCP4_PACKET_OPTION **OptionList;
UINT32 Index;
if ((Dhcp4Event != Dhcp4RcvdOffer) && (Dhcp4Event != Dhcp4SelectOffer)) {
return EFI_SUCCESS;
}
OptionCount = 0;
Status = This->Parse (This, Packet, &OptionCount, NULL);
if (Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_READY;
}
OptionList = AllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
if (OptionList == NULL) {
return EFI_NOT_READY;
}
Status = This->Parse (This, Packet, &OptionCount, OptionList);
if (EFI_ERROR (Status)) {
FreePool (OptionList);
return EFI_NOT_READY;
}
for (Index = 0; Index < OptionCount; Index++) {
if (OptionList[Index]->OpCode != DHCP4_TAG_ROOT_PATH) {
continue;
}
Status = IScsiDhcpExtractRootPath (
(CHAR8 *) &OptionList[Index]->Data[0],
OptionList[Index]->Length,
(ISCSI_ATTEMPT_CONFIG_NVDATA *) Context
);
break;
}
if ((Index == OptionCount)) {
Status = EFI_NOT_READY;
}
FreePool (OptionList);
return Status;
}
/**
Parse the DHCP ACK to get the address configuration and DNS information.
@param[in] Dhcp4 The DHCP4 protocol.
@param[in, out] ConfigData The session configuration data.
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
@retval EFI_NO_MAPPING DHCP failed to acquire address and other information.
@retval EFI_INVALID_PARAMETER The DHCP ACK's DNS option is malformatted.
@retval EFI_DEVICE_ERROR Other errors as indicated.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
EFI_STATUS
IScsiParseDhcpAck (
IN EFI_DHCP4_PROTOCOL *Dhcp4,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
)
{
EFI_STATUS Status;
EFI_DHCP4_MODE_DATA Dhcp4ModeData;
UINT32 OptionCount;
EFI_DHCP4_PACKET_OPTION **OptionList;
UINT32 Index;
ISCSI_SESSION_CONFIG_NVDATA *NvData;
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
if (EFI_ERROR (Status)) {
return Status;
}
if (Dhcp4ModeData.State != Dhcp4Bound) {
return EFI_NO_MAPPING;
}
NvData = &ConfigData->SessionConfigData;
CopyMem (&NvData->LocalIp, &Dhcp4ModeData.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&NvData->SubnetMask, &Dhcp4ModeData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&NvData->Gateway, &Dhcp4ModeData.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
OptionCount = 0;
OptionList = NULL;
Status = Dhcp4->Parse (Dhcp4, Dhcp4ModeData.ReplyPacket, &OptionCount, OptionList);
if (Status != EFI_BUFFER_TOO_SMALL) {
return EFI_DEVICE_ERROR;
}
OptionList = AllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
if (OptionList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = Dhcp4->Parse (Dhcp4, Dhcp4ModeData.ReplyPacket, &OptionCount, OptionList);
if (EFI_ERROR (Status)) {
FreePool (OptionList);
return EFI_DEVICE_ERROR;
}
for (Index = 0; Index < OptionCount; Index++) {
//
// Get DNS server addresses and DHCP server address from this offer.
//
if (OptionList[Index]->OpCode == DHCP4_TAG_DNS) {
if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {
Status = EFI_INVALID_PARAMETER;
break;
}
//
// Primary DNS server address.
//
CopyMem (&ConfigData->PrimaryDns, &OptionList[Index]->Data[0], sizeof (EFI_IPv4_ADDRESS));
if (OptionList[Index]->Length > 4) {
//
// Secondary DNS server address.
//
CopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[4], sizeof (EFI_IPv4_ADDRESS));
}
} else if (OptionList[Index]->OpCode == DHCP4_TAG_SERVER_ID) {
if (OptionList[Index]->Length != 4) {
Status = EFI_INVALID_PARAMETER;
break;
}
CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[0], sizeof (EFI_IPv4_ADDRESS));
}
}
FreePool (OptionList);
return Status;
}
/**
Parse the DHCP ACK to get the address configuration and DNS information.
@param[in] Image The handle of the driver image.
@param[in] Controller The handle of the controller.
@param[in, out] ConfigData The attempt configuration data.
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_NO_MEDIA There was a media error.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiDoDhcp (
IN EFI_HANDLE Image,
IN EFI_HANDLE Controller,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
)
{
EFI_HANDLE Dhcp4Handle;
EFI_DHCP4_PROTOCOL *Dhcp4;
EFI_STATUS Status;
EFI_DHCP4_PACKET_OPTION *ParaList;
EFI_DHCP4_CONFIG_DATA Dhcp4ConfigData;
ISCSI_SESSION_CONFIG_NVDATA *NvData;
BOOLEAN MediaPresent;
Dhcp4Handle = NULL;
Dhcp4 = NULL;
ParaList = NULL;
//
// Check media status before doing DHCP.
//
MediaPresent = TRUE;
NetLibDetectMedia (Controller, &MediaPresent);
if (!MediaPresent) {
return EFI_NO_MEDIA;
}
//
// Create a DHCP4 child instance and get the protocol.
//
Status = NetLibCreateServiceChild (
Controller,
Image,
&gEfiDhcp4ServiceBindingProtocolGuid,
&Dhcp4Handle
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->OpenProtocol (
Dhcp4Handle,
&gEfiDhcp4ProtocolGuid,
(VOID **) &Dhcp4,
Image,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
NvData = &ConfigData->SessionConfigData;
ParaList = AllocatePool (sizeof (EFI_DHCP4_PACKET_OPTION) + 3);
if (ParaList == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
//
// Ask the server to reply with Netmask, Router, DNS, and RootPath options.
//
ParaList->OpCode = DHCP4_TAG_PARA_LIST;
ParaList->Length = (UINT8) (NvData->TargetInfoFromDhcp ? 4 : 3);
ParaList->Data[0] = DHCP4_TAG_NETMASK;
ParaList->Data[1] = DHCP4_TAG_ROUTER;
ParaList->Data[2] = DHCP4_TAG_DNS;
ParaList->Data[3] = DHCP4_TAG_ROOT_PATH;
ZeroMem (&Dhcp4ConfigData, sizeof (EFI_DHCP4_CONFIG_DATA));
Dhcp4ConfigData.OptionCount = 1;
Dhcp4ConfigData.OptionList = &ParaList;
if (NvData->TargetInfoFromDhcp) {
//
// Use callback to select an offer that contains target information.
//
Dhcp4ConfigData.Dhcp4Callback = IScsiDhcpSelectOffer;
Dhcp4ConfigData.CallbackContext = ConfigData;
}
Status = Dhcp4->Configure (Dhcp4, &Dhcp4ConfigData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
Status = Dhcp4->Start (Dhcp4, NULL);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// Parse the ACK to get required information.
//
Status = IScsiParseDhcpAck (Dhcp4, ConfigData);
ON_EXIT:
if (ParaList != NULL) {
FreePool (ParaList);
}
if (Dhcp4 != NULL) {
Dhcp4->Stop (Dhcp4);
Dhcp4->Configure (Dhcp4, NULL);
gBS->CloseProtocol (
Dhcp4Handle,
&gEfiDhcp4ProtocolGuid,
Image,
Controller
);
}
NetLibDestroyServiceChild (
Controller,
Image,
&gEfiDhcp4ServiceBindingProtocolGuid,
Dhcp4Handle
);
return Status;
}

View File

@ -0,0 +1,62 @@
/** @file
The head file of iSCSI DHCP4 related configuration routines.
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_DHCP_H_
#define _ISCSI_DHCP_H_
#define DHCP4_TAG_PARA_LIST 55
#define DHCP4_TAG_NETMASK 1
#define DHCP4_TAG_ROUTER 3
#define DHCP4_TAG_DNS 6
#define DHCP4_TAG_SERVER_ID 54
#define DHCP4_TAG_ROOT_PATH 17
#define ISCSI_ROOT_PATH_ID "iscsi:"
#define ISCSI_ROOT_PATH_FIELD_DELIMITER ':'
#define RP_FIELD_IDX_SERVERNAME 0
#define RP_FIELD_IDX_PROTOCOL 1
#define RP_FIELD_IDX_PORT 2
#define RP_FIELD_IDX_LUN 3
#define RP_FIELD_IDX_TARGETNAME 4
#define RP_FIELD_IDX_MAX 5
typedef struct _ISCSI_ATTEMPT_CONFIG_NVDATA ISCSI_ATTEMPT_CONFIG_NVDATA;
typedef struct _ISCSI_ROOT_PATH_FIELD {
CHAR8 *Str;
UINT8 Len;
} ISCSI_ROOT_PATH_FIELD;
/**
Parse the DHCP ACK to get the address configuration and DNS information.
@param[in] Image The handle of the driver image.
@param[in] Controller The handle of the controller.
@param[in, out] ConfigData The attempt configuration data.
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_NO_MEDIA There was a media error.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiDoDhcp (
IN EFI_HANDLE Image,
IN EFI_HANDLE Controller,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
);
#endif

View File

@ -0,0 +1,505 @@
/** @file
iSCSI DHCP6 related configuration routines.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
/**
Extract the Root Path option and get the required target information from
Boot File Uniform Resource Locator (URL) Option.
@param[in] RootPath The RootPath string.
@param[in] Length Length of the RootPath option payload.
@param[in, out] ConfigData The iSCSI session configuration data read from
nonvolatile device.
@retval EFI_SUCCESS All required information is extracted from the
RootPath option.
@retval EFI_NOT_FOUND The RootPath is not an iSCSI RootPath.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_INVALID_PARAMETER The RootPath is malformatted.
**/
EFI_STATUS
IScsiDhcp6ExtractRootPath (
IN CHAR8 *RootPath,
IN UINT16 Length,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
)
{
EFI_STATUS Status;
UINT16 IScsiRootPathIdLen;
CHAR8 *TmpStr;
ISCSI_ROOT_PATH_FIELD Fields[RP_FIELD_IDX_MAX];
ISCSI_ROOT_PATH_FIELD *Field;
UINT32 FieldIndex;
UINT8 Index;
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
EFI_IP_ADDRESS Ip;
UINT8 IpMode;
ConfigNvData = &ConfigData->SessionConfigData;
//
// "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
//
IScsiRootPathIdLen = (UINT16) AsciiStrLen (ISCSI_ROOT_PATH_ID);
if ((Length <= IScsiRootPathIdLen) ||
(CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
return EFI_NOT_FOUND;
}
//
// Skip the iSCSI RootPath ID "iscsi:".
//
RootPath = RootPath + IScsiRootPathIdLen;
Length = (UINT16) (Length - IScsiRootPathIdLen);
TmpStr = (CHAR8 *) AllocatePool (Length + 1);
if (TmpStr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (TmpStr, RootPath, Length);
TmpStr[Length] = '\0';
Index = 0;
FieldIndex = 0;
ZeroMem (&Fields[0], sizeof (Fields));
//
// Extract SERVERNAME field in the Root Path option.
//
if (TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_START_DELIMITER) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
} else {
Index++;
}
Fields[RP_FIELD_IDX_SERVERNAME].Str = &TmpStr[Index];
while ((TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_END_DELIMITER) && (Index < Length)) {
Index++;
}
//
// Skip ']' and ':'.
//
TmpStr[Index] = '\0';
Index += 2;
Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8) AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);
//
// Extract others fields in the Root Path option string.
//
for (FieldIndex = 1; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {
if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
Fields[FieldIndex].Str = &TmpStr[Index];
}
while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
Index++;
}
if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
if (FieldIndex != RP_FIELD_IDX_TARGETNAME) {
TmpStr[Index] = '\0';
Index++;
}
if (Fields[FieldIndex].Str != NULL) {
Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
}
}
}
if (FieldIndex != RP_FIELD_IDX_MAX) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
(Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||
(Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)
) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Get the IP address of the target.
//
Field = &Fields[RP_FIELD_IDX_SERVERNAME];
if (ConfigNvData->IpMode < IP_MODE_AUTOCONFIG) {
IpMode = ConfigNvData->IpMode;
} else {
IpMode = ConfigData->AutoConfigureMode;
}
Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// Check the protocol type.
//
Field = &Fields[RP_FIELD_IDX_PROTOCOL];
if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Get the port of the iSCSI target.
//
Field = &Fields[RP_FIELD_IDX_PORT];
if (Field->Str != NULL) {
ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
} else {
ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
}
//
// Get the LUN.
//
Field = &Fields[RP_FIELD_IDX_LUN];
if (Field->Str != NULL) {
Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
} else {
ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
}
//
// Get the target iSCSI Name.
//
Field = &Fields[RP_FIELD_IDX_TARGETNAME];
if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
//
// Validate the iSCSI name.
//
Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
AsciiStrCpy (ConfigNvData->TargetName, Field->Str);
ON_EXIT:
FreePool (TmpStr);
return Status;
}
/**
EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol
instance to intercept events that occurs in the DHCPv6 Information Request
exchange process.
@param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that
is used to configure this callback function.
@param[in] Context Pointer to the context that is initialized in
the EFI_DHCP6_PROTOCOL.InfoRequest().
@param[in] Packet Pointer to Reply packet that has been received.
The EFI DHCPv6 Protocol instance is responsible
for freeing the buffer.
@retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to finish
Information Request exchange process.
@retval EFI_NOT_READY Tell the EFI DHCPv6 Protocol instance to continue
Information Request exchange process.
@retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort
the Information Request exchange process.
@retval EFI_UNSUPPORTED Tell the EFI DHCPv6 Protocol instance to finish
the Information Request exchange process because some
request information are not received.
**/
EFI_STATUS
EFIAPI
IScsiDhcp6ParseReply (
IN EFI_DHCP6_PROTOCOL *This,
IN VOID *Context,
IN EFI_DHCP6_PACKET *Packet
)
{
EFI_STATUS Status;
UINT32 Index;
UINT32 OptionCount;
EFI_DHCP6_PACKET_OPTION *BootFileOpt;
EFI_DHCP6_PACKET_OPTION **OptionList;
ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;
OptionCount = 0;
BootFileOpt = NULL;
Status = This->Parse (This, Packet, &OptionCount, NULL);
if (Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_READY;
}
OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *));
if (OptionList == NULL) {
return EFI_NOT_READY;
}
Status = This->Parse (This, Packet, &OptionCount, OptionList);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_READY;
goto Exit;
}
ConfigData = (ISCSI_ATTEMPT_CONFIG_NVDATA *) Context;
for (Index = 0; Index < OptionCount; Index++) {
OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode);
OptionList[Index]->OpLen = NTOHS (OptionList[Index]->OpLen);
//
// Get DNS server addresses from this reply packet.
//
if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {
if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
//
// Primary DNS server address.
//
CopyMem (&ConfigData->PrimaryDns, &OptionList[Index]->Data[0], sizeof (EFI_IPv6_ADDRESS));
if (OptionList[Index]->OpLen > 16) {
//
// Secondary DNS server address
//
CopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[16], sizeof (EFI_IPv6_ADDRESS));
}
} else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_URL) {
//
// The server sends this option to inform the client about an URL to a boot file.
//
BootFileOpt = OptionList[Index];
}
}
if (BootFileOpt == NULL) {
Status = EFI_UNSUPPORTED;
goto Exit;
}
//
// Get iSCSI root path from Boot File Uniform Resource Locator (URL) Option
//
Status = IScsiDhcp6ExtractRootPath (
(CHAR8 *) BootFileOpt->Data,
BootFileOpt->OpLen,
ConfigData
);
Exit:
FreePool (OptionList);
return Status;
}
/**
Parse the DHCP ACK to get the address configuration and DNS information.
@param[in] Image The handle of the driver image.
@param[in] Controller The handle of the controller;
@param[in, out] ConfigData The attempt configuration data.
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
@retval EFI_NO_MAPPING DHCP failed to acquire address and other
information.
@retval EFI_INVALID_PARAMETER The DHCP ACK's DNS option is malformatted.
@retval EFI_DEVICE_ERROR Some unexpected error occurred.
@retval EFI_OUT_OF_RESOURCES There is no sufficient resource to finish the
operation.
@retval EFI_NO_MEDIA There was a media error.
**/
EFI_STATUS
IScsiDoDhcp6 (
IN EFI_HANDLE Image,
IN EFI_HANDLE Controller,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
)
{
EFI_HANDLE Dhcp6Handle;
EFI_DHCP6_PROTOCOL *Dhcp6;
EFI_STATUS Status;
EFI_STATUS TimerStatus;
EFI_DHCP6_PACKET_OPTION *Oro;
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;
EFI_EVENT Timer;
BOOLEAN MediaPresent;
//
// Check media status before doing DHCP.
//
MediaPresent = TRUE;
NetLibDetectMedia (Controller, &MediaPresent);
if (!MediaPresent) {
return EFI_NO_MEDIA;
}
//
// iSCSI will only request target info from DHCPv6 server.
//
if (!ConfigData->SessionConfigData.TargetInfoFromDhcp) {
return EFI_SUCCESS;
}
Dhcp6Handle = NULL;
Dhcp6 = NULL;
Oro = NULL;
Timer = NULL;
//
// Create a DHCP6 child instance and get the protocol.
//
Status = NetLibCreateServiceChild (
Controller,
Image,
&gEfiDhcp6ServiceBindingProtocolGuid,
&Dhcp6Handle
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->OpenProtocol (
Dhcp6Handle,
&gEfiDhcp6ProtocolGuid,
(VOID **) &Dhcp6,
Image,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);
if (Oro == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
//
// Ask the server to reply with DNS and Boot File URL options by info request.
// All members in EFI_DHCP6_PACKET_OPTION are in network order.
//
Oro->OpCode = HTONS (DHCP6_OPT_REQUEST_OPTION);
Oro->OpLen = HTONS (2 * 2);
Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;
Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;
InfoReqReXmit.Irt = 4;
InfoReqReXmit.Mrc = 1;
InfoReqReXmit.Mrt = 10;
InfoReqReXmit.Mrd = 30;
Status = Dhcp6->InfoRequest (
Dhcp6,
TRUE,
Oro,
0,
NULL,
&InfoReqReXmit,
NULL,
IScsiDhcp6ParseReply,
ConfigData
);
if (Status == EFI_NO_MAPPING) {
Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
Status = gBS->SetTimer (
Timer,
TimerRelative,
ISCSI_GET_MAPPING_TIMEOUT
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
do {
TimerStatus = gBS->CheckEvent (Timer);
if (!EFI_ERROR (TimerStatus)) {
Status = Dhcp6->InfoRequest (
Dhcp6,
TRUE,
Oro,
0,
NULL,
&InfoReqReXmit,
NULL,
IScsiDhcp6ParseReply,
ConfigData
);
}
} while (TimerStatus == EFI_NOT_READY);
}
ON_EXIT:
if (Oro != NULL) {
FreePool (Oro);
}
if (Timer != NULL) {
gBS->CloseEvent (Timer);
}
if (Dhcp6 != NULL) {
gBS->CloseProtocol (
Dhcp6Handle,
&gEfiDhcp6ProtocolGuid,
Image,
Controller
);
}
NetLibDestroyServiceChild (
Controller,
Image,
&gEfiDhcp6ServiceBindingProtocolGuid,
Dhcp6Handle
);
return Status;
}

View File

@ -0,0 +1,79 @@
/** @file
The header file of iSCSI DHCP6 related configuration routines.
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_DHCP6_H_
#define _ISCSI_DHCP6_H_
#define DHCP6_OPT_REQUEST_OPTION 6
#define DHCP6_OPT_VENDOR_INFO 17
#define DHCP6_OPT_DNS_SERVERS 23
///
/// Assigned by IANA, RFC 5970
///
#define DHCP6_OPT_BOOT_FILE_URL 59
#define ISCSI_ROOT_PATH_ID "iscsi:"
#define ISCSI_ROOT_PATH_FIELD_DELIMITER ':'
#define ISCSI_ROOT_PATH_ADDR_START_DELIMITER '['
#define ISCSI_ROOT_PATH_ADDR_END_DELIMITER ']'
/**
Extract the Root Path option and get the required target information from
Boot File Uniform Resource Locator (URL) Option.
@param[in] RootPath The RootPath string.
@param[in] Length Length of the RootPath option payload.
@param[in, out] ConfigData The iSCSI session configuration data read from
nonvolatile device.
@retval EFI_SUCCESS All required information is extracted from the
RootPath option.
@retval EFI_NOT_FOUND The RootPath is not an iSCSI RootPath.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@retval EFI_INVALID_PARAMETER The RootPath is malformatted.
**/
EFI_STATUS
IScsiDhcp6ExtractRootPath (
IN CHAR8 *RootPath,
IN UINT16 Length,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
);
/**
Parse the DHCP ACK to get the address configuration and DNS information.
@param[in] Image The handle of the driver image.
@param[in] Controller The handle of the controller;
@param[in, out] ConfigData The attempt configuration data.
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
@retval EFI_NO_MAPPING DHCP failed to acquire address and other
information.
@retval EFI_INVALID_PARAMETER The DHCP ACK's DNS option is malformatted.
@retval EFI_DEVICE_ERROR Some unexpected error happened.
@retval EFI_OUT_OF_RESOURCES There is no sufficient resource to finish the
operation.
@retval EFI_NO_MEDIA There was a media error.
**/
EFI_STATUS
IScsiDoDhcp6 (
IN EFI_HANDLE Image,
IN EFI_HANDLE Controller,
IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,678 @@
/** @file
The header file of IScsiDriver.c.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_DRIVER_H_
#define _ISCSI_DRIVER_H_
#define ISCSI_V4_PRIVATE_GUID \
{ \
0xfa3cde4c, 0x87c2, 0x427d, { 0xae, 0xde, 0x7d, 0xd0, 0x96, 0xc8, 0x8c, 0x58 } \
}
#define ISCSI_V6_PRIVATE_GUID \
{ \
0x28be27e5, 0x66cc, 0x4a31, { 0xa3, 0x15, 0xdb, 0x14, 0xc3, 0x74, 0x4d, 0x85 } \
}
#define ISCSI_INITIATOR_NAME_VAR_NAME L"I_NAME"
#define IP_MODE_AUTOCONFIG_IP4 3
#define IP_MODE_AUTOCONFIG_IP6 4
#define IP_MODE_AUTOCONFIG_SUCCESS 5
extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName;
extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName;
extern EFI_AUTHENTICATION_INFO_PROTOCOL gIScsiAuthenticationInfo;
extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate;
typedef struct {
CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE];
LIST_ENTRY NicInfoList;
UINT8 NicCount;
UINT8 CurrentNic;
UINT8 MaxNic;
BOOLEAN Ipv6Flag;
BOOLEAN OneSessionEstablished;
BOOLEAN EnableMpio;
UINT8 MpioCount; // The number of attempts in MPIO.
UINT8 Krb5MpioCount; // The number of attempts login with KRB5 in MPIO.
UINT8 SinglePathCount; // The number of single path attempts.
UINT8 ValidSinglePathCount; // The number of valid single path attempts.
UINT8 BootSelectedIndex;
UINT8 AttemptCount;
LIST_ENTRY AttemptConfigs; // User configured Attempt list.
CHAR8 InitiatorName[ISCSI_NAME_MAX_SIZE];
UINTN InitiatorNameLength;
} ISCSI_PRIVATE_DATA;
extern ISCSI_PRIVATE_DATA *mPrivate;
typedef struct {
LIST_ENTRY Link;
UINT32 HwAddressSize;
EFI_MAC_ADDRESS PermanentAddress;
UINT8 NicIndex;
UINT16 VlanId;
UINTN BusNumber;
UINTN DeviceNumber;
UINTN FunctionNumber;
} ISCSI_NIC_INFO;
typedef struct _ISCSI_PRIVATE_PROTOCOL {
UINT32 Reserved;
} ISCSI_PRIVATE_PROTOCOL;
//
// EFI Driver Binding Protocol for iSCSI driver.
//
/**
Tests to see if this driver supports a given controller. If a child device is provided,
it tests to see if this driver supports creating a handle for the specified child device.
This function checks to see if the driver specified by This supports the device specified by
ControllerHandle. Drivers typically use the device path attached to
ControllerHandle and/or the services from the bus I/O abstraction attached to
ControllerHandle to determine if the driver supports ControllerHandle. This function
may be called many times during platform initialization. In order to reduce boot times, the tests
performed by this function must be very small and take as little time as possible to execute. This
function must not change the state of any hardware devices, and this function must be aware that the
device specified by ControllerHandle may already be managed by the same driver or a
different driver. This function must match its calls to AllocatePages() with FreePages(),
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
Since ControllerHandle may have been previously started by the same driver, if a protocol is
already in the opened state, then it must not be closed with CloseProtocol(). This is required
to guarantee the state of ControllerHandle is not modified by this function.
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
@param[in] ControllerHandle The handle of the controller to test. This handle
must support a protocol interface that supplies
an I/O abstraction to the driver.
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
parameter is ignored by device drivers, and is optional for bus
drivers. For bus drivers, if this parameter is not NULL, then
the bus driver must determine if the bus controller specified
by ControllerHandle and the child controller specified
by RemainingDevicePath are both supported by this
bus driver.
@retval EFI_SUCCESS The device specified by ControllerHandle and
RemainingDevicePath is supported by the driver specified by This.
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
RemainingDevicePath is already managed by the driver
specified by This.
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
RemainingDevicePath is already managed by a different
driver or an application that requires exclusive access.
Currently not implemented.
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
IScsiDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
/**
Starts a device controller or a bus controller.
The Start() function is designed to be invoked from the EFI boot service ConnectController().
As a result, much of the error checking on the parameters to Start() has been moved into this
common boot service. It is legal to call Start() from other locations,
but the following calling restrictions must be followed or the system behavior will not be deterministic.
1. ControllerHandle must be a valid EFI_HANDLE.
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
EFI_DEVICE_PATH_PROTOCOL.
3. Prior to calling Start(), the Supported() function for the driver specified by This must
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
@param[in] ControllerHandle The handle of the controller to start. This handle
must support a protocol interface that supplies
an I/O abstraction to the driver.
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
parameter is ignored by device drivers, and is optional for bus
drivers. For a bus driver, if this parameter is NULL, then handles
for all the children of Controller are created by this driver.
If this parameter is not NULL and the first Device Path Node is
not the End of Device Path Node, then only the handle for the
child device specified by the first Device Path Node of
RemainingDevicePath is created by this driver.
If the first Device Path Node of RemainingDevicePath is
the End of Device Path Node, no child handle is created by this
driver.
@retval EFI_SUCCESS The device was started.
@retval EFI_DEVICE_ERROR The device could not be started due to a device error. Currently not implemented.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
@retval Others The driver failed to start the device.
**/
EFI_STATUS
EFIAPI
IScsiDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
/**
Stops a device controller or a bus controller.
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
As a result, much of the error checking on the parameters to Stop() has been moved
into this common boot service. It is legal to call Stop() from other locations,
but the following calling restrictions must be followed or the system behavior will not be deterministic.
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
same driver's Start() function.
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
Start() function, and the Start() function must have called OpenProtocol() on
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
@param[in] ControllerHandle A handle to the device being stopped. The handle must
support a bus specific I/O protocol for the driver
to use to stop the device.
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
if NumberOfChildren is 0.
@retval EFI_SUCCESS The device was stopped.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
**/
EFI_STATUS
EFIAPI
IScsiDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
);
//
// EFI Component Name(2) Protocol for iSCSI driver.
//
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param[out] DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
IScsiComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] ControllerHandle The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param[in] ChildHandle The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is
determined by the driver writer. Language is
specified inRFC 4646 or ISO 639-2 language code
format.
@param[out] ControllerName A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
IScsiComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
//
// EFI iSCSI Initiator Name Protocol for iSCSI driver.
//
/**
Retrieves the current set value of iSCSI Initiator Name.
@param[in] This Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL
instance.
@param[in, out] BufferSize Size of the buffer in bytes pointed to by Buffer /
Actual size of the variable data buffer.
@param[out] Buffer Pointer to the buffer for data to be read.
@retval EFI_SUCCESS Data was successfully retrieved into the provided
buffer and the BufferSize was sufficient to handle
the iSCSI initiator name.
@retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the result. BufferSize
will be updated with the size required to complete
the request. Buffer will not be affected.
@retval EFI_INVALID_PARAMETER BufferSize is NULL. BufferSize and Buffer will not
be affected.
@retval EFI_INVALID_PARAMETER Buffer is NULL. BufferSize and Buffer will not be
affected.
@retval EFI_DEVICE_ERROR The iSCSI initiator name could not be retrieved
due to a hardware error.
**/
EFI_STATUS
EFIAPI
IScsiGetInitiatorName (
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
);
/**
Sets the iSSI Initiator Name.
@param[in] This Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL
instance.
@param[in, out] BufferSize Size of the buffer in bytes pointed to by Buffer.
@param[in] Buffer Pointer to the buffer for data to be written.
@retval EFI_SUCCESS Data was successfully stored by the protocol.
@retval EFI_UNSUPPORTED Platform policies do not allow for data to be
written.
@retval EFI_INVALID_PARAMETER BufferSize exceeds the maximum allowed limit.
BufferSize will be updated with the maximum size
required to complete the request.
@retval EFI_INVALID_PARAMETER Buffersize is NULL. BufferSize and Buffer will not
be affected.
@retval EFI_INVALID_PARAMETER Buffer is NULL. BufferSize and Buffer will not be
affected.
@retval EFI_DEVICE_ERROR The data could not be stored due to a hardware
error.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the data
@retval EFI_PROTOCOL_ERROR Input iSCSI initiator name does not adhere to RFC
3720
**/
EFI_STATUS
EFIAPI
IScsiSetInitiatorName (
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
);
//
// EFI_AUTHENTICATION_INFO_PROTOCOL for iSCSI driver.
//
/**
Retrieves the authentication information associated with a particular controller handle.
@param[in] This Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL.
@param[in] ControllerHandle Handle to the Controller.
@param[out] Buffer Pointer to the authentication information. This function is
responsible for allocating the buffer and it is the caller's
responsibility to free buffer when the caller is finished with buffer.
@retval EFI_DEVICE_ERROR The authentication information could not be
retrieved due to a hardware error.
**/
EFI_STATUS
EFIAPI
IScsiGetAuthenticationInfo (
IN EFI_AUTHENTICATION_INFO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
OUT VOID **Buffer
);
/**
Set the authentication information for a given controller handle.
@param[in] This Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL.
@param[in] ControllerHandle Handle to the Controller.
@param[in] Buffer Pointer to the authentication information.
@retval EFI_UNSUPPORTED If the platform policies do not allow setting of
the authentication information.
**/
EFI_STATUS
EFIAPI
IScsiSetAuthenticationInfo (
IN EFI_AUTHENTICATION_INFO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN VOID *Buffer
);
//
// EFI_EXT_SCSI_PASS_THRU_PROTOCOL for iSCSI driver.
//
/**
Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel.
This function supports both blocking I/O and nonblocking I/O. The blocking I/O
functionality is required, and the nonblocking I/O functionality is optional.
@param[in] This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
@param[in] Target The Target is an array of size TARGET_MAX_BYTES and it
represents the id of the SCSI device to send the SCSI
Request Packet. Each transport driver may choose to
utilize a subset of this size to suit the needs
of transport target representation. For example, a
Fibre Channel driver may use only 8 bytes (WWN)
to represent an FC target.
@param[in] Lun The LUN of the SCSI device to send the SCSI Request Packet.
@param[in, out] Packet A pointer to the SCSI Request Packet to send to the
SCSI device specified by Target and Lun.
@param[in] Event If nonblocking I/O is not supported then Event is ignored,
and blocking I/O is performed. If Event is NULL, then
blocking I/O is performed. If Event is not NULL and non
blocking I/O is supported, then nonblocking I/O is performed,
and Event will be signaled when the SCSI Request Packet
completes.
@retval EFI_SUCCESS The SCSI Request Packet was sent by the host. For
bi-directional commands, InTransferLength bytes
were transferred from InDataBuffer.
For write and bi-directional commands, OutTransferLength
bytes were transferred by OutDataBuffer.
@retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was not executed.
The number of bytes that could be transferred is
returned in InTransferLength. For write and
bi-directional commands, OutTransferLength bytes
were transferred by OutDataBuffer.
@retval EFI_NOT_READY The SCSI Request Packet could not be sent because
there are too many SCSI Request Packets already
queued. The caller may retry later.
@retval EFI_DEVICE_ERROR A device error occurred while attempting to send
the SCSI Request Packet.
@retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket
are invalid.
@retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
is not supported by the host adapter.
This includes the case of Bi-directional SCSI
commands not supported by the implementation.
The SCSI Request Packet was not sent,
so no additional status information is available.
@retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
Request Packet to execute.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruFunction (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun,
IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
IN EFI_EVENT Event OPTIONAL
);
/**
Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on
a SCSI channel. These can either be the list SCSI devices that are actually
present on the SCSI channel, or the list of legal Target Ids and LUNs for the
SCSI channel. Regardless, the caller of this function must probe the Target ID
and LUN returned to see if a SCSI device is actually present at that location
on the SCSI channel.
@param[in] This The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
@param[in, out] Target On input, a pointer to the Target ID of a SCSI
device present on the SCSI channel. On output, a
pointer to the Target ID of the next SCSI device
present on a SCSI channel. An input value of
0xFFFFFFFF retrieves the Target ID of the first
SCSI device present on a SCSI channel.
@param[in, out] Lun On input, a pointer to the LUN of a SCSI device
present on the SCSI channel. On output, a pointer
to the LUN of the next SCSI device present on a
SCSI channel.
@retval EFI_SUCCESS The Target ID and Lun of the next SCSI device on
the SCSI channel was returned in Target and Lun.
@retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI
channel.
@retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF,and Target and Lun were
not returned on a previous call to
GetNextDevice().
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetNextTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN OUT UINT8 **Target,
IN OUT UINT64 *Lun
);
/**
Allocate and build a device path node for a SCSI device on a SCSI channel.
@param[in] This Protocol instance pointer.
@param[in] Target The Target ID of the SCSI device for which a
device path node is to be allocated and built.
@param[in] Lun The LUN of the SCSI device for which a device
path node is to be allocated and built.
@param[in, out] DevicePath A pointer to a single device path node that
describes the SCSI device specified by Target and
Lun. This function is responsible for allocating
the buffer DevicePath with the boot service
AllocatePool(). It is the caller's
responsibility to free DevicePath when the caller
is finished with DevicePath.
@retval EFI_SUCCESS The device path node that describes the SCSI
device specified by Target and Lun was allocated
and returned in DevicePath.
@retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does
not exist on the SCSI channel.
@retval EFI_INVALID_PARAMETER DevicePath is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate
DevicePath.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruBuildDevicePath (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
);
/**
Translate a device path node to a Target ID and LUN.
@param[in] This Protocol instance pointer.
@param[in] DevicePath A pointer to the device path node that describes
a SCSI device on the SCSI channel.
@param[out] Target A pointer to the Target ID of a SCSI device on
the SCSI channel.
@param[out] Lun A pointer to the LUN of a SCSI device on the SCSI
channel.
@retval EFI_SUCCESS DevicePath was successfully translated to a
Target ID and LUN, and they were returned in
Target and Lun.
@retval EFI_INVALID_PARAMETER DevicePath/Target/Lun is NULL.
@retval EFI_UNSUPPORTED This driver does not support the device path node
type in DevicePath.
@retval EFI_NOT_FOUND A valid translation from DevicePath to a Target
ID and LUN does not exist.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT UINT8 **Target,
OUT UINT64 *Lun
);
/**
Resets a SCSI channel.This operation resets all the SCSI devices connected to
the SCSI channel.
@param[in] This Protocol instance pointer.
@retval EFI_UNSUPPORTED It is not supported.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruResetChannel (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
);
/**
Resets a SCSI device that is connected to a SCSI channel.
@param[in] This Protocol instance pointer.
@param[in] Target The Target ID of the SCSI device to reset.
@param[in] Lun The LUN of the SCSI device to reset.
@retval EFI_UNSUPPORTED It is not supported.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruResetTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun
);
/**
Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.
@param[in] This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL
instance.
@param[in, out] Target (TARGET_MAX_BYTES) of a SCSI device present on
the SCSI channel. On output, a pointer to the
Target ID (an array of TARGET_MAX_BYTES) of the
next SCSI device present on a SCSI channel.
An input value of 0xF(all bytes in the array are 0xF)
in the Target array retrieves the Target ID of the
first SCSI device present on a SCSI channel.
@retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI
channel was returned in Target.
@retval EFI_INVALID_PARAMETER Target or Lun is NULL.
@retval EFI_TIMEOUT Target array is not all 0xF, and Target was not
returned on a previous call to GetNextTarget().
@retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetNextTarget (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN OUT UINT8 **Target
);
#endif

View File

@ -0,0 +1,106 @@
## @file
# Component description file for IScsi module.
#
# Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = IScsiDxe
FILE_GUID = 86CDDF93-4872-4597-8AF9-A35AE4D3725F
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = IScsiDriverEntryPoint
UNLOAD_IMAGE = IScsiUnload
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF
#
# DRIVER_BINDING = gIScsiDriverBinding
# COMPONENT_NAME = gIScsiComponentName
# COMPONENT_NAME2 = gIScsiComponentName2
#
[Sources]
ComponentName.c
IScsiAuthenticationInfo.c
IScsiCHAP.h
IScsiCHAP.c
IScsiConfig.c
IScsiConfig.h
IScsiConfigNVDataStruc.h
IScsiConfigStrings.uni
IScsiConfigVfr.vfr
IScsiDhcp.c
IScsiDhcp.h
IScsiDhcp6.c
IScsiDhcp6.h
IScsiDriver.c
IScsiDriver.h
IScsiExtScsiPassThru.c
IScsiIbft.c
IScsiIbft.h
IScsiInitiatorName.c
IScsiImpl.h
IScsiMisc.c
IScsiMisc.h
IScsiProto.c
IScsiProto.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
DevicePathLib
HiiLib
MemoryAllocationLib
NetLib
TcpIoLib
PrintLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
UefiRuntimeServicesTableLib
UefiHiiServicesLib
BaseCryptLib
[Protocols]
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDriverBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiPciIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDhcp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDhcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDhcp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiTcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiTcp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiTcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiTcp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiExtScsiPassThruProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiConfigAccessProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiIScsiInitiatorNameProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiAuthenticationInfoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[Guids]
gEfiEventExitBootServicesGuid
gEfiIfrTianoGuid ## CONSUMES ## GUID
gEfiAcpiTableGuid ## CONSUMES ## GUID
gEfiAcpi10TableGuid ## CONSUMES ## GUID
gEfiAcpi20TableGuid ## CONSUMES ## GUID

View File

@ -0,0 +1,409 @@
/** @file
The implementation of EFI_EXT_SCSI_PASS_THRU_PROTOCOL.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate = {
NULL,
IScsiExtScsiPassThruFunction,
IScsiExtScsiPassThruGetNextTargetLun,
IScsiExtScsiPassThruBuildDevicePath,
IScsiExtScsiPassThruGetTargetLun,
IScsiExtScsiPassThruResetChannel,
IScsiExtScsiPassThruResetTargetLun,
IScsiExtScsiPassThruGetNextTarget
};
/**
Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel.
This function supports both blocking I/O and nonblocking I/O. The blocking I/O
functionality is required, and the nonblocking I/O functionality is optional.
@param[in] This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
@param[in] Target The Target is an array of size TARGET_MAX_BYTES and it
represents the id of the SCSI device to send the SCSI
Request Packet. Each transport driver may choose to
utilize a subset of this size to suit the needs
of transport target representation. For example, a
Fibre Channel driver may use only 8 bytes (WWN)
to represent an FC target.
@param[in] Lun The LUN of the SCSI device to send the SCSI Request Packet.
@param[in, out] Packet A pointer to the SCSI Request Packet to send to the
SCSI device specified by Target and Lun.
@param[in] Event If nonblocking I/O is not supported then Event is ignored,
and blocking I/O is performed. If Event is NULL, then
blocking I/O is performed. If Event is not NULL and non
blocking I/O is supported, then nonblocking I/O is performed,
and Event will be signaled when the SCSI Request Packet
completes.
@retval EFI_SUCCESS The SCSI Request Packet was sent by the host. For
bi-directional commands, InTransferLength bytes
were transferred from InDataBuffer.
For write and bi-directional commands, OutTransferLength
bytes were transferred by OutDataBuffer.
@retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was not executed.
The number of bytes that could be transferred is
returned in InTransferLength. For write and
bi-directional commands, OutTransferLength bytes
were transferred by OutDataBuffer.
@retval EFI_NOT_READY The SCSI Request Packet could not be sent because
there are too many SCSI Request Packets already
queued. The caller may retry later.
@retval EFI_DEVICE_ERROR A device error occurred while attempting to send
the SCSI Request Packet.
@retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket,
are invalid.
@retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
is not supported by the host adapter.
This includes the case of Bi-directional SCSI
commands not supported by the implementation.
The SCSI Request Packet was not sent,
so no additional status information is available.
@retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
Request Packet to execute.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruFunction (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun,
IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
IN EFI_EVENT Event OPTIONAL
)
{
if (Target[0] != 0) {
return EFI_INVALID_PARAMETER;
}
if ((Packet == NULL) || (Packet->Cdb == NULL)) {
return EFI_INVALID_PARAMETER;
}
return IScsiExecuteScsiCommand (This, Target, Lun, Packet);
}
/**
Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on
a SCSI channel. These can either be the list SCSI devices that are actually
present on the SCSI channel, or the list of legal Target Ids and LUNs for the
SCSI channel. Regardless, the caller of this function must probe the Target ID
and LUN returned to see if a SCSI device is actually present at that location
on the SCSI channel.
@param[in] This The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
@param[in, out] Target On input, a pointer to the Target ID of a SCSI
device present on the SCSI channel. On output, a
pointer to the Target ID of the next SCSI device
present on a SCSI channel. An input value of
0xFFFFFFFF retrieves the Target ID of the first
SCSI device present on a SCSI channel.
@param[in, out] Lun On input, a pointer to the LUN of a SCSI device
present on the SCSI channel. On output, a pointer
to the LUN of the next SCSI device present on a
SCSI channel.
@retval EFI_SUCCESS The Target ID and Lun of the next SCSI device on
the SCSI channel was returned in Target and Lun.
@retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI
channel.
@retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF,and Target and Lun were
not returned on a previous call to
GetNextDevice().
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetNextTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN OUT UINT8 **Target,
IN OUT UINT64 *Lun
)
{
ISCSI_DRIVER_DATA *Private;
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
UINT8 TargetId[TARGET_MAX_BYTES];
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
ConfigNvData = &Private->Session->ConfigData->SessionConfigData;
if ((*Target)[0] == 0 && (CompareMem (Lun, ConfigNvData->BootLun, sizeof (UINT64)) == 0)) {
//
// Only one <Target, Lun> pair per iSCSI Driver instance.
//
return EFI_NOT_FOUND;
}
SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
if (CompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {
(*Target)[0] = 0;
CopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));
return EFI_SUCCESS;
}
return EFI_INVALID_PARAMETER;
}
/**
Allocate and build a device path node for a SCSI device on a SCSI channel.
@param[in] This Protocol instance pointer.
@param[in] Target The Target ID of the SCSI device for which a
device path node is to be allocated and built.
@param[in] Lun The LUN of the SCSI device for which a device
path node is to be allocated and built.
@param[in, out] DevicePath A pointer to a single device path node that
describes the SCSI device specified by Target and
Lun. This function is responsible for allocating
the buffer DevicePath with the boot service
AllocatePool(). It is the caller's
responsibility to free DevicePath when the caller
is finished with DevicePath.
@retval EFI_SUCCESS The device path node that describes the SCSI
device specified by Target and Lun was allocated
and returned in DevicePath.
@retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does
not exist on the SCSI channel.
@retval EFI_INVALID_PARAMETER DevicePath is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate
DevicePath.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruBuildDevicePath (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
)
{
ISCSI_DRIVER_DATA *Private;
ISCSI_SESSION *Session;
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
EFI_DEV_PATH *Node;
UINTN DevPathNodeLen;
if ((DevicePath == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (Target[0] != 0) {
return EFI_NOT_FOUND;
}
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
Session = Private->Session;
ConfigNvData = &Session->ConfigData->SessionConfigData;
AuthConfig = Session->AuthData.CHAP.AuthConfig;
if (CompareMem (&Lun, ConfigNvData->BootLun, sizeof (UINT64)) != 0) {
return EFI_NOT_FOUND;
}
DevPathNodeLen = sizeof (ISCSI_DEVICE_PATH) + AsciiStrLen (ConfigNvData->TargetName) + 1;
Node = AllocateZeroPool (DevPathNodeLen);
if (Node == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Node->DevPath.Type = MESSAGING_DEVICE_PATH;
Node->DevPath.SubType = MSG_ISCSI_DP;
SetDevicePathNodeLength (&Node->DevPath, DevPathNodeLen);
//
// 0 for TCP, others are reserved.
//
Node->Iscsi.NetworkProtocol = 0;
Node->Iscsi.LoginOption = 0;
switch (Session->AuthType) {
case ISCSI_AUTH_TYPE_NONE:
Node->Iscsi.LoginOption |= 0x0800;
break;
case ISCSI_AUTH_TYPE_CHAP:
//
// Bit12: 0=CHAP_BI, 1=CHAP_UNI
//
if (AuthConfig->CHAPType == ISCSI_CHAP_UNI) {
Node->Iscsi.LoginOption |= 0x1000;
}
break;
default:
break;
}
CopyMem (&Node->Iscsi.Lun, ConfigNvData->BootLun, sizeof (UINT64));
Node->Iscsi.TargetPortalGroupTag = Session->TargetPortalGroupTag;
AsciiStrCpy ((CHAR8 *) Node + sizeof (ISCSI_DEVICE_PATH), ConfigNvData->TargetName);
*DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;
return EFI_SUCCESS;
}
/**
Translate a device path node to a Target ID and LUN.
@param[in] This Protocol instance pointer.
@param[in] DevicePath A pointer to the device path node that describes
a SCSI device on the SCSI channel.
@param[out] Target A pointer to the Target ID of a SCSI device on
the SCSI channel.
@param[out] Lun A pointer to the LUN of a SCSI device on the SCSI
channel.
@retval EFI_SUCCESS DevicePath was successfully translated to a
Target ID and LUN, and they were returned in
Target and Lun.
@retval EFI_INVALID_PARAMETER DevicePath/Target/Lun is NULL.
@retval EFI_UNSUPPORTED This driver does not support the device path node
type in DevicePath.
@retval EFI_NOT_FOUND A valid translation does not exist from DevicePath
to a TargetID and LUN.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT UINT8 **Target,
OUT UINT64 *Lun
)
{
ISCSI_DRIVER_DATA *Private;
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
(DevicePath->SubType != MSG_ISCSI_DP) ||
(DevicePathNodeLength (DevicePath) <= sizeof (ISCSI_DEVICE_PATH))
) {
return EFI_UNSUPPORTED;
}
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
ConfigNvData = &Private->Session->ConfigData->SessionConfigData;
SetMem (*Target, TARGET_MAX_BYTES, 0xFF);
(*Target)[0] = 0;
if (AsciiStrCmp (ConfigNvData->TargetName, (CHAR8 *) DevicePath + sizeof (ISCSI_DEVICE_PATH)) != 0) {
return EFI_UNSUPPORTED;
}
CopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));
return EFI_SUCCESS;
}
/**
Resets a SCSI channel. This operation resets all the SCSI devices connected to
the SCSI channel.
@param[in] This Protocol instance pointer.
@retval EFI_UNSUPPORTED It is not supported.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruResetChannel (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
)
{
return EFI_UNSUPPORTED;
}
/**
Resets a SCSI device that is connected to a SCSI channel.
@param[in] This Protocol instance pointer.
@param[in] Target The Target ID of the SCSI device to reset.
@param[in] Lun The LUN of the SCSI device to reset.
@retval EFI_UNSUPPORTED It is not supported.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruResetTargetLun (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN UINT8 *Target,
IN UINT64 Lun
)
{
return EFI_UNSUPPORTED;
}
/**
Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.
@param[in] This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL
instance.
@param[in, out] Target (TARGET_MAX_BYTES) of a SCSI device present on
the SCSI channel. On output, a pointer to the
Target ID (an array of TARGET_MAX_BYTES) of the
next SCSI device present on a SCSI channel.
An input value of 0xF(all bytes in the array are 0xF)
in the Target array retrieves the Target ID of the
first SCSI device present on a SCSI channel.
@retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI
channel was returned in Target.
@retval EFI_INVALID_PARAMETER Target or Lun is NULL.
@retval EFI_TIMEOUT Target array is not all 0xF, and Target was not
returned on a previous call to GetNextTarget().
@retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetNextTarget (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
IN OUT UINT8 **Target
)
{
UINT8 TargetId[TARGET_MAX_BYTES];
SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
if (CompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {
(*Target)[0] = 0;
return EFI_SUCCESS;
} else if ((*Target)[0] == 0) {
return EFI_NOT_FOUND;
} else {
return EFI_INVALID_PARAMETER;
}
}

View File

@ -0,0 +1,546 @@
/** @file
Implementation for iSCSI Boot Firmware Table publication.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
BOOLEAN mIbftInstalled = FALSE;
UINTN mTableKey;
/**
Initialize the header of the iSCSI Boot Firmware Table.
@param[out] Header The header of the iSCSI Boot Firmware Table.
@param[in] OemId The OEM ID.
@param[in] OemTableId The OEM table ID for the iBFT.
**/
VOID
IScsiInitIbfTableHeader (
OUT EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header,
IN UINT8 *OemId,
IN UINT64 *OemTableId
)
{
Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;
Header->Length = IBFT_HEAP_OFFSET;
Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;
Header->Checksum = 0;
CopyMem (Header->OemId, OemId, sizeof (Header->OemId));
CopyMem (&Header->OemTableId, OemTableId, sizeof (UINT64));
}
/**
Initialize the control section of the iSCSI Boot Firmware Table.
@param[in] Table The ACPI table.
**/
VOID
IScsiInitControlSection (
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table
)
{
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
UINTN NumOffset;
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;
Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;
Control->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);
//
// If in multipathing mode, enable the Boot Failover Flag.
// If in single path mode, disable it. Mix-model is not allowed.
//
// BUGBUG: if Boot Failover Flag is set to 1, the OS installer cannot
// find the iSCSI mapped disk. So still keep not set for single path mode.
//
if (mPrivate->EnableMpio) {
Control->Header.Flags = 0;
NumOffset = 2 * (mPrivate->MpioCount - mPrivate->Krb5MpioCount);
} else {
NumOffset = 2 * mPrivate->ValidSinglePathCount;
}
//
// Each attempt occupies two offsets: one for the NIC section;
// the other for the Target section.
//
if (NumOffset > 4) {
//
// Need expand the control section if more than 2 NIC/Target attempts
// exist.
//
Control->Header.Length = (UINT16) (Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));
}
}
/**
Add one item into the heap.
@param[in, out] Heap On input, the current address of the heap. On output, the address of
the heap after the item is added.
@param[in] Data The data to add into the heap.
@param[in] Len Length of the Data in byte.
**/
VOID
IScsiAddHeapItem (
IN OUT UINT8 **Heap,
IN VOID *Data,
IN UINTN Len
)
{
//
// Add one byte for the NULL delimiter.
//
*Heap -= Len + 1;
CopyMem (*Heap, Data, Len);
*(*Heap + Len) = 0;
}
/**
Fill the Initiator section of the iSCSI Boot Firmware Table.
@param[in] Table The ACPI table.
@param[in, out] Heap The heap.
**/
VOID
IScsiFillInitiatorSection (
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
IN OUT UINT8 **Heap
)
{
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
//
// Initiator section immediately follows the control section.
//
Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *)
((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));
Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);
Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;
Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;
Initiator->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);
Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID |
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED;
//
// Fill the iSCSI Initiator Name into the heap.
//
IScsiAddHeapItem (Heap, mPrivate->InitiatorName, mPrivate->InitiatorNameLength - 1);
Initiator->IScsiNameLength = (UINT16) (mPrivate->InitiatorNameLength - 1);
Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
}
/**
Map the v4 IP address into v6 IP address.
@param[in] V4 The v4 IP address.
@param[out] V6 The v6 IP address.
**/
VOID
IScsiMapV4ToV6Addr (
IN EFI_IPv4_ADDRESS *V4,
OUT EFI_IPv6_ADDRESS *V6
)
{
UINTN Index;
ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));
V6->Addr[10] = 0xff;
V6->Addr[11] = 0xff;
for (Index = 0; Index < 4; Index++) {
V6->Addr[12 + Index] = V4->Addr[Index];
}
}
/**
Fill the NIC and target sections in iSCSI Boot Firmware Table.
@param[in] Table The buffer of the ACPI table.
@param[in, out] Heap The heap buffer used to store the variable length
parameters such as iSCSI name.
**/
VOID
IScsiFillNICAndTargetSections (
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
IN OUT UINT8 **Heap
)
{
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;
ISCSI_SESSION_CONFIG_NVDATA *NvData;
ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
UINT16 *SectionOffset;
UINTN Index;
UINT16 Length;
LIST_ENTRY *Entry;
ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;
ISCSI_NIC_INFO *NicInfo;
BOOLEAN Flag;
//
// Get the offset of the first Nic and Target section.
//
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +
Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));
Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
SectionOffset = &Control->NIC0Offset;
Index = 0;
Flag = TRUE;
NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
if (Index == 0) {
//
// First entry should be boot selected entry.
//
Attempt = IScsiConfigGetAttemptByConfigIndex (mPrivate->BootSelectedIndex);
if (Attempt == NULL) {
//
// First boot selected entry can not be found.
//
break;
}
ASSERT (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED);
} else {
if (Index == 1 && Flag) {
Entry = mPrivate->AttemptConfigs.ForwardLink;
Flag = FALSE;
}
Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
if (Attempt->AttemptConfigIndex == mPrivate->BootSelectedIndex) {
continue;
}
}
if (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED) {
continue;
}
//
// Krb5 attempt will not be recorded in iBFT.
//
if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {
continue;
}
//
// If multipath mode is enabled, only the attempts in MPIO will be recorded in iBFT.
//
if (mPrivate->EnableMpio && Attempt->SessionConfigData.Enabled != ISCSI_ENABLED_FOR_MPIO) {
continue;
}
//
// Only the valid attempts will be recorded.
//
if (!Attempt->ValidiBFTPath) {
continue;
}
NvData = &Attempt->SessionConfigData;
AuthConfig = &Attempt->AuthConfigData.CHAP;
//
// Fill the Nic section.
//
Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;
Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;
Nic->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);
Nic->Header.Index = (UINT8) Index;
Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;
if (Index == 0) {
Nic->Header.Flags |= EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED;
}
if (NvData->InitiatorInfoFromDhcp) {
Nic->Origin = IpPrefixOriginDhcp;
} else {
Nic->Origin = IpPrefixOriginManual;
}
if (NvData->IpMode == IP_MODE_IP4 || NvData->IpMode == IP_MODE_AUTOCONFIG) {
//
// Get the subnet mask prefix length.
//
Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&NvData->SubnetMask);
//
// Map the various v4 addresses into v6 addresses.
//
IScsiMapV4ToV6Addr (&NvData->LocalIp, &Nic->Ip);
IScsiMapV4ToV6Addr (&NvData->Gateway, &Nic->Gateway);
IScsiMapV4ToV6Addr (&Attempt->PrimaryDns.v4, &Nic->PrimaryDns);
IScsiMapV4ToV6Addr (&Attempt->SecondaryDns.v4, &Nic->SecondaryDns);
IScsiMapV4ToV6Addr (&Attempt->DhcpServer.v4, &Nic->DhcpServer);
} else if (NvData->IpMode == IP_MODE_IP6 || NvData->IpMode == IP_MODE_AUTOCONFIG) {
//
// TODO: The subnet mask/local ip/gateway/dhcpserver for iBFT-IPv6 needs to be
// confirmed with spec owner.
//
CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS));
CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS));
//
// TODO: DHCP server address cannot be retrieved by DHCPv6 process since
// DHCP server option is removed.
//CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
//
} else {
ASSERT (FALSE);
}
//
// Get Nic Info: VLAN tag, Mac address, PCI location.
//
NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);
ASSERT (NicInfo != NULL);
Nic->VLanTag = NicInfo->VlanId;
CopyMem (Nic->Mac, &NicInfo->PermanentAddress, sizeof (Nic->Mac));
Nic->PciLocation = (UINT16) ((NicInfo->BusNumber << 8) |
(NicInfo->DeviceNumber << 3) | NicInfo->FunctionNumber);
*SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);
SectionOffset++;
//
// Fill the Target section.
//
Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;
Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;
Target->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);
Target->Header.Index = (UINT8) Index;
Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID;
if (Index == 0) {
Target->Header.Flags |= EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;
}
Target->Port = NvData->TargetPort;
if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
Target->CHAPType = AuthConfig->CHAPType;
} else if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_NONE) {
Target->CHAPType = ISCSI_AUTH_TYPE_NONE;
}
Target->NicIndex = (UINT8) Index;
if (NvData->IpMode == IP_MODE_IP4 || NvData->IpMode == IP_MODE_AUTOCONFIG) {
IScsiMapV4ToV6Addr (&NvData->TargetIp.v4, &Target->Ip);
} else if (NvData->IpMode == IP_MODE_IP6 || NvData->IpMode == IP_MODE_AUTOCONFIG) {
CopyMem (&Target->Ip, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));
} else {
ASSERT (FALSE);
}
CopyMem (Target->BootLun, NvData->BootLun, sizeof (Target->BootLun));
//
// Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.
//
Length = (UINT16) AsciiStrLen (NvData->TargetName);
IScsiAddHeapItem (Heap, NvData->TargetName, Length);
Target->IScsiNameLength = Length;
Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
//
// CHAP Name
//
Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);
IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);
Target->CHAPNameLength = Length;
Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
//
// CHAP Secret
//
Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);
IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);
Target->CHAPSecretLength = Length;
Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {
//
// Reverse CHAP Name.
//
Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);
IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);
Target->ReverseCHAPNameLength = Length;
Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
//
// Reverse CHAP Secret.
//
Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);
IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);
Target->ReverseCHAPSecretLength = Length;
Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
}
}
*SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);
SectionOffset++;
//
// Advance to the next NIC/Target pair.
//
Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));
Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
Index++;
}
}
/**
Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
session status.
**/
VOID
IScsiPublishIbft (
IN VOID
)
{
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;
EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
UINT8 *Heap;
UINT8 Checksum;
UINTN Index;
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
if (EFI_ERROR (Status)) {
return ;
}
//
// Find ACPI table RSD_PTR from the system table.
//
for (Index = 0, Rsdp = NULL; Index < gST->NumberOfTableEntries; Index++) {
if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) ||
CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid) ||
CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpiTableGuid)
) {
//
// A match was found.
//
Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) gST->ConfigurationTable[Index].VendorTable;
break;
}
}
if (Rsdp == NULL) {
return ;
} else {
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
}
if (mIbftInstalled) {
Status = AcpiTableProtocol->UninstallAcpiTable (
AcpiTableProtocol,
mTableKey
);
if (EFI_ERROR (Status)) {
return ;
}
mIbftInstalled = FALSE;
}
//
// If there is no valid attempt configuration, just return.
//
if ((!mPrivate->EnableMpio && mPrivate->ValidSinglePathCount == 0) ||
(mPrivate->EnableMpio && mPrivate->MpioCount <= mPrivate->Krb5MpioCount)) {
return ;
}
//
// Allocate 4k bytes to hold the ACPI table.
//
Table = AllocateZeroPool (IBFT_MAX_SIZE);
if (Table == NULL) {
return ;
}
Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;
//
// Fill in the various section of the iSCSI Boot Firmware Table.
//
IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);
IScsiInitControlSection (Table);
IScsiFillInitiatorSection (Table, &Heap);
IScsiFillNICAndTargetSections (Table, &Heap);
Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);
Table->Checksum = Checksum;
//
// Install or update the iBFT table.
//
Status = AcpiTableProtocol->InstallAcpiTable (
AcpiTableProtocol,
Table,
Table->Length,
&mTableKey
);
if (EFI_ERROR(Status)) {
return;
}
mIbftInstalled = TRUE;
FreePool (Table);
}

View File

@ -0,0 +1,39 @@
/** @file
Some extra definitions for iBFT.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_IBFT_H_
#define _ISCSI_IBFT_H_
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/IScsiBootFirmwareTable.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/PciIo.h>
#define IBFT_TABLE_VAR_NAME L"iBFT"
#define IBFT_MAX_SIZE 4096
#define IBFT_HEAP_OFFSET 2048
#define IBFT_ROUNDUP(size) NET_ROUNDUP ((size), EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_STRUCTURE_ALIGNMENT)
/**
Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
session status.
**/
VOID
IScsiPublishIbft (
IN VOID
);
#endif

View File

@ -0,0 +1,197 @@
/** @file
The shared head file for iSCSI driver.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_IMPL_H_
#define _ISCSI_IMPL_H_
#include <Uefi.h>
#include <Protocol/ComponentName.h>
#include <Protocol/ComponentName2.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DevicePath.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/Dhcp4.h>
#include <Protocol/Dhcp6.h>
#include <Protocol/Tcp4.h>
#include <Protocol/Tcp6.h>
#include <Protocol/AuthenticationInfo.h>
#include <Protocol/IScsiInitiatorName.h>
#include <Protocol/ScsiPassThruExt.h>
#include <Library/HiiLib.h>
#include <Library/UefiHiiServicesLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/DpcLib.h>
#include <Library/NetLib.h>
#include <Library/TcpIoLib.h>
#include <Library/BaseCryptLib.h>
#include <Guid/MdeModuleHii.h>
#include <Guid/EventGroup.h>
#include <Guid/Acpi.h>
#include "IScsiConfigNVDataStruc.h"
#include "IScsiDriver.h"
#include "IScsiProto.h"
#include "IScsiCHAP.h"
#include "IScsiDhcp.h"
#include "IScsiDhcp6.h"
#include "IScsiIbft.h"
#include "IScsiMisc.h"
#include "IScsiConfig.h"
#define ISCSI_AUTH_INITIAL 0
#define ISCSI_SESSION_SIGNATURE SIGNATURE_32 ('I', 'S', 'S', 'N')
///
/// 10 seconds
///
#define ISCSI_GET_MAPPING_TIMEOUT 100000000U
///
/// 3 seconds
///
#define ISCSI_WAIT_IPSEC_TIMEOUT 30000000U
struct _ISCSI_SESSION {
UINT32 Signature;
ISCSI_DRIVER_DATA *Private;
ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;
UINT8 AuthType;
union {
ISCSI_CHAP_AUTH_DATA CHAP;
} AuthData;
UINT8 State;
UINT8 Isid[6];
UINT16 Tsih;
UINT32 CmdSN;
UINT32 ExpCmdSN;
UINT32 MaxCmdSN;
UINT32 InitiatorTaskTag;
UINT16 NextCid;
LIST_ENTRY Conns;
UINT32 NumConns;
LIST_ENTRY TcbList;
//
// Session-wide parameters
//
UINT16 TargetPortalGroupTag;
UINT32 MaxConnections;
BOOLEAN InitialR2T;
BOOLEAN ImmediateData;
UINT32 MaxBurstLength;
UINT32 FirstBurstLength;
UINT32 DefaultTime2Wait;
UINT32 DefaultTime2Retain;
UINT16 MaxOutstandingR2T;
BOOLEAN DataPDUInOrder;
BOOLEAN DataSequenceInOrder;
UINT8 ErrorRecoveryLevel;
};
#define ISCSI_CONNECTION_SIGNATURE SIGNATURE_32 ('I', 'S', 'C', 'N')
struct _ISCSI_CONNECTION {
UINT32 Signature;
LIST_ENTRY Link;
EFI_EVENT TimeoutEvent;
ISCSI_SESSION *Session;
UINT8 State;
UINT8 CurrentStage;
UINT8 NextStage;
UINT8 AuthStep;
BOOLEAN PartialReqSent;
BOOLEAN PartialRspRcvd;
BOOLEAN TransitInitiated;
BOOLEAN ParamNegotiated;
UINT16 Cid;
UINT32 ExpStatSN;
//
// Queues...
//
NET_BUF_QUEUE RspQue;
BOOLEAN Ipv6Flag;
TCP_IO TcpIo;
//
// Connection-only parameters.
//
UINT32 MaxRecvDataSegmentLength;
ISCSI_DIGEST_TYPE HeaderDigest;
ISCSI_DIGEST_TYPE DataDigest;
};
#define ISCSI_DRIVER_DATA_SIGNATURE SIGNATURE_32 ('I', 'S', 'D', 'A')
#define ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU(PassThru) \
CR ( \
PassThru, \
ISCSI_DRIVER_DATA, \
IScsiExtScsiPassThru, \
ISCSI_DRIVER_DATA_SIGNATURE \
)
#define ISCSI_DRIVER_DATA_FROM_IDENTIFIER(Identifier) \
CR ( \
Identifier, \
ISCSI_DRIVER_DATA, \
IScsiIdentifier, \
ISCSI_DRIVER_DATA_SIGNATURE \
)
struct _ISCSI_DRIVER_DATA {
UINT32 Signature;
EFI_HANDLE Image;
EFI_HANDLE Controller;
ISCSI_PRIVATE_PROTOCOL IScsiIdentifier;
EFI_EVENT ExitBootServiceEvent;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL IScsiExtScsiPassThru;
EFI_EXT_SCSI_PASS_THRU_MODE ExtScsiPassThruMode;
EFI_HANDLE ExtScsiPassThruHandle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_HANDLE ChildHandle;
ISCSI_SESSION *Session;
};
#endif

View File

@ -0,0 +1,136 @@
/** @file
Implementation for EFI iSCSI Initiator Name Protocol.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IScsiImpl.h"
EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName = {
IScsiGetInitiatorName,
IScsiSetInitiatorName
};
/**
Retrieves the current set value of iSCSI Initiator Name.
@param[in] This Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL
instance.
@param[in, out] BufferSize Size of the buffer in bytes pointed to by Buffer /
Actual size of the variable data buffer.
@param[out] Buffer Pointer to the buffer for data to be read.
The data is a null-terminated UTF-8 encoded string.
The maximum length is 223 characters, including the null-terminator.
@retval EFI_SUCCESS Data was successfully retrieved into the provided
buffer and the BufferSize was sufficient to handle
the iSCSI initiator name.
@retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the result. BufferSize
will be updated with the size required to complete
the request. Buffer will not be affected.
@retval EFI_INVALID_PARAMETER BufferSize is NULL. BufferSize and Buffer will not
be affected.
@retval EFI_INVALID_PARAMETER Buffer is NULL. BufferSize and Buffer will not be
affected.
@retval EFI_DEVICE_ERROR The iSCSI initiator name could not be retrieved
due to a hardware error.
**/
EFI_STATUS
EFIAPI
IScsiGetInitiatorName (
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
EFI_STATUS Status;
if ((BufferSize == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
Status = gRT->GetVariable (
ISCSI_INITIATOR_NAME_VAR_NAME,
&gEfiIScsiInitiatorNameProtocolGuid,
NULL,
BufferSize,
Buffer
);
return Status;
}
/**
Sets the iSSI Initiator Name.
@param[in] This Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL
instance.
@param[in, out] BufferSize Size of the buffer in bytes pointed to by Buffer.
@param[in] Buffer Pointer to the buffer for data to be written.
The data is a null-terminated UTF-8 encoded string.
The maximum length is 223 characters, including the null-terminator.
@retval EFI_SUCCESS Data was successfully stored by the protocol.
@retval EFI_UNSUPPORTED Platform policies do not allow for data to be
written.
@retval EFI_INVALID_PARAMETER BufferSize exceeds the maximum allowed limit.
BufferSize will be updated with the maximum size
required to complete the request.
@retval EFI_INVALID_PARAMETER Buffersize is NULL. BufferSize and Buffer will not
be affected.
@retval EFI_INVALID_PARAMETER Buffer is NULL. BufferSize and Buffer will not be
affected.
@retval EFI_DEVICE_ERROR The data could not be stored due to a hardware
error.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the data
@retval EFI_PROTOCOL_ERROR Input iSCSI initiator name does not adhere to RFC
3720
**/
EFI_STATUS
EFIAPI
IScsiSetInitiatorName (
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
if ((BufferSize == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (*BufferSize > ISCSI_NAME_MAX_SIZE) {
*BufferSize = ISCSI_NAME_MAX_SIZE;
return EFI_INVALID_PARAMETER;
}
//
// Only support iqn iSCSI names.
//
Status = IScsiNormalizeName ((CHAR8 *) Buffer, *BufferSize - 1);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gRT->SetVariable (
ISCSI_INITIATOR_NAME_VAR_NAME,
&gEfiIScsiInitiatorNameProtocolGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
*BufferSize,
Buffer
);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,343 @@
/** @file
Miscellaneous definitions for iSCSI driver.
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _ISCSI_MISC_H_
#define _ISCSI_MISC_H_
typedef struct _ISCSI_DRIVER_DATA ISCSI_DRIVER_DATA;
#pragma pack(1)
typedef struct _ISCSI_SESSION_CONFIG_NVDATA {
UINT16 TargetPort;
UINT8 Enabled;
UINT8 IpMode;
EFI_IPv4_ADDRESS LocalIp;
EFI_IPv4_ADDRESS SubnetMask;
EFI_IPv4_ADDRESS Gateway;
BOOLEAN InitiatorInfoFromDhcp;
BOOLEAN TargetInfoFromDhcp;
CHAR8 TargetName[ISCSI_NAME_MAX_SIZE];
EFI_IP_ADDRESS TargetIp;
UINT8 BootLun[8];
UINT16 ConnectTimeout; ///< timout value in milliseconds
UINT8 ConnectRetryCount;
UINT8 IsId[6];
} ISCSI_SESSION_CONFIG_NVDATA;
#pragma pack()
/**
Calculate the prefix length of the IPv4 subnet mask.
@param[in] SubnetMask The IPv4 subnet mask.
@return The prefix length of the subnet mask.
@retval 0 Other errors as indicated.
**/
UINT8
IScsiGetSubnetMaskPrefixLength (
IN EFI_IPv4_ADDRESS *SubnetMask
);
/**
Convert the hexadecimal encoded LUN string into the 64-bit LUN.
@param[in] Str The hexadecimal encoded LUN string.
@param[out] Lun Storage to return the 64-bit LUN.
@retval EFI_SUCCESS The 64-bit LUN is stored in Lun.
@retval EFI_INVALID_PARAMETER The string is malformatted.
**/
EFI_STATUS
IScsiAsciiStrToLun (
IN CHAR8 *Str,
OUT UINT8 *Lun
);
/**
Convert the 64-bit LUN into the hexadecimal encoded LUN string.
@param[in] Lun The 64-bit LUN.
@param[out] String The storage to return the hexadecimal encoded LUN string.
**/
VOID
IScsiLunToUnicodeStr (
IN UINT8 *Lun,
OUT CHAR16 *String
);
/**
Convert the mac address into a hexadecimal encoded "-" seperated string.
@param[in] Mac The mac address.
@param[in] Len Length in bytes of the mac address.
@param[in] VlanId VLAN ID of the network device.
@param[out] Str The storage to return the mac string.
**/
VOID
IScsiMacAddrToStr (
IN EFI_MAC_ADDRESS *Mac,
IN UINT32 Len,
IN UINT16 VlanId,
OUT CHAR16 *Str
);
/**
Convert the formatted IP address into the binary IP address.
@param[in] Str The UNICODE string.
@param[in] IpMode Indicates whether the IP address is v4 or v6.
@param[out] Ip The storage to return the ASCII string.
@retval EFI_SUCCESS The binary IP address is returned in Ip.
@retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is
invalid.
**/
EFI_STATUS
IScsiAsciiStrToIp (
IN CHAR8 *Str,
IN UINT8 IpMode,
OUT EFI_IP_ADDRESS *Ip
);
/**
Convert the binary encoded buffer into a hexadecimal encoded string.
@param[in] BinBuffer The buffer containing the binary data.
@param[in] BinLength Length of the binary buffer.
@param[in, out] HexStr Pointer to the string.
@param[in, out] HexLength The length of the string.
@retval EFI_SUCCESS The binary data is converted to the hexadecimal string
and the length of the string is updated.
@retval EFI_BUFFER_TOO_SMALL The string is too small.
@retval EFI_INVALID_PARAMETER The IP string is malformatted.
**/
EFI_STATUS
IScsiBinToHex (
IN UINT8 *BinBuffer,
IN UINT32 BinLength,
IN OUT CHAR8 *HexStr,
IN OUT UINT32 *HexLength
);
/**
Convert the hexadecimal string into a binary encoded buffer.
@param[in, out] BinBuffer The binary buffer.
@param[in, out] BinLength Length of the binary buffer.
@param[in] HexStr The hexadecimal string.
@retval EFI_SUCCESS The hexadecimal string is converted into a binary
encoded buffer.
@retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.
**/
EFI_STATUS
IScsiHexToBin (
IN OUT UINT8 *BinBuffer,
IN OUT UINT32 *BinLength,
IN CHAR8 *HexStr
);
/**
Convert the decimal-constant string or hex-constant string into a numerical value.
@param[in] Str String in decimal or hex.
@return The numerical value.
**/
UINTN
IScsiNetNtoi (
IN CHAR8 *Str
);
/**
Generate random numbers.
@param[in, out] Rand The buffer to contain random numbers.
@param[in] RandLength The length of the Rand buffer.
**/
VOID
IScsiGenRandom (
IN OUT UINT8 *Rand,
IN UINTN RandLength
);
/**
Record the NIC information in a global structure.
@param[in] Controller The handle of the controller.
@retval EFI_SUCCESS The operation is completed.
@retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this
operation.
**/
EFI_STATUS
IScsiAddNic (
IN EFI_HANDLE Controller
);
/**
Delete the recorded NIC information from a global structure. Also delete corresponding
attempts.
@param[in] Controller The handle of the controller.
@retval EFI_SUCCESS The operation completed.
@retval EFI_NOT_FOUND The NIC information to be deleted is not recorded.
**/
EFI_STATUS
IScsiRemoveNic (
IN EFI_HANDLE Controller
);
/**
Get the recorded NIC information from a global structure by the Index.
@param[in] NicIndex The index indicates the position of NIC info.
@return Pointer to the NIC info or NULL if not found.
**/
ISCSI_NIC_INFO *
IScsiGetNicInfoByIndex (
IN UINT8 NicIndex
);
/**
Get the NIC's PCI location and return it accroding to the composited
format defined in iSCSI Boot Firmware Table.
@param[in] Controller The handle of the controller.
@param[out] Bus The bus number.
@param[out] Device The device number.
@param[out] Function The function number.
@return The composited representation of the NIC PCI location.
**/
UINT16
IScsiGetNICPciLocation (
IN EFI_HANDLE Controller,
OUT UINTN *Bus,
OUT UINTN *Device,
OUT UINTN *Function
);
/**
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. If failure, return NULL.
@param[in] Name String part of EFI variable name.
@param[in] VendorGuid GUID part of EFI variable name.
@param[out] VariableSize Returns the size of the EFI variable that was read.
@return Dynamically allocated memory that contains a copy of the EFI variable.
@return Caller is responsible freeing the buffer.
@retval NULL Variable was not read.
**/
VOID *
IScsiGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
);
/**
Create the iSCSI driver data.
@param[in] Image The handle of the driver image.
@param[in] Controller The handle of the controller.
@return The iSCSI driver data created.
@retval NULL Other errors as indicated.
**/
ISCSI_DRIVER_DATA *
IScsiCreateDriverData (
IN EFI_HANDLE Image,
IN EFI_HANDLE Controller
);
/**
Clean the iSCSI driver data.
@param[in] Private The iSCSI driver data.
**/
VOID
IScsiCleanDriverData (
IN ISCSI_DRIVER_DATA *Private
);
/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
@retval EFI_SUCCESS Obtained the configuration of this instance.
@retval EFI_ABORTED The operation was aborted.
@retval Others Other errors as indicated.
**/
EFI_STATUS
IScsiGetConfigData (
IN ISCSI_DRIVER_DATA *Private
);
/**
Get the device path of the iSCSI tcp connection and update it.
@param[in] Session The iSCSI session data.
@return The updated device path.
@retval NULL Other errors as indicated.
**/
EFI_DEVICE_PATH_PROTOCOL *
IScsiGetTcpConnDevicePath (
IN ISCSI_SESSION *Session
);
/**
Abort the session when the transition from BS to RT is initiated.
@param[in] Event The event signaled.
@param[in] Context The iSCSI driver data.
**/
VOID
EFIAPI
IScsiOnExitBootService (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,7 @@
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
@ -91,8 +92,8 @@
NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
[Components.IA32, Components.X64, Components.IPF]
NetworkPkg/IScsiDxe/IScsiDxe.inf
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
NetworkPkg/Application/Ping6/Ping6.inf
NetworkPkg/Application/IfConfig6/IfConfig6.inf