iPXE
icmpv4.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <string.h>
27 #include <errno.h>
28 #include <ipxe/iobuf.h>
29 #include <ipxe/in.h>
30 #include <ipxe/tcpip.h>
31 #include <ipxe/icmp.h>
32 
33 /** @file
34  *
35  * ICMPv4 protocol
36  *
37  */
38 
39 struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol;
40 
41 /**
42  * Process a received packet
43  *
44  * @v iobuf I/O buffer
45  * @v netdev Network device
46  * @v st_src Partially-filled source address
47  * @v st_dest Partially-filled destination address
48  * @v pshdr_csum Pseudo-header checksum
49  * @ret rc Return status code
50  */
51 static int icmpv4_rx ( struct io_buffer *iobuf,
52  struct net_device *netdev __unused,
53  struct sockaddr_tcpip *st_src,
54  struct sockaddr_tcpip *st_dest __unused,
55  uint16_t pshdr_csum __unused ) {
56  struct icmp_header *icmp = iobuf->data;
57  size_t len = iob_len ( iobuf );
58  unsigned int csum;
59  unsigned int type;
60  int rc;
61 
62  /* Sanity check */
63  if ( len < sizeof ( *icmp ) ) {
64  DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n",
65  len, sizeof ( *icmp ) );
66  rc = -EINVAL;
67  goto discard;
68  }
69 
70  /* Verify checksum */
71  csum = tcpip_chksum ( icmp, len );
72  if ( csum != 0 ) {
73  DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n",
74  csum );
75  DBG_HD ( icmp, len );
76  rc = -EINVAL;
77  goto discard;
78  }
79 
80  /* Handle ICMP packet */
81  type = icmp->type;
82  switch ( type ) {
83  case ICMP_ECHO_REQUEST:
84  return icmp_rx_echo_request ( iobuf, st_src,
85  &icmpv4_echo_protocol );
86  case ICMP_ECHO_REPLY:
87  return icmp_rx_echo_reply ( iobuf, st_src );
88  default:
89  DBG ( "ICMP ignoring type %d\n", type );
90  rc = 0;
91  break;
92  }
93 
94  discard:
95  free_iob ( iobuf );
96  return rc;
97 }
98 
99 /** ICMPv4 TCP/IP protocol */
100 struct tcpip_protocol icmpv4_protocol __tcpip_protocol = {
101  .name = "ICMPv4",
102  .rx = icmpv4_rx,
103  .tcpip_proto = IP_ICMP,
104 };
105 
106 /** ICMPv4 echo protocol */
107 struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol = {
108  .family = AF_INET,
109  .request = ICMP_ECHO_REQUEST,
110  .reply = ICMP_ECHO_REPLY,
111  .tcpip_protocol = &icmpv4_protocol,
112  .net_checksum = 0,
113 };
#define EINVAL
Invalid argument.
Definition: errno.h:428
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
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)
Process a received packet.
Definition: icmpv4.c:51
Error codes.
#define DBG_HD(...)
Definition: compiler.h:500
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
uint32_t type
Operating system type.
Definition: ena.h:12
uint8_t type
Type.
Definition: icmp.h:21
#define IP_ICMP
Definition: in.h:12
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static struct net_device * netdev
Definition: gdbudp.c:52
Transport-network layer interface.
const char * name
Protocol name.
Definition: tcpip.h:106
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
A network device.
Definition: netdevice.h:352
struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol
ICMPv4 echo protocol.
Definition: icmpv4.c:39
#define ICMP_ECHO_REQUEST
Definition: icmp.h:62
A transport-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:104
An ICMP echo protocol.
Definition: icmp.h:41
void * data
Start of data.
Definition: iobuf.h:48
An ICMP header.
Definition: icmp.h:19
ICMP protocol.
struct tcpip_protocol icmpv4_protocol __tcpip_protocol
ICMPv4 TCP/IP protocol.
Definition: icmpv4.c:100
#define ICMP_ECHO_REPLY
Definition: icmp.h:61
sa_family_t family
Address family.
Definition: icmp.h:43
int icmp_rx_echo_reply(struct io_buffer *iobuf, struct sockaddr_tcpip *st_src)
Process a received ICMP echo request.
Definition: icmp.c:196
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:165
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition: tcpip.c:203
uint32_t len
Length.
Definition: ena.h:14
String functions.
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
A persistent I/O buffer.
Definition: iobuf.h:33