Compare commits

..

21 Commits
tpl ... asn1fix

Author SHA1 Message Date
4bd064de23 [build] Fix building on older versions of gcc
Older versions of gcc (observed with gcc 4.5.3) require attributes to
be specified on the first declaration of a symbol, and will silently
ignore attributes specified after the initial declaration.  This
causes the ASN.1 OID-identified algorithms to end up misaligned.

Fix by adding __asn1_algorithm to the initial declarations in asn1.h.

Debugged-by: Dentcho Bankov <dbankov@vmware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-08-23 17:52:41 +01:00
ef2c844d01 [efi] Attempt NII initialisation both with and without cable detection
We currently use a heuristic to determine whether or not to request
cable detection in PXE_OPCODE_INITIALIZE, based on the need to work
around a known Emulex driver bug (see commit c0b61ba "[efi] Work
around bugs in Emulex NII driver") and the need to accommodate links
that are legitimately slow to come up (see commit 6324227 "[efi] Skip
cable detection at initialisation where possible").

This heuristic appears to fail with newer Emulex drivers.  Attempt to
support all known drivers (past and present) by first attempting
initialisation with cable detection, then falling back to attempting
initialisation without cable detection.

Reported-by: Kwang Woo Lee <kwleeyh@gmail.com>
Tested-by: Kwang Woo Lee <kwleeyh@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-08-17 14:28:21 +01:00
c63e61df75 [efi] Use device path to locate filesystem from which we were loaded
The file:/ URI syntax may be used to refer to local files on the
filesystem from which the iPXE binary was loaded.  This is currently
implemented by directly using the DeviceHandle recorded in our
EFI_LOADED_IMAGE_PROTOCOL.

This mechanism will fail when a USB-enabled build of iPXE is loaded
from USB storage and subsequently installs its own USB host controller
drivers, since doing so will disconnect and reconnect the existing USB
storage drivers and thereby invalidate the original storage device
handle.

Fix by recording the device path for the loaded image's DeviceHandle
at initialisation time and later using the recorded device path to
locate the appropriate device handle.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-08-03 15:41:30 +01:00
fd47fa8fe1 [efi] Match EDK2 numbering for USB ports
The various USB specifications all use one-based numbering for ports.
This scheme is applied consistently across the various relevant
specifications, covering both port numbers that appear on the wire
(i.e. downstream hub port numbers) and port numbers that exist only
logically (i.e. root hub port numbers).

The UEFI specification is ambiguous about the port numbers as used for
the ParentPortNumber field within a USB_DEVICE_PATH structure.  As of
UEFI specification version 2.8 errata B:

- section 10.3.4.5 just states "USB Parent Port Number" with no
  indication of being zero-based or one-based

- section 17.1.1 notes that for the EFI_USB2_HC_PROTOCOL, references
  to PortNumber parameters are zero-based for root hub ports

- section 17.1.1 also mentions a TranslatorPortNumber used by
  EFI_USB2_HC_PROTOCOL, with no indication of being zero-based or
  one-based

- there are no other mentions of USB port numbering schemes.

Experimentation and inspection of the EDK2 codebase reveals that at
least the EDK2 reference implementation will use zero-based numbering
for both root and non-root hub ports when populating a USB_DEVICE_PATH
structure (though will inconsistently use one-based numbering for the
TranslatorPortNumber parameter).

Use zero-based numbering for both root and non-root hub ports when
constructing a USB_DEVICE_PATH in order to match the behaviour of the
EDK2 implementation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-08-03 15:12:43 +01:00
70b1a641c5 [comboot] Fix stack pointer retrieval after COM32 binary returns
This change fixes the offset used when retrieving the iPXE stack
pointer after a COM32 binary returns.  The iPXE stack pointer is saved
at the top of the available memory then the the top of the stack for
the COM32 binary is set just below it.  However seven more items are
pushed on the COM32 stack before the entry point is invoked so when
the COM32 binary returns the location of the iPXE stack pointer is 28
(and not 24) bytes above the current stack pointer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-27 15:41:46 +01:00
b760523357 [efi] Check the status code from AllocatePool()
According to the latest UEFI specification (Version 2.8 Errata B)
p. 7.2:

  "Buffer: A pointer to a pointer to the allocated buffer if the call
   succeeds; undefined otherwise."

So implementations are obliged neither to return NULL, if the
allocation fails, nor to preserve the contents of the pointer.

Make the logic more reliable by checking the status code from
AllocatePool() instead of checking the returned pointer for NULL

Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-22 12:54:18 +01:00
a08ee6e722 [cmdline] Add "--timeout" parameter to "ifconf" command
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-22 12:44:51 +01:00
145311c62e [intelx] Added PCI_ROM entry for Intel x553/x557-AT and x553 (SFP+) NICs
Signed-off-by: Rob Taglang <rob@taglang.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-22 12:31:26 +01:00
afaf4272b1 [intel] Set INTEL_NO_PHY_RST on i218v
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-22 12:21:49 +01:00
c4d1ae0fcd [intel] Add INTEL_NO_PHY_RST for I218LM
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-22 12:19:04 +01:00
8bc85ec6fa [deflate] Fix typo in comment describing length codes
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 15:59:04 +01:00
8d243e65c3 [build] Fix a GNUism that FreeBSD's sed(1) cannot deal with
At the moment '\s*' is silently interpreted as just 's*', but in the
future it will be an error:

sed: 1: "s/\.o\s*:/_DEPS +=/": RE error: trailing backslash (\)

cf. https://bugs.freebsd.org/229925

Signed-off-by: Tobias Kortkamp <t@tobik.me>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 15:51:19 +01:00
ee2dc525b4 [wpa] Fix erroneous debug message in wpa_derive_ptk
Split debug message since eth_ntoa() uses a static result buffer.

Originally-fixed-by: Michael Bazzinotti <bazz@bazz1.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 15:34:39 +01:00
0de5e60144 [libc] Fix memcmp() to return proper values
Fix memcmp() to return proper standard positive/negative values for
unequal comparisons.  Current implementation is backwards (i.e. the
functions are returning negative when should be positive and
vice-versa).

Currently most consumers of these functions only check the return value
for ==0 or !=0 and so we can safely change the implementation without
breaking things.

However, there is one call that checks the polarity of this function,
and that is prf_sha1() for wireless WPA 4-way handshake.  Due to the
incorrect memcmp() polarity, the WPA handshake creates an incorrect
PTK, and the handshake would fail after step 2.  Undoubtedly, the AP
noticed the supplicant failed the mic check.  This commit fixes that
issue.

Similar to commit 3946aa9 ("[libc] Fix strcmp()/strncmp() to return
proper values").

Signed-off-by: Michael Bazzinotti <bazz@bazz1.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 15:29:18 +01:00
6ec33b8d6c [pcbios] Take alignment into account when checking for available space
Signed-off-by: David Decotigny <ddecotig@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 14:51:32 +01:00
45a0ca6de2 [pcbios] Fix "out of memory" detection when expanding bottom area
This caused iPXE to reject images even when enough memory was
available.

Signed-off-by: David Decotigny <ddecotig@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 14:50:24 +01:00
cede0c5ba1 [libgcc] Change __divmoddi4 from int64 [unknown] to int64_t
Matches the header file libgcc.h and solves

  __divmoddi4.c:3:56: error: unknown type name ‘int64’

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 14:33:32 +01:00
bit
4277942ac0 [build] Fix default target in sdsk image
gensdsk currently creates a syslinux.cfg file that is invalid if the
filename ends in lkrn.  Fix by setting the default target to label($b)
instead of filename($g).

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 14:29:12 +01:00
366206517e [dns] Use all configured DNS servers
When no response is obtained from the first configured DNS server,
fall back to attempting the other configured servers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-15 19:10:30 +01:00
a95a2eafc5 [xfer] Remove address family from definition of a socket opener
All implemented socket openers provide definitions for both IPv4 and
IPv6 using exactly the same opener method.  Simplify the logic by
omitting the address family from the definition.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-15 18:46:58 +01:00
78ca890c35 [sfc] Add PCI ID for Solarflare SFC9120 and Solarflare SFC9140
This patch adds support for 2 Solarflare NICs.

Signed-off-by: LaDerrick H <ipxelist243@lacutt.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-15 12:29:46 +01:00
28 changed files with 279 additions and 135 deletions

View File

@ -856,7 +856,7 @@ define deps_template_parts
@$(MKDIR) -p $(BIN)/deps/$(dir $(1))
$(Q)$(CPP) $(CFLAGS) $(CFLAGS_$(2)) $(CFLAGS_$(3)) -DOBJECT=$(3) \
-Wno-error -M $(1) -MG -MP | \
sed 's/\.o\s*:/_DEPS +=/' > $(BIN)/deps/$(1).d
sed 's/\.o[[:blank:]]*:/_DEPS +=/' > $(BIN)/deps/$(1).d
endef
# rules_template : generate rules for a given source file

View File

@ -110,7 +110,7 @@ static int com32_exec_loop ( struct image *image ) {
/* Disable interrupts */
"cli\n\t"
/* Restore stack pointer */
"movl 24(%%esp), %%esp\n\t"
"movl 28(%%esp), %%esp\n\t"
/* Restore registers */
"popal\n\t" )
:

View File

@ -190,14 +190,14 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
/* Expand/shrink block if possible */
if ( ptr == bottom ) {
/* Update block */
if ( new_size > ( heap_size - extmem.size ) ) {
DBG ( "EXTMEM out of space\n" );
return UNULL;
}
new = userptr_add ( ptr, - ( new_size - extmem.size ) );
align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) );
new_size += align;
new = userptr_add ( new, -align );
if ( new_size > ( heap_size + extmem.size ) ) {
DBG ( "EXTMEM out of space\n" );
return UNULL;
}
DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n",
user_to_phys ( ptr, 0 ),
user_to_phys ( ptr, extmem.size ),

View File

@ -147,10 +147,8 @@ int xfer_open_socket ( struct interface *intf, int semantics,
socket_family_name ( peer->sa_family ) );
for_each_table_entry ( opener, SOCKET_OPENERS ) {
if ( ( opener->semantics == semantics ) &&
( opener->family == peer->sa_family ) ) {
if ( opener->semantics == semantics )
return opener->open ( intf, peer, local );
}
}
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "

View File

@ -116,7 +116,7 @@ int memcmp ( const void *first, const void *second, size_t len ) {
int diff;
while ( len-- ) {
diff = ( *(second_bytes++) - *(first_bytes++) );
diff = ( *(first_bytes++) - *(second_bytes++) );
if ( diff )
return diff;
}

View File

@ -56,7 +56,7 @@ static uint8_t deflate_reverse[256];
* does not fit the pattern (it represents a length of 258; following
* the pattern from the earlier codes would give a length of 259), and
* has no extra bits. Codes 286-287 are invalid, but can occur. We
* treat any code greater than 284 as meaning "length 285, no extra
* treat any code greater than 284 as meaning "length 258, no extra
* bits".
*/
static uint8_t deflate_litlen_base[28];

View File

@ -788,6 +788,20 @@ static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
return rc;
}
/**
* Initialise UNDI with cable detection
*
* @v nii NII NIC
* @ret rc Return status code
*/
static int nii_initialise_cable ( struct nii_nic *nii ) {
unsigned int flags;
/* Initialise UNDI */
flags = PXE_OPFLAGS_INITIALIZE_DETECT_CABLE;
return nii_initialise_flags ( nii, flags );
}
/**
* Initialise UNDI
*
@ -1122,7 +1136,6 @@ static void nii_poll ( struct net_device *netdev ) {
*/
static int nii_open ( struct net_device *netdev ) {
struct nii_nic *nii = netdev->priv;
unsigned int flags;
int rc;
/* Initialise NIC
@ -1140,15 +1153,21 @@ static int nii_open ( struct net_device *netdev ) {
* presence during initialisation on links that are physically
* slow to reach link-up.
*
* Attempt to work around both of these problems by requesting
* cable detection at this point if any only if the driver is
* not capable of reporting link status changes at runtime via
* PXE_OPCODE_GET_STATUS.
* Attempt to work around both of these problems by first
* attempting to initialise with cable presence detection,
* then falling back to initialising without cable presence
* detection.
*/
flags = ( nii->media ? PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
: PXE_OPFLAGS_INITIALIZE_DETECT_CABLE );
if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 )
goto err_initialise;
if ( ( rc = nii_initialise_cable ( nii ) ) != 0 ) {
DBGC ( nii, "NII %s could not initialise with cable "
"detection: %s\n", nii->dev.name, strerror ( rc ) );
if ( ( rc = nii_initialise ( nii ) ) != 0 ) {
DBGC ( nii, "NII %s could not initialise without "
"cable detection: %s\n",
nii->dev.name, strerror ( rc ) );
goto err_initialise;
}
}
/* Attempt to set station address */
if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {

View File

@ -1134,8 +1134,8 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x1539, "i211", "I211", 0 ),
PCI_ROM ( 0x8086, 0x153a, "i217lm", "I217-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", 0),
PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", 0),
PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),

View File

@ -475,6 +475,8 @@ static struct pci_device_id intelx_nics[] = {
PCI_ROM ( 0x8086, 0x1560, "x540t1", "X540-AT2/X540-BT2 (with single port NVM)", 0 ),
PCI_ROM ( 0x8086, 0x1563, "x550t2", "X550-T2", 0 ),
PCI_ROM ( 0x8086, 0x15ab, "x552", "X552", 0 ),
PCI_ROM ( 0x8086, 0x15c8, "x553t", "X553/X557-AT", 0 ),
PCI_ROM ( 0x8086, 0x15ce, "x553-sfp", "X553 (SFP+)", 0 ),
PCI_ROM ( 0x8086, 0x15e5, "x553", "X553", 0 ),
};

View File

@ -1314,6 +1314,8 @@ const struct efx_nic_type hunt_nic_type = {
};
static struct pci_device_id hunt_nics[] = {
PCI_ROM(0x1924, 0x0903, "SFC9120", "Solarflare SFC9120 Adapter", 0),
PCI_ROM(0x1924, 0x0923, "SFC9140", "Solarflare SFC9140 Adapter", 0),
PCI_ROM(0x1924, 0x0a03, "SFC9220", "Solarflare SFN8xxx Adapter", 0),
PCI_ROM(0x1924, 0x0b03, "SFC9250", "Solarflare X25xx Adapter", 0),
};

View File

@ -193,6 +193,8 @@ static int ifstat_exec ( int argc, char **argv ) {
/** "ifconf" options */
struct ifconf_options {
/** Configuration timeout */
unsigned long timeout;
/** Configurator */
struct net_device_configurator *configurator;
};
@ -202,6 +204,9 @@ static struct option_descriptor ifconf_opts[] = {
OPTION_DESC ( "configurator", 'c', required_argument,
struct ifconf_options, configurator,
parse_netdev_configurator ),
OPTION_DESC ( "timeout", 't', required_argument,
struct ifconf_options, timeout,
parse_timeout ),
};
/**
@ -216,7 +221,8 @@ static int ifconf_payload ( struct net_device *netdev,
int rc;
/* Attempt configuration */
if ( ( rc = ifconf ( netdev, opts->configurator ) ) != 0 ) {
if ( ( rc = ifconf ( netdev, opts->configurator,
opts->timeout ) ) != 0 ) {
/* Close device on failure, to avoid memory exhaustion */
netdev_close ( netdev );

View File

@ -313,22 +313,27 @@ struct asn1_algorithm {
#define __asn1_algorithm __table_entry ( ASN1_ALGORITHMS, 01 )
/* ASN.1 OID-identified algorithms */
extern struct asn1_algorithm rsa_encryption_algorithm;
extern struct asn1_algorithm md5_with_rsa_encryption_algorithm;
extern struct asn1_algorithm sha1_with_rsa_encryption_algorithm;
extern struct asn1_algorithm sha256_with_rsa_encryption_algorithm;
extern struct asn1_algorithm sha384_with_rsa_encryption_algorithm;
extern struct asn1_algorithm sha512_with_rsa_encryption_algorithm;
extern struct asn1_algorithm sha224_with_rsa_encryption_algorithm;
extern struct asn1_algorithm oid_md4_algorithm;
extern struct asn1_algorithm oid_md5_algorithm;
extern struct asn1_algorithm oid_sha1_algorithm;
extern struct asn1_algorithm oid_sha256_algorithm;
extern struct asn1_algorithm oid_sha384_algorithm;
extern struct asn1_algorithm oid_sha512_algorithm;
extern struct asn1_algorithm oid_sha224_algorithm;
extern struct asn1_algorithm oid_sha512_224_algorithm;
extern struct asn1_algorithm oid_sha512_256_algorithm;
extern struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm md5_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm
sha1_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm
sha256_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm
sha384_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm
sha512_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm
sha224_with_rsa_encryption_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_md4_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_md5_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha1_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha256_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha384_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm;
/** An ASN.1 bit string */
struct asn1_bit_string {

View File

@ -70,8 +70,6 @@ struct uri_opener {
struct socket_opener {
/** Communication semantics (e.g. SOCK_STREAM) */
int semantics;
/** Address family (e.g. AF_INET) */
int family;
/** Open socket
*
* @v intf Object interface

View File

@ -14,7 +14,8 @@ struct net_device_configurator;
extern int ifopen ( struct net_device *netdev );
extern int ifconf ( struct net_device *netdev,
struct net_device_configurator *configurator );
struct net_device_configurator *configurator,
unsigned long timeout );
extern void ifclose ( struct net_device *netdev );
extern void ifstat ( struct net_device *netdev );
extern int iflinkwait ( struct net_device *netdev, unsigned long timeout );

View File

@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/rotate.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/Protocol/LoadedImage.h>
/** Image handle passed to entry point */
@ -34,6 +35,9 @@ EFI_HANDLE efi_image_handle;
/** Loaded image protocol for this image */
EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
/** Device path for the loaded image's device handle */
EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
/** System table passed to entry point
*
* We construct the symbol name efi_systab via the PLATFORM macro.
@ -152,6 +156,9 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
struct efi_protocol *prot;
struct efi_config_table *tab;
void *loaded_image;
void *device_path;
void *device_path_copy;
size_t device_path_len;
EFI_STATUS efirc;
int rc;
@ -230,6 +237,33 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
DBGC ( systab, "EFI image base address %p\n",
efi_loaded_image->ImageBase );
/* Get loaded image's device handle's device path */
if ( ( efirc = bs->OpenProtocol ( efi_loaded_image->DeviceHandle,
&efi_device_path_protocol_guid,
&device_path, image_handle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( systab, "EFI could not get loaded image's device path: "
"%s", strerror ( rc ) );
goto err_no_device_path;
}
/* Make a copy of the loaded image's device handle's device
* path, since the device handle itself may become invalidated
* when we load our own drivers.
*/
device_path_len = ( efi_devpath_len ( device_path ) +
sizeof ( EFI_DEVICE_PATH_PROTOCOL ) );
if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, device_path_len,
&device_path_copy ) ) != 0 ) {
rc = -EEFI ( efirc );
goto err_alloc_device_path;
}
memcpy ( device_path_copy, device_path, device_path_len );
efi_loaded_image_path = device_path_copy;
DBGC ( systab, "EFI image device path %s\n",
efi_devpath_text ( efi_loaded_image_path ) );
/* EFI is perfectly capable of gracefully shutting down any
* loaded devices if it decides to fall back to a legacy boot.
* For no particularly comprehensible reason, it doesn't
@ -261,6 +295,9 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
err_driver_install:
bs->CloseEvent ( efi_shutdown_event );
err_create_event:
bs->FreePool ( efi_loaded_image_path );
err_alloc_device_path:
err_no_device_path:
err_no_loaded_image:
err_missing_table:
err_missing_protocol:
@ -291,6 +328,9 @@ static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle __unused ) {
/* Uninstall exit boot services event */
bs->CloseEvent ( efi_shutdown_event );
/* Free copy of loaded image's device handle's device path */
bs->FreePool ( efi_loaded_image_path );
DBGC ( systab, "EFI image unloaded\n" );
return 0;

View File

@ -307,6 +307,7 @@ static int efi_local_open_volume ( struct efi_local *local,
EFI_GUID *protocol = &efi_simple_file_system_protocol_guid;
int ( * check ) ( struct efi_local *local, EFI_HANDLE device,
EFI_FILE_PROTOCOL *root, const char *volume );
EFI_DEVICE_PATH_PROTOCOL *path;
EFI_FILE_PROTOCOL *root;
EFI_HANDLE *handles;
EFI_HANDLE device;
@ -328,8 +329,18 @@ static int efi_local_open_volume ( struct efi_local *local,
}
check = efi_local_check_volume_name;
} else {
/* Use our loaded image's device handle */
handles = &efi_loaded_image->DeviceHandle;
/* Locate filesystem from which we were loaded */
path = efi_loaded_image_path;
if ( ( efirc = bs->LocateDevicePath ( protocol, &path,
&device ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( local, "LOCAL %p could not locate file system "
"on %s: %s\n", local,
efi_devpath_text ( efi_loaded_image_path ),
strerror ( rc ) );
return rc;
}
handles = &device;
num_handles = 1;
check = NULL;
}

View File

@ -247,16 +247,17 @@ static int efi_snp_hii_append ( struct efi_snp_device *snpdev __unused,
const char *key, const char *value,
wchar_t **results ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_STATUS efirc;
size_t len;
void *new;
/* Allocate new string */
len = ( ( *results ? ( wcslen ( *results ) + 1 /* "&" */ ) : 0 ) +
strlen ( key ) + 1 /* "=" */ + strlen ( value ) + 1 /* NUL */ );
bs->AllocatePool ( EfiBootServicesData, ( len * sizeof ( wchar_t ) ),
&new );
if ( ! new )
return -ENOMEM;
if ( ( efirc = bs->AllocatePool ( EfiBootServicesData,
( len * sizeof ( wchar_t ) ),
&new ) ) != 0 )
return -EEFI ( efirc );
/* Populate string */
efi_snprintf ( new, len, "%ls%s%s=%s", ( *results ? *results : L"" ),

View File

@ -1100,7 +1100,7 @@ static int efi_usb_install ( struct efi_usb_device *usbdev,
usbpath->Header.Type = MESSAGING_DEVICE_PATH;
usbpath->Header.SubType = MSG_USB_DP;
usbpath->Header.Length[0] = sizeof ( *usbpath );
usbpath->ParentPortNumber = usb->port->address;
usbpath->ParentPortNumber = ( usb->port->address - 1 );
}
/* Add to list of interfaces */

View File

@ -1,6 +1,6 @@
#include "libgcc.h"
__libgcc int64_t __divmoddi4(int64_t num, int64_t den, int64 *rem_p)
__libgcc int64_t __divmoddi4(int64_t num, int64_t den, int64_t *rem_p)
{
int minus = 0;
int64_t v;

View File

@ -304,8 +304,9 @@ static void wpa_derive_ptk ( struct wpa_common_ctx *ctx )
memcpy ( ptk_data.nonce2, ctx->Anonce, WPA_NONCE_LEN );
}
DBGC2 ( ctx, "WPA %p A1 %s, A2 %s\n", ctx, eth_ntoa ( ptk_data.mac1 ),
eth_ntoa ( ptk_data.mac2 ) );
DBGC2 ( ctx, "WPA %p A1 %s", ctx, eth_ntoa ( ptk_data.mac1 ) );
DBGC2 ( ctx, ", A2 %s\n", eth_ntoa ( ptk_data.mac2 ) );
DBGC2 ( ctx, "WPA %p Nonce1, Nonce2:\n", ctx );
DBGC2_HD ( ctx, ptk_data.nonce1, WPA_NONCE_LEN );
DBGC2_HD ( ctx, ptk_data.nonce2, WPA_NONCE_LEN );

View File

@ -259,17 +259,9 @@ static int ping_open ( struct interface *xfer, struct sockaddr *peer,
return rc;
}
/** Ping IPv4 socket opener */
struct socket_opener ping_ipv4_socket_opener __socket_opener = {
/** Ping socket opener */
struct socket_opener ping_socket_opener __socket_opener = {
.semantics = PING_SOCK_ECHO,
.family = AF_INET,
.open = ping_open,
};
/** Ping IPv6 socket opener */
struct socket_opener ping_ipv6_socket_opener __socket_opener = {
.semantics = PING_SOCK_ECHO,
.family = AF_INET6,
.open = ping_open,
};

View File

@ -1743,17 +1743,9 @@ static struct interface_descriptor tcp_xfer_desc =
***************************************************************************
*/
/** TCP IPv4 socket opener */
struct socket_opener tcp_ipv4_socket_opener __socket_opener = {
/** TCP socket opener */
struct socket_opener tcp_socket_opener __socket_opener = {
.semantics = TCP_SOCK_STREAM,
.family = AF_INET,
.open = tcp_open,
};
/** TCP IPv6 socket opener */
struct socket_opener tcp_ipv6_socket_opener __socket_opener = {
.semantics = TCP_SOCK_STREAM,
.family = AF_INET6,
.open = tcp_open,
};

View File

@ -396,17 +396,9 @@ static struct interface_descriptor udp_xfer_desc =
***************************************************************************
*/
/** UDP IPv4 socket opener */
struct socket_opener udp_ipv4_socket_opener __socket_opener = {
/** UDP socket opener */
struct socket_opener udp_socket_opener __socket_opener = {
.semantics = UDP_SOCK_DGRAM,
.family = AF_INET,
.open = udp_open,
};
/** UDP IPv6 socket opener */
struct socket_opener udp_ipv6_socket_opener __socket_opener = {
.semantics = UDP_SOCK_DGRAM,
.family = AF_INET6,
.open = udp_open,
};

View File

@ -63,18 +63,33 @@ FEATURE ( FEATURE_PROTOCOL, "DNS", DHCP_EB_FEATURE_DNS, 1 );
#define EINFO_ENXIO_NO_NAMESERVER \
__einfo_uniqify ( EINFO_ENXIO, 0x02, "No DNS servers available" )
/** The DNS server */
static union {
struct sockaddr sa;
struct sockaddr_tcpip st;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} nameserver = {
.st = {
.st_port = htons ( DNS_PORT ),
},
/** A DNS server list */
struct dns_server {
/** Server list */
union {
/** IPv4 addresses */
struct in_addr *in;
/** IPv6 addresses */
struct in6_addr *in6;
/** Raw data */
void *data;
};
/** Number of servers */
unsigned int count;
};
/** IPv4 DNS server list */
static struct dns_server dns4;
/** IPv6 DNS server list */
static struct dns_server dns6;
/** Total number of DNS servers */
static unsigned int dns_count;
/** Current DNS server index */
static unsigned int dns_index;
/** The DNS search list */
static struct dns_name dns_search;
@ -555,6 +570,9 @@ static int dns_question ( struct dns_request *dns ) {
/* Restore name */
dns->name.offset = offsetof ( typeof ( dns->buf ), name );
/* Reset query ID */
dns->buf.query.id = 0;
DBGC2 ( dns, "DNS %p question is %s type %s\n", dns,
dns_name ( &dns->name ), dns_type ( dns->question->qtype ) );
@ -569,24 +587,54 @@ static int dns_question ( struct dns_request *dns ) {
*/
static int dns_send_packet ( struct dns_request *dns ) {
struct dns_header *query = &dns->buf.query;
union {
struct sockaddr sa;
struct sockaddr_tcpip st;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} nameserver;
struct xfer_metadata meta;
unsigned int index;
/* Start retransmission timer */
start_timer ( &dns->timer );
/* Generate query identifier */
query->id = random();
/* Construct DNS server address */
memset ( &nameserver, 0, sizeof ( nameserver ) );
nameserver.st.st_port = htons ( DNS_PORT );
if ( ! dns_count ) {
DBGC ( dns, "DNS %p lost DNS servers mid query\n", dns );
return -EINVAL;
}
index = ( dns_index % dns_count );
if ( index < dns6.count ) {
nameserver.sin6.sin6_family = AF_INET6;
memcpy ( &nameserver.sin6.sin6_addr, &dns6.in6[index],
sizeof ( nameserver.sin6.sin6_addr ) );
} else {
nameserver.sin.sin_family = AF_INET;
nameserver.sin.sin_addr = dns4.in[index - dns6.count];
}
/* Construct metadata */
memset ( &meta, 0, sizeof ( meta ) );
meta.dest = &nameserver.sa;
/* Generate query identifier if applicable */
if ( ! query->id )
query->id = random();
/* Send query */
DBGC ( dns, "DNS %p sending query ID %#04x for %s type %s\n", dns,
ntohs ( query->id ), dns_name ( &dns->name ),
dns_type ( dns->question->qtype ) );
DBGC ( dns, "DNS %p sending %s query ID %#04x for %s type %s\n", dns,
sock_ntoa ( &nameserver.sa ), ntohs ( query->id ),
dns_name ( &dns->name ), dns_type ( dns->question->qtype ) );
/* Send the data */
return xfer_deliver_raw ( &dns->socket, query, dns->len );
return xfer_deliver_raw_meta ( &dns->socket, query, dns->len, &meta );
}
/**
* Handle DNS retransmission timer expiry
* Handle DNS (re)transmission timer expiry
*
* @v timer Retry timer
* @v fail Failure indicator
@ -595,11 +643,18 @@ static void dns_timer_expired ( struct retry_timer *timer, int fail ) {
struct dns_request *dns =
container_of ( timer, struct dns_request, timer );
/* Terminate DNS request on failure */
if ( fail ) {
dns_done ( dns, -ETIMEDOUT );
} else {
dns_send_packet ( dns );
return;
}
/* Move to next DNS server if this is a retransmission */
if ( dns->buf.query.id )
dns_index++;
/* Send DNS query */
dns_send_packet ( dns );
}
/**
@ -927,7 +982,7 @@ static int dns_resolv ( struct interface *resolv,
int rc;
/* Fail immediately if no DNS servers */
if ( ! nameserver.sa.sa_family ) {
if ( dns_count == 0 ) {
DBG ( "DNS not attempting to resolve \"%s\": "
"no DNS servers\n", name );
rc = -ENXIO_NO_NAMESERVER;
@ -953,17 +1008,8 @@ static int dns_resolv ( struct interface *resolv,
memcpy ( dns->search.data, dns_search.data, search_len );
/* Determine initial query type */
switch ( nameserver.sa.sa_family ) {
case AF_INET:
dns->qtype = htons ( DNS_TYPE_A );
break;
case AF_INET6:
dns->qtype = htons ( DNS_TYPE_AAAA );
break;
default:
rc = -ENOTSUP;
goto err_type;
}
dns->qtype = ( ( dns6.count != 0 ) ?
htons ( DNS_TYPE_AAAA ) : htons ( DNS_TYPE_A ) );
/* Construct query */
query = &dns->buf.query;
@ -984,7 +1030,7 @@ static int dns_resolv ( struct interface *resolv,
/* Open UDP connection */
if ( ( rc = xfer_open_socket ( &dns->socket, SOCK_DGRAM,
&nameserver.sa, NULL ) ) != 0 ) {
NULL, NULL ) ) != 0 ) {
DBGC ( dns, "DNS %p could not open socket: %s\n",
dns, strerror ( rc ) );
goto err_open_socket;
@ -1001,7 +1047,6 @@ static int dns_resolv ( struct interface *resolv,
err_open_socket:
err_question:
err_encode:
err_type:
ref_put ( &dns->refcnt );
err_alloc_dns:
err_no_nameserver:
@ -1096,6 +1141,31 @@ const struct setting dnssl_setting __setting ( SETTING_IP_EXTRA, dnssl ) = {
.type = &setting_type_dnssl,
};
/**
* Apply DNS server addresses
*
*/
static void apply_dns_servers ( void ) {
int len;
/* Free existing server addresses */
free ( dns4.data );
free ( dns6.data );
dns4.data = NULL;
dns6.data = NULL;
dns4.count = 0;
dns6.count = 0;
/* Fetch DNS server addresses */
len = fetch_raw_setting_copy ( NULL, &dns_setting, &dns4.data );
if ( len >= 0 )
dns4.count = ( len / sizeof ( dns4.in[0] ) );
len = fetch_raw_setting_copy ( NULL, &dns6_setting, &dns6.data );
if ( len >= 0 )
dns6.count = ( len / sizeof ( dns6.in6[0] ) );
dns_count = ( dns4.count + dns6.count );
}
/**
* Apply DNS search list
*
@ -1109,8 +1179,7 @@ static void apply_dns_search ( void ) {
memset ( &dns_search, 0, sizeof ( dns_search ) );
/* Fetch DNS search list */
len = fetch_setting_copy ( NULL, &dnssl_setting, NULL, NULL,
&dns_search.data );
len = fetch_raw_setting_copy ( NULL, &dnssl_setting, &dns_search.data );
if ( len >= 0 ) {
dns_search.len = len;
return;
@ -1138,19 +1207,31 @@ static void apply_dns_search ( void ) {
* @ret rc Return status code
*/
static int apply_dns_settings ( void ) {
void *dbgcol = &dns_count;
/* Fetch DNS server address */
nameserver.sa.sa_family = 0;
if ( fetch_ipv6_setting ( NULL, &dns6_setting,
&nameserver.sin6.sin6_addr ) >= 0 ) {
nameserver.sin6.sin6_family = AF_INET6;
} else if ( fetch_ipv4_setting ( NULL, &dns_setting,
&nameserver.sin.sin_addr ) >= 0 ) {
nameserver.sin.sin_family = AF_INET;
}
if ( nameserver.sa.sa_family ) {
DBG ( "DNS using nameserver %s\n",
sock_ntoa ( &nameserver.sa ) );
apply_dns_servers();
if ( DBG_LOG && ( dns_count != 0 ) ) {
union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} u;
unsigned int i;
DBGC ( dbgcol, "DNS servers:" );
for ( i = 0 ; i < dns6.count ; i++ ) {
u.sin6.sin6_family = AF_INET6;
memcpy ( &u.sin6.sin6_addr, &dns6.in6[i],
sizeof ( u.sin6.sin6_addr ) );
DBGC ( dbgcol, " %s", sock_ntoa ( &u.sa ) );
}
for ( i = 0 ; i < dns4.count ; i++ ) {
u.sin.sin_family = AF_INET;
u.sin.sin_addr = dns4.in[i];
DBGC ( dbgcol, " %s", sock_ntoa ( &u.sa ) );
}
DBGC ( dbgcol, "\n" );
}
/* Fetch DNS search list */
@ -1159,16 +1240,16 @@ static int apply_dns_settings ( void ) {
struct dns_name name;
int offset;
DBG ( "DNS search list:" );
DBGC ( dbgcol, "DNS search list:" );
memcpy ( &name, &dns_search, sizeof ( name ) );
while ( name.offset != name.len ) {
DBG ( " %s", dns_name ( &name ) );
DBGC ( dbgcol, " %s", dns_name ( &name ) );
offset = dns_skip_search ( &name );
if ( offset < 0 )
break;
name.offset = offset;
}
DBG ( "\n" );
DBGC ( dbgcol, "\n" );
}
return 0;

View File

@ -109,6 +109,7 @@ static void string_test_exec ( void ) {
ok ( memcmp ( "", "", 0 ) == 0 );
ok ( memcmp ( "Foo", "Foo", 3 ) == 0 );
ok ( memcmp ( "Foo", "Bar", 3 ) != 0 );
ok ( memcmp ( "abc", "def", 3 ) < 0 );
/* Test strstr() */
{

View File

@ -396,7 +396,7 @@ int netboot ( struct net_device *netdev ) {
ifstat ( netdev );
/* Configure device */
if ( ( rc = ifconf ( netdev, NULL ) ) != 0 )
if ( ( rc = ifconf ( netdev, NULL, 0 ) ) != 0 )
goto err_dhcp;
route();

View File

@ -264,10 +264,12 @@ static int ifconf_progress ( struct ifpoller *ifpoller ) {
*
* @v netdev Network device
* @v configurator Network device configurator, or NULL to use all
* @v timeout Timeout period, in ticks
* @ret rc Return status code
*/
int ifconf ( struct net_device *netdev,
struct net_device_configurator *configurator ) {
struct net_device_configurator *configurator,
unsigned long timeout ) {
int rc;
/* Ensure device is open and link is up */
@ -296,5 +298,5 @@ int ifconf ( struct net_device *netdev,
( configurator ? configurator->name : "" ),
( configurator ? "] " : "" ),
netdev->name, netdev->ll_protocol->ntoa ( netdev->ll_addr ) );
return ifpoller_wait ( netdev, configurator, 0, ifconf_progress );
return ifpoller_wait ( netdev, configurator, timeout, ifconf_progress );
}

View File

@ -48,7 +48,7 @@ do
g=${g:0:8}.krn
case "$first" in
"")
echo DEFAULT $g
echo DEFAULT $b
;;
esac
first=$g