iPXE
Defines | Functions | Variables
icmpv6.c File Reference

ICMPv6 protocol. More...

#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/in.h>
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
#include <ipxe/ping.h>
#include <ipxe/icmpv6.h>

Go to the source code of this file.

Defines

#define EHOSTUNREACH_ROUTE   __einfo_error ( EINFO_EHOSTUNREACH_ROUTE )
#define EINFO_EHOSTUNREACH_ROUTE
#define EHOSTUNREACH_PROHIBITED   __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )
#define EINFO_EHOSTUNREACH_PROHIBITED
#define EHOSTUNREACH_ADDRESS   __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )
#define EINFO_EHOSTUNREACH_ADDRESS
#define EHOSTUNREACH_PORT   __einfo_error ( EINFO_EHOSTUNREACH_PORT )
#define EINFO_EHOSTUNREACH_PORT
#define EHOSTUNREACH_CODE(code)
#define ETIMEDOUT_HOP   __einfo_error ( EINFO_ETIMEDOUT_HOP )
#define EINFO_ETIMEDOUT_HOP
#define ETIMEDOUT_REASSEMBLY   __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )
#define EINFO_ETIMEDOUT_REASSEMBLY
#define ETIMEDOUT_CODE(code)
#define EPROTO_BAD_HEADER   __einfo_error ( EINFO_EPROTO_BAD_HEADER )
#define EINFO_EPROTO_BAD_HEADER
#define EPROTO_NEXT_HEADER   __einfo_error ( EINFO_EPROTO_NEXT_HEADER )
#define EINFO_EPROTO_NEXT_HEADER
#define EPROTO_OPTION   __einfo_error ( EINFO_EPROTO_OPTION )
#define EINFO_EPROTO_OPTION
#define EPROTO_CODE(code)

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int icmpv6_rx_echo_request (struct io_buffer *iobuf, struct net_device *netdev __unused, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest __unused)
 Process received ICMPv6 echo request packet.
static int icmpv6_rx_echo_reply (struct io_buffer *iobuf, struct net_device *netdev __unused, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest __unused)
 Process received ICMPv6 echo reply packet.
static struct icmpv6_handlericmpv6_handler (unsigned int type)
 Identify ICMPv6 handler.
static int icmpv6_rx (struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum)
 Process a received packet.

Variables

struct icmp_echo_protocol
icmpv6_echo_protocol 
__icmp_echo_protocol
 ICMPv6 echo protocol.
struct icmpv6_handler
icmpv6_echo_request_handler 
__icmpv6_handler
 ICMPv6 echo request handler.
struct tcpip_protocol
icmpv6_protocol 
__tcpip_protocol
 ICMPv6 TCP/IP protocol.

Detailed Description

ICMPv6 protocol.

Definition in file icmpv6.c.


Define Documentation

Definition at line 42 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EHOSTUNREACH, 0,                        \
                          "No route to destination" )

Definition at line 44 of file icmpv6.c.

Definition at line 47 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EHOSTUNREACH, 1,                        \
                          "Communication administratively prohibited" )

Definition at line 49 of file icmpv6.c.

Definition at line 52 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EHOSTUNREACH, 3,                        \
                          "Address unreachable" )

Definition at line 54 of file icmpv6.c.

Definition at line 57 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EHOSTUNREACH, 4,                        \
                          "Port unreachable" )

Definition at line 59 of file icmpv6.c.

#define EHOSTUNREACH_CODE (   code)
Value:

Definition at line 62 of file icmpv6.c.

Referenced by icmpv6_rx().

Definition at line 67 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_ETIMEDOUT, 0,                           \
                          "Hop limit exceeded in transit" )

Definition at line 69 of file icmpv6.c.

Definition at line 72 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_ETIMEDOUT, 1,                           \
                          "Fragment reassembly time exceeded" )

Definition at line 74 of file icmpv6.c.

#define ETIMEDOUT_CODE (   code)
Value:

Definition at line 77 of file icmpv6.c.

Referenced by icmpv6_rx().

Definition at line 81 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EPROTO, 0,                              \
                          "Erroneous header field" )

Definition at line 83 of file icmpv6.c.

Definition at line 86 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EPROTO, 1,                              \
                          "Unrecognised next header type" )

Definition at line 88 of file icmpv6.c.

Definition at line 91 of file icmpv6.c.

Value:
__einfo_uniqify ( EINFO_EPROTO, 2,                              \
                          "Unrecognised IPv6 option" )

Definition at line 93 of file icmpv6.c.

#define EPROTO_CODE (   code)
Value:

Definition at line 96 of file icmpv6.c.

Referenced by icmpv6_rx().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int icmpv6_rx_echo_request ( struct io_buffer iobuf,
struct net_device *netdev  __unused,
struct sockaddr_in6 sin6_src,
struct sockaddr_in6 *sin6_dest  __unused 
) [static]

Process received ICMPv6 echo request packet.

Parameters:
iobufI/O buffer
netdevNetwork device
sin6_srcSource socket address
sin6_destDestination socket address
Return values:
rcReturn status code

Definition at line 111 of file icmpv6.c.

