diff options
Diffstat (limited to 'qemu/roms/ipxe/src/net/icmpv6.c')
-rw-r--r-- | qemu/roms/ipxe/src/net/icmpv6.c | 86 |
1 files changed, 83 insertions, 3 deletions
diff --git a/qemu/roms/ipxe/src/net/icmpv6.c b/qemu/roms/ipxe/src/net/icmpv6.c index 479800e7d..8555aaf0b 100644 --- a/qemu/roms/ipxe/src/net/icmpv6.c +++ b/qemu/roms/ipxe/src/net/icmpv6.c @@ -15,9 +15,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <string.h> #include <errno.h> @@ -34,6 +38,65 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ +/* Disambiguate the various error causes */ +#define EHOSTUNREACH_ROUTE \ + __einfo_error ( EINFO_EHOSTUNREACH_ROUTE ) +#define EINFO_EHOSTUNREACH_ROUTE \ + __einfo_uniqify ( EINFO_EHOSTUNREACH, 0, \ + "No route to destination" ) +#define EHOSTUNREACH_PROHIBITED \ + __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED ) +#define EINFO_EHOSTUNREACH_PROHIBITED \ + __einfo_uniqify ( EINFO_EHOSTUNREACH, 1, \ + "Communication administratively prohibited" ) +#define EHOSTUNREACH_ADDRESS \ + __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS ) +#define EINFO_EHOSTUNREACH_ADDRESS \ + __einfo_uniqify ( EINFO_EHOSTUNREACH, 3, \ + "Address unreachable" ) +#define EHOSTUNREACH_PORT \ + __einfo_error ( EINFO_EHOSTUNREACH_PORT ) +#define EINFO_EHOSTUNREACH_PORT \ + __einfo_uniqify ( EINFO_EHOSTUNREACH, 4, \ + "Port unreachable" ) +#define EHOSTUNREACH_CODE( code ) \ + EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \ + EHOSTUNREACH_ROUTE, EHOSTUNREACH_PROHIBITED, \ + EHOSTUNREACH_ADDRESS, EHOSTUNREACH_PORT ) + +#define ETIMEDOUT_HOP \ + __einfo_error ( EINFO_ETIMEDOUT_HOP ) +#define EINFO_ETIMEDOUT_HOP \ + __einfo_uniqify ( EINFO_ETIMEDOUT, 0, \ + "Hop limit exceeded in transit" ) +#define ETIMEDOUT_REASSEMBLY \ + __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY ) +#define EINFO_ETIMEDOUT_REASSEMBLY \ + __einfo_uniqify ( EINFO_ETIMEDOUT, 1, \ + "Fragment reassembly time exceeded" ) +#define ETIMEDOUT_CODE( code ) \ + EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \ + ETIMEDOUT_HOP, ETIMEDOUT_REASSEMBLY ) + +#define EPROTO_BAD_HEADER \ + __einfo_error ( EINFO_EPROTO_BAD_HEADER ) +#define EINFO_EPROTO_BAD_HEADER \ + __einfo_uniqify ( EINFO_EPROTO, 0, \ + "Erroneous header field" ) +#define EPROTO_NEXT_HEADER \ + __einfo_error ( EINFO_EPROTO_NEXT_HEADER ) +#define EINFO_EPROTO_NEXT_HEADER \ + __einfo_uniqify ( EINFO_EPROTO, 1, \ + "Unrecognised next header type" ) +#define EPROTO_OPTION \ + __einfo_error ( EINFO_EPROTO_OPTION ) +#define EINFO_EPROTO_OPTION \ + __einfo_uniqify ( EINFO_EPROTO, 2, \ + "Unrecognised IPv6 option" ) +#define EPROTO_CODE( code ) \ + EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \ + EPROTO_BAD_HEADER, EPROTO_NEXT_HEADER, EPROTO_OPTION ) + struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol; /** @@ -144,8 +207,25 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, /* Identify handler */ handler = icmpv6_handler ( icmp->type ); if ( ! handler ) { - DBGC ( netdev, "ICMPv6 unrecognised type %d\n", icmp->type ); - rc = -ENOTSUP; + switch ( icmp->type ) { + case ICMPV6_DESTINATION_UNREACHABLE: + rc = -EHOSTUNREACH_CODE ( icmp->code ); + break; + case ICMPV6_PACKET_TOO_BIG: + rc = -ERANGE; + break; + case ICMPV6_TIME_EXCEEDED: + rc = -ETIMEDOUT_CODE ( icmp->code ); + break; + case ICMPV6_PARAMETER_PROBLEM: + rc = -EPROTO_CODE ( icmp->code ); + break; + default: + DBGC ( netdev, "ICMPv6 unrecognised type %d code %d\n", + icmp->type, icmp->code ); + rc = -ENOTSUP; + break; + }; goto done; } |