summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/80211/net80211.c56
-rw-r--r--src/net/80211/sec80211.c16
-rw-r--r--src/net/infiniband.c12
-rw-r--r--src/net/infiniband/ib_srp.c13
-rw-r--r--src/net/netdevice.c20
-rw-r--r--src/net/tcp/iscsi.c55
-rw-r--r--src/net/udp/tftp.c71
7 files changed, 145 insertions, 98 deletions
diff --git a/src/net/80211/net80211.c b/src/net/80211/net80211.c
index 8df2c3155..7b3911452 100644
--- a/src/net/80211/net80211.c
+++ b/src/net/80211/net80211.c
@@ -23,6 +23,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <string.h>
#include <byteswap.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
#include <ipxe/settings.h>
#include <ipxe/if_arp.h>
#include <ipxe/ethernet.h>
@@ -32,52 +34,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/sec80211.h>
#include <ipxe/timer.h>
#include <ipxe/nap.h>
-#include <unistd.h>
-#include <errno.h>
+#include <ipxe/errortab.h>
+#include <ipxe/net80211_err.h>
/** @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 69fad8ffc..ea4b0d006 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 dd98e9228..5daecd52e 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 f4ec544c8..ef0078d43 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 9b42ad37f..6c91b4897 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 d35e3715a..69d185047 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 70ba4f62e..d49f4256c 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 );