ibft.c File Reference

iSCSI boot firmware table More...

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <realmode.h>
#include <gpxe/pci.h>
#include <gpxe/acpi.h>
#include <gpxe/in.h>
#include <gpxe/netdevice.h>
#include <gpxe/ethernet.h>
#include <gpxe/dhcp.h>
#include <gpxe/iscsi.h>
#include <gpxe/ibft.h>

Go to the source code of this file.

Defines

#define ibftab   __use_data16 ( ibftab )

Functions

 FILE_LICENCE (BSD2)
struct gpxe_ibft __data16 (ibftab)
 The iBFT used by gPXE.
static void ibft_set_ipaddr (struct ibft_ipaddr *ipaddr, struct in_addr in)
 Fill in an IP address field within iBFT.
static void ibft_set_ipaddr_option (struct ibft_ipaddr *ipaddr, struct setting *setting)
 Fill in an IP address within iBFT from configuration setting.
static const char * ibft_ipaddr (struct ibft_ipaddr *ipaddr)
 Read IP address from iBFT (for debugging).
static int ibft_alloc_string (struct ibft_string_block *strings, struct ibft_string *string, size_t len)
 Allocate a string within iBFT.
static int ibft_set_string (struct ibft_string_block *strings, struct ibft_string *string, const char *data)
 Fill in a string field within iBFT.
static int ibft_set_string_option (struct ibft_string_block *strings, struct ibft_string *string, struct setting *setting)
 Fill in a string field within iBFT from configuration setting.
static const char * ibft_string (struct ibft_string_block *strings, struct ibft_string *string)
 Read string from iBFT (for debugging).
static int ibft_fill_nic (struct ibft_nic *nic, struct ibft_string_block *strings, struct net_device *netdev)
 Fill in NIC portion of iBFT.
static int ibft_fill_initiator (struct ibft_initiator *initiator, struct ibft_string_block *strings)
 Fill in Initiator portion of iBFT.
static int ibft_fill_target_chap (struct ibft_target *target, struct ibft_string_block *strings, struct iscsi_session *iscsi)
 Fill in Target CHAP portion of iBFT.
static int ibft_fill_target_reverse_chap (struct ibft_target *target, struct ibft_string_block *strings, struct iscsi_session *iscsi)
 Fill in Target Reverse CHAP portion of iBFT.
static int ibft_fill_target (struct ibft_target *target, struct ibft_string_block *strings, struct iscsi_session *iscsi)
 Fill in Target portion of iBFT.
int ibft_fill_data (struct net_device *netdev, struct iscsi_session *iscsi)
 Fill in all variable portions of iBFT.


Detailed Description

iSCSI boot firmware table

The information in this file is derived from the document "iSCSI Boot Firmware Table (iBFT)" as published by IBM at

ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf

Definition in file ibft.c.


Define Documentation

#define ibftab   __use_data16 ( ibftab )

Definition at line 56 of file ibft.c.

Referenced by ibft_fill_data().


Function Documentation

FILE_LICENCE ( BSD2   ) 

struct gpxe_ibft __data16 ( ibftab   )  [read]

The iBFT used by gPXE.

static void ibft_set_ipaddr ( struct ibft_ipaddr ipaddr,
struct in_addr  in 
) [static]

Fill in an IP address field within iBFT.

Parameters:
ipaddr IP address field
in IPv4 address

Definition at line 120 of file ibft.c.

References ibft_ipaddr::in, memset(), ibft_ipaddr::ones, and in_addr::s_addr.

Referenced by ibft_fill_target(), and ibft_set_ipaddr_option().

00120                                                                               {
00121         memset ( ipaddr, 0, sizeof ( ipaddr ) );
00122         if ( in.s_addr ) {
00123                 ipaddr->in = in;
00124                 ipaddr->ones = 0xffff;
00125         }
00126 }

static void ibft_set_ipaddr_option ( struct ibft_ipaddr ipaddr,
struct setting setting 
) [static]

Fill in an IP address within iBFT from configuration setting.

Parameters:
ipaddr IP address field
setting Configuration setting
tag DHCP option tag

Definition at line 135 of file ibft.c.

References fetch_ipv4_setting(), ibft_set_ipaddr(), and NULL.

Referenced by ibft_fill_nic().

00136                                                                {
00137         struct in_addr in = { 0 };
00138         fetch_ipv4_setting ( NULL, setting, &in );
00139         ibft_set_ipaddr ( ipaddr, in );
00140 }

static const char* ibft_ipaddr ( struct ibft_ipaddr ipaddr  )  [static]

Read IP address from iBFT (for debugging).

Parameters:
strings iBFT string block descriptor
string String field
Return values:
ipaddr IP address string

Definition at line 149 of file ibft.c.

References ibft_ipaddr::in, and inet_ntoa().

