diff --git a/src/Makefile b/src/Makefile index ea2445a6..5079f937 100644 --- a/src/Makefile +++ b/src/Makefile @@ -43,6 +43,7 @@ ELF2EFI32 := ./util/elf2efi32 ELF2EFI64 := ./util/elf2efi64 EFIROM := ./util/efirom ICCFIX := ./util/iccfix +EINFO := ./util/einfo DOXYGEN := doxygen BINUTILS_DIR := /usr BFD_DIR := $(BINUTILS_DIR) diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping index 2562e623..0d94987f 100644 --- a/src/Makefile.housekeeping +++ b/src/Makefile.housekeeping @@ -550,6 +550,18 @@ $(BIN)/embedded.o : override CC := env CCACHE_DISABLE=1 $(CC) CFLAGS_embedded = -DEMBED_ALL="$(EMBED_ALL)" +# Generate error usage information +# +$(BIN)/%.einfo : $(BIN)/%.o + $(QM)$(ECHO) " [EINFO] $@" + $(Q)$(OBJCOPY) -O binary -j .einfo --set-section-flags .einfo=alloc \ + $< $@ + +EINFOS := $(patsubst $(BIN)/%.o,$(BIN)/%.einfo,$(BOBJS)) +$(BIN)/errors : $(EINFOS) $(EINFO) + $(QM)$(ECHO) " [EINFO] $@" + $(Q)$(EINFO) $(EINFOS) | sort > $@ + # Generate the NIC file from the parsed source files. The NIC file is # only for rom-o-matic. # @@ -902,6 +914,15 @@ $(ICCFIX) : util/iccfix.c $(MAKEDEPS) $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $< CLEANUP += $(ICCFIX) +############################################################################### +# +# The error usage information utility +# +$(EINFO) : util/einfo.c $(MAKEDEPS) + $(QM)$(ECHO) " [HOSTCC] $@" + $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $< +CLEANUP += $(EINFO) + ############################################################################### # # Local configs diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 0ce2c10f..610bfa16 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -162,6 +162,8 @@ SECTIONS { *(.eh_frame.*) *(.rel) *(.rel.*) + *(.einfo) + *(.einfo.*) *(.discard) } diff --git a/src/arch/x86/scripts/efi.lds b/src/arch/x86/scripts/efi.lds index 4368f732..d9963ef3 100644 --- a/src/arch/x86/scripts/efi.lds +++ b/src/arch/x86/scripts/efi.lds @@ -99,6 +99,8 @@ SECTIONS { *(.eh_frame.*) *(.rel) *(.rel.*) + *(.einfo) + *(.einfo.*) *(.discard) } } diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index f9fab87c..baa1c644 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -77,11 +77,13 @@ static struct ipoib_mac ipoib_broadcast = { }; /** Link status for "broadcast join in progress" */ -#define EINPROGRESS_JOINING ( EINPROGRESS | EUNIQ_01 ) +#define EINPROGRESS_JOINING __einfo_error ( EINFO_EINPROGRESS_JOINING ) +#define EINFO_EINPROGRESS_JOINING __einfo_uniqify \ + ( EINFO_EINPROGRESS, 0x01, "Joining" ) /** Human-readable message for the link status */ struct errortab ipoib_errors[] __errortab = { - { EINPROGRESS_JOINING, "Joining" }, + __einfo_errortab ( EINFO_EINPROGRESS_JOINING ), }; /**************************************************************************** diff --git a/src/hci/strerror.c b/src/hci/strerror.c index 1b75f980..3caee497 100644 --- a/src/hci/strerror.c +++ b/src/hci/strerror.c @@ -102,21 +102,21 @@ const char * strerror ( int errno ) { /** The most common errors */ struct errortab common_errors[] __errortab = { - { 0, "No error" }, - { EACCES, "Permission denied" }, - { ECANCELED, "Operation cancelled" }, - { ECONNRESET, "Connection reset" }, - { EINVAL, "Invalid argument" }, - { EIO, "Input/output error" }, - { ENETUNREACH, "Network unreachable" }, - { ENODEV, "No such device" }, - { ENOENT, "File not found" }, - { ENOEXEC, "Not an executable image" }, - { ENOMEM, "Out of memory" }, - { ENOSPC, "No space left on device" }, - { ENOTCONN, "Not connected" }, - { ENOTSUP, "Not supported" }, - { EPERM, "Operation not permitted" }, - { ERANGE, "Out of range" }, - { ETIMEDOUT, "Connection timed out" }, + __einfo_errortab ( EINFO_ENOERR ), + __einfo_errortab ( EINFO_EACCES ), + __einfo_errortab ( EINFO_ECANCELED ), + __einfo_errortab ( EINFO_ECONNRESET ), + __einfo_errortab ( EINFO_EINVAL ), + __einfo_errortab ( EINFO_EIO ), + __einfo_errortab ( EINFO_ENETUNREACH ), + __einfo_errortab ( EINFO_ENODEV ), + __einfo_errortab ( EINFO_ENOENT ), + __einfo_errortab ( EINFO_ENOEXEC ), + __einfo_errortab ( EINFO_ENOMEM ), + __einfo_errortab ( EINFO_ENOSPC ), + __einfo_errortab ( EINFO_ENOTCONN ), + __einfo_errortab ( EINFO_ENOTSUP ), + __einfo_errortab ( EINFO_EPERM ), + __einfo_errortab ( EINFO_ERANGE ), + __einfo_errortab ( EINFO_ETIMEDOUT ), }; diff --git a/src/hci/wireless_errors.c b/src/hci/wireless_errors.c index 0909c017..63c6251c 100644 --- a/src/hci/wireless_errors.c +++ b/src/hci/wireless_errors.c @@ -20,99 +20,89 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +#include /* Record errors as though they come from the 802.11 stack */ #undef ERRFILE #define ERRFILE ERRFILE_net80211 /** All 802.11 errors - * - * These follow the 802.11 standard as much as is feasible, but most - * have been abbreviated to fit the 50-character limit imposed by - * strerror. */ struct errortab wireless_errors[] __errortab = { - /* iPXE 802.11 stack errors */ - { EINVAL | EUNIQ_01, "Packet too short" }, - { EINVAL | EUNIQ_02, "Packet 802.11 version not supported" }, - { EINVAL | EUNIQ_03, "Packet not a data packet" }, - { EINVAL | EUNIQ_04, "Packet not from an Access Point" }, - { EINVAL | EUNIQ_05, "Packet has invalid LLC header" }, - { EINVAL | EUNIQ_06, "Packet decryption error", }, - { EINVAL | EUNIQ_07, "Invalid active scan requested" }, - - /* 802.11 status codes (IEEE Std 802.11-2007, Table 7-23) */ - /* Maximum error length: 50 chars | */ - { ECONNREFUSED | EUNIQ_01, "Unspecified failure" }, - { ECONNREFUSED | EUNIQ_0A, "Cannot support all requested capabilities" }, - { ECONNREFUSED | EUNIQ_0B, "Reassociation denied due to lack of association" }, - { ECONNREFUSED | EUNIQ_0C, "Association denied for another reason" }, - { ECONNREFUSED | EUNIQ_0D, "Authentication algorithm unsupported" }, - { ECONNREFUSED | EUNIQ_0E, "Authentication sequence number unexpected" }, - { ECONNREFUSED | EUNIQ_0F, "Authentication rejected due to challenge failure" }, - { ECONNREFUSED | EUNIQ_10, "Authentication rejected due to timeout" }, - { ECONNREFUSED | EUNIQ_11, "Association denied because AP is out of resources" }, - { ECONNREFUSED | EUNIQ_12, "Association denied; basic rate support required" }, - { ECONNREFUSED | EUNIQ_13, "Association denied; short preamble support req'd" }, - { ECONNREFUSED | EUNIQ_14, "Association denied; PBCC modulation support req'd" }, - { ECONNREFUSED | EUNIQ_15, "Association denied; Channel Agility support req'd" }, - { ECONNREFUSED | EUNIQ_16, "Association denied; Spectrum Management required" }, - { ECONNREFUSED | EUNIQ_17, "Association denied; Power Capability unacceptable" }, - { ECONNREFUSED | EUNIQ_18, "Association denied; Supported Channels unacceptable" }, - { ECONNREFUSED | EUNIQ_19, "Association denied; Short Slot Tume support req'd" }, - { ECONNREFUSED | EUNIQ_1A, "Association denied; DSSS-OFDM support required" }, - { EHOSTUNREACH, "Unspecified, QoS-related failure" }, - { EHOSTUNREACH | EUNIQ_01, "Association denied; QoS AP out of QoS resources" }, - { EHOSTUNREACH | EUNIQ_02, "Association denied due to excessively poor link" }, - { EHOSTUNREACH | EUNIQ_03, "Association denied; QoS support required" }, - { EHOSTUNREACH | EUNIQ_05, "The request has been declined" }, - { EHOSTUNREACH | EUNIQ_06, "Request unsuccessful due to invalid parameters" }, - { EHOSTUNREACH | EUNIQ_07, "TS not created due to bad specification" }, - { EHOSTUNREACH | EUNIQ_08, "Invalid information element" }, - { EHOSTUNREACH | EUNIQ_09, "Invalid group cipher" }, - { EHOSTUNREACH | EUNIQ_0A, "Invalid pairwise cipher" }, - { EHOSTUNREACH | EUNIQ_0B, "Invalid AKMP" }, - { EHOSTUNREACH | EUNIQ_0C, "Unsupported RSN information element version" }, - { EHOSTUNREACH | EUNIQ_0D, "Invalid RSN information element capabilities" }, - { EHOSTUNREACH | EUNIQ_0E, "Cipher suite rejected because of security policy" }, - { EHOSTUNREACH | EUNIQ_0F, "TS not created due to insufficient delay" }, - { EHOSTUNREACH | EUNIQ_10, "Direct link is not allowed in the BSS by policy" }, - { EHOSTUNREACH | EUNIQ_11, "The Destination STA is not present within the BSS" }, - { EHOSTUNREACH | EUNIQ_12, "The Destination STA is not a QoS STA" }, - { EHOSTUNREACH | EUNIQ_13, "Association denied; Listen Interval is too large" }, - - /* 802.11 reason codes (IEEE Std 802.11-2007, Table 7-22) */ - /* Maximum error length: 50 chars | */ - { ECONNRESET | EUNIQ_01, "Unspecified reason" }, - { ECONNRESET | EUNIQ_02, "Previous authentication no longer valid" }, - { ECONNRESET | EUNIQ_03, "Deauthenticated due to leaving network" }, - { ECONNRESET | EUNIQ_04, "Disassociated due to inactivity" }, - { ECONNRESET | EUNIQ_05, "Disassociated because AP is out of resources" }, - { ECONNRESET | EUNIQ_06, "Class 2 frame received from nonauthenticated STA" }, - { ECONNRESET | EUNIQ_07, "Class 3 frame received from nonassociated STA" }, - { ECONNRESET | EUNIQ_08, "Disassociated due to roaming" }, - { ECONNRESET | EUNIQ_09, "STA requesting (re)association not authenticated" }, - { ECONNRESET | EUNIQ_0A, "Disassociated; Power Capability unacceptable" }, - { ECONNRESET | EUNIQ_0B, "Disassociated; Supported Channels unacceptable" }, - { ECONNRESET | EUNIQ_0D, "Invalid information element" }, - { ECONNRESET | EUNIQ_0E, "Message integrity code (MIC) failure" }, - { ECONNRESET | EUNIQ_0F, "4-Way Handshake timeout" }, - { ECONNRESET | EUNIQ_10, "Group Key Handshake timeout" }, - { ECONNRESET | EUNIQ_11, "4-Way Handshake information element changed unduly" }, - { ECONNRESET | EUNIQ_12, "Invalid group cipher" }, - { ECONNRESET | EUNIQ_13, "Invalid pairwise cipher" }, - { ECONNRESET | EUNIQ_14, "Invalid AKMP" }, - { ECONNRESET | EUNIQ_15, "Unsupported RSN information element version" }, - { ECONNRESET | EUNIQ_16, "Invalid RSN information element capabilities" }, - { ECONNRESET | EUNIQ_17, "IEEE 802.1X authentication failed" }, - { ECONNRESET | EUNIQ_18, "Cipher suite rejected because of security policy" }, - { ENETRESET, "Disassociated for unspecified, QoS-related reason" }, - { ENETRESET | EUNIQ_01, "Disassociated; QoS AP is out of QoS resources" }, - { ENETRESET | EUNIQ_02, "Disassociated due to excessively poor link" }, - { ENETRESET | EUNIQ_03, "Disassociated due to TXOP limit violation" }, - { ENETRESET | EUNIQ_04, "Requested; STA is leaving the BSS (or resetting)" }, - { ENETRESET | EUNIQ_05, "Requested; does not want to use the mechanism" }, - { ENETRESET | EUNIQ_06, "Requested; setup is required" }, - { ENETRESET | EUNIQ_07, "Requested from peer STA due to timeout" }, - { ENETRESET | EUNIQ_0D, "Peer STA does not support requested cipher suite" }, + __einfo_errortab ( EINFO_EINVAL_PKT_TOO_SHORT ), + __einfo_errortab ( EINFO_EINVAL_PKT_VERSION ), + __einfo_errortab ( EINFO_EINVAL_PKT_NOT_DATA ), + __einfo_errortab ( EINFO_EINVAL_PKT_NOT_FROMDS ), + __einfo_errortab ( EINFO_EINVAL_PKT_LLC_HEADER ), + __einfo_errortab ( EINFO_EINVAL_CRYPTO_REQUEST ), + __einfo_errortab ( EINFO_EINVAL_ACTIVE_SCAN ), + __einfo_errortab ( EINFO_ECONNREFUSED_FAILURE ), + __einfo_errortab ( EINFO_ECONNREFUSED_CAPAB_UNSUPP ), + __einfo_errortab ( EINFO_ECONNREFUSED_REASSOC_INVALID ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_DENIED ), + __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP ), + __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_SEQ_INVALID ), + __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_CHALL_INVALID ), + __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_TIMEOUT ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NO_ROOM ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_RATE ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_PMBL ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_PBCC ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_BAD_POWER ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_BAD_CHANNELS ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_SLOT ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_DSSS_OFDM ), + __einfo_errortab ( EINFO_EHOSTUNREACH_QOS_FAILURE ), + __einfo_errortab ( EINFO_EHOSTUNREACH_QOS_NO_ROOM ), + __einfo_errortab ( EINFO_EHOSTUNREACH_LINK_IS_HORRIBLE ), + __einfo_errortab ( EINFO_EHOSTUNREACH_ASSOC_NEED_QOS ), + __einfo_errortab ( EINFO_EHOSTUNREACH_REQUEST_DECLINED ), + __einfo_errortab ( EINFO_EHOSTUNREACH_REQUEST_INVALID ), + __einfo_errortab ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_AGAIN ), + __einfo_errortab ( EINFO_EHOSTUNREACH_INVALID_IE ), + __einfo_errortab ( EINFO_EHOSTUNREACH_GROUP_CIPHER_INVALID ), + __einfo_errortab ( EINFO_EHOSTUNREACH_PAIR_CIPHER_INVALID ), + __einfo_errortab ( EINFO_EHOSTUNREACH_AKMP_INVALID ), + __einfo_errortab ( EINFO_EHOSTUNREACH_RSN_VERSION_UNSUPP ), + __einfo_errortab ( EINFO_EHOSTUNREACH_RSN_CAPAB_INVALID ), + __einfo_errortab ( EINFO_EHOSTUNREACH_CIPHER_REJECTED ), + __einfo_errortab ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_WAIT ), + __einfo_errortab ( EINFO_EHOSTUNREACH_DIRECT_LINK_FORBIDDEN ), + __einfo_errortab ( EINFO_EHOSTUNREACH_DEST_NOT_PRESENT ), + __einfo_errortab ( EINFO_EHOSTUNREACH_DEST_NOT_QOS ), + __einfo_errortab ( EINFO_EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH ), + __einfo_errortab ( EINFO_ECONNRESET_UNSPECIFIED ), + __einfo_errortab ( EINFO_ECONNRESET_AUTH_NO_LONGER_VALID ), + __einfo_errortab ( EINFO_ECONNRESET_LEAVING ), + __einfo_errortab ( EINFO_ECONNRESET_INACTIVITY ), + __einfo_errortab ( EINFO_ECONNRESET_OUT_OF_RESOURCES ), + __einfo_errortab ( EINFO_ECONNRESET_NEED_AUTH ), + __einfo_errortab ( EINFO_ECONNRESET_NEED_ASSOC ), + __einfo_errortab ( EINFO_ECONNRESET_LEAVING_TO_ROAM ), + __einfo_errortab ( EINFO_ECONNRESET_REASSOC_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_BAD_POWER ), + __einfo_errortab ( EINFO_ECONNRESET_BAD_CHANNELS ), + __einfo_errortab ( EINFO_ECONNRESET_INVALID_IE ), + __einfo_errortab ( EINFO_ECONNRESET_MIC_FAILURE ), + __einfo_errortab ( EINFO_ECONNRESET_4WAY_TIMEOUT ), + __einfo_errortab ( EINFO_ECONNRESET_GROUPKEY_TIMEOUT ), + __einfo_errortab ( EINFO_ECONNRESET_4WAY_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_GROUP_CIPHER_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_PAIR_CIPHER_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_AKMP_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_RSN_VERSION_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_RSN_CAPAB_INVALID ), + __einfo_errortab ( EINFO_ECONNRESET_8021X_FAILURE ), + __einfo_errortab ( EINFO_ECONNRESET_CIPHER_REJECTED ), + __einfo_errortab ( EINFO_ENETRESET_QOS_UNSPECIFIED ), + __einfo_errortab ( EINFO_ENETRESET_QOS_OUT_OF_RESOURCES ), + __einfo_errortab ( EINFO_ENETRESET_LINK_IS_HORRIBLE ), + __einfo_errortab ( EINFO_ENETRESET_INVALID_TXOP ), + __einfo_errortab ( EINFO_ENETRESET_REQUESTED_LEAVING ), + __einfo_errortab ( EINFO_ENETRESET_REQUESTED_NO_USE ), + __einfo_errortab ( EINFO_ENETRESET_REQUESTED_NEED_SETUP ), + __einfo_errortab ( EINFO_ENETRESET_REQUESTED_TIMEOUT ), + __einfo_errortab ( EINFO_ENETRESET_CIPHER_UNSUPPORTED ), }; diff --git a/src/image/segment.c b/src/image/segment.c index 9099c8fe..c3f0b8d5 100644 --- a/src/image/segment.c +++ b/src/image/segment.c @@ -31,6 +31,19 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +/** + * Segment-specific error messages + * + * This error happens sufficiently often to merit a user-friendly + * description. + */ +#define ERANGE_SEGMENT __einfo_error ( EINFO_ERANGE_SEGMENT ) +#define EINFO_ERANGE_SEGMENT \ + __einfo_uniqify ( EINFO_ERANGE, 0x01, "Requested memory not available" ) +struct errortab segment_errors[] __errortab = { + __einfo_errortab ( EINFO_ERANGE_SEGMENT ), +}; + /** * Prepare segment for loading * @@ -73,15 +86,5 @@ int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ) { /* No suitable memory region found */ DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n", start, mid, end ); - return -ERANGE; + return -ERANGE_SEGMENT; } - -/** - * Segment-specific error messages - * - * This error happens sufficiently often to merit a user-friendly - * description. - */ -struct errortab segment_errors[] __errortab = { - { ERANGE, "Requested memory not available" }, -}; diff --git a/src/include/errno.h b/src/include/errno.h index 0757fadb..45d53823 100644 --- a/src/include/errno.h +++ b/src/include/errno.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef ERRNO_H #define ERRNO_H @@ -40,19 +58,13 @@ FILE_LICENCE ( GPL2_OR_LATER ); * * * The convention within the code is that errors are negative and - * expressed using the POSIX error code and (optionally) a per-file - * disambiguator, e.g. + * expressed using the POSIX error, e.g. * * return -EINVAL; * - * or - * - * #define ETCP_BAD_CHECKSUM EUNIQ_02 - * return -( EINVAL | ETCP_BAD_CHECKSUM ) - * * By various bits of preprocessor magic, the PXE error code and file * identifier are already incorporated into the definition of the - * POSIX error code, which keeps the code relatively clean. + * POSIX error macro, which keeps the code relatively clean. * * * Functions that wish to return failures should be declared as @@ -69,6 +81,21 @@ FILE_LICENCE ( GPL2_OR_LATER ); * As illustrated in the above example, error returns should generally * be directly propagated upward to the calling function. * + * + * Individual files may declare localised errors using + * __einfo_uniqify(). For example, iscsi.c declares a localised + * version of EACCES for the error of "access denied due to incorrect + * target username": + * + * #define EACCES_INCORRECT_TARGET_USERNAME \ + * __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME ) + * #define EINFO_EACCES_INCORRECT_TARGET_USERNAME \ + * __einfo_uniqify ( EINFO_EACCESS, 0x01, "Incorrect target username" ) + * + * which can then be used as: + * + * return -EACCES_INCORRECT_TARGET_USERNAME; + * */ /* Get definitions for file identifiers */ @@ -85,8 +112,121 @@ extern char missing_errfile_declaration[] __attribute__ (( deprecated )); #define ERRFILE ( 0 * ( ( int ) missing_errfile_declaration ) ) #endif -/** Derive PXENV_STATUS code from iPXE error number */ -#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) +/** + * Declare error information + * + * @v pxe PXE error number (0x00-0xff) + * @v posix POSIX error number (0x00-0x7f) + * @v uniq Error disambiguator (0x00-0x1f) + * @v desc Error description + * @ret einfo Error information + */ +#define __einfo( pxe, posix, uniq, desc ) ( pxe, posix, uniq, desc ) + +/** + * Get PXE error number + * + * @v einfo Error information + * @ret pxe PXE error number + */ +#define __einfo_pxe( einfo ) __einfo_extract_pxe einfo +#define __einfo_extract_pxe( pxe, posix, uniq, desc ) pxe + +/** + * Get POSIX error number + * + * @v einfo Error information + * @ret posix POSIX error number + */ +#define __einfo_posix( einfo ) __einfo_extract_posix einfo +#define __einfo_extract_posix( pxe, posix, uniq, desc ) posix + +/** + * Get error disambiguator + * + * @v einfo Error information + * @ret uniq Error disambiguator + */ +#define __einfo_uniq( einfo ) __einfo_extract_uniq einfo +#define __einfo_extract_uniq( pxe, posix, uniq, desc ) uniq + +/** + * Get error description + * + * @v einfo Error information + * @ret desc Error description + */ +#define __einfo_desc( einfo ) __einfo_extract_desc einfo +#define __einfo_extract_desc( pxe, posix, uniq, desc ) desc + +/** + * Declare disambiguated error + * + * @v einfo_base Base error information + * @v uniq Error disambiguator + * @v desc Error description + * @ret einfo Error information + */ +#define __einfo_uniqify( einfo_base, uniq, desc ) \ + __einfo ( __einfo_pxe ( einfo_base ), \ + __einfo_posix ( einfo_base ), \ + uniq, desc ) + +/** + * Get error number + * + * @v einfo Error information + * @ret errno Error number + */ +#define __einfo_errno( einfo ) \ + ( ( __einfo_posix ( einfo ) << 24 ) | ( ERRFILE ) | \ + ( __einfo_uniq ( einfo ) << 8 ) | \ + ( __einfo_pxe ( einfo ) << 0 ) ) + +/** + * Disambiguate a base error based on non-constant information + * + * @v error_base Base error + * @v uniq Error disambiguator + * @v ... List of expected possible disambiguated errors + * @ret error Error + * + * EUNIQ() should be used when information from an external source is + * being incorporated into an error. For example, the 802.11 stack + * uses EUNIQ() to incorporate 802.11 status codes returned by an + * access point into an error. + * + * EUNIQ() should not be used for constant error disambiguators; use + * __einfo_uniqify() instead. + */ +#define EUNIQ( errno, uniq, ... ) ( { \ + euniq_discard ( 0, ##__VA_ARGS__); \ + ( (errno) | ( (uniq) << 8 ) ); } ) +static inline void euniq_discard ( int dummy __unused, ... ) {} + +/** + * Declare error + * + * @v einfo Error information + * @ret error Error + */ +#define __einfo_error( einfo ) ( { \ + __asm__ ( ".section \".einfo\", \"\", @progbits\n\t" \ + ".align 8\n\t" \ + "\n1:\n\t" \ + ".long ( 4f - 1b )\n\t" \ + ".long %c0\n\t" \ + ".long ( 2f - 1b )\n\t" \ + ".long ( 3f - 1b )\n\t" \ + ".long %c1\n\t" \ + "\n2:\t.asciz \"" __einfo_desc ( einfo ) "\"\n\t" \ + "\n3:\t.asciz \"" __FILE__ "\"\n\t" \ + ".align 8\n\t" \ + "\n4:\n\t" \ + ".previous\n\t" : : \ + "i" ( __einfo_errno ( einfo) ), \ + "i" ( __LINE__ ) ); \ + __einfo_errno ( einfo ); } ) /** * @defgroup pxeerrors PXE error codes @@ -199,309 +339,420 @@ extern char missing_errfile_declaration[] __attribute__ (( deprecated )); /** @} */ +/** Derive PXENV_STATUS code from iPXE error number */ +#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) + /** * @defgroup posixerrors POSIX error codes * * The names and meanings (but not the values) of these error codes - * are defined by POSIX. We choose to assign unique values which - * incorporate the closest equivalent PXE error code, so that code may - * simply use ENOMEM, rather than having to use the cumbersome - * (ENOMEM|PXENV_STATUS_OUT_OF_RESOURCES). + * are defined by POSIX. * * @{ */ /** Operation completed successfully */ -#define ENOERR ( ERRFILE | PXENV_STATUS_SUCCESS | 0x00000000 ) +#define ENOERR __einfo_error ( EINFO_ENOERR ) +#define EINFO_ENOERR __einfo ( PXENV_STATUS_SUCCESS, 0x00, 0, \ + "Operation completed successfully" ) -/** Arg list too long */ -#define E2BIG ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x01000000 ) +/** Argument list too long */ +#define E2BIG __einfo_error ( EINFO_E2BIG ) +#define EINFO_E2BIG __einfo ( PXENV_STATUS_BAD_FUNC, 0x01, 0, \ + "Argument list too long" ) /** Permission denied */ -#define EACCES ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x02000000 ) +#define EACCES __einfo_error ( EINFO_EACCES ) +#define EINFO_EACCES __einfo ( PXENV_STATUS_TFTP_ACCESS_VIOLATION, 0x02, 0, \ + "Permission denied" ) -/** Address in use */ -#define EADDRINUSE ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x03000000 ) +/** Address already in use */ +#define EADDRINUSE __einfo_error ( EINFO_EADDRINUSE ) +#define EINFO_EADDRINUSE __einfo ( PXENV_STATUS_UDP_OPEN, 0x03, 0, \ + "Address already in use" ) /** Address not available */ -#define EADDRNOTAVAIL ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x04000000 ) +#define EADDRNOTAVAIL __einfo_error ( EINFO_EADDRNOTAVAIL ) +#define EINFO_EADDRNOTAVAIL __einfo ( PXENV_STATUS_UDP_OPEN, 0x04, 0, \ + "Address not available" ) /** Address family not supported */ -#define EAFNOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x05000000 ) +#define EAFNOSUPPORT __einfo_error ( EINFO_EAFNOSUPPORT ) +#define EINFO_EAFNOSUPPORT __einfo ( PXENV_STATUS_UNSUPPORTED, 0x05, 0, \ + "Address family not supported" ) /** Resource temporarily unavailable */ -#define EAGAIN ( ERRFILE | PXENV_STATUS_FAILURE | 0x06000000 ) +#define EAGAIN __einfo_error ( EINFO_EAGAIN ) +#define EINFO_EAGAIN __einfo ( PXENV_STATUS_FAILURE, 0x06, 0, \ + "Resource temporarily unavailable" ) /** Connection already in progress */ -#define EALREADY ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x07000000 ) +#define EALREADY __einfo_error ( EINFO_EALREADY ) +#define EINFO_EALREADY __einfo ( PXENV_STATUS_UDP_OPEN, 0x07, 0, \ + "Connection already in progress" ) /** Bad file descriptor */ -#define EBADF ( ERRFILE | PXENV_STATUS_TFTP_CLOSED | 0x08000000 ) +#define EBADF __einfo_error ( EINFO_EBADF ) +#define EINFO_EBADF __einfo ( PXENV_STATUS_TFTP_CLOSED, 0x08, 0, \ + "Bad file descriptor" ) /** Bad message */ -#define EBADMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x09000000 ) +#define EBADMSG __einfo_error ( EINFO_EBADMSG ) +#define EINFO_EBADMSG __einfo ( PXENV_STATUS_FAILURE, 0x09, 0, \ + "Bad message" ) -/** Resource busy */ -#define EBUSY ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x0a000000 ) +/** Device or resource busy */ +#define EBUSY __einfo_error ( EINFO_EBUSY ) +#define EINFO_EBUSY __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x0a, 0, \ + "Device or resource busy" ) /** Operation canceled */ -#define ECANCELED \ - ( ERRFILE | PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE | 0x0b000000 ) +#define ECANCELED __einfo_error ( EINFO_ECANCELED ) +#define EINFO_ECANCELED __einfo ( PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE, \ + 0x0b, 0, "Operation canceled" ) /** No child processes */ -#define ECHILD ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x0c000000 ) +#define ECHILD __einfo_error ( EINFO_ECHILD ) +#define EINFO_ECHILD __einfo ( PXENV_STATUS_TFTP_FILE_NOT_FOUND, 0x0c, 0, \ + "No child processes" ) /** Connection aborted */ -#define ECONNABORTED \ - ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0d000000 ) +#define ECONNABORTED __einfo_error ( EINFO_ECONNABORTED ) +#define EINFO_ECONNABORTED \ + __einfo ( PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION, 0x0d, 0, \ + "Connection aborted" ) /** Connection refused */ -#define ECONNREFUSED \ - ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION | 0x0e000000 ) +#define ECONNREFUSED __einfo_error ( EINFO_ECONNREFUSED ) +#define EINFO_ECONNREFUSED __einfo ( PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION, \ + 0x0e, 0, "Connection refused" ) /** Connection reset */ -#define ECONNRESET \ - ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0f000000 ) +#define ECONNRESET __einfo_error ( EINFO_ECONNRESET ) +#define EINFO_ECONNRESET \ + __einfo ( PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION, 0x0f, 0, \ + "Connection reset" ) /** Resource deadlock avoided */ -#define EDEADLK ( ERRFILE | PXENV_STATUS_FAILURE | 0x10000000 ) +#define EDEADLK __einfo_error ( EINFO_EDEADLK ) +#define EINFO_EDEADLK __einfo ( PXENV_STATUS_FAILURE, 0x10, 0, \ + "Resource deadlock avoided" ) /** Destination address required */ -#define EDESTADDRREQ ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x11000000 ) +#define EDESTADDRREQ __einfo_error ( EINFO_EDESTADDRREQ ) +#define EINFO_EDESTADDRREQ __einfo ( PXENV_STATUS_BAD_FUNC, 0x11, 0, \ + "Destination address required" ) -/** Domain error */ -#define EDOM ( ERRFILE | PXENV_STATUS_FAILURE | 0x12000000 ) +/** Mathematics argument out of domain of function */ +#define EDOM __einfo_error ( EINFO_EDOM ) +#define EINFO_EDOM __einfo ( PXENV_STATUS_FAILURE, 0x12, 0, \ + "Mathematics argument out of domain of function" ) -/** Reserved */ -#define EDQUOT ( ERRFILE | PXENV_STATUS_FAILURE | 0x13000000 ) +/** Disk quota exceeded */ +#define EDQUOT __einfo_error ( EINFO_EDQUOT ) +#define EINFO_EDQUOT __einfo ( PXENV_STATUS_FAILURE, 0x13, 0, \ + "Disk quote exceeded" ) /** File exists */ -#define EEXIST ( ERRFILE | PXENV_STATUS_FAILURE | 0x14000000 ) +#define EEXIST __einfo_error ( EINFO_EEXIST ) +#define EINFO_EEXIST __einfo ( PXENV_STATUS_FAILURE, 0x14, 0, \ + "File exists" ) /** Bad address */ -#define EFAULT ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x15000000 ) +#define EFAULT __einfo_error ( EINFO_EFAULT ) +#define EINFO_EFAULT __einfo ( PXENV_STATUS_MCOPY_PROBLEM, 0x15, 0, \ + "Bad address" ) /** File too large */ -#define EFBIG ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x16000000 ) +#define EFBIG __einfo_error ( EINFO_EFBIG ) +#define EINFO_EFBIG __einfo ( PXENV_STATUS_MCOPY_PROBLEM, 0x16, 0, \ + "File too large" ) /** Host is unreachable */ -#define EHOSTUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x17000000 ) +#define EHOSTUNREACH __einfo_error ( EINFO_EHOSTUNREACH ) +#define EINFO_EHOSTUNREACH __einfo ( PXENV_STATUS_ARP_TIMEOUT, 0x17, 0, \ + "Host is unreachable" ) /** Identifier removed */ -#define EIDRM ( ERRFILE | PXENV_STATUS_FAILURE | 0x18000000 ) +#define EIDRM __einfo_error ( EINFO_EIDRM ) +#define EINFO_EIDRM __einfo ( PXENV_STATUS_FAILURE, 0x18, 0, \ + "Identifier removed" ) /** Illegal byte sequence */ -#define EILSEQ ( ERRFILE | PXENV_STATUS_FAILURE | 0x19000000 ) +#define EILSEQ __einfo_error ( EINFO_EILSEQ ) +#define EINFO_EILSEQ __einfo ( PXENV_STATUS_FAILURE, 0x19, 0, \ + "Illegal byte sequence" ) /** Operation in progress */ -#define EINPROGRESS ( ERRFILE | PXENV_STATUS_FAILURE | 0x1a000000 ) +#define EINPROGRESS __einfo_error ( EINFO_EINPROGRESS ) +#define EINFO_EINPROGRESS __einfo ( PXENV_STATUS_FAILURE, 0x1a, 0, \ + "Operation in progress" ) /** Interrupted function call */ -#define EINTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1b000000 ) +#define EINTR __einfo_error ( EINFO_EINTR ) +#define EINFO_EINTR __einfo ( PXENV_STATUS_FAILURE, 0x1b, 0, \ + "Interrupted function call" ) /** Invalid argument */ -#define EINVAL ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x1c000000 ) +#define EINVAL __einfo_error ( EINFO_EINVAL ) +#define EINFO_EINVAL __einfo ( PXENV_STATUS_BAD_FUNC, 0x1c, 0, \ + "Invalid argument" ) /** Input/output error */ -#define EIO \ - ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x1d000000 ) +#define EIO __einfo_error ( EINFO_EIO ) +#define EINFO_EIO __einfo ( PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION, \ + 0x1d, 0, "Input/output error" ) /** Socket is connected */ -#define EISCONN ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x1e000000 ) +#define EISCONN __einfo_error ( EINFO_EISCONN ) +#define EINFO_EISCONN __einfo ( PXENV_STATUS_UDP_OPEN, 0x1e, 0, \ + "Socket is connected" ) /** Is a directory */ -#define EISDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1f000000 ) +#define EISDIR __einfo_error ( EINFO_EISDIR ) +#define EINFO_EISDIR __einfo ( PXENV_STATUS_FAILURE, 0x1f, 0, \ + "Is a directory" ) /** Too many levels of symbolic links */ -#define ELOOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x20000000 ) +#define ELOOP __einfo_error ( EINFO_ELOOP ) +#define EINFO_ELOOP __einfo ( PXENV_STATUS_FAILURE, 0x20, 0, \ + "Too many levels of symbolic links" ) /** Too many open files */ -#define EMFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x21000000 ) +#define EMFILE __einfo_error ( EINFO_EMFILE ) +#define EINFO_EMFILE __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x21, 0, \ + "Too many open files" ) /** Too many links */ -#define EMLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x22000000 ) +#define EMLINK __einfo_error ( EINFO_EMLINK ) +#define EINFO_EMLINK __einfo ( PXENV_STATUS_FAILURE, 0x22, 0, \ + "Too many links" ) -/** Inappropriate message buffer length */ -#define EMSGSIZE ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x23000000 ) +/** Message too long */ +#define EMSGSIZE __einfo_error ( EINFO_EMSGSIZE ) +#define EINFO_EMSGSIZE __einfo ( PXENV_STATUS_BAD_FUNC, 0x23, 0, \ + "Message too long" ) -/** Reserved */ -#define EMULTIHOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x24000000 ) +/** Multihop attempted */ +#define EMULTIHOP __einfo_error ( EINFO_EMULTIHOP ) +#define EINFO_EMULTIHOP __einfo ( PXENV_STATUS_FAILURE, 0x24, 0, \ + "Multihop attempted" ) /** Filename too long */ -#define ENAMETOOLONG ( ERRFILE | PXENV_STATUS_FAILURE | 0x25000000 ) +#define ENAMETOOLONG __einfo_error ( EINFO_ENAMETOOLONG ) +#define EINFO_ENAMETOOLONG __einfo ( PXENV_STATUS_FAILURE, 0x25, 0, \ + "Filename too long" ) /** Network is down */ -#define ENETDOWN ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x26000000 ) +#define ENETDOWN __einfo_error ( EINFO_ENETDOWN ) +#define EINFO_ENETDOWN __einfo ( PXENV_STATUS_ARP_TIMEOUT, 0x26, 0, \ + "Network is down" ) /** Connection aborted by network */ -#define ENETRESET ( ERRFILE | PXENV_STATUS_FAILURE | 0x27000000 ) +#define ENETRESET __einfo_error ( EINFO_ENETRESET ) +#define EINFO_ENETRESET __einfo ( PXENV_STATUS_FAILURE, 0x27, 0, \ + "Connection aborted by network" ) /** Network unreachable */ -#define ENETUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x28000000 ) +#define ENETUNREACH __einfo_error ( EINFO_ENETUNREACH ) +#define EINFO_ENETUNREACH __einfo ( PXENV_STATUS_ARP_TIMEOUT, 0x28, 0, \ + "Network unreachable" ) /** Too many open files in system */ -#define ENFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x29000000 ) +#define ENFILE __einfo_error ( EINFO_ENFILE ) +#define EINFO_ENFILE __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x29, 0, \ + "Too many open files in system" ) /** No buffer space available */ -#define ENOBUFS ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x2a000000 ) +#define ENOBUFS __einfo_error ( EINFO_ENOBUFS ) +#define EINFO_ENOBUFS __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x2a, 0, \ + "No buffer space available" ) /** No message is available on the STREAM head read queue */ -#define ENODATA ( ERRFILE | PXENV_STATUS_FAILURE | 0x2b000000 ) +#define ENODATA __einfo_error ( EINFO_ENODATA ) +#define EINFO_ENODATA \ + __einfo ( PXENV_STATUS_FAILURE, 0x2b, 0, \ + "No message is available on the STREAM head read queue" ) /** No such device */ -#define ENODEV ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2c000000 ) +#define ENODEV __einfo_error ( EINFO_ENODEV ) +#define EINFO_ENODEV __einfo ( PXENV_STATUS_TFTP_FILE_NOT_FOUND, 0x2c, 0, \ + "No such device" ) /** No such file or directory */ -#define ENOENT ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2d000000 ) +#define ENOENT __einfo_error ( EINFO_ENOENT ) +#define EINFO_ENOENT __einfo ( PXENV_STATUS_TFTP_FILE_NOT_FOUND, 0x2d, 0, \ + "No such file or directory" ) /** Exec format error */ -#define ENOEXEC ( ERRFILE | PXENV_STATUS_FAILURE | 0x2e000000 ) +#define ENOEXEC __einfo_error ( EINFO_ENOEXEC ) +#define EINFO_ENOEXEC __einfo ( PXENV_STATUS_FAILURE, 0x2e, 0, \ + "Exec format error" ) /** No locks available */ -#define ENOLCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x2f000000 ) +#define ENOLCK __einfo_error ( EINFO_ENOLCK ) +#define EINFO_ENOLCK __einfo ( PXENV_STATUS_FAILURE, 0x2f, 0, \ + "No locks available" ) -/** Reserved */ -#define ENOLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x30000000 ) +/** Link has been severed */ +#define ENOLINK __einfo_error ( EINFO_ENOLINK ) +#define EINFO_ENOLINK __einfo ( PXENV_STATUS_FAILURE, 0x30, 0, \ + "Link has been severed" ) /** Not enough space */ -#define ENOMEM ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x31000000 ) +#define ENOMEM __einfo_error ( EINFO_ENOMEM ) +#define EINFO_ENOMEM __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x31, 0, \ + "Not enough space" ) /** No message of the desired type */ -#define ENOMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x32000000 ) +#define ENOMSG __einfo_error ( EINFO_ENOMSG ) +#define EINFO_ENOMSG __einfo ( PXENV_STATUS_FAILURE, 0x32, 0, \ + "No message of the desired type" ) /** Protocol not available */ -#define ENOPROTOOPT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x33000000 ) +#define ENOPROTOOPT __einfo_error ( EINFO_ENOPROTOOPT ) +#define EINFO_ENOPROTOOPT __einfo ( PXENV_STATUS_UNSUPPORTED, 0x33, 0, \ + "Protocol not available" ) /** No space left on device */ -#define ENOSPC ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x34000000 ) +#define ENOSPC __einfo_error ( EINFO_ENOSPC ) +#define EINFO_ENOSPC __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x34, 0, \ + "No space left on device" ) /** No STREAM resources */ -#define ENOSR ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x35000000 ) +#define ENOSR __einfo_error ( EINFO_ENOSR ) +#define EINFO_ENOSR __einfo ( PXENV_STATUS_OUT_OF_RESOURCES, 0x35, 0, \ + "No STREAM resources" ) /** Not a STREAM */ -#define ENOSTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x36000000 ) +#define ENOSTR __einfo_error ( EINFO_ENOSTR ) +#define EINFO_ENOSTR __einfo ( PXENV_STATUS_FAILURE, 0x36, 0, \ + "Not a STREAM" ) /** Function not implemented */ -#define ENOSYS ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x37000000 ) +#define ENOSYS __einfo_error ( EINFO_ENOSYS ) +#define EINFO_ENOSYS __einfo ( PXENV_STATUS_UNSUPPORTED, 0x37, 0, \ + "Function not implemented" ) /** The socket is not connected */ -#define ENOTCONN ( ERRFILE | PXENV_STATUS_FAILURE | 0x38000000 ) +#define ENOTCONN __einfo_error ( EINFO_ENOTCONN ) +#define EINFO_ENOTCONN __einfo ( PXENV_STATUS_FAILURE, 0x38, 0, \ + "The socket is not connected" ) /** Not a directory */ -#define ENOTDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x39000000 ) +#define ENOTDIR __einfo_error ( EINFO_ENOTDIR ) +#define EINFO_ENOTDIR __einfo ( PXENV_STATUS_FAILURE, 0x39, 0, \ + "Not a directory" ) /** Directory not empty */ -#define ENOTEMPTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3a000000 ) +#define ENOTEMPTY __einfo_error ( EINFO_ENOTEMPTY ) +#define EINFO_ENOTEMPTY __einfo ( PXENV_STATUS_FAILURE, 0x3a, 0, \ + "Directory not empty" ) /** Not a socket */ -#define ENOTSOCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x3b000000 ) +#define ENOTSOCK __einfo_error ( EINFO_ENOTSOCK ) +#define EINFO_ENOTSOCK __einfo ( PXENV_STATUS_FAILURE, 0x3b, 0, \ + "Not a socket" ) -/** Not supported */ -#define ENOTSUP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3c000000 ) +/** Operation not supported */ +#define ENOTSUP __einfo_error ( EINFO_ENOTSUP ) +#define EINFO_ENOTSUP __einfo ( PXENV_STATUS_UNSUPPORTED, 0x3c, 0, \ + "Operation not supported" ) /** Inappropriate I/O control operation */ -#define ENOTTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3d000000 ) +#define ENOTTY __einfo_error ( EINFO_ENOTTY ) +#define EINFO_ENOTTY __einfo ( PXENV_STATUS_FAILURE, 0x3d, 0, \ + "Inappropriate I/O control operation" ) /** No such device or address */ -#define ENXIO ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x3e000000 ) +#define ENXIO __einfo_error ( EINFO_ENXIO ) +#define EINFO_ENXIO __einfo ( PXENV_STATUS_TFTP_FILE_NOT_FOUND, 0x3e, 0, \ + "No such device or address" ) /** Operation not supported on socket */ -#define EOPNOTSUPP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3f000000 ) +#define EOPNOTSUPP __einfo_error ( EINFO_EOPNOTSUPP ) +#define EINFO_EOPNOTSUPP __einfo ( PXENV_STATUS_UNSUPPORTED, 0x3f, 0, \ + "Operation not supported on socket" ) /** Value too large to be stored in data type */ -#define EOVERFLOW ( ERRFILE | PXENV_STATUS_FAILURE | 0x40000000 ) +#define EOVERFLOW __einfo_error ( EINFO_EOVERFLOW ) +#define EINFO_EOVERFLOW __einfo ( PXENV_STATUS_FAILURE, 0x40, 0, \ + "Value too large to be stored in data type" ) /** Operation not permitted */ -#define EPERM ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x41000000 ) +#define EPERM __einfo_error ( EINFO_EPERM ) +#define EINFO_EPERM __einfo ( PXENV_STATUS_TFTP_ACCESS_VIOLATION, 0x41, 0, \ + "Operation not permitted" ) /** Broken pipe */ -#define EPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x42000000 ) +#define EPIPE __einfo_error ( EINFO_EPIPE ) +#define EINFO_EPIPE __einfo ( PXENV_STATUS_FAILURE, 0x42, 0, \ + "Broken pipe" ) /** Protocol error */ -#define EPROTO ( ERRFILE | PXENV_STATUS_FAILURE | 0x43000000 ) +#define EPROTO __einfo_error ( EINFO_EPROTO ) +#define EINFO_EPROTO __einfo ( PXENV_STATUS_FAILURE, 0x43, 0, \ + "Protocol error" ) /** Protocol not supported */ -#define EPROTONOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x44000000 ) +#define EPROTONOSUPPORT __einfo_error ( EINFO_EPROTONOSUPPORT ) +#define EINFO_EPROTONOSUPPORT __einfo ( PXENV_STATUS_UNSUPPORTED, 0x44, 0, \ + "Protocol not supported" ) /** Protocol wrong type for socket */ -#define EPROTOTYPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x45000000 ) +#define EPROTOTYPE __einfo_error ( EINFO_EPROTOTYPE ) +#define EINFO_EPROTOTYPE __einfo ( PXENV_STATUS_FAILURE, 0x45, 0, \ + "Protocol wrong type for socket" ) /** Result too large */ -#define ERANGE ( ERRFILE | PXENV_STATUS_FAILURE | 0x46000000 ) +#define ERANGE __einfo_error ( EINFO_ERANGE ) +#define EINFO_ERANGE __einfo ( PXENV_STATUS_FAILURE, 0x46, 0, \ + "Result too large" ) /** Read-only file system */ -#define EROFS ( ERRFILE | PXENV_STATUS_FAILURE | 0x47000000 ) +#define EROFS __einfo_error ( EINFO_EROFS ) +#define EINFO_EROFS __einfo ( PXENV_STATUS_FAILURE, 0x47, 0, \ + "Read-only file system" ) /** Invalid seek */ -#define ESPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x48000000 ) +#define ESPIPE __einfo_error ( EINFO_ESPIPE ) +#define EINFO_ESPIPE __einfo ( PXENV_STATUS_FAILURE, 0x48, 0, \ + "Invalid seek" ) /** No such process */ -#define ESRCH ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x49000000 ) +#define ESRCH __einfo_error ( EINFO_ESRCH ) +#define EINFO_ESRCH __einfo ( PXENV_STATUS_TFTP_FILE_NOT_FOUND, 0x49, 0, \ + "No such process" ) /** Stale file handle */ -#define ESTALE ( ERRFILE | PXENV_STATUS_FAILURE | 0x4a000000 ) +#define ESTALE __einfo_error ( EINFO_ESTALE ) +#define EINFO_ESTALE __einfo ( PXENV_STATUS_FAILURE, 0x4a, 0, \ + "Stale file handle" ) -/** STREAM ioctl() timeout */ -#define ETIME ( ERRFILE | PXENV_STATUS_FAILURE | 0x4b000000 ) +/** Timer expired */ +#define ETIME __einfo_error ( EINFO_ETIME ) +#define EINFO_ETIME __einfo ( PXENV_STATUS_FAILURE, 0x4b, 0, \ + "Timer expired" ) -/** Operation timed out */ -#define ETIMEDOUT ( ERRFILE | PXENV_STATUS_TFTP_READ_TIMEOUT | 0x4c000000 ) +/** Connection timed out */ +#define ETIMEDOUT __einfo_error ( EINFO_ETIMEDOUT ) +#define EINFO_ETIMEDOUT __einfo ( PXENV_STATUS_TFTP_READ_TIMEOUT, 0x4c, 0, \ + "Connection timed out" ) /** Text file busy */ -#define ETXTBSY ( ERRFILE | PXENV_STATUS_FAILURE | 0x4d000000 ) +#define ETXTBSY __einfo_error ( EINFO_ETXTBSY ) +#define EINFO_ETXTBSY __einfo ( PXENV_STATUS_FAILURE, 0x4d, 0, \ + "Text file busy" ) -/** Operation would block (different from EAGAIN!) */ -#define EWOULDBLOCK ( ERRFILE | PXENV_STATUS_TFTP_OPEN | 0x4e000000 ) +/** Operation would block */ +#define EWOULDBLOCK __einfo_error ( EINFO_EWOULDBLOCK ) +#define EINFO_EWOULDBLOCK __einfo ( PXENV_STATUS_TFTP_OPEN, 0x4e, 0, \ + "Operation would block" ) /** Improper link */ -#define EXDEV ( ERRFILE | PXENV_STATUS_FAILURE | 0x4f000000 ) - -/** @} */ - -/** - * @defgroup euniq Per-file error disambiguators - * - * Files which use the same error number multiple times should - * probably define their own error subspace using these - * disambiguators. For example: - * - * #define ETCP_HEADER_TOO_SHORT EUNIQ_01 - * #define ETCP_BAD_CHECKSUM EUNIQ_02 - * - * @{ - */ - -#define EUNIQ_01 0x00000100 -#define EUNIQ_02 0x00000200 -#define EUNIQ_03 0x00000300 -#define EUNIQ_04 0x00000400 -#define EUNIQ_05 0x00000500 -#define EUNIQ_06 0x00000600 -#define EUNIQ_07 0x00000700 -#define EUNIQ_08 0x00000800 -#define EUNIQ_09 0x00000900 -#define EUNIQ_0A 0x00000a00 -#define EUNIQ_0B 0x00000b00 -#define EUNIQ_0C 0x00000c00 -#define EUNIQ_0D 0x00000d00 -#define EUNIQ_0E 0x00000e00 -#define EUNIQ_0F 0x00000f00 -#define EUNIQ_10 0x00001000 -#define EUNIQ_11 0x00001100 -#define EUNIQ_12 0x00001200 -#define EUNIQ_13 0x00001300 -#define EUNIQ_14 0x00001400 -#define EUNIQ_15 0x00001500 -#define EUNIQ_16 0x00001600 -#define EUNIQ_17 0x00001700 -#define EUNIQ_18 0x00001800 -#define EUNIQ_19 0x00001900 -#define EUNIQ_1A 0x00001a00 -#define EUNIQ_1B 0x00001b00 -#define EUNIQ_1C 0x00001c00 -#define EUNIQ_1D 0x00001d00 -#define EUNIQ_1E 0x00001e00 -#define EUNIQ_1F 0x00001f00 +#define EXDEV __einfo_error ( EINFO_EXDEV ) +#define EINFO_EXDEV __einfo ( PXENV_STATUS_FAILURE, 0x4f, 0, \ + "Improper link" ) /** @} */ diff --git a/src/include/ipxe/errortab.h b/src/include/ipxe/errortab.h index 945cde31..a2f6a70f 100644 --- a/src/include/ipxe/errortab.h +++ b/src/include/ipxe/errortab.h @@ -20,4 +20,9 @@ struct errortab { #define __errortab __table_entry ( ERRORTAB, 01 ) +#define __einfo_errortab( einfo ) { \ + .errno = __einfo_errno ( einfo ), \ + .text = __einfo_desc ( einfo ), \ + } + #endif /* _IPXE_ERRORTAB_H */ diff --git a/src/include/ipxe/ieee80211.h b/src/include/ipxe/ieee80211.h index 8f4aa965..4e44f434 100644 --- a/src/include/ipxe/ieee80211.h +++ b/src/include/ipxe/ieee80211.h @@ -1,6 +1,7 @@ #ifndef _IPXE_IEEE80211_H #define _IPXE_IEEE80211_H +#include #include /* for ETH_ALEN */ #include diff --git a/src/include/ipxe/net80211_err.h b/src/include/ipxe/net80211_err.h new file mode 100644 index 00000000..2175b143 --- /dev/null +++ b/src/include/ipxe/net80211_err.h @@ -0,0 +1,633 @@ +#ifndef _IPXE_NET80211_ERR_H +#define _IPXE_NET80211_ERR_H + +#include +#include + +/* + * The iPXE 802.11 MAC layer. + * + * Copyright (c) 2009 Joshua Oreman . + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * The iPXE 802.11 MAC layer errors. + */ + +/* Disambiguate the EINVAL's a bit */ +#define EINVAL_PKT_TOO_SHORT __einfo_error ( EINFO_EINVAL_PKT_TOO_SHORT ) +#define EINFO_EINVAL_PKT_TOO_SHORT __einfo_uniqify \ + ( EINFO_EINVAL, 0x01, "Packet too short" ) +#define EINVAL_PKT_VERSION __einfo_error ( EINFO_EINVAL_PKT_VERSION ) +#define EINFO_EINVAL_PKT_VERSION __einfo_uniqify \ + ( EINFO_EINVAL, 0x02, "Packet 802.11 version not supported" ) +#define EINVAL_PKT_NOT_DATA __einfo_error ( EINFO_EINVAL_PKT_NOT_DATA ) +#define EINFO_EINVAL_PKT_NOT_DATA __einfo_uniqify \ + ( EINFO_EINVAL, 0x03, "Packet not a data packet" ) +#define EINVAL_PKT_NOT_FROMDS __einfo_error ( EINFO_EINVAL_PKT_NOT_FROMDS ) +#define EINFO_EINVAL_PKT_NOT_FROMDS __einfo_uniqify \ + ( EINFO_EINVAL, 0x04, "Packet not from an Access Point" ) +#define EINVAL_PKT_LLC_HEADER __einfo_error ( EINFO_EINVAL_PKT_LLC_HEADER ) +#define EINFO_EINVAL_PKT_LLC_HEADER __einfo_uniqify \ + ( EINFO_EINVAL, 0x05, "Packet has invalid LLC header" ) +#define EINVAL_CRYPTO_REQUEST __einfo_error ( EINFO_EINVAL_CRYPTO_REQUEST ) +#define EINFO_EINVAL_CRYPTO_REQUEST __einfo_uniqify \ + ( EINFO_EINVAL, 0x06, "Packet decryption error" ) +#define EINVAL_ACTIVE_SCAN __einfo_error ( EINFO_EINVAL_ACTIVE_SCAN ) +#define EINFO_EINVAL_ACTIVE_SCAN __einfo_uniqify \ + ( EINFO_EINVAL, 0x07, "Invalid active scan requested" ) + +/* + * 802.11 error codes: The AP can give us a status code explaining why + * authentication failed, or a reason code explaining why we were + * deauthenticated/disassociated. These codes range from 0-63 (the + * field is 16 bits wide, but only up to 45 or so are defined yet; we + * allow up to 63 for extensibility). This is encoded into an error + * code as such: + * + * status & 0x1f goes here --vv-- + * Status code 0-31: ECONNREFUSED | EUNIQ_(status & 0x1f) (0e1a6038) + * Status code 32-63: EHOSTUNREACH | EUNIQ_(status & 0x1f) (171a6011) + * Reason code 0-31: ECONNRESET | EUNIQ_(reason & 0x1f) (0f1a6039) + * Reason code 32-63: ENETRESET | EUNIQ_(reason & 0x1f) (271a6001) + * + * The POSIX error codes more or less convey the appropriate message + * (status codes occur when we can't associate at all, reason codes + * when we lose association unexpectedly) and let us extract the + * complete 802.11 error code from the rc value. + * + * The error messages follow the 802.11 standard as much as is + * feasible, but most have been abbreviated to fit the 50-character + * limit imposed by strerror(). + */ + +/* 802.11 status codes (IEEE Std 802.11-2007, Table 7-23) */ + +#define ECONNREFUSED_FAILURE __einfo_error \ + ( EINFO_ECONNREFUSED_FAILURE ) +#define EINFO_ECONNREFUSED_FAILURE __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_FAILURE & 0x1f ), \ + "Unspecified failure" ) + +#define ECONNREFUSED_CAPAB_UNSUPP __einfo_error \ + ( EINFO_ECONNREFUSED_CAPAB_UNSUPP ) +#define EINFO_ECONNREFUSED_CAPAB_UNSUPP __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_CAPAB_UNSUPP & 0x1f ), \ + "Cannot support all requested capabilities" ) + +#define ECONNREFUSED_REASSOC_INVALID __einfo_error \ + ( EINFO_ECONNREFUSED_REASSOC_INVALID ) +#define EINFO_ECONNREFUSED_REASSOC_INVALID __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_REASSOC_INVALID & 0x1f ), \ + "Reassociation denied due to lack of association" ) + +#define ECONNREFUSED_ASSOC_DENIED __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_DENIED ) +#define EINFO_ECONNREFUSED_ASSOC_DENIED __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_DENIED & 0x1f ), \ + "Association denied for another reason" ) + +#define ECONNREFUSED_AUTH_ALGO_UNSUPP __einfo_error \ + ( EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP ) +#define EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_AUTH_ALGO_UNSUPP & 0x1f ), \ + "Authentication algorithm unsupported" ) + +#define ECONNREFUSED_AUTH_SEQ_INVALID __einfo_error \ + ( EINFO_ECONNREFUSED_AUTH_SEQ_INVALID ) +#define EINFO_ECONNREFUSED_AUTH_SEQ_INVALID __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_AUTH_SEQ_INVALID & 0x1f ), \ + "Authentication sequence number unexpected" ) + +#define ECONNREFUSED_AUTH_CHALL_INVALID __einfo_error \ + ( EINFO_ECONNREFUSED_AUTH_CHALL_INVALID ) +#define EINFO_ECONNREFUSED_AUTH_CHALL_INVALID __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_AUTH_CHALL_INVALID & 0x1f ), \ + "Authentication rejected due to challenge failure" ) + +#define ECONNREFUSED_AUTH_TIMEOUT __einfo_error \ + ( EINFO_ECONNREFUSED_AUTH_TIMEOUT ) +#define EINFO_ECONNREFUSED_AUTH_TIMEOUT __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_AUTH_TIMEOUT & 0x1f ), \ + "Authentication rejected due to timeout" ) + +#define ECONNREFUSED_ASSOC_NO_ROOM __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NO_ROOM ) +#define EINFO_ECONNREFUSED_ASSOC_NO_ROOM __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NO_ROOM & 0x1f ), \ + "Association denied because AP is out of resources" ) + +#define ECONNREFUSED_ASSOC_NEED_RATE __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_RATE ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_RATE __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_RATE & 0x1f ), \ + "Association denied; basic rate support required" ) + +#define ECONNREFUSED_ASSOC_NEED_SHORT_PMBL __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_PMBL ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_PMBL __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL & 0x1f ), \ + "Association denied; short preamble support req'd" ) + +#define ECONNREFUSED_ASSOC_NEED_PBCC __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_PBCC ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_PBCC __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_PBCC & 0x1f ), \ + "Association denied; PBCC modulation support req'd" ) + +#define ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY & 0x1f ), \ + "Association denied; Channel Agility support req'd" ) + +#define ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT & 0x1f ), \ + "Association denied; Spectrum Management required" ) + +#define ECONNREFUSED_ASSOC_BAD_POWER __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_BAD_POWER ) +#define EINFO_ECONNREFUSED_ASSOC_BAD_POWER __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_BAD_POWER & 0x1f ), \ + "Association denied; Power Capability unacceptable" ) + +#define ECONNREFUSED_ASSOC_BAD_CHANNELS __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_BAD_CHANNELS ) +#define EINFO_ECONNREFUSED_ASSOC_BAD_CHANNELS __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_BAD_CHANNELS & 0x1f ), \ + "Association denied; Supported Channels unacceptable" ) + +#define ECONNREFUSED_ASSOC_NEED_SHORT_SLOT __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_SLOT ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_SLOT __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT & 0x1f ), \ + "Association denied; Short Slot Tume support req'd" ) + +#define ECONNREFUSED_ASSOC_NEED_DSSS_OFDM __einfo_error \ + ( EINFO_ECONNREFUSED_ASSOC_NEED_DSSS_OFDM ) +#define EINFO_ECONNREFUSED_ASSOC_NEED_DSSS_OFDM __einfo_uniqify \ + ( EINFO_ECONNREFUSED, \ + ( IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM & 0x1f ), \ + "Association denied; DSSS-OFDM support required" ) + +#define EHOSTUNREACH_QOS_FAILURE __einfo_error \ + ( EINFO_EHOSTUNREACH_QOS_FAILURE ) +#define EINFO_EHOSTUNREACH_QOS_FAILURE __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_QOS_FAILURE & 0x1f ), \ + "Unspecified, QoS-related failure" ) + +#define EHOSTUNREACH_QOS_NO_ROOM __einfo_error \ + ( EINFO_EHOSTUNREACH_QOS_NO_ROOM ) +#define EINFO_EHOSTUNREACH_QOS_NO_ROOM __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_QOS_NO_ROOM & 0x1f ), \ + "Association denied; QoS AP out of QoS resources" ) + +#define EHOSTUNREACH_LINK_IS_HORRIBLE __einfo_error \ + ( EINFO_EHOSTUNREACH_LINK_IS_HORRIBLE ) +#define EINFO_EHOSTUNREACH_LINK_IS_HORRIBLE __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_LINK_IS_HORRIBLE & 0x1f ), \ + "Association denied due to excessively poor link" ) + +#define EHOSTUNREACH_ASSOC_NEED_QOS __einfo_error \ + ( EINFO_EHOSTUNREACH_ASSOC_NEED_QOS ) +#define EINFO_EHOSTUNREACH_ASSOC_NEED_QOS __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_ASSOC_NEED_QOS & 0x1f ), \ + "Association denied; QoS support required" ) + +#define EHOSTUNREACH_REQUEST_DECLINED __einfo_error \ + ( EINFO_EHOSTUNREACH_REQUEST_DECLINED ) +#define EINFO_EHOSTUNREACH_REQUEST_DECLINED __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_REQUEST_DECLINED & 0x1f ), \ + "The request has been declined" ) + +#define EHOSTUNREACH_REQUEST_INVALID __einfo_error \ + ( EINFO_EHOSTUNREACH_REQUEST_INVALID ) +#define EINFO_EHOSTUNREACH_REQUEST_INVALID __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_REQUEST_INVALID & 0x1f ), \ + "Request unsuccessful due to invalid parameters" ) + +#define EHOSTUNREACH_TS_NOT_CREATED_AGAIN __einfo_error \ + ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_AGAIN ) +#define EINFO_EHOSTUNREACH_TS_NOT_CREATED_AGAIN __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_TS_NOT_CREATED_AGAIN & 0x1f ), \ + "TS not created due to bad specification" ) + +#define EHOSTUNREACH_INVALID_IE __einfo_error \ + ( EINFO_EHOSTUNREACH_INVALID_IE ) +#define EINFO_EHOSTUNREACH_INVALID_IE __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_INVALID_IE & 0x1f ), \ + "Invalid information element" ) + +#define EHOSTUNREACH_GROUP_CIPHER_INVALID __einfo_error \ + ( EINFO_EHOSTUNREACH_GROUP_CIPHER_INVALID ) +#define EINFO_EHOSTUNREACH_GROUP_CIPHER_INVALID __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_GROUP_CIPHER_INVALID & 0x1f ), \ + "Invalid group cipher" ) + +#define EHOSTUNREACH_PAIR_CIPHER_INVALID __einfo_error \ + ( EINFO_EHOSTUNREACH_PAIR_CIPHER_INVALID ) +#define EINFO_EHOSTUNREACH_PAIR_CIPHER_INVALID __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_PAIR_CIPHER_INVALID & 0x1f ), \ + "Invalid pairwise cipher" ) + +#define EHOSTUNREACH_AKMP_INVALID __einfo_error \ + ( EINFO_EHOSTUNREACH_AKMP_INVALID ) +#define EINFO_EHOSTUNREACH_AKMP_INVALID __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_AKMP_INVALID & 0x1f ), \ + "Invalid AKMP" ) + +#define EHOSTUNREACH_RSN_VERSION_UNSUPP __einfo_error \ + ( EINFO_EHOSTUNREACH_RSN_VERSION_UNSUPP ) +#define EINFO_EHOSTUNREACH_RSN_VERSION_UNSUPP __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_RSN_VERSION_UNSUPP & 0x1f ), \ + "Unsupported RSN information element version" ) + +#define EHOSTUNREACH_RSN_CAPAB_INVALID __einfo_error \ + ( EINFO_EHOSTUNREACH_RSN_CAPAB_INVALID ) +#define EINFO_EHOSTUNREACH_RSN_CAPAB_INVALID __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_RSN_CAPAB_INVALID & 0x1f ), \ + "Invalid RSN information element capabilities" ) + +#define EHOSTUNREACH_CIPHER_REJECTED __einfo_error \ + ( EINFO_EHOSTUNREACH_CIPHER_REJECTED ) +#define EINFO_EHOSTUNREACH_CIPHER_REJECTED __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_CIPHER_REJECTED & 0x1f ), \ + "Cipher suite rejected because of security policy" ) + +#define EHOSTUNREACH_TS_NOT_CREATED_WAIT __einfo_error \ + ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_WAIT ) +#define EINFO_EHOSTUNREACH_TS_NOT_CREATED_WAIT __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_TS_NOT_CREATED_WAIT & 0x1f ), \ + "TS not created due to insufficient delay" ) + +#define EHOSTUNREACH_DIRECT_LINK_FORBIDDEN __einfo_error \ + ( EINFO_EHOSTUNREACH_DIRECT_LINK_FORBIDDEN ) +#define EINFO_EHOSTUNREACH_DIRECT_LINK_FORBIDDEN __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_DIRECT_LINK_FORBIDDEN & 0x1f ), \ + "Direct link is not allowed in the BSS by policy" ) + +#define EHOSTUNREACH_DEST_NOT_PRESENT __einfo_error \ + ( EINFO_EHOSTUNREACH_DEST_NOT_PRESENT ) +#define EINFO_EHOSTUNREACH_DEST_NOT_PRESENT __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_DEST_NOT_PRESENT & 0x1f ), \ + "The Destination STA is not present within the BSS" ) + +#define EHOSTUNREACH_DEST_NOT_QOS __einfo_error \ + ( EINFO_EHOSTUNREACH_DEST_NOT_QOS ) +#define EINFO_EHOSTUNREACH_DEST_NOT_QOS __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_DEST_NOT_QOS & 0x1f ), \ + "The Destination STA is not a QoS STA" ) + +#define EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH __einfo_error \ + ( EINFO_EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH ) +#define EINFO_EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH __einfo_uniqify \ + ( EINFO_EHOSTUNREACH, \ + ( IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH & 0x1f ), \ + "Association denied; Listen Interval is too large" ) + +/* 802.11 reason codes (IEEE Std 802.11-2007, Table 7-22) */ + +#define ECONNRESET_UNSPECIFIED __einfo_error \ + ( EINFO_ECONNRESET_UNSPECIFIED ) +#define EINFO_ECONNRESET_UNSPECIFIED __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_UNSPECIFIED & 0x1f ), \ + "Unspecified reason" ) + +#define ECONNRESET_AUTH_NO_LONGER_VALID __einfo_error \ + ( EINFO_ECONNRESET_AUTH_NO_LONGER_VALID ) +#define EINFO_ECONNRESET_AUTH_NO_LONGER_VALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_AUTH_NO_LONGER_VALID & 0x1f ), \ + "Previous authentication no longer valid" ) + +#define ECONNRESET_LEAVING __einfo_error \ + ( EINFO_ECONNRESET_LEAVING ) +#define EINFO_ECONNRESET_LEAVING __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_LEAVING & 0x1f ), \ + "Deauthenticated due to leaving network" ) + +#define ECONNRESET_INACTIVITY __einfo_error \ + ( EINFO_ECONNRESET_INACTIVITY ) +#define EINFO_ECONNRESET_INACTIVITY __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_INACTIVITY & 0x1f ), \ + "Disassociated due to inactivity" ) + +#define ECONNRESET_OUT_OF_RESOURCES __einfo_error \ + ( EINFO_ECONNRESET_OUT_OF_RESOURCES ) +#define EINFO_ECONNRESET_OUT_OF_RESOURCES __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_OUT_OF_RESOURCES & 0x1f ), \ + "Disassociated because AP is out of resources" ) + +#define ECONNRESET_NEED_AUTH __einfo_error \ + ( EINFO_ECONNRESET_NEED_AUTH ) +#define EINFO_ECONNRESET_NEED_AUTH __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_NEED_AUTH & 0x1f ), \ + "Class 2 frame received from nonauthenticated STA" ) + +#define ECONNRESET_NEED_ASSOC __einfo_error \ + ( EINFO_ECONNRESET_NEED_ASSOC ) +#define EINFO_ECONNRESET_NEED_ASSOC __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_NEED_ASSOC & 0x1f ), \ + "Class 3 frame received from nonassociated STA" ) + +#define ECONNRESET_LEAVING_TO_ROAM __einfo_error \ + ( EINFO_ECONNRESET_LEAVING_TO_ROAM ) +#define EINFO_ECONNRESET_LEAVING_TO_ROAM __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_LEAVING_TO_ROAM & 0x1f ), \ + "Disassociated due to roaming" ) + +#define ECONNRESET_REASSOC_INVALID __einfo_error \ + ( EINFO_ECONNRESET_REASSOC_INVALID ) +#define EINFO_ECONNRESET_REASSOC_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_REASSOC_INVALID & 0x1f ), \ + "STA requesting (re)association not authenticated" ) + +#define ECONNRESET_BAD_POWER __einfo_error \ + ( EINFO_ECONNRESET_BAD_POWER ) +#define EINFO_ECONNRESET_BAD_POWER __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_BAD_POWER & 0x1f ), \ + "Disassociated; Power Capability unacceptable" ) + +#define ECONNRESET_BAD_CHANNELS __einfo_error \ + ( EINFO_ECONNRESET_BAD_CHANNELS ) +#define EINFO_ECONNRESET_BAD_CHANNELS __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_BAD_CHANNELS & 0x1f ), \ + "Disassociated; Supported Channels unacceptable" ) + +#define ECONNRESET_INVALID_IE __einfo_error \ + ( EINFO_ECONNRESET_INVALID_IE ) +#define EINFO_ECONNRESET_INVALID_IE __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_INVALID_IE & 0x1f ), \ + "Invalid information element" ) + +#define ECONNRESET_MIC_FAILURE __einfo_error \ + ( EINFO_ECONNRESET_MIC_FAILURE ) +#define EINFO_ECONNRESET_MIC_FAILURE __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_MIC_FAILURE & 0x1f ), \ + "Message integrity code (MIC) failure" ) + +#define ECONNRESET_4WAY_TIMEOUT __einfo_error \ + ( EINFO_ECONNRESET_4WAY_TIMEOUT ) +#define EINFO_ECONNRESET_4WAY_TIMEOUT __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_4WAY_TIMEOUT & 0x1f ), \ + "4-Way Handshake timeout" ) + +#define ECONNRESET_GROUPKEY_TIMEOUT __einfo_error \ + ( EINFO_ECONNRESET_GROUPKEY_TIMEOUT ) +#define EINFO_ECONNRESET_GROUPKEY_TIMEOUT __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_GROUPKEY_TIMEOUT & 0x1f ), \ + "Group Key Handshake timeout" ) + +#define ECONNRESET_4WAY_INVALID __einfo_error \ + ( EINFO_ECONNRESET_4WAY_INVALID ) +#define EINFO_ECONNRESET_4WAY_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_4WAY_INVALID & 0x1f ), \ + "4-Way Handshake information element changed unduly" ) + +#define ECONNRESET_GROUP_CIPHER_INVALID __einfo_error \ + ( EINFO_ECONNRESET_GROUP_CIPHER_INVALID ) +#define EINFO_ECONNRESET_GROUP_CIPHER_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_GROUP_CIPHER_INVALID & 0x1f ), \ + "Invalid group cipher" ) + +#define ECONNRESET_PAIR_CIPHER_INVALID __einfo_error \ + ( EINFO_ECONNRESET_PAIR_CIPHER_INVALID ) +#define EINFO_ECONNRESET_PAIR_CIPHER_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_PAIR_CIPHER_INVALID & 0x1f ), \ + "Invalid pairwise cipher" ) + +#define ECONNRESET_AKMP_INVALID __einfo_error \ + ( EINFO_ECONNRESET_AKMP_INVALID ) +#define EINFO_ECONNRESET_AKMP_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_AKMP_INVALID & 0x1f ), \ + "Invalid AKMP" ) + +#define ECONNRESET_RSN_VERSION_INVALID __einfo_error \ + ( EINFO_ECONNRESET_RSN_VERSION_INVALID ) +#define EINFO_ECONNRESET_RSN_VERSION_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_RSN_VERSION_INVALID & 0x1f ), \ + "Unsupported RSN information element version" ) + +#define ECONNRESET_RSN_CAPAB_INVALID __einfo_error \ + ( EINFO_ECONNRESET_RSN_CAPAB_INVALID ) +#define EINFO_ECONNRESET_RSN_CAPAB_INVALID __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_RSN_CAPAB_INVALID & 0x1f ), \ + "Invalid RSN information element capabilities" ) + +#define ECONNRESET_8021X_FAILURE __einfo_error \ + ( EINFO_ECONNRESET_8021X_FAILURE ) +#define EINFO_ECONNRESET_8021X_FAILURE __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_8021X_FAILURE & 0x1f ), \ + "IEEE 802.1X authentication failed" ) + +#define ECONNRESET_CIPHER_REJECTED __einfo_error \ + ( EINFO_ECONNRESET_CIPHER_REJECTED ) +#define EINFO_ECONNRESET_CIPHER_REJECTED __einfo_uniqify \ + ( EINFO_ECONNRESET, \ + ( IEEE80211_REASON_CIPHER_REJECTED & 0x1f ), \ + "Cipher suite rejected because of security policy" ) + +#define ENETRESET_QOS_UNSPECIFIED __einfo_error \ + ( EINFO_ENETRESET_QOS_UNSPECIFIED ) +#define EINFO_ENETRESET_QOS_UNSPECIFIED __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_QOS_UNSPECIFIED & 0x1f ), \ + "Disassociated for unspecified, QoS-related reason" ) + +#define ENETRESET_QOS_OUT_OF_RESOURCES __einfo_error \ + ( EINFO_ENETRESET_QOS_OUT_OF_RESOURCES ) +#define EINFO_ENETRESET_QOS_OUT_OF_RESOURCES __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_QOS_OUT_OF_RESOURCES & 0x1f ), \ + "Disassociated; QoS AP is out of QoS resources" ) + +#define ENETRESET_LINK_IS_HORRIBLE __einfo_error \ + ( EINFO_ENETRESET_LINK_IS_HORRIBLE ) +#define EINFO_ENETRESET_LINK_IS_HORRIBLE __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_LINK_IS_HORRIBLE & 0x1f ), \ + "Disassociated due to excessively poor link" ) + +#define ENETRESET_INVALID_TXOP __einfo_error \ + ( EINFO_ENETRESET_INVALID_TXOP ) +#define EINFO_ENETRESET_INVALID_TXOP __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_INVALID_TXOP & 0x1f ), \ + "Disassociated due to TXOP limit violation" ) + +#define ENETRESET_REQUESTED_LEAVING __einfo_error \ + ( EINFO_ENETRESET_REQUESTED_LEAVING ) +#define EINFO_ENETRESET_REQUESTED_LEAVING __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_REQUESTED_LEAVING & 0x1f ), \ + "Requested; STA is leaving the BSS (or resetting)" ) + +#define ENETRESET_REQUESTED_NO_USE __einfo_error \ + ( EINFO_ENETRESET_REQUESTED_NO_USE ) +#define EINFO_ENETRESET_REQUESTED_NO_USE __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_REQUESTED_NO_USE & 0x1f ), \ + "Requested; does not want to use the mechanism" ) + +#define ENETRESET_REQUESTED_NEED_SETUP __einfo_error \ + ( EINFO_ENETRESET_REQUESTED_NEED_SETUP ) +#define EINFO_ENETRESET_REQUESTED_NEED_SETUP __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_REQUESTED_NEED_SETUP & 0x1f ), \ + "Requested; setup is required" ) + +#define ENETRESET_REQUESTED_TIMEOUT __einfo_error \ + ( EINFO_ENETRESET_REQUESTED_TIMEOUT ) +#define EINFO_ENETRESET_REQUESTED_TIMEOUT __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_REQUESTED_TIMEOUT & 0x1f ), \ + "Requested from peer STA due to timeout" ) + +#define ENETRESET_CIPHER_UNSUPPORTED __einfo_error \ + ( EINFO_ENETRESET_CIPHER_UNSUPPORTED ) +#define EINFO_ENETRESET_CIPHER_UNSUPPORTED __einfo_uniqify \ + ( EINFO_ENETRESET, \ + ( IEEE80211_REASON_CIPHER_UNSUPPORTED & 0x1f ), \ + "Peer STA does not support requested cipher suite" ) + +/** Make return status code from 802.11 status code */ +#define E80211_STATUS( stat ) \ + EUNIQ ( ( ( stat & 0x20 ) ? EHOSTUNREACH : ECONNREFUSED ), \ + ( stat &0x1f ), \ + ECONNREFUSED_FAILURE, \ + ECONNREFUSED_CAPAB_UNSUPP, \ + ECONNREFUSED_REASSOC_INVALID, \ + ECONNREFUSED_ASSOC_DENIED, \ + ECONNREFUSED_AUTH_ALGO_UNSUPP, \ + ECONNREFUSED_AUTH_SEQ_INVALID, \ + ECONNREFUSED_AUTH_CHALL_INVALID, \ + ECONNREFUSED_AUTH_TIMEOUT, \ + ECONNREFUSED_ASSOC_NO_ROOM, \ + ECONNREFUSED_ASSOC_NEED_RATE, \ + ECONNREFUSED_ASSOC_NEED_SHORT_PMBL, \ + ECONNREFUSED_ASSOC_NEED_PBCC, \ + ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY, \ + ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT, \ + ECONNREFUSED_ASSOC_BAD_POWER, \ + ECONNREFUSED_ASSOC_BAD_CHANNELS, \ + ECONNREFUSED_ASSOC_NEED_SHORT_SLOT, \ + ECONNREFUSED_ASSOC_NEED_DSSS_OFDM, \ + EHOSTUNREACH_QOS_FAILURE, \ + EHOSTUNREACH_QOS_NO_ROOM, \ + EHOSTUNREACH_LINK_IS_HORRIBLE, \ + EHOSTUNREACH_ASSOC_NEED_QOS, \ + EHOSTUNREACH_REQUEST_DECLINED, \ + EHOSTUNREACH_REQUEST_INVALID, \ + EHOSTUNREACH_TS_NOT_CREATED_AGAIN, \ + EHOSTUNREACH_INVALID_IE, \ + EHOSTUNREACH_GROUP_CIPHER_INVALID, \ + EHOSTUNREACH_PAIR_CIPHER_INVALID, \ + EHOSTUNREACH_AKMP_INVALID, \ + EHOSTUNREACH_RSN_VERSION_UNSUPP, \ + EHOSTUNREACH_RSN_CAPAB_INVALID, \ + EHOSTUNREACH_CIPHER_REJECTED, \ + EHOSTUNREACH_TS_NOT_CREATED_WAIT, \ + EHOSTUNREACH_DIRECT_LINK_FORBIDDEN, \ + EHOSTUNREACH_DEST_NOT_PRESENT, \ + EHOSTUNREACH_DEST_NOT_QOS, \ + EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH ) + +/** Make return status code from 802.11 reason code */ +#define E80211_REASON( reas ) \ + EUNIQ ( ( ( reas & 0x20 ) ? ENETRESET : ECONNRESET ), \ + ( reas & 0x1f ), \ + ECONNRESET_UNSPECIFIED, \ + ECONNRESET_AUTH_NO_LONGER_VALID, \ + ECONNRESET_LEAVING, \ + ECONNRESET_INACTIVITY, \ + ECONNRESET_OUT_OF_RESOURCES, \ + ECONNRESET_NEED_AUTH, \ + ECONNRESET_NEED_ASSOC, \ + ECONNRESET_LEAVING_TO_ROAM, \ + ECONNRESET_REASSOC_INVALID, \ + ECONNRESET_BAD_POWER, \ + ECONNRESET_BAD_CHANNELS, \ + ECONNRESET_INVALID_IE, \ + ECONNRESET_MIC_FAILURE, \ + ECONNRESET_4WAY_TIMEOUT, \ + ECONNRESET_GROUPKEY_TIMEOUT, \ + ECONNRESET_4WAY_INVALID, \ + ECONNRESET_GROUP_CIPHER_INVALID, \ + ECONNRESET_PAIR_CIPHER_INVALID, \ + ECONNRESET_AKMP_INVALID, \ + ECONNRESET_RSN_VERSION_INVALID, \ + ECONNRESET_RSN_CAPAB_INVALID, \ + ECONNRESET_8021X_FAILURE, \ + ECONNRESET_CIPHER_REJECTED, \ + ENETRESET_QOS_UNSPECIFIED, \ + ENETRESET_QOS_OUT_OF_RESOURCES, \ + ENETRESET_LINK_IS_HORRIBLE, \ + ENETRESET_INVALID_TXOP, \ + ENETRESET_REQUESTED_LEAVING, \ + ENETRESET_REQUESTED_NO_USE, \ + ENETRESET_REQUESTED_NEED_SETUP, \ + ENETRESET_REQUESTED_TIMEOUT, \ + ENETRESET_CIPHER_UNSUPPORTED ) + +#endif /* _IPXE_NET80211_ERR_H */ diff --git a/src/net/80211/net80211.c b/src/net/80211/net80211.c index 8df2c315..7b391145 100644 --- a/src/net/80211/net80211.c +++ b/src/net/80211/net80211.c @@ -23,6 +23,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include +#include #include #include #include @@ -32,52 +34,14 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include -#include -#include +#include +#include /** @file * * 802.11 device management */ -/* Disambiguate the EINVAL's a bit */ -#define EINVAL_PKT_TOO_SHORT ( EINVAL | EUNIQ_01 ) -#define EINVAL_PKT_VERSION ( EINVAL | EUNIQ_02 ) -#define EINVAL_PKT_NOT_DATA ( EINVAL | EUNIQ_03 ) -#define EINVAL_PKT_NOT_FROMDS ( EINVAL | EUNIQ_04 ) -#define EINVAL_PKT_LLC_HEADER ( EINVAL | EUNIQ_05 ) -#define EINVAL_CRYPTO_REQUEST ( EINVAL | EUNIQ_06 ) -#define EINVAL_ACTIVE_SCAN ( EINVAL | EUNIQ_07 ) - -/* - * 802.11 error codes: The AP can give us a status code explaining why - * authentication failed, or a reason code explaining why we were - * deauthenticated/disassociated. These codes range from 0-63 (the - * field is 16 bits wide, but only up to 45 or so are defined yet; we - * allow up to 63 for extensibility). This is encoded into an error - * code as such: - * - * status & 0x1f goes here --vv-- - * Status code 0-31: ECONNREFUSED | EUNIQ_(status & 0x1f) (0e1a6038) - * Status code 32-63: EHOSTUNREACH | EUNIQ_(status & 0x1f) (171a6011) - * Reason code 0-31: ECONNRESET | EUNIQ_(reason & 0x1f) (0f1a6039) - * Reason code 32-63: ENETRESET | EUNIQ_(reason & 0x1f) (271a6001) - * - * The POSIX error codes more or less convey the appropriate message - * (status codes occur when we can't associate at all, reason codes - * when we lose association unexpectedly) and let us extract the - * complete 802.11 error code from the rc value. - */ - -/** Make return status code from 802.11 status code */ -#define E80211_STATUS( stat ) ( ((stat & 0x20)? EHOSTUNREACH : ECONNREFUSED) \ - | ((stat & 0x1f) << 8) ) - -/** Make return status code from 802.11 reason code */ -#define E80211_REASON( reas ) ( ((reas & 0x20)? ENETRESET : ECONNRESET) \ - | ((reas & 0x1f) << 8) ) - - /** List of 802.11 devices */ static struct list_head net80211_devices = LIST_HEAD_INIT ( net80211_devices ); @@ -2838,3 +2802,15 @@ void net80211_tx_complete ( struct net80211_device *dev, /* Pass completion onward */ netdev_tx_complete_err ( dev->netdev, iob, rc ); } + +/** Common 802.11 errors */ +struct errortab common_wireless_errors[] __errortab = { + __einfo_errortab ( EINFO_EINVAL_CRYPTO_REQUEST ), + __einfo_errortab ( EINFO_ECONNRESET_UNSPECIFIED ), + __einfo_errortab ( EINFO_ECONNRESET_INACTIVITY ), + __einfo_errortab ( EINFO_ECONNRESET_4WAY_TIMEOUT ), + __einfo_errortab ( EINFO_ECONNRESET_8021X_FAILURE ), + __einfo_errortab ( EINFO_ECONNREFUSED_FAILURE ), + __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_DENIED ), + __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP ), +}; diff --git a/src/net/80211/sec80211.c b/src/net/80211/sec80211.c index 69fad8ff..ea4b0d00 100644 --- a/src/net/80211/sec80211.c +++ b/src/net/80211/sec80211.c @@ -34,6 +34,20 @@ FILE_LICENCE ( GPL2_OR_LATER ); * static data in this file. */ +/* Unsupported cryptosystem error numbers */ +#define ENOTSUP_WEP __einfo_error ( EINFO_ENOTSUP_WEP ) +#define EINFO_ENOTSUP_WEP __einfo_uniqify ( EINFO_ENOTSUP, \ + ( 0x10 | NET80211_CRYPT_WEP ), "WEP not supported" ) +#define ENOTSUP_TKIP __einfo_error ( EINFO_ENOTSUP_TKIP ) +#define EINFO_ENOTSUP_TKIP __einfo_uniqify ( EINFO_ENOTSUP, \ + ( 0x10 | NET80211_CRYPT_TKIP ), "TKIP not supported" ) +#define ENOTSUP_CCMP __einfo_error ( EINFO_ENOTSUP_CCMP ) +#define EINFO_ENOTSUP_CCMP __einfo_uniqify ( EINFO_ENOTSUP, \ + ( 0x10 | NET80211_CRYPT_CCMP ), "CCMP not supported" ) +#define ENOTSUP_CRYPT( crypt ) \ + EUNIQ ( ENOTSUP, ( 0x10 | (crypt) ), \ + ENOTSUP_WEP, ENOTSUP_TKIP, ENOTSUP_CCMP ) + /** Mapping from net80211 crypto/secprot types to RSN OUI descriptors */ struct descriptor_map { /** Value of net80211_crypto_alg or net80211_security_proto */ @@ -130,7 +144,7 @@ int sec80211_install ( struct net80211_crypto **which, if ( ! crypto ) { DBG ( "802.11-Sec no support for cryptosystem %d\n", crypt ); - return -( ENOTSUP | EUNIQ_10 | ( crypt << 8 ) ); + return -ENOTSUP_CRYPT ( crypt ); } *which = crypto; diff --git a/src/net/infiniband.c b/src/net/infiniband.c index dd98e922..5daecd52 100644 --- a/src/net/infiniband.c +++ b/src/net/infiniband.c @@ -50,13 +50,17 @@ struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices ); static struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices ); /* Disambiguate the various possible EINPROGRESSes */ -#define EINPROGRESS_INIT ( EINPROGRESS | EUNIQ_01 ) -#define EINPROGRESS_ARMED ( EINPROGRESS | EUNIQ_02 ) +#define EINPROGRESS_INIT __einfo_error ( EINFO_EINPROGRESS_INIT ) +#define EINFO_EINPROGRESS_INIT __einfo_uniqify \ + ( EINFO_EINPROGRESS, 0x01, "Initialising" ) +#define EINPROGRESS_ARMED __einfo_error ( EINFO_EINPROGRESS_ARMED ) +#define EINFO_EINPROGRESS_ARMED __einfo_uniqify \ + ( EINFO_EINPROGRESS, 0x02, "Armed" ) /** Human-readable message for the link statuses */ struct errortab infiniband_errors[] __errortab = { - { EINPROGRESS_INIT, "Initialising" }, - { EINPROGRESS_ARMED, "Armed" }, + __einfo_errortab ( EINFO_EINPROGRESS_INIT ), + __einfo_errortab ( EINFO_EINPROGRESS_ARMED ), }; /*************************************************************************** diff --git a/src/net/infiniband/ib_srp.c b/src/net/infiniband/ib_srp.c index f4ec544c..ef0078d4 100644 --- a/src/net/infiniband/ib_srp.c +++ b/src/net/infiniband/ib_srp.c @@ -46,10 +46,15 @@ FILE_LICENCE ( BSD2 ); */ /* Disambiguate the various possible EINVALs */ -#define EINVAL_BYTE_STRING_LEN ( EINVAL | EUNIQ_01 ) -#define EINVAL_BYTE_STRING ( EINVAL | EUNIQ_02 ) -#define EINVAL_INTEGER ( EINVAL | EUNIQ_03 ) -#define EINVAL_RP_TOO_SHORT ( EINVAL | EUNIQ_04 ) +#define EINVAL_BYTE_STRING_LEN __einfo_error ( EINFO_EINVAL_BYTE_STRING_LEN ) +#define EINFO_EINVAL_BYTE_STRING_LEN __einfo_uniqify \ + ( EINFO_EINVAL, 0x01, "Invalid byte string length" ) +#define EINVAL_INTEGER __einfo_error ( EINFO_EINVAL_INTEGER ) +#define EINFO_EINVAL_INTEGER __einfo_uniqify \ + ( EINFO_EINVAL, 0x03, "Invalid integer" ) +#define EINVAL_RP_TOO_SHORT __einfo_error ( EINFO_EINVAL_RP_TOO_SHORT ) +#define EINFO_EINVAL_RP_TOO_SHORT __einfo_uniqify \ + ( EINFO_EINVAL, 0x04, "Root path too short" ) /** IB SRP parse flags */ enum ib_srp_parse_flags { diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 9b42ad37..6c91b489 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -46,11 +46,13 @@ struct list_head net_devices = LIST_HEAD_INIT ( net_devices ); static struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices ); /** Default link status code */ -#define EUNKNOWN_LINK_STATUS EINPROGRESS +#define EUNKNOWN_LINK_STATUS __einfo_error ( EINFO_EUNKNOWN_LINK_STATUS ) +#define EINFO_EUNKNOWN_LINK_STATUS \ + __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" ) /** Human-readable message for the default link status */ struct errortab netdev_errors[] __errortab = { - { EUNKNOWN_LINK_STATUS, "Unknown" }, + __einfo_errortab ( EINFO_EUNKNOWN_LINK_STATUS ), }; /** @@ -60,16 +62,12 @@ struct errortab netdev_errors[] __errortab = { */ void netdev_link_down ( struct net_device *netdev ) { - switch ( netdev->link_rc ) { - case 0: - case -EUNKNOWN_LINK_STATUS: + /* Avoid clobbering a more detailed link status code, if one + * is already set. + */ + if ( ( netdev->link_rc == 0 ) || + ( netdev->link_rc == -EUNKNOWN_LINK_STATUS ) ) { netdev->link_rc = -ENOTCONN; - break; - default: - /* Avoid clobbering a more detailed link status code, - * if one is already set. - */ - break; } } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index d35e3715..69d18504 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -48,17 +48,50 @@ FILE_LICENCE ( GPL2_OR_LATER ); FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 ); /* Disambiguate the various error causes */ -#define EACCES_INCORRECT_TARGET_USERNAME ( EACCES | EUNIQ_01 ) -#define EACCES_INCORRECT_TARGET_PASSWORD ( EACCES | EUNIQ_02 ) -#define ENOTSUP_INITIATOR_STATUS ( ENOTSUP | EUNIQ_01 ) -#define ENOTSUP_OPCODE ( ENOTSUP | EUNIQ_02 ) -#define ENOTSUP_DISCOVERY ( ENOTSUP | EUNIQ_03 ) -#define EPERM_INITIATOR_AUTHENTICATION ( EPERM | EUNIQ_01 ) -#define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 ) -#define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 ) -#define EPROTO_INVALID_CHAP_IDENTIFIER ( EPROTO | EUNIQ_02 ) -#define EPROTO_INVALID_LARGE_BINARY ( EPROTO | EUNIQ_03 ) -#define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 ) +#define EACCES_INCORRECT_TARGET_USERNAME \ + __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME ) +#define EINFO_EACCES_INCORRECT_TARGET_USERNAME \ + __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" ) +#define EACCES_INCORRECT_TARGET_PASSWORD \ + __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD ) +#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD \ + __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" ) +#define ENOTSUP_INITIATOR_STATUS \ + __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS ) +#define EINFO_ENOTSUP_INITIATOR_STATUS \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" ) +#define ENOTSUP_OPCODE \ + __einfo_error ( EINFO_ENOTSUP_OPCODE ) +#define EINFO_ENOTSUP_OPCODE \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" ) +#define ENOTSUP_DISCOVERY \ + __einfo_error ( EINFO_ENOTSUP_DISCOVERY ) +#define EINFO_ENOTSUP_DISCOVERY \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" ) +#define EPERM_INITIATOR_AUTHENTICATION \ + __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION ) +#define EINFO_EPERM_INITIATOR_AUTHENTICATION \ + __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" ) +#define EPERM_INITIATOR_AUTHORISATION \ + __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION ) +#define EINFO_EPERM_INITIATOR_AUTHORISATION \ + __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" ) +#define EPROTO_INVALID_CHAP_ALGORITHM \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM ) +#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM \ + __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" ) +#define EPROTO_INVALID_CHAP_IDENTIFIER \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER ) +#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER \ + __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" ) +#define EPROTO_INVALID_LARGE_BINARY \ + __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY ) +#define EINFO_EPROTO_INVALID_LARGE_BINARY \ + __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary" ) +#define EPROTO_INVALID_CHAP_RESPONSE \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE ) +#define EINFO_EPROTO_INVALID_CHAP_RESPONSE \ + __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" ) /** iSCSI initiator name (explicitly specified) */ static char *iscsi_explicit_initiator_iqn; diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 70ba4f62..d49f4256 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -48,13 +48,27 @@ FILE_LICENCE ( GPL2_OR_LATER ); FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 ); /* TFTP-specific error codes */ -#define ETFTP_INVALID_BLKSIZE EUNIQ_01 -#define ETFTP_INVALID_TSIZE EUNIQ_02 -#define ETFTP_MC_NO_PORT EUNIQ_03 -#define ETFTP_MC_NO_MC EUNIQ_04 -#define ETFTP_MC_INVALID_MC EUNIQ_05 -#define ETFTP_MC_INVALID_IP EUNIQ_06 -#define ETFTP_MC_INVALID_PORT EUNIQ_07 +#define EINVAL_BLKSIZE __einfo_error ( EINFO_EINVAL_BLKSIZE ) +#define EINFO_EINVAL_BLKSIZE __einfo_uniqify \ + ( EINFO_EINVAL, 0x01, "Invalid blksize" ) +#define EINVAL_TSIZE __einfo_error ( EINFO_EINVAL_TSIZE ) +#define EINFO_EINVAL_TSIZE __einfo_uniqify \ + ( EINFO_EINVAL, 0x02, "Invalid tsize" ) +#define EINVAL_MC_NO_PORT __einfo_error ( EINFO_EINVAL_MC_NO_PORT ) +#define EINFO_EINVAL_MC_NO_PORT __einfo_uniqify \ + ( EINFO_EINVAL, 0x03, "Missing multicast port" ) +#define EINVAL_MC_NO_MC __einfo_error ( EINFO_EINVAL_MC_NO_MC ) +#define EINFO_EINVAL_MC_NO_MC __einfo_uniqify \ + ( EINFO_EINVAL, 0x04, "Missing multicast mc" ) +#define EINVAL_MC_INVALID_MC __einfo_error ( EINFO_EINVAL_MC_INVALID_MC ) +#define EINFO_EINVAL_MC_INVALID_MC __einfo_uniqify \ + ( EINFO_EINVAL, 0x05, "Missing multicast IP" ) +#define EINVAL_MC_INVALID_IP __einfo_error ( EINFO_EINVAL_MC_INVALID_IP ) +#define EINFO_EINVAL_MC_INVALID_IP __einfo_uniqify \ + ( EINFO_EINVAL, 0x06, "Invalid multicast IP" ) +#define EINVAL_MC_INVALID_PORT __einfo_error ( EINFO_EINVAL_MC_INVALID_PORT ) +#define EINFO_EINVAL_MC_INVALID_PORT __einfo_uniqify \ + ( EINFO_EINVAL, 0x07, "Invalid multicast port" ) /** * A TFTP request @@ -560,7 +574,7 @@ static int tftp_process_blksize ( struct tftp_request *tftp, if ( *end ) { DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n", tftp, value ); - return -( EINVAL | ETFTP_INVALID_BLKSIZE ); + return -EINVAL_BLKSIZE; } DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize ); @@ -582,7 +596,7 @@ static int tftp_process_tsize ( struct tftp_request *tftp, if ( *end ) { DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n", tftp, value ); - return -( EINVAL | ETFTP_INVALID_TSIZE ); + return -EINVAL_TSIZE; } DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize ); @@ -616,13 +630,13 @@ static int tftp_process_multicast ( struct tftp_request *tftp, port = strchr ( addr, ',' ); if ( ! port ) { DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp ); - return -( EINVAL | ETFTP_MC_NO_PORT ); + return -EINVAL_MC_NO_PORT; } *(port++) = '\0'; mc = strchr ( port, ',' ); if ( ! mc ) { DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp ); - return -( EINVAL | ETFTP_MC_NO_MC ); + return -EINVAL_MC_NO_MC; } *(mc++) = '\0'; @@ -631,7 +645,7 @@ static int tftp_process_multicast ( struct tftp_request *tftp, tftp->flags &= ~TFTP_FL_SEND_ACK; if ( *mc_end ) { DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc ); - return -( EINVAL | ETFTP_MC_INVALID_MC ); + return -EINVAL_MC_INVALID_MC; } DBGC ( tftp, "TFTP %p is%s the master client\n", tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) ); @@ -640,7 +654,7 @@ static int tftp_process_multicast ( struct tftp_request *tftp, if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) { DBGC ( tftp, "TFTP %p multicast invalid IP address " "%s\n", tftp, addr ); - return -( EINVAL | ETFTP_MC_INVALID_IP ); + return -EINVAL_MC_INVALID_IP; } DBGC ( tftp, "TFTP %p multicast IP address %s\n", tftp, inet_ntoa ( socket.sin.sin_addr ) ); @@ -648,7 +662,7 @@ static int tftp_process_multicast ( struct tftp_request *tftp, if ( *port_end ) { DBGC ( tftp, "TFTP %p multicast invalid port %s\n", tftp, port ); - return -( EINVAL | ETFTP_MC_INVALID_PORT ); + return -EINVAL_MC_INVALID_PORT; } DBGC ( tftp, "TFTP %p multicast port %d\n", tftp, ntohs ( socket.sin.sin_port ) ); @@ -872,12 +886,20 @@ static int tftp_rx_data ( struct tftp_request *tftp, return rc; } -/** Translation between TFTP errors and internal error numbers */ -static const int tftp_errors[] = { - [TFTP_ERR_FILE_NOT_FOUND] = ENOENT, - [TFTP_ERR_ACCESS_DENIED] = EACCES, - [TFTP_ERR_ILLEGAL_OP] = ENOTSUP, -}; +/** + * Convert TFTP error code to return status code + * + * @v errcode TFTP error code + * @ret rc Return status code + */ +static int tftp_errcode_to_rc ( unsigned int errcode ) { + switch ( errcode ) { + case TFTP_ERR_FILE_NOT_FOUND: return -ENOENT; + case TFTP_ERR_ACCESS_DENIED: return -EACCES; + case TFTP_ERR_ILLEGAL_OP: return -ENOTTY; + default: return -ENOTSUP; + } +} /** * Receive ERROR @@ -889,8 +911,7 @@ static const int tftp_errors[] = { */ static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) { struct tftp_error *error = buf; - unsigned int err; - int rc = 0; + int rc; /* Sanity check */ if ( len < sizeof ( *error ) ) { @@ -903,11 +924,7 @@ static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) { "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg ); /* Determine final operation result */ - err = ntohs ( error->errcode ); - if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) ) - rc = -tftp_errors[err]; - if ( ! rc ) - rc = -ENOTSUP; + rc = tftp_errcode_to_rc ( ntohs ( error->errcode ) ); /* Close TFTP request */ tftp_done ( tftp, rc ); diff --git a/src/usr/iwmgmt.c b/src/usr/iwmgmt.c index 27e77950..db0d1b44 100644 --- a/src/usr/iwmgmt.c +++ b/src/usr/iwmgmt.c @@ -26,7 +26,6 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include -#include /** @file * @@ -225,20 +224,3 @@ int iwlist ( struct net80211_device *dev ) { dev->netdev->name, strerror ( rc ) ); return rc; } - - -/* Record error codes as though they come from the 802.11 stack */ -#undef ERRFILE -#define ERRFILE ERRFILE_net80211 - -/** Common 802.11 errors */ -struct errortab common_wireless_errors[] __errortab = { - { EINVAL | EUNIQ_06, "Packet decryption error" }, - { ECONNRESET | EUNIQ_01, "Unspecified reason" }, - { ECONNRESET | EUNIQ_04, "Disassociated due to inactivity" }, - { ECONNRESET | EUNIQ_0F, "4-Way Handshake timeout" }, - { ECONNRESET | EUNIQ_17, "IEEE 802.1X authentication failed" }, - { ECONNREFUSED | EUNIQ_01, "Unspecified failure" }, - { ECONNREFUSED | EUNIQ_0C, "Association denied" }, - { ECONNREFUSED | EUNIQ_0D, "Authentication method not supported" }, -}; diff --git a/src/util/.gitignore b/src/util/.gitignore index a3752470..633ca322 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore @@ -6,3 +6,4 @@ elf2efi32 elf2efi64 efirom iccfix +einfo diff --git a/src/util/einfo.c b/src/util/einfo.c new file mode 100644 index 00000000..06736f21 --- /dev/null +++ b/src/util/einfo.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define eprintf(...) fprintf ( stderr, __VA_ARGS__ ) + +/** Command-line options */ +struct options { +}; + +/** Error usage information */ +struct einfo { + uint32_t size; + uint32_t error; + uint32_t desc; + uint32_t file; + uint32_t line; +} __attribute__ (( packed )); + +/** + * Process einfo file + * + * @v infile Filename + * @v opts Command-line options + */ +static void einfo ( const char *infile, struct options *opts ) { + int fd; + struct stat stat; + size_t len; + void *start; + struct einfo *einfo; + + /* Open einfo file */ + if ( ( fd = open ( infile, O_RDONLY ) ) < 0 ) { + eprintf ( "Cannot open \"%s\": %s\n", + infile, strerror ( errno ) ); + exit ( 1 ); + } + + /* Get file size */ + if ( fstat ( fd, &stat ) < 0 ) { + eprintf ( "Cannot stat \"%s\": %s\n", + infile, strerror ( errno ) ); + exit ( 1 ); + } + len = stat.st_size; + + if ( len ) { + + /* Map file */ + if ( ( start = mmap ( NULL, len, PROT_READ, MAP_SHARED, + fd, 0 ) ) == MAP_FAILED ) { + eprintf ( "Cannot mmap \"%s\": %s\n", + infile, strerror ( errno ) ); + exit ( 1 ); + } + + /* Iterate over einfo records */ + for ( einfo = start ; ( ( void * ) einfo ) < ( start + len ) ; + einfo = ( ( ( void * ) einfo ) + einfo->size ) ) { + printf ( "%08x\t%s\t%d\t%s\n", einfo->error, + ( ( ( void * ) einfo ) + einfo->file ), + einfo->line, + ( ( ( void * ) einfo ) + einfo->desc ) ); + } + + } + + /* Unmap and close file */ + munmap ( start, len ); + close ( fd ); +} + +/** + * Print help + * + * @v program_name Program name + */ +static void print_help ( const char *program_name ) { + eprintf ( "Syntax: %s file1.einfo [file2.einfo...]\n", + program_name ); +} + +/** + * Parse command-line options + * + * @v argc Argument count + * @v argv Argument list + * @v opts Options structure to populate + */ +static int parse_options ( const int argc, char **argv, + struct options *opts ) { + char *end; + int c; + + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { 0, 0, 0, 0 } + }; + + if ( ( c = getopt_long ( argc, argv, "s:h", + long_options, + &option_index ) ) == -1 ) { + break; + } + + switch ( c ) { + case 'h': + print_help ( argv[0] ); + exit ( 0 ); + case '?': + default: + exit ( 2 ); + } + } + return optind; +} + +int main ( int argc, char **argv ) { + struct options opts = { + }; + unsigned int infile_index; + const char *infile; + + /* Parse command-line arguments */ + infile_index = parse_options ( argc, argv, &opts ); + if ( argc <= infile_index ) { + print_help ( argv[0] ); + exit ( 2 ); + } + + /* Process each einfo file */ + for ( ; infile_index < argc ; infile_index++ ) { + infile = argv[infile_index]; + einfo ( infile, &opts ); + } + + return 0; +}