#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. | |
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 ibftab __use_data16 ( ibftab ) |
| 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.
| 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.
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).
| strings | iBFT string block descriptor | |
| string | String field |
| ipaddr | IP address string |
Definition at line 149 of file ibft.c.
References ibft_ipaddr::in, and inet_ntoa().
| static int ibft_alloc_string | ( | struct ibft_string_block * | strings, | |
| struct ibft_string * | string, | |||
| size_t | len | |||
| ) | [static] |
Allocate a string within iBFT.
| strings | iBFT string block descriptor | |
| string | String field to fill in | |
| len | Length of string to allocate (excluding NUL) |
| 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.
| strings | iBFT string block descriptor | |
| string | String field | |
| data | String to fill in, or NULL |
| 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.
| 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).
| strings | iBFT string block descriptor | |
| string | String field |
| 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.
| 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.
| initiator | Initiator portion of iBFT | |
| strings | iBFT string block descriptor |
| 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.
| target | Target portion of iBFT | |
| strings | iBFT string block descriptor | |
| iscsi | iSCSI session |
| 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.
| target | Target portion of iBFT | |
| strings | iBFT string block descriptor | |
| iscsi | iSCSI session |
| 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.
| target | Target portion of iBFT | |
| strings | iBFT string block descriptor | |
| iscsi | iSCSI session |
| 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.
| netdev | Network device | |
| initiator_iqn | Initiator IQN | |
| st_target | Target socket address | |
| target_iqn | Target IQN |
| 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 }
1.5.7.1