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

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. More...
 
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. More...
 
static struct icmpv6_handlericmpv6_handler (unsigned int type)
 Identify ICMPv6 handler. More...
 
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. More...
 

Variables

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

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.

◆ EINFO_EHOSTUNREACH_ROUTE

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

Definition at line 45 of file icmpv6.c.

◆ EHOSTUNREACH_PROHIBITED

#define EHOSTUNREACH_PROHIBITED   __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )

Definition at line 48 of file icmpv6.c.

◆ EINFO_EHOSTUNREACH_PROHIBITED

#define EINFO_EHOSTUNREACH_PROHIBITED
Value:
"Communication administratively prohibited" )
#define EINFO_EHOSTUNREACH
Definition: errno.h:405
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 50 of file icmpv6.c.

◆ EHOSTUNREACH_ADDRESS

#define EHOSTUNREACH_ADDRESS   __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )

Definition at line 53 of file icmpv6.c.

◆ EINFO_EHOSTUNREACH_ADDRESS

#define EINFO_EHOSTUNREACH_ADDRESS
Value:
"Address unreachable" )
#define EINFO_EHOSTUNREACH
Definition: errno.h:405
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 55 of file icmpv6.c.

◆ EHOSTUNREACH_PORT

#define EHOSTUNREACH_PORT   __einfo_error ( EINFO_EHOSTUNREACH_PORT )

Definition at line 58 of file icmpv6.c.

◆ EINFO_EHOSTUNREACH_PORT

#define EINFO_EHOSTUNREACH_PORT
Value:
"Port unreachable" )
#define EINFO_EHOSTUNREACH
Definition: errno.h:405
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 60 of file icmpv6.c.

◆ EHOSTUNREACH_CODE

#define EHOSTUNREACH_CODE (   code)
Value:
EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \
static unsigned int code
Response code.
Definition: hyperv.h:26
#define EHOSTUNREACH_ROUTE
Definition: icmpv6.c:43
#define EHOSTUNREACH_PROHIBITED
Definition: icmpv6.c:48
#define EINFO_EHOSTUNREACH
Definition: errno.h:405
#define EHOSTUNREACH_PORT
Definition: icmpv6.c:58
#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

Definition at line 63 of file icmpv6.c.

◆ ETIMEDOUT_HOP

#define ETIMEDOUT_HOP   __einfo_error ( EINFO_ETIMEDOUT_HOP )

Definition at line 68 of file icmpv6.c.

◆ EINFO_ETIMEDOUT_HOP

#define EINFO_ETIMEDOUT_HOP
Value:
"Hop limit exceeded in transit" )
#define EINFO_ETIMEDOUT
Definition: errno.h:671
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 70 of file icmpv6.c.

◆ ETIMEDOUT_REASSEMBLY

#define ETIMEDOUT_REASSEMBLY   __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )

Definition at line 73 of file icmpv6.c.

◆ EINFO_ETIMEDOUT_REASSEMBLY

#define EINFO_ETIMEDOUT_REASSEMBLY
Value:
"Fragment reassembly time exceeded" )
#define EINFO_ETIMEDOUT
Definition: errno.h:671
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 75 of file icmpv6.c.

◆ ETIMEDOUT_CODE

#define ETIMEDOUT_CODE (   code)
Value:
EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \
static unsigned int code
Response code.
Definition: hyperv.h:26
#define EINFO_ETIMEDOUT
Definition: errno.h:671
#define ETIMEDOUT_HOP
Definition: icmpv6.c:68
#define ETIMEDOUT_REASSEMBLY
Definition: icmpv6.c:73
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition: errno.h:226

Definition at line 78 of file icmpv6.c.

◆ EPROTO_BAD_HEADER

#define EPROTO_BAD_HEADER   __einfo_error ( EINFO_EPROTO_BAD_HEADER )

Definition at line 82 of file icmpv6.c.

◆ EINFO_EPROTO_BAD_HEADER

#define EINFO_EPROTO_BAD_HEADER
Value:
"Erroneous header field" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 84 of file icmpv6.c.

◆ EPROTO_NEXT_HEADER