00149                                                                {
00150         return inet_ntoa ( ipaddr->in );
00151 }

static int ibft_alloc_string ( struct ibft_string_block strings,
struct ibft_string string,
size_t  len 
) [static]

Allocate a string within iBFT.

Parameters:
strings iBFT string block descriptor
string String field to fill in
len Length of string to allocate (excluding NUL)
Return values:
rc Return status code

Definition at line 161 of file ibft.c.

References ibft_table::acpi, dest, ENOMEM, acpi_description_header::length, ibft_string_block::offset, and ibft_string_block::table.

Referenced by ibft_set_string(), and ibft_set_string_option().

00162                                                                         {
00163         char *dest;
00164         unsigned int remaining;
00165 
00166         dest = ( ( ( char * ) strings->table ) + strings->offset );
00167         remaining = ( strings->table->acpi.length - strings->offset );
00168         if ( len >= remaining )
00169                 return -ENOMEM;
00170 
00171         string->offset = strings->offset;
00172         string->length = len;
00173         strings->offset += ( len + 1 );
00174         return 0;
00175 }

static int ibft_set_string ( struct ibft_string_block strings,
struct ibft_string string,
const char *  data 
) [static]

Fill in a string field within iBFT.

Parameters:
strings iBFT string block descriptor
string String field
data String to fill in, or NULL
Return values:
rc Return status code

Definition at line 185 of file ibft.c.

References dest, ibft_alloc_string(), strcpy(), strlen(), and ibft_string_block::table.

Referenced by ibft_fill_initiator(), ibft_fill_target(), ibft_fill_target_chap(), and ibft_fill_target_reverse_chap().

00186                                                                             {
00187         char *dest;
00188         int rc;
00189 
00190         if ( ! data )
00191                 return 0;
00192 
00193         if ( ( rc = ibft_alloc_string ( strings, string,
00194                                         strlen ( data ) ) ) != 0 )
00195                 return rc;
00196         dest = ( ( ( char * ) strings->table ) + string->offset );
00197         strcpy ( dest, data );
00198 
00199         return 0;
00200 }

static int ibft_set_string_option ( struct ibft_string_block strings,
struct ibft_string string,
struct setting setting 
) [static]

Fill in a string field within iBFT from configuration setting.

Parameters:
strings iBFT string block descriptor
string String field
setting Configuration setting
Return values:
rc Return status code

Definition at line 210 of file ibft.c.

References dest, fetch_setting_len(), fetch_string_setting(), ibft_alloc_string(), NULL, and ibft_string_block::table.

Referenced by ibft_fill_nic().

00212                                                               {
00213         int len;
00214         char *dest;
00215         int rc;
00216 
00217         len = fetch_setting_len ( NULL, setting );
00218         if ( len < 0 ) {
00219                 string->offset = 0;
00220                 string->length = 0;
00221                 return 0;
00222         }
00223 
00224         if ( ( rc = ibft_alloc_string ( strings, string, len ) ) != 0 )
00225                 return rc;
00226         dest = ( ( ( char * ) strings->table ) + string->offset );
00227         fetch_string_setting ( NULL, setting, dest, ( len + 1 ) );
00228         return 0;
00229 }

static const char* ibft_string ( struct ibft_string_block strings,
struct ibft_string string 
) [static]

Read string from iBFT (for debugging).

Parameters:
strings iBFT string block descriptor
string String field
Return values:
data String content (or "<empty>")

Definition at line 238 of file ibft.c.

References NULL, ibft_string::offset, and ibft_string_block::table.

00239                                                                {
00240         return ( string->offset ?
00241                  ( ( ( char * ) strings->table ) + string->offset ) : NULL );
00242 }

static int ibft_fill_nic ( struct ibft_nic nic,
struct ibft_string_block strings,
struct net_device netdev 
) [static]

Fill in NIC portion of iBFT.

Parameters:
nic NIC portion of iBFT
strings iBFT string block descriptor
netdev Network device
Return values:
rc Return status code

Definition at line 252 of file ibft.c.

References DBG, device::desc, net_device::dev, ibft_nic::dns, ll_protocol::eth_addr, eth_ntoa(), fetch_ipv4_setting(), ibft_nic::gateway, ibft_nic::hostname, ibft_set_ipaddr_option(), ibft_set_string_option(), ibft_nic::ip_address, net_device::ll_addr, net_device::ll_protocol, device_description::location, ibft_nic::mac_address, NULL, ibft_nic::pci_bus_dev_func, in_addr::s_addr, strerror(), and ibft_nic::subnet_mask_prefix.

Referenced by ibft_fill_data().

