summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ipxe/errfile.h3
-rw-r--r--src/include/ipxe/icmp.h50
-rw-r--r--src/include/ipxe/icmpv6.h23
-rw-r--r--src/include/ipxe/ndp.h2
-rw-r--r--src/include/ipxe/ping.h18
-rw-r--r--src/net/icmp.c229
-rw-r--r--src/net/icmpv4.c109
-rw-r--r--src/net/icmpv6.c85
-rw-r--r--src/net/ipv4.c4
9 files changed, 402 insertions, 121 deletions
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index c55107a9..376f88c2 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -184,7 +184,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_slam ( ERRFILE_NET | 0x00160000 )
#define ERRFILE_ib_sma ( ERRFILE_NET | 0x00170000 )
#define ERRFILE_ib_packet ( ERRFILE_NET | 0x00180000 )
-#define ERRFILE_icmp ( ERRFILE_NET | 0x00190000 )
+#define ERRFILE_icmpv4 ( ERRFILE_NET | 0x00190000 )
#define ERRFILE_ib_qset ( ERRFILE_NET | 0x001a0000 )
#define ERRFILE_ib_gma ( ERRFILE_NET | 0x001b0000 )
#define ERRFILE_ib_pathrec ( ERRFILE_NET | 0x001c0000 )
@@ -216,6 +216,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_oncrpc_iob ( ERRFILE_NET | 0x00360000 )
#define ERRFILE_neighbour ( ERRFILE_NET | 0x00370000 )
#define ERRFILE_socket ( ERRFILE_NET | 0x00380000 )
+#define ERRFILE_icmp ( ERRFILE_NET | 0x00390000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
diff --git a/src/include/ipxe/icmp.h b/src/include/ipxe/icmp.h
index e402ce40..0480ddfa 100644
--- a/src/include/ipxe/icmp.h
+++ b/src/include/ipxe/icmp.h
@@ -9,6 +9,12 @@
FILE_LICENCE ( GPL2_OR_LATER );
+#include <stdint.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/socket.h>
+#include <ipxe/tcpip.h>
+#include <ipxe/tables.h>
+
/** An ICMP header */
struct icmp_header {
/** Type */
@@ -19,7 +25,49 @@ struct icmp_header {
uint16_t chksum;
} __attribute__ (( packed ));
-#define ICMP_ECHO_RESPONSE 0
+/** An ICMP echo request/reply */
+struct icmp_echo {
+ /** ICMPv6 header */
+ struct icmp_header icmp;
+ /** Identifier */
+ uint16_t ident;
+ /** Sequence number */
+ uint16_t sequence;
+ /** Data */
+ uint8_t data[0];
+} __attribute__ (( packed ));
+
+/** An ICMP echo protocol */
+struct icmp_echo_protocol {
+ /** Address family */
+ sa_family_t family;
+ /** Request type */
+ uint8_t request;
+ /** Reply type */
+ uint8_t reply;
+ /** TCP/IP protocol */
+ struct tcpip_protocol *tcpip_protocol;
+ /** Include network-layer checksum within packet */
+ int net_checksum;
+};
+
+/** ICMP echo protocol table */
+#define ICMP_ECHO_PROTOCOLS \
+ __table ( struct icmp_echo_protocol, "icmp_echo_protocols" )
+
+/** Declare an ICMP echo protocol */
+#define __icmp_echo_protocol __table_entry ( ICMP_ECHO_PROTOCOLS, 01 )
+
+#define ICMP_ECHO_REPLY 0
#define ICMP_ECHO_REQUEST 8
+extern int icmp_tx_echo_request ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_dest );
+
+extern int icmp_rx_echo_request ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src,
+ struct icmp_echo_protocol *echo_protocol );
+extern int icmp_rx_echo_reply ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src );
+
#endif /* _IPXE_ICMP_H */
diff --git a/src/include/ipxe/icmpv6.h b/src/include/ipxe/icmpv6.h
index c8f0be05..c09a71a0 100644
--- a/src/include/ipxe/icmpv6.h
+++ b/src/include/ipxe/icmpv6.h
@@ -13,28 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/tables.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
-
-/** An ICMPv6 header */
-struct icmpv6_header {
- /** Type */
- uint8_t type;
- /** Code */
- uint8_t code;
- /** Checksum */
- uint16_t chksum;
-} __attribute__ (( packed ));
-
-/** An ICMPv6 echo request/reply */
-struct icmpv6_echo {
- /** ICMPv6 header */
- struct icmpv6_header icmp;
- /** Identifier */
- uint16_t ident;
- /** Sequence number */
- uint16_t sequence;
- /** Data */
- uint8_t data[0];
-} __attribute__ (( packed ));
+#include <ipxe/icmp.h>
/** An ICMPv6 handler */
struct icmpv6_handler {
diff --git a/src/include/ipxe/ndp.h b/src/include/ipxe/ndp.h
index 7b98637f..1f05e9ab 100644
--- a/src/include/ipxe/ndp.h
+++ b/src/include/ipxe/ndp.h
@@ -31,7 +31,7 @@ struct ndp_option {
/** An NDP header */
struct ndp_header {
/** ICMPv6 header */
- struct icmpv6_header icmp;
+ struct icmp_header icmp;
/** Flags */
uint8_t flags;
/** Reserved */
diff --git a/src/include/ipxe/ping.h b/src/include/ipxe/ping.h
new file mode 100644
index 00000000..6cd376b6
--- /dev/null
+++ b/src/include/ipxe/ping.h
@@ -0,0 +1,18 @@
+#ifndef _IPXE_PING_H
+#define _IPXE_PING_H
+
+/** @file
+ *
+ * ICMP ping protocol
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/iobuf.h>
+#include <ipxe/tcpip.h>
+
+extern int ping_rx ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src );
+
+#endif /* _IPXE_PING_H */
diff --git a/src/net/icmp.c b/src/net/icmp.c
index 6142b748..1bbf8bd3 100644
--- a/src/net/icmp.c
+++ b/src/net/icmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -20,10 +20,13 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <string.h>
+#include <byteswap.h>
#include <errno.h>
#include <ipxe/iobuf.h>
#include <ipxe/in.h>
#include <ipxe/tcpip.h>
+#include <ipxe/ping.h>
+#include <ipxe/crc32.h>
#include <ipxe/icmp.h>
/** @file
@@ -32,76 +35,192 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
-struct tcpip_protocol icmp_protocol __tcpip_protocol;
+/**
+ * Identify ICMP echo protocol
+ *
+ * @v st_family Address family
+ * @ret echo_protocol ICMP echo protocol, or NULL
+ */
+static struct icmp_echo_protocol * icmp_echo_protocol ( sa_family_t family ) {
+ struct icmp_echo_protocol *echo_protocol;
+
+ for_each_table_entry ( echo_protocol, ICMP_ECHO_PROTOCOLS ) {
+ if ( echo_protocol->family == family )
+ return echo_protocol;
+ }
+ return NULL;
+}
/**
- * Process a received packet
+ *
+ * Determine debugging colour for ICMP debug messages
+ *
+ * @v st_peer Peer address
+ * @ret col Debugging colour (for DBGC())
+ */
+static uint32_t icmpcol ( struct sockaddr_tcpip *st_peer ) {
+
+ return crc32_le ( 0, st_peer, sizeof ( *st_peer ) );
+}
+
+/**
+ * Transmit ICMP echo packet
*
* @v iobuf I/O buffer
- * @v netdev Network device
- * @v st_src Partially-filled source address
- * @v st_dest Partially-filled destination address
- * @v pshdr_csum Pseudo-header checksum
+ * @v st_dest Destination socket address
+ * @v echo_protocol ICMP echo protocol
* @ret rc Return status code
*/
-static int icmp_rx ( struct io_buffer *iobuf,
- struct net_device *netdev __unused,
- struct sockaddr_tcpip *st_src,
- struct sockaddr_tcpip *st_dest,
- uint16_t pshdr_csum __unused ) {
- struct icmp_header *icmp = iobuf->data;
- size_t len = iob_len ( iobuf );
- unsigned int csum;
+static int icmp_tx_echo ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_dest,
+ struct icmp_echo_protocol *echo_protocol ) {
+ struct icmp_echo *echo = iobuf->data;
int rc;
- /* Sanity check */
- if ( len < sizeof ( *icmp ) ) {
- DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n",
- len, sizeof ( *icmp ) );
- rc = -EINVAL;
- goto done;
- }
+ /* Set ICMP type and (re)calculate checksum */
+ echo->icmp.chksum = 0;
+ echo->icmp.chksum = tcpip_chksum ( echo, iob_len ( iobuf ) );
- /* Verify checksum */
- csum = tcpip_chksum ( icmp, len );
- if ( csum != 0 ) {
- DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n",
- csum );
- DBG_HD ( icmp, len );
- rc = -EINVAL;
- goto done;
+ /* Transmit packet */
+ if ( ( rc = tcpip_tx ( iobuf, echo_protocol->tcpip_protocol, NULL,
+ st_dest, NULL,
+ ( echo_protocol->net_checksum ?
+ &echo->icmp.chksum : NULL ) ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/**
+ * Transmit ICMP echo request
+ *
+ * @v iobuf I/O buffer
+ * @v st_dest Destination socket address
+ * @ret rc Return status code
+ */
+int icmp_tx_echo_request ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_dest ) {
+ struct icmp_echo *echo = iobuf->data;
+ struct icmp_echo_protocol *echo_protocol;
+ int rc;
+
+ /* Identify ICMP echo protocol */
+ echo_protocol = icmp_echo_protocol ( st_dest->st_family );
+ if ( ! echo_protocol ) {
+ DBGC ( icmpcol ( st_dest ), "ICMP TX echo request unknown "
+ "address family %d\n", st_dest->st_family );
+ free_iob ( iobuf );
+ return -ENOTSUP;
}
- /* We respond only to pings */
- if ( icmp->type != ICMP_ECHO_REQUEST ) {
- DBG ( "ICMP ignoring type %d\n", icmp->type );
- rc = 0;
- goto done;
+ /* Set type */
+ echo->icmp.type = echo_protocol->request;
+
+ /* Transmit request */
+ DBGC ( icmpcol ( st_dest ), "ICMP TX echo request id %04x seq %04x\n",
+ ntohs ( echo->ident ), ntohs ( echo->sequence ) );
+ if ( ( rc = icmp_tx_echo ( iobuf, st_dest, echo_protocol ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/**
+ * Transmit ICMP echo reply
+ *
+ * @v iobuf I/O buffer
+ * @v st_dest Destination socket address
+ * @ret rc Return status code
+ */
+static int icmp_tx_echo_reply ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_dest,
+ struct icmp_echo_protocol *echo_protocol ) {
+ struct icmp_echo *echo = iobuf->data;
+ int rc;
+
+ /* Set type */
+ echo->icmp.type = echo_protocol->reply;
+
+ /* Transmit reply */
+ DBGC ( icmpcol ( st_dest ), "ICMP TX echo reply id %04x seq %04x\n",
+ ntohs ( echo->ident ), ntohs ( echo->sequence ) );
+ if ( ( rc = icmp_tx_echo ( iobuf, st_dest, echo_protocol ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/**
+ * Process a received ICMP echo request
+ *
+ * @v iobuf I/O buffer
+ * @v st_src Source socket address
+ * @v echo_protocol ICMP echo protocol
+ * @ret rc Return status code
+ */
+int icmp_rx_echo_request ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src,
+ struct icmp_echo_protocol *echo_protocol ) {
+ struct icmp_echo *echo = iobuf->data;
+ int rc;
+
+ /* Sanity check */
+ if ( iob_len ( iobuf ) < sizeof ( *echo ) ) {
+ DBGC ( icmpcol ( st_src ), "ICMP RX echo request too short at "
+ "%zd bytes (min %zd bytes)\n",
+ iob_len ( iobuf ), sizeof ( *echo ) );
+ free_iob ( iobuf );
+ return -EINVAL;
}
+ DBGC ( icmpcol ( st_src ), "ICMP RX echo request id %04x seq %04x\n",
+ ntohs ( echo->ident ), ntohs ( echo->sequence ) );
- DBG ( "ICMP responding to ping\n" );
+ /* Transmit echo reply */
+ if ( ( rc = icmp_tx_echo_reply ( iobuf, st_src, echo_protocol ) ) != 0 )
+ return rc;
- /* Change type to response and recalculate checksum */
- icmp->type = ICMP_ECHO_RESPONSE;
- icmp->chksum = 0;
- icmp->chksum = tcpip_chksum ( icmp, len );
+ return 0;
+}
- /* Transmit the response */
- if ( ( rc = tcpip_tx ( iob_disown ( iobuf ), &icmp_protocol, st_dest,
- st_src, NULL, NULL ) ) != 0 ) {
- DBG ( "ICMP could not transmit ping response: %s\n",
- strerror ( rc ) );
- goto done;
+/**
+ * Process a received ICMP echo request
+ *
+ * @v iobuf I/O buffer
+ * @v st_src Source socket address
+ * @ret rc Return status code
+ */
+int icmp_rx_echo_reply ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src ) {
+ struct icmp_echo *echo = iobuf->data;
+ int rc;
+
+ /* Sanity check */
+ if ( iob_len ( iobuf ) < sizeof ( *echo ) ) {
+ DBGC ( icmpcol ( st_src ), "ICMP RX echo reply too short at "
+ "%zd bytes (min %zd bytes)\n",
+ iob_len ( iobuf ), sizeof ( *echo ) );
+ free_iob ( iobuf );
+ return -EINVAL;
}
+ DBGC ( icmpcol ( st_src ), "ICMP RX echo reply id %04x seq %04x\n",
+ ntohs ( echo->ident ), ntohs ( echo->sequence ) );
- done:
- free_iob ( iobuf );
- return rc;
+ /* Deliver to ping protocol */
+ if ( ( rc = ping_rx ( iobuf, st_src ) ) != 0 )
+ return rc;
+
+ return 0;
}
-/** ICMP TCP/IP protocol */
-struct tcpip_protocol icmp_protocol __tcpip_protocol = {
- .name = "ICMP",
- .rx = icmp_rx,
- .tcpip_proto = IP_ICMP,
-};
+/**
+ * Receive ping reply (when no ping protocol is present)
+ *
+ * @v iobuf I/O buffer
+ * @v st_src Source socket address
+ * @ret rc Return status code
+ */
+__weak int ping_rx ( struct io_buffer *iobuf,
+ struct sockaddr_tcpip *st_src __unused ) {
+ free_iob ( iobuf );
+ return 0;
+}
diff --git a/src/net/icmpv4.c b/src/net/icmpv4.c
new file mode 100644
index 00000000..996ba149
--- /dev/null
+++ b/src/net/icmpv4.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/in.h>
+#include <ipxe/tcpip.h>
+#include <ipxe/icmp.h>
+
+/** @file
+ *
+ * ICMPv4 protocol
+ *
+ */
+
+struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol;
+
+/**
+ * Process a received packet
+ *
+ * @v iobuf I/O buffer
+ * @v netdev Network device
+ * @v st_src Partially-filled source address
+ * @v st_dest Partially-filled destination address
+ * @v pshdr_csum Pseudo-header checksum
+ * @ret rc Return status code
+ */
+static int icmpv4_rx ( struct io_buffer *iobuf,
+ struct net_device *netdev __unused,
+ struct sockaddr_tcpip *st_src,
+ struct sockaddr_tcpip *st_dest __unused,
+ uint16_t pshdr_csum __unused ) {
+ struct icmp_header *icmp = iobuf->data;
+ size_t len = iob_len ( iobuf );
+ unsigned int csum;
+ unsigned int type;
+ int rc;
+
+ /* Sanity check */
+ if ( len < sizeof ( *icmp ) ) {
+ DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n",
+ len, sizeof ( *icmp ) );
+ rc = -EINVAL;
+ goto discard;
+ }
+
+ /* Verify checksum */
+ csum = tcpip_chksum ( icmp, len );
+ if ( csum != 0 ) {
+ DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n",
+ csum );
+ DBG_HD ( icmp, len );
+ rc = -EINVAL;
+ goto discard;
+ }
+
+ /* Handle ICMP packet */
+ type = icmp->type;
+ switch ( type ) {
+ case ICMP_ECHO_REQUEST:
+ return icmp_rx_echo_request ( iobuf, st_src,
+ &icmpv4_echo_protocol );
+ case ICMP_ECHO_REPLY:
+ return icmp_rx_echo_reply ( iobuf, st_src );
+ default:
+ DBG ( "ICMP ignoring type %d\n", type );
+ rc = 0;
+ break;
+ }
+
+ discard:
+ free_iob ( iobuf );
+ return rc;
+}
+
+/** ICMPv4 TCP/IP protocol */
+struct tcpip_protocol icmpv4_protocol __tcpip_protocol = {
+ .name = "ICMPv4",
+ .rx = icmpv4_rx,
+ .tcpip_proto = IP_ICMP,
+};
+
+/** ICMPv4 echo protocol */
+struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol = {
+ .family = AF_INET,
+ .request = ICMP_ECHO_REQUEST,
+ .reply = ICMP_ECHO_REPLY,
+ .tcpip_protocol = &icmpv4_protocol,
+ .net_checksum = 0,
+};
diff --git a/src/net/icmpv6.c b/src/net/icmpv6.c
index 54426be8..479800e7 100644
--- a/src/net/icmpv6.c
+++ b/src/net/icmpv6.c
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/in.h>
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
+#include <ipxe/ping.h>
#include <ipxe/icmpv6.h>
/** @file
@@ -33,6 +34,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
+struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol;
+
/**
* Process received ICMPv6 echo request packet
*
@@ -42,50 +45,45 @@ FILE_LICENCE ( GPL2_OR_LATER );
* @v sin6_dest Destination socket address
* @ret rc Return status code
*/
-static int icmpv6_rx_echo ( struct io_buffer *iobuf,
- struct net_device *netdev,
- struct sockaddr_in6 *sin6_src,
- struct sockaddr_in6 *sin6_dest __unused ) {
+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 ) {
struct sockaddr_tcpip *st_src =
( ( struct sockaddr_tcpip * ) sin6_src );
- struct icmpv6_echo *echo = iobuf->data;
- size_t len = iob_len ( iobuf );
- int rc;
- /* Sanity check */
- if ( iob_len ( iobuf ) < sizeof ( *echo ) ) {
- DBGC ( netdev, "ICMPv6 echo request too short at %zd bytes "
- "(min %zd bytes)\n", iob_len ( iobuf ),
- sizeof ( *echo ) );
- rc = -EINVAL;
- goto done;
- }
- DBGC ( netdev, "ICMPv6 echo request from %s (id %#04x seq %#04x)\n",
- inet6_ntoa ( &sin6_dest->sin6_addr ), ntohs ( echo->ident ),
- ntohs ( echo->sequence ) );
-
- /* Convert echo request to echo reply and recalculate checksum */
- echo->icmp.type = ICMPV6_ECHO_REPLY;
- echo->icmp.chksum = 0;
- echo->icmp.chksum = tcpip_chksum ( echo, len );
-
- /* Transmit echo reply */
- if ( ( rc = tcpip_tx ( iob_disown ( iobuf ), &icmpv6_protocol, NULL,
- st_src, netdev, &echo->icmp.chksum ) ) != 0 ) {
- DBGC ( netdev, "ICMPv6 could not transmit reply: %s\n",
- strerror ( rc ) );
- goto done;
- }
-
- done:
- free_iob ( iobuf );
- return rc;
+ return icmp_rx_echo_request ( iobuf, st_src, &icmpv6_echo_protocol );
}
-/** ICMPv6 echo request handlers */
-struct icmpv6_handler icmpv6_echo_handler __icmpv6_handler = {
+/** ICMPv6 echo request handler */
+struct icmpv6_handler icmpv6_echo_request_handler __icmpv6_handler = {
.type = ICMPV6_ECHO_REQUEST,
- .rx = icmpv6_rx_echo,
+ .rx = icmpv6_rx_echo_request,
+};
+
+/**
+ * Process received ICMPv6 echo reply packet
+ *
+ * @v iobuf I/O buffer
+ * @v netdev Network device
+ * @v sin6_src Source socket address
+ * @v sin6_dest Destination socket address
+ * @ret rc Return status code
+ */
+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 ) {
+ struct sockaddr_tcpip *st_src =
+ ( ( struct sockaddr_tcpip * ) sin6_src );
+
+ return icmp_rx_echo_reply ( iobuf, st_src );
+}
+
+/** ICMPv6 echo reply handler */
+struct icmpv6_handler icmpv6_echo_reply_handler __icmpv6_handler = {
+ .type = ICMPV6_ECHO_REPLY,
+ .rx = icmpv6_rx_echo_reply,
};
/**
@@ -119,7 +117,7 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev,
struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) {
struct sockaddr_in6 *sin6_src = ( ( struct sockaddr_in6 * ) st_src );
struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
- struct icmpv6_header *icmp = iobuf->data;
+ struct icmp_header *icmp = iobuf->data;
size_t len = iob_len ( iobuf );
struct icmpv6_handler *handler;
unsigned int csum;
@@ -170,3 +168,12 @@ struct tcpip_protocol icmpv6_protocol __tcpip_protocol = {
.rx = icmpv6_rx,
.tcpip_proto = IP_ICMP6,
};
+
+/** ICMPv6 echo protocol */
+struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol = {
+ .family = AF_INET6,
+ .request = ICMPV6_ECHO_REQUEST,
+ .reply = ICMPV6_ECHO_REPLY,
+ .tcpip_protocol = &icmpv6_protocol,
+ .net_checksum = 1,
+};
diff --git a/src/net/ipv4.c b/src/net/ipv4.c
index 7956d18b..438fe9ac 100644
--- a/src/net/ipv4.c
+++ b/src/net/ipv4.c
@@ -669,5 +669,5 @@ struct settings_applicator ipv4_settings_applicator __settings_applicator = {
.apply = ipv4_create_routes,
};
-/* Drag in ICMP */
-REQUIRE_OBJECT ( icmp );
+/* Drag in ICMPv4 */
+REQUIRE_OBJECT ( icmpv4 );