#define EPROTO_NEXT_HEADER   __einfo_error ( EINFO_EPROTO_NEXT_HEADER )

Definition at line 87 of file icmpv6.c.

◆ EINFO_EPROTO_NEXT_HEADER

#define EINFO_EPROTO_NEXT_HEADER
Value:
"Unrecognised next header type" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 89 of file icmpv6.c.

◆ EPROTO_OPTION

#define EPROTO_OPTION   __einfo_error ( EINFO_EPROTO_OPTION )

Definition at line 92 of file icmpv6.c.

◆ EINFO_EPROTO_OPTION

#define EINFO_EPROTO_OPTION
Value:
"Unrecognised IPv6 option" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 94 of file icmpv6.c.

◆ EPROTO_CODE

#define EPROTO_CODE (   code)
Value:
EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \
static unsigned int code
Response code.
Definition: hyperv.h:26
#define EPROTO_BAD_HEADER
Definition: icmpv6.c:82
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition: errno.h:226
#define EPROTO_OPTION
Definition: icmpv6.c:92
#define EPROTO_NEXT_HEADER
Definition: icmpv6.c:87
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 97 of file icmpv6.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ icmpv6_rx_echo_request()

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 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 }
TCP/IP socket address.
Definition: tcpip.h:76
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

References icmp_rx_echo_request().

◆ icmpv6_rx_echo_reply()

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 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 }
TCP/IP socket address.
Definition: tcpip.h:76
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 icmp_rx_echo_reply().

◆ icmpv6_handler()

static 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 }
uint32_t type
Operating system type.
Definition: ena.h:12
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
unsigned int type
Type.
Definition: icmpv6.h:22
An ICMPv6 handler.
Definition: icmpv6.h:20
#define ICMPV6_HANDLERS
ICMPv6 handler table.
Definition: icmpv6.h:39
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

Referenced by icmpv6_rx().

◆ icmpv6_rx()

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 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 }
#define ETIMEDOUT_CODE(code)
Definition: icmpv6.c:78
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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
uint8_t code
Code.
Definition: icmp.h:24
#define ICMPV6_PACKET_TOO_BIG
ICMPv6 packet too big.
Definition: icmpv6.h:48
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define ICMPV6_DESTINATION_UNREACHABLE
ICMPv6 destination unreachable.
Definition: icmpv6.h:45
#define DBGC(...)
Definition: compiler.h:505
#define EHOSTUNREACH_CODE(code)
Definition: icmpv6.c:63
#define EPROTO_CODE(code)
Definition: icmpv6.c:97
uint8_t type
Type.
Definition: icmp.h:22
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:53
#define ICMPV6_PARAMETER_PROBLEM
ICMPv6 parameter problem.
Definition: icmpv6.h:54
#define ERANGE
Result too large.
Definition: errno.h:640
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
static struct icmpv6_handler * icmpv6_handler(unsigned int type)
Identify ICMPv6 handler.
Definition: icmpv6.c:159
An ICMPv6 handler.
Definition: icmpv6.h:20
void * data
Start of data.
Definition: iobuf.h:53
An ICMP header.
Definition: icmp.h:20
IPv6 socket address.
Definition: in.h:118
#define ICMPV6_TIME_EXCEEDED
ICMPv6 time exceeded.
Definition: icmpv6.h:51
struct bofm_section_header done
Definition: bofm_test.c:46
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_REPLY
ICMPv6 echo reply.
Definition: icmpv6.h:60
#define ICMPV6_ECHO_REQUEST
ICMPv6 echo request.
Definition: icmpv6.h:57

ICMPv6 echo protocol.

Definition at line 101 of file icmpv6.c.

◆ __icmpv6_handler

struct icmpv6_handler icmpv6_echo_reply_handler __icmpv6_handler
Initial value:
= {
}
#define ICMPV6_ECHO_REQUEST
ICMPv6 echo request.
Definition: icmpv6.h:57
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.

◆ __tcpip_protocol

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

ICMPv6 TCP/IP protocol.

ICMPv4 TCP/IP protocol.

Definition at line 247 of file icmpv6.c.