References icmp_rx_echo_request().

                                                                              {
        struct sockaddr_tcpip *st_src =
                ( ( struct sockaddr_tcpip * ) sin6_src );

        return icmp_rx_echo_request ( iobuf, st_src, &icmpv6_echo_protocol );
}
static int icmpv6_rx_echo_reply ( struct io_buffer iobuf,
struct net_device *netdev  __unused,
struct sockaddr_in6 sin6_src,
struct sockaddr_in6 *sin6_dest  __unused 
) [static]

Process received ICMPv6 echo reply packet.

Parameters:
iobufI/O buffer
netdevNetwork device
sin6_srcSource socket address
sin6_destDestination socket address
Return values:
rcReturn status code

Definition at line 136 of file icmpv6.c.

References icmp_rx_echo_reply().

                                                                            {
        struct sockaddr_tcpip *st_src =
                ( ( struct sockaddr_tcpip * ) sin6_src );

        return icmp_rx_echo_reply ( iobuf, st_src );
}
static struct icmpv6_handler* icmpv6_handler ( unsigned int  type) [static, read]

Identify ICMPv6 handler.

Parameters:
typeICMPv6 type
Return values:
handlerICMPv6 handler, or NULL if not found

Definition at line 158 of file icmpv6.c.

References for_each_table_entry, ICMPV6_HANDLERS, NULL, and icmpv6_handler::type.

Referenced by icmpv6_rx().

                                                                    {
        struct icmpv6_handler *handler;

        for_each_table_entry ( handler, ICMPV6_HANDLERS ) {
                if ( handler->type == type )
                        return handler;
        }
        return NULL;
}
static int icmpv6_rx ( struct io_buffer iobuf,
struct net_device netdev,
struct sockaddr_tcpip st_src,
struct sockaddr_tcpip st_dest,
uint16_t  pshdr_csum 
) [static]

Process a received packet.

Parameters:
iobufI/O buffer
netdevNetwork device
st_srcPartially-filled source address
st_destPartially-filled destination address
pshdr_csumPseudo-header checksum
Return values:
rcReturn status code

Definition at line 178 of file icmpv6.c.

References icmp_header::code, io_buffer::data, DBGC, DBGC_HDA, done, EHOSTUNREACH_CODE, EINVAL, ENOTSUP, EPROTO_CODE, ERANGE, ETIMEDOUT_CODE, free_iob(), ICMPV6_DESTINATION_UNREACHABLE, icmpv6_handler(), ICMPV6_PACKET_TOO_BIG, ICMPV6_PARAMETER_PROBLEM, ICMPV6_TIME_EXCEEDED, iob_disown, iob_len(), len, rc, icmpv6_handler::rx, strerror(), tcpip_continue_chksum(), and icmp_header::type.

                                                                             {
        struct sockaddr_in6 *sin6_src = ( ( struct sockaddr_in6 * ) st_src );
        struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
        struct icmp_header *icmp = iobuf->data;
        size_t len = iob_len ( iobuf );
        struct icmpv6_handler *handler;
        unsigned int csum;
        int rc;

        /* Sanity check */
        if ( len < sizeof ( *icmp ) ) {
                DBGC ( netdev, "ICMPv6 packet too short at %zd bytes (min %zd "
                       "bytes)\n", len, sizeof ( *icmp ) );
                rc = -EINVAL;
                goto done;
        }

        /* Verify checksum */
        csum = tcpip_continue_chksum ( pshdr_csum, icmp, len );
        if ( csum != 0 ) {
                DBGC ( netdev, "ICMPv6 checksum incorrect (is %04x, should be "
                       "0000)\n", csum );
                DBGC_HDA ( netdev, 0, icmp, len );
                rc = -EINVAL;
                goto done;
        }

        /* Identify handler */
        handler = icmpv6_handler ( icmp->type );
        if ( ! handler ) {
                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;
        }

        /* Pass to handler */
        if ( ( rc = handler->rx ( iob_disown ( iobuf ), netdev, sin6_src,
                                  sin6_dest ) ) != 0 ) {
                DBGC ( netdev, "ICMPv6 could not handle type %d: %s\n",
                       icmp->type, strerror ( rc ) );
                goto done;
        }

 done:
        free_iob ( iobuf );
        return rc;
}

Variable Documentation

struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol
Initial value:
 {
        .family = AF_INET6,
        .request = ICMPV6_ECHO_REQUEST,
        .reply = ICMPV6_ECHO_REPLY,
        .tcpip_protocol = &icmpv6_protocol,
        .net_checksum = 1,
}

ICMPv6 echo protocol.

Definition at line 100 of file icmpv6.c.

struct icmpv6_handler icmpv6_echo_reply_handler __icmpv6_handler
Initial value:

ICMPv6 echo request handler.

ICMPv6 echo reply handler.

Definition at line 122 of file icmpv6.c.

struct tcpip_protocol icmpv6_protocol __tcpip_protocol
Initial value:
 {
        .name = "ICMPv6",
        .rx = icmpv6_rx,
        .tcpip_proto = IP_ICMP6,
}

ICMPv6 TCP/IP protocol.

ICMPv4 TCP/IP protocol.

Definition at line 246 of file icmpv6.c.