iPXE
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.

Macros

#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)
 FILE_SECBOOT (PERMITTED)
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_handler * icmpv6_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.

Macro Definition Documentation

◆ EHOSTUNREACH_ROUTE

#define EHOSTUNREACH_ROUTE    __einfo_error ( EINFO_EHOSTUNREACH_ROUTE )

Definition at line 43 of file icmpv6.c.

43#define EHOSTUNREACH_ROUTE \
44 __einfo_error ( EINFO_EHOSTUNREACH_ROUTE )

◆ EINFO_EHOSTUNREACH_ROUTE

#define EINFO_EHOSTUNREACH_ROUTE
Value:
"No route to destination" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition errno.h:181
#define EINFO_EHOSTUNREACH
Definition errno.h:405

Definition at line 45 of file icmpv6.c.

45#define EINFO_EHOSTUNREACH_ROUTE \
46 __einfo_uniqify ( EINFO_EHOSTUNREACH, 0, \
47 "No route to destination" )

◆ EHOSTUNREACH_PROHIBITED

#define EHOSTUNREACH_PROHIBITED    __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )

Definition at line 48 of file icmpv6.c.

48#define EHOSTUNREACH_PROHIBITED \
49 __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )

◆ EINFO_EHOSTUNREACH_PROHIBITED

#define EINFO_EHOSTUNREACH_PROHIBITED
Value:
"Communication administratively prohibited" )

Definition at line 50 of file icmpv6.c.

50#define EINFO_EHOSTUNREACH_PROHIBITED \
51 __einfo_uniqify ( EINFO_EHOSTUNREACH, 1, \
52 "Communication administratively prohibited" )

◆ EHOSTUNREACH_ADDRESS

#define EHOSTUNREACH_ADDRESS    __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )

Definition at line 53 of file icmpv6.c.

53#define EHOSTUNREACH_ADDRESS \
54 __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )

◆ EINFO_EHOSTUNREACH_ADDRESS

#define EINFO_EHOSTUNREACH_ADDRESS
Value:
"Address unreachable" )

Definition at line 55 of file icmpv6.c.

55#define EINFO_EHOSTUNREACH_ADDRESS \
56 __einfo_uniqify ( EINFO_EHOSTUNREACH, 3, \
57 "Address unreachable" )

◆ EHOSTUNREACH_PORT

#define EHOSTUNREACH_PORT    __einfo_error ( EINFO_EHOSTUNREACH_PORT )

Definition at line 58 of file icmpv6.c.

58#define EHOSTUNREACH_PORT \
59 __einfo_error ( EINFO_EHOSTUNREACH_PORT )

◆ EINFO_EHOSTUNREACH_PORT

#define EINFO_EHOSTUNREACH_PORT
Value:
"Port unreachable" )

Definition at line 60 of file icmpv6.c.

60#define EINFO_EHOSTUNREACH_PORT \
61 __einfo_uniqify ( EINFO_EHOSTUNREACH, 4, \
62 "Port unreachable" )

◆ EHOSTUNREACH_CODE

#define EHOSTUNREACH_CODE ( code)
Value:
EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \
static unsigned int code
Response code.
Definition hyperv.h:26
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition errno.h:226
#define EHOSTUNREACH_ADDRESS
Definition icmpv6.c:53
#define EHOSTUNREACH_ROUTE
Definition icmpv6.c:43
#define EHOSTUNREACH_PORT
Definition icmpv6.c:58
#define EHOSTUNREACH_PROHIBITED
Definition icmpv6.c:48

Definition at line 63 of file icmpv6.c.

63#define EHOSTUNREACH_CODE( code ) \
64 EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \
65 EHOSTUNREACH_ROUTE, EHOSTUNREACH_PROHIBITED, \
66 EHOSTUNREACH_ADDRESS, EHOSTUNREACH_PORT )

Referenced by icmpv6_rx().

◆ ETIMEDOUT_HOP