00254                                                        {
00255         struct ll_protocol *ll_protocol = netdev->ll_protocol;
00256         struct in_addr netmask_addr = { 0 };
00257         unsigned int netmask_count = 0;
00258         int rc;
00259 
00260         /* Extract values from DHCP configuration */
00261         ibft_set_ipaddr_option ( &nic->ip_address, &ip_setting );
00262         DBG ( "iBFT NIC IP = %s\n", ibft_ipaddr ( &nic->ip_address ) );
00263         ibft_set_ipaddr_option ( &nic->gateway, &gateway_setting );
00264         DBG ( "iBFT NIC gateway = %s\n", ibft_ipaddr ( &nic->gateway ) );
00265         ibft_set_ipaddr_option ( &nic->dns[0], &dns_setting );
00266         DBG ( "iBFT NIC DNS = %s\n", ibft_ipaddr ( &nic->dns[0] ) );
00267         if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
00268                                              &hostname_setting ) ) != 0 )
00269                 return rc;
00270         DBG ( "iBFT NIC hostname = %s\n",
00271               ibft_string ( strings, &nic->hostname ) );
00272 
00273         /* Derive subnet mask prefix from subnet mask */
00274         fetch_ipv4_setting ( NULL, &netmask_setting, &netmask_addr );
00275         while ( netmask_addr.s_addr ) {
00276                 if ( netmask_addr.s_addr & 0x1 )
00277                         netmask_count++;
00278                 netmask_addr.s_addr >>= 1;
00279         }
00280         nic->subnet_mask_prefix = netmask_count;
00281         DBG ( "iBFT NIC subnet = /%d\n", nic->subnet_mask_prefix );
00282 
00283         /* Extract values from net-device configuration */
00284         if ( ( rc = ll_protocol->eth_addr ( netdev->ll_addr,
00285                                             nic->mac_address ) ) != 0 ) {
00286                 DBG ( "Could not determine iBFT MAC: %s\n", strerror ( rc ) );
00287                 return rc;
00288         }
00289         DBG ( "iBFT NIC MAC = %s\n", eth_ntoa ( nic->mac_address ) );
00290         nic->pci_bus_dev_func = netdev->dev->desc.location;
00291         DBG ( "iBFT NIC PCI = %04x\n", nic->pci_bus_dev_func );
00292 
00293         return 0;
00294 }

static int ibft_fill_initiator ( struct ibft_initiator initiator,
struct ibft_string_block strings 
) [static]

Fill in Initiator portion of iBFT.

Parameters:
initiator Initiator portion of iBFT
strings iBFT string block descriptor
Return values:
rc Return status code

Definition at line 303 of file ibft.c.

References DBG, ibft_set_string(), ibft_initiator::initiator_name, and iscsi_initiator_iqn().

Referenced by ibft_fill_data().

00304                                                                      {
00305         const char *initiator_iqn = iscsi_initiator_iqn();
00306         int rc;
00307 
00308         if ( ( rc = ibft_set_string ( strings, &initiator->initiator_name,
00309                                       initiator_iqn ) ) != 0 )
00310                 return rc;
00311         DBG ( "iBFT initiator hostname = %s\n",
00312               ibft_string ( strings, &initiator->initiator_name ) );
00313 
00314         return 0;
00315 }

static int ibft_fill_target_chap ( struct ibft_target target,
struct ibft_string_block strings,
struct iscsi_session iscsi 
) [static]

Fill in Target CHAP portion of iBFT.

Parameters:
target Target portion of iBFT
strings iBFT string block descriptor
iscsi iSCSI session
Return values:
rc Return status code

Definition at line 325 of file ibft.c.

References assert, ibft_target::chap_name, ibft_target::chap_secret, ibft_target::chap_type, DBG, IBFT_CHAP_ONE_WAY, ibft_set_string(), iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_STATUS_AUTH_FORWARD_REQUIRED, and iscsi_session::status.

Referenced by ibft_fill_target().

00327                                                                  {
00328         int rc;
00329 
00330         if ( ! ( iscsi->status & ISCSI_STATUS_AUTH_FORWARD_REQUIRED ) )
00331                 return 0;
00332 
00333         assert ( iscsi->initiator_username );
00334         assert ( iscsi->initiator_password );
00335 
00336         target->chap_type = IBFT_CHAP_ONE_WAY;
00337         if ( ( rc = ibft_set_string ( strings, &target->chap_name,
00338                                       iscsi->initiator_username ) ) != 0 )
00339                 return rc;
00340         DBG ( "iBFT target username = %s\n",
00341               ibft_string ( strings, &target->chap_name ) );
00342         if ( ( rc = ibft_set_string ( strings, &target->chap_secret,
00343                                       iscsi->initiator_password ) ) != 0 )
00344                 return rc;
00345         DBG ( "iBFT target password = <redacted>\n" );
00346 
00347         return 0;
00348 }

static int ibft_fill_target_reverse_chap ( struct ibft_target target,
struct ibft_string_block strings,
struct iscsi_session iscsi 
) [static]

