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 FILE_SECBOOT ( PERMITTED );
26 
27 #include <string.h>
28 #include <errno.h>
29 #include <ipxe/iobuf.h>
30 #include <ipxe/in.h>
31 #include <ipxe/tcpip.h>
32 #include <ipxe/icmp.h>
33 
34 /** @file
35  *
36  * ICMPv4 protocol
37  *
38  */
39 
40 struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol;
41 
42 /**
43  * Process a received packet
44  *
45  * @v iobuf I/O buffer
46  * @v netdev Network device
47  * @v st_src Partially-filled source address
48  * @v st_dest Partially-filled destination address
49  * @v pshdr_csum Pseudo-header checksum
50  * @ret rc Return status code
51  */
52 static int icmpv4_rx ( struct io_buffer *iobuf,
53  struct net_device *netdev __unused,
54  struct sockaddr_tcpip *st_src,
55  struct sockaddr_tcpip *st_dest __unused,
56  uint16_t pshdr_csum __unused ) {
57  struct icmp_header *icmp = iobuf->data;
58  size_t len = iob_len ( iobuf );
59  unsigned int csum;
60  unsigned int type;
61  int rc;
62 
63  /* Sanity check */
64  if ( len < sizeof ( *icmp ) ) {
65  DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n",
66  len, sizeof ( *icmp ) );
67  rc = -EINVAL;
68  goto discard;
69  }
70 
71  /* Verify checksum */
72  csum = tcpip_chksum ( icmp, len );
73  if ( csum != 0 ) {
74  DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n",
75  csum );
76  DBG_HD ( icmp, len );
77  rc = -EINVAL;
78  goto discard;
79  }
80 
81  /* Handle ICMP packet */
82  type = icmp->type;
83  switch ( type ) {
84  case ICMP_ECHO_REQUEST:
85  return icmp_rx_echo_request ( iobuf, st_src,
86  &icmpv4_echo_protocol );
87  case ICMP_ECHO_REPLY:
88  return icmp_rx_echo_reply ( iobuf, st_src );
89  default:
90  DBG ( "ICMP ignoring type %d\n", type );
91  rc = 0;
92  break;
93  }
94 
95  discard:
96  free_iob ( iobuf );
97  return rc;
98 }
99 
100 /** ICMPv4 TCP/IP protocol */
101 struct tcpip_protocol icmpv4_protocol __tcpip_protocol = {
102  .name = "ICMPv4",
103  .rx = icmpv4_rx,
104  .tcpip_proto = IP_ICMP,
105 };
106 
107 /** ICMPv4 echo protocol */
108 struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol = {
109  .family = AF_INET,
110  .request = ICMP_ECHO_REQUEST,
111  .reply = ICMP_ECHO_REPLY,
112  .tcpip_protocol = &icmpv4_protocol,
113  .net_checksum = 0,
114 };
#define EINVAL
Invalid argument.
Definition: errno.h:429
TCP/IP socket address.
Definition: tcpip.h:76
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:52
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:153
uint32_t type
Operating system type.
Definition: ena.h:12
uint8_t type
Type.
Definition: icmp.h:22
#define IP_ICMP
Definition: in.h:13
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
Transport-network layer interface.
FILE_SECBOOT(PERMITTED)
const char * name
Protocol name.
Definition: tcpip.h:107
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
A network device.
Definition: netdevice.h:353
struct icmp_echo_protocol icmpv4_echo_protocol __icmp_echo_protocol
ICMPv4 echo protocol.
Definition: icmpv4.c:40
#define ICMP_ECHO_REQUEST
Definition: icmp.h:63
A transport-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:105
An ICMP echo protocol.
Definition: icmp.h:42
void * data
Start of data.
Definition: iobuf.h:53
An ICMP header.
Definition: icmp.h:20
ICMP protocol.
struct tcpip_protocol icmpv4_protocol __tcpip_protocol
ICMPv4 TCP/IP protocol.
Definition: icmpv4.c:101
#define ICMP_ECHO_REPLY
Definition: icmp.h:62
sa_family_t family
Address family.
Definition: icmp.h:44
int icmp_rx_echo_reply(struct io_buffer *iobuf, struct sockaddr_tcpip *st_src)
Process a received ICMP echo request.
Definition: icmp.c:197
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
#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:204
String functions.
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:64
A persistent I/O buffer.
Definition: iobuf.h:38