#define ETIMEDOUT_HOP    __einfo_error ( EINFO_ETIMEDOUT_HOP )

Definition at line 68 of file icmpv6.c.

68#define ETIMEDOUT_HOP \
69 __einfo_error ( EINFO_ETIMEDOUT_HOP )

◆ EINFO_ETIMEDOUT_HOP

#define EINFO_ETIMEDOUT_HOP
Value:
"Hop limit exceeded in transit" )
#define EINFO_ETIMEDOUT
Definition errno.h:671

Definition at line 70 of file icmpv6.c.

70#define EINFO_ETIMEDOUT_HOP \
71 __einfo_uniqify ( EINFO_ETIMEDOUT, 0, \
72 "Hop limit exceeded in transit" )

◆ ETIMEDOUT_REASSEMBLY

#define ETIMEDOUT_REASSEMBLY    __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )

Definition at line 73 of file icmpv6.c.

73#define ETIMEDOUT_REASSEMBLY \
74 __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )

◆ EINFO_ETIMEDOUT_REASSEMBLY

#define EINFO_ETIMEDOUT_REASSEMBLY
Value:
"Fragment reassembly time exceeded" )

Definition at line 75 of file icmpv6.c.

75#define EINFO_ETIMEDOUT_REASSEMBLY \
76 __einfo_uniqify ( EINFO_ETIMEDOUT, 1, \
77 "Fragment reassembly time exceeded" )

◆ ETIMEDOUT_CODE

#define ETIMEDOUT_CODE ( code)
Value:
EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \
#define ETIMEDOUT_HOP
Definition icmpv6.c:68
#define ETIMEDOUT_REASSEMBLY
Definition icmpv6.c:73

Definition at line 78 of file icmpv6.c.

78#define ETIMEDOUT_CODE( code ) \
79 EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \
80 ETIMEDOUT_HOP, ETIMEDOUT_REASSEMBLY )

Referenced by icmpv6_rx().

◆ EPROTO_BAD_HEADER

#define EPROTO_BAD_HEADER    __einfo_error ( EINFO_EPROTO_BAD_HEADER )

Definition at line 82 of file icmpv6.c.

82#define EPROTO_BAD_HEADER \
83 __einfo_error ( EINFO_EPROTO_BAD_HEADER )

◆ EINFO_EPROTO_BAD_HEADER

#define EINFO_EPROTO_BAD_HEADER
Value:
"Erroneous header field" )
#define EINFO_EPROTO
Definition errno.h:626

Definition at line 84 of file icmpv6.c.

84#define EINFO_EPROTO_BAD_HEADER \
85 __einfo_uniqify ( EINFO_EPROTO, 0, \
86 "Erroneous header field" )

◆ EPROTO_NEXT_HEADER

#define EPROTO_NEXT_HEADER    __einfo_error ( EINFO_EPROTO_NEXT_HEADER )

Definition at line 87 of file icmpv6.c.

87#define EPROTO_NEXT_HEADER \
88 __einfo_error ( EINFO_EPROTO_NEXT_HEADER )

◆ EINFO_EPROTO_NEXT_HEADER

#define EINFO_EPROTO_NEXT_HEADER
Value:
"Unrecognised next header type" )

Definition at line 89 of file icmpv6.c.

89#define EINFO_EPROTO_NEXT_HEADER \
90 __einfo_uniqify ( EINFO_EPROTO, 1, \
91 "Unrecognised next header type" )

◆ EPROTO_OPTION

#define EPROTO_OPTION    __einfo_error ( EINFO_EPROTO_OPTION )

Definition at line 92 of file icmpv6.c.

92#define EPROTO_OPTION \
93 __einfo_error ( EINFO_EPROTO_OPTION )

◆ EINFO_EPROTO_OPTION

#define EINFO_EPROTO_OPTION
Value:
"Unrecognised IPv6 option" )

Definition at line 94 of file icmpv6.c.

94#define EINFO_EPROTO_OPTION \
95 __einfo_uniqify ( EINFO_EPROTO, 2, \
96 "Unrecognised IPv6 option" )

◆ EPROTO_CODE

#define EPROTO_CODE ( code)
Value:
EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \
#define EPROTO_BAD_HEADER
Definition icmpv6.c:82
#define EPROTO_OPTION
Definition icmpv6.c:92
#define EPROTO_NEXT_HEADER
Definition icmpv6.c:87

Definition at line 97 of file icmpv6.c.

97#define EPROTO_CODE( code ) \
98 EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \
99 EPROTO_BAD_HEADER, EPROTO_NEXT_HEADER, EPROTO_OPTION )

Referenced by icmpv6_rx().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ icmpv6_rx_echo_request()

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 112 of file icmpv6.c.

115 {
116 struct sockaddr_tcpip *st_src =
117 ( ( struct sockaddr_tcpip * ) sin6_src );
118
119 return icmp_rx_echo_request ( iobuf, st_src, &icmpv6_echo_protocol );
120}
int icmp_rx_echo_request(struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct icmp_echo_protocol *echo_protocol)
Process a received ICMP echo request.
Definition icmp.c:166
TCP/IP socket address.
Definition tcpip.h:76

References __unused, icmp_rx_echo_request(), and netdev.

◆ icmpv6_rx_echo_reply()

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 137 of file icmpv6.c.

140 {
141 struct sockaddr_tcpip *st_src =
142 ( ( struct sockaddr_tcpip * ) sin6_src );
143
144 return icmp_rx_echo_reply ( iobuf, st_src );
145}
int icmp_rx_echo_reply(struct io_buffer *iobuf, struct sockaddr_tcpip *st_src)
Process a received ICMP echo request.
Definition icmp.c:197

References __unused, icmp_rx_echo_reply(), and netdev.

◆ icmpv6_handler()

struct icmpv6_handler * icmpv6_handler ( unsigned int type)
static

Identify ICMPv6 handler.

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

Definition at line 159 of file icmpv6.c.

159 {
160 struct icmpv6_handler *handler;
161
163 if ( handler->type == type )
164 return handler;
165 }
166 return NULL;
167}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
uint32_t type
Operating system type.
Definition ena.h:1
#define ICMPV6_HANDLERS
ICMPv6 handler table.
Definition icmpv6.h:39
An ICMPv6 handler.
Definition icmpv6.h:20
unsigned int type
Type.
Definition icmpv6.h:22
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

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

Referenced by icmpv6_rx().

◆ icmpv6_rx()

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 179 of file icmpv6.c.

181 {
182 struct sockaddr_in6 *sin6_src = ( ( struct sockaddr_in6 * ) st_src );
183 struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
184 struct icmp_header *icmp = iobuf->data;
185 size_t len = iob_len ( iobuf );
186 struct icmpv6_handler *handler;
187 unsigned int csum;
188 int rc;
189
190 /* Sanity check */
191 if ( len < sizeof ( *icmp ) ) {
192 DBGC ( netdev, "ICMPv6 packet too short at %zd bytes (min %zd "
193 "bytes)\n", len, sizeof ( *icmp ) );
194 rc = -EINVAL;
195 goto done;
196 }
197
198 /* Verify checksum */
199 csum = tcpip_continue_chksum ( pshdr_csum, icmp, len );
200 if ( csum != 0 ) {
201 DBGC ( netdev, "ICMPv6 checksum incorrect (is %04x, should be "
202 "0000)\n", csum );
203 DBGC_HDA ( netdev, 0, icmp, len );
204 rc = -EINVAL;
205 goto done;
206 }
207
208 /* Identify handler */
209 handler = icmpv6_handler ( icmp->type );
210 if ( ! handler ) {
211 switch ( icmp->type ) {
213 rc = -EHOSTUNREACH_CODE ( icmp->code );
214 break;
216 rc = -ERANGE;
217 break;
219 rc = -ETIMEDOUT_CODE ( icmp->code );
220 break;
222 rc = -EPROTO_CODE ( icmp->code );
223 break;
224 default:
225 DBGC ( netdev, "ICMPv6 unrecognised type %d code %d\n",
226 icmp->type, icmp->code );
227 rc = -ENOTSUP;
228 break;
229 };
230 goto done;
231 }
232
233 /* Pass to handler */
234 if ( ( rc = handler->rx ( iob_disown ( iobuf ), netdev, sin6_src,
235 sin6_dest ) ) != 0 ) {
236 DBGC ( netdev, "ICMPv6 could not handle type %d: %s\n",
237 icmp->type, strerror ( rc ) );
238 goto done;
239 }
240
241 done:
242 free_iob ( iobuf );
243 return rc;
244}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
struct bofm_section_header done
Definition bofm_test.c:46
ring len
Length.
Definition dwmac.h:226
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ERANGE
Result too large.
Definition errno.h:640
#define EHOSTUNREACH_CODE(code)
Definition icmpv6.c:63
static struct icmpv6_handler * icmpv6_handler(unsigned int type)
Identify ICMPv6 handler.
Definition icmpv6.c:159
#define ETIMEDOUT_CODE(code)
Definition icmpv6.c:78
#define EPROTO_CODE(code)
Definition icmpv6.c:97
#define ICMPV6_PACKET_TOO_BIG
ICMPv6 packet too big.
Definition icmpv6.h:48
#define ICMPV6_DESTINATION_UNREACHABLE
ICMPv6 destination unreachable.
Definition icmpv6.h:45
#define ICMPV6_TIME_EXCEEDED
ICMPv6 time exceeded.
Definition icmpv6.h:51
#define ICMPV6_PARAMETER_PROBLEM
ICMPv6 parameter problem.
Definition icmpv6.h:54
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An ICMP header.
Definition icmp.h:20
uint8_t type
Type.
Definition icmp.h:22
uint8_t code
Code.
Definition icmp.h:24
int(* rx)(struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest)
Process received packet.
Definition icmpv6.h:33
void * data
Start of data.
Definition iobuf.h:53
IPv6 socket address.
Definition in.h:118
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition x86_tcpip.c:46

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, netdev, rc, icmpv6_handler::rx, strerror(), tcpip_continue_chksum(), and icmp_header::type.

Variable Documentation

◆ __icmp_echo_protocol

struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol
Initial value:
= {
.family = AF_INET6,
.request = ICMPV6_ECHO_REQUEST,
.tcpip_protocol = &icmpv6_protocol,
.net_checksum = 1,
}
#define AF_INET6
IPv6 Internet addresses.
Definition socket.h:65
#define ICMPV6_ECHO_REQUEST
ICMPv6 echo request.
Definition icmpv6.h:57
#define ICMPV6_ECHO_REPLY
ICMPv6 echo reply.
Definition icmpv6.h:60

ICMPv6 echo protocol.

Definition at line 101 of file icmpv6.c.

◆ __icmpv6_handler

struct icmpv6_handler icmpv6_echo_reply_handler __icmpv6_handler
Initial value:
= {
}
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.
Definition icmpv6.c:112

ICMPv6 echo request handler.

ICMPv6 echo reply handler.

Definition at line 123 of file icmpv6.c.

123 {
124 .type = ICMPV6_ECHO_REQUEST,
126};

◆ __tcpip_protocol

struct tcpip_protocol icmpv6_protocol __tcpip_protocol
Initial value:
= {
.name = "ICMPv6",
.rx = icmpv6_rx,
.tcpip_proto = IP_ICMP6,
}
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.
Definition icmpv6.c:179
#define IP_ICMP6
Definition in.h:16

ICMPv6 TCP/IP protocol.

ICMPv4 TCP/IP protocol.

Definition at line 247 of file icmpv6.c.

247 {
248 .name = "ICMPv6",
249 .rx = icmpv6_rx,
250 .tcpip_proto = IP_ICMP6,
251};