Fill in Target Reverse CHAP portion of iBFT.

Parameters:
target Target portion of iBFT
strings iBFT string block descriptor
iscsi iSCSI session
Return values:
rc Return status code

Definition at line 358 of file ibft.c.

References assert, ibft_target::chap_name, ibft_target::chap_type, DBG, IBFT_CHAP_MUTUAL, ibft_set_string(), iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_STATUS_AUTH_REVERSE_REQUIRED, ibft_target::reverse_chap_name, ibft_target::reverse_chap_secret, iscsi_session::status, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by ibft_fill_target().

00360                                                                          {
00361         int rc;
00362 
00363         if ( ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) )
00364                 return 0;
00365 
00366         assert ( iscsi->initiator_username );
00367         assert ( iscsi->initiator_password );
00368         assert ( iscsi->target_username );
00369         assert ( iscsi->target_password );
00370 
00371         target->chap_type = IBFT_CHAP_MUTUAL;
00372         if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_name,
00373                                       iscsi->target_username ) ) != 0 )
00374                 return rc;
00375         DBG ( "iBFT target reverse username = %s\n",
00376               ibft_string ( strings, &target->chap_name ) );
00377         if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_secret,
00378                                       iscsi->target_password ) ) != 0 )
00379                 return rc;
00380         DBG ( "iBFT target reverse password = <redacted>\n" );
00381 
00382         return 0;
00383 }

static int ibft_fill_target ( struct ibft_target target,
struct ibft_string_block strings,
struct iscsi_session iscsi 
) [static]

Fill in Target portion of iBFT.

Parameters:
target Target portion of iBFT
strings iBFT string block descriptor
iscsi iSCSI session
Return values:
rc Return status code

Definition at line 393 of file ibft.c.

References DBG, ibft_fill_target_chap(), ibft_fill_target_reverse_chap(), ibft_set_ipaddr(), ibft_set_string(), ibft_target::ip_address, ntohs, sockaddr_in::sin_addr, sockaddr_in::sin_port, ibft_target::socket, iscsi_session::target_iqn, ibft_target::target_name, and iscsi_session::target_sockaddr.

Referenced by ibft_fill_data().

00395                                                             {
00396         struct sockaddr_in *sin_target =
00397                 ( struct sockaddr_in * ) &iscsi->target_sockaddr;
00398         int rc;
00399 
00400         /* Fill in Target values */
00401         ibft_set_ipaddr ( &target->ip_address, sin_target->sin_addr );
00402         DBG ( "iBFT target IP = %s\n", ibft_ipaddr ( &target->ip_address ) );
00403         target->socket = ntohs ( sin_target->sin_port );
00404         DBG ( "iBFT target port = %d\n", target->socket );
00405         if ( ( rc = ibft_set_string ( strings, &target->target_name,
00406                                       iscsi->target_iqn ) ) != 0 )
00407                 return rc;
00408         DBG ( "iBFT target name = %s\n",
00409               ibft_string ( strings, &target->target_name ) );
00410         if ( ( rc = ibft_fill_target_chap ( target, strings, iscsi ) ) != 0 )
00411                 return rc;
00412         if ( ( rc = ibft_fill_target_reverse_chap ( target, strings,
00413                                                     iscsi ) ) != 0 )
00414                 return rc;
00415 
00416         return 0;
00417 }

int ibft_fill_data ( struct net_device netdev,
struct iscsi_session iscsi 
)

Fill in all variable portions of iBFT.

Parameters:
netdev Network device
initiator_iqn Initiator IQN
st_target Target socket address
target_iqn Target IQN
Return values:
rc Return status code

Definition at line 429 of file ibft.c.

References acpi_fix_checksum(), ibft_fill_initiator(), ibft_fill_nic(), ibft_fill_target(), ibftab, offsetof, and ibft_string_block::table.

Referenced by iscsiboot().

00430                                                    {
00431         struct ibft_string_block strings = {
00432                 .table = &ibftab.table,
00433                 .offset = offsetof ( typeof ( ibftab ), strings ),
00434         };
00435         int rc;
00436 
00437         /* Fill in NIC, Initiator and Target portions */
00438         if ( ( rc = ibft_fill_nic ( &ibftab.nic, &strings, netdev ) ) != 0 )
00439                 return rc;
00440         if ( ( rc = ibft_fill_initiator ( &ibftab.initiator,
00441                                           &strings ) ) != 0 )
00442                 return rc;
00443         if ( ( rc = ibft_fill_target ( &ibftab.target, &strings,
00444                                        iscsi ) ) != 0 )
00445                 return rc;
00446 
00447         /* Update checksum */
00448         acpi_fix_checksum ( &ibftab.table.acpi );
00449 
00450         return 0;
00451 }


Generated on Tue Apr 6 20:01:13 2010 for gPXE by  doxygen 1.5.7.1