iPXE
ping.c File Reference

ICMP ping protocol. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
#include <ipxe/icmp.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/netdevice.h>
#include <ipxe/ping.h>

Go to the source code of this file.

Data Structures

struct  ping_connection
 A ping connection. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static LIST_HEAD (ping_conns)
 List of registered ping connections.
static struct ping_connectionping_demux (unsigned int port)
 Identify ping connection by local port number.
static int ping_port_available (int port)
 Check if local port number is available.
int ping_rx (struct io_buffer *iobuf, struct sockaddr_tcpip *st_src)
 Process ICMP ping reply.
static struct io_bufferping_alloc_iob (struct ping_connection *ping __unused, size_t len)
 Allocate I/O buffer for ping.
static int ping_deliver (struct ping_connection *ping, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Deliver datagram as I/O buffer.
static void ping_close (struct ping_connection *ping, int rc)
 Close ping connection.
static int ping_open (struct interface *xfer, struct sockaddr *peer, struct sockaddr *local)
 Open a ping connection.

Variables

static struct interface_operation ping_xfer_operations []
 Ping data transfer interface operations.
static struct interface_descriptor ping_xfer_desc
 Ping data transfer interface descriptor.
struct socket_opener ping_socket_opener __socket_opener
 Ping socket opener.
int ping_sock_echo = PING_SOCK_ECHO
 Linkage hack.

Detailed Description

ICMP ping protocol.

Definition in file ping.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ LIST_HEAD()

LIST_HEAD ( ping_conns )
static

List of registered ping connections.

◆ ping_demux()

struct ping_connection * ping_demux ( unsigned int port)
static

Identify ping connection by local port number.

Parameters
portLocal port number
Return values
pingPing connection, or NULL

Definition at line 76 of file ping.c.

76 {
77 struct ping_connection *ping;
78
79 list_for_each_entry ( ping, &ping_conns, list ) {
80 if ( ping->port == port )
81 return ping;
82 }
83 return NULL;
84}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
u8 port
Port number.
Definition CIB_PRM.h:3
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
int ping(const char *hostname, unsigned long timeout, size_t len, unsigned int count, int quiet)
Ping a host.
Definition pingmgmt.c:70
A ping connection.
Definition ping.c:52
struct list_head list
List of ping connections.
Definition ping.c:56

References ping_connection::list, list_for_each_entry, NULL, ping(), and port.

Referenced by ping_port_available(), and ping_rx().

◆ ping_port_available()

int ping_port_available ( int port)
static

Check if local port number is available.

Parameters
portLocal port number
Return values
portLocal port number, or negative error

Definition at line 92 of file ping.c.

92 {
93
94 return ( ping_demux ( port ) ? -EADDRINUSE : port );
95}
#define EADDRINUSE
Address already in use.
Definition errno.h:347
static struct ping_connection * ping_demux(unsigned int port)
Identify ping connection by local port number.
Definition ping.c:76

References EADDRINUSE, ping_demux(), and port.

Referenced by ping_open().

◆ ping_rx()

int ping_rx ( struct io_buffer * iobuf,
struct sockaddr_tcpip * st_src )

Process ICMP ping reply.

Parameters
iobufI/O buffer
st_srcSource address
Return values
rcReturn status code

Definition at line 104 of file ping.c.

104 {
105 struct icmp_echo *echo;
106 struct ping_connection *ping;
107 struct xfer_metadata meta;
108 int rc;
109
110 /* Sanity check: should already have been checked by ICMP layer */
111 assert ( iob_len ( iobuf ) >= sizeof ( *echo ) );
112 echo = iobuf->data;
113
114 /* Identify connection */
115 ping = ping_demux ( ntohs ( echo->ident ) );
116 DBGC ( ping, "PING %p reply id %#04x seq %#04x\n",
117 ping, ntohs ( echo->ident ), ntohs ( echo->sequence ) );
118 if ( ! ping ) {
119 rc = -ENOTCONN;
120 goto discard;
121 }
122
123 /* Strip header, construct metadata, and pass data to upper layer */
124 iob_pull ( iobuf, sizeof ( *echo ) );
125 memset ( &meta, 0, sizeof ( meta ) );
126 meta.src = ( ( struct sockaddr * ) st_src );
127 meta.flags = XFER_FL_ABS_OFFSET;
128 meta.offset = ntohs ( echo->sequence );
129 return xfer_deliver ( &ping->xfer, iob_disown ( iobuf ), &meta );
130
131 discard:
132 free_iob ( iobuf );
133 return rc;
134}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
uint8_t meta
Metadata flags.
Definition ena.h:3
#define DBGC(...)
Definition compiler.h:530
#define ENOTCONN
The socket is not connected.
Definition errno.h:613
#define ntohs(value)
Definition byteswap.h:137
void * memset(void *dest, int character, size_t len) __nonnull
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:277
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
int echo(void)
Definition kb.c:133
An ICMP echo request/reply.
Definition icmp.h:30
void * data
Start of data.
Definition iobuf.h:113
Generalized socket address structure.
Definition socket.h:97
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48

References assert, io_buffer::data, DBGC, echo(), ENOTCONN, free_iob(), iob_disown, iob_len(), iob_pull, memset(), meta, ntohs, ping(), ping_demux(), rc, xfer_deliver(), and XFER_FL_ABS_OFFSET.

◆ ping_alloc_iob()

struct io_buffer * ping_alloc_iob ( struct ping_connection *ping __unused,
size_t len )
static

Allocate I/O buffer for ping.

Parameters
pingPing connection
lenPayload size
Return values
iobufI/O buffer, or NULL

Definition at line 144 of file ping.c.

144 {
145 size_t header_len;
146 struct io_buffer *iobuf;
147
148 header_len = ( MAX_LL_NET_HEADER_LEN + sizeof ( struct icmp_echo ) );
149 iobuf = alloc_iob ( header_len + len );
150 if ( iobuf )
151 iob_reserve ( iobuf, header_len );
152 return iobuf;
153}
ring len
Length.
Definition dwmac.h:226
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_reserve(iobuf, len)
Definition iobuf.h:132
#define MAX_LL_NET_HEADER_LEN
Maximum combined length of a link-layer and network-layer header.
Definition netdevice.h:59
A persistent I/O buffer.
Definition iobuf.h:98

References __unused, alloc_iob(), iob_reserve, len, MAX_LL_NET_HEADER_LEN, and ping().

◆ ping_deliver()

int ping_deliver ( struct ping_connection * ping,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Deliver datagram as I/O buffer.

Parameters
pingPing connection
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 163 of file ping.c.

164 {
165 struct icmp_echo *echo = iob_push ( iobuf, sizeof ( *echo ) );
166 int rc;
167
168 /* Construct header */
169 memset ( echo, 0, sizeof ( *echo ) );
170 echo->ident = htons ( ping->port );
171 echo->sequence = htons ( meta->offset );
172
173 /* Transmit echo request */
174 if ( ( rc = icmp_tx_echo_request ( iob_disown ( iobuf ),
175 &ping->peer ) ) != 0 ) {
176 DBGC ( ping, "PING %p could not transmit: %s\n",
177 ping, strerror ( rc ) );
178 return rc;
179 }
180
181 return 0;
182}
int icmp_tx_echo_request(struct io_buffer *iobuf, struct sockaddr_tcpip *st_dest)
Transmit ICMP echo request.
Definition icmp.c:106
#define htons(value)
Definition byteswap.h:136
#define iob_push(iobuf, len)
Definition iobuf.h:149
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References DBGC, echo(), htons, icmp_tx_echo_request(), iob_disown, iob_push, memset(), meta, ping(), rc, and strerror().

◆ ping_close()

void ping_close ( struct ping_connection * ping,
int rc )
static

Close ping connection.

Parameters
pingPing connection
rcReason for close

Definition at line 190 of file ping.c.

190 {
191
192 /* Close data transfer interface */
193 intf_shutdown ( &ping->xfer, rc );
194
195 /* Remove from list of connections and drop list's reference */
196 list_del ( &ping->list );
197 ref_put ( &ping->refcnt );
198
199 DBGC ( ping, "PING %p closed\n", ping );
200}
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References DBGC, intf_shutdown(), list_del, ping(), rc, and ref_put.

◆ ping_open()

int ping_open ( struct interface * xfer,
struct sockaddr * peer,
struct sockaddr * local )
static

Open a ping connection.

Parameters
xferData transfer interface
peerPeer socket address
localLocal socket address, or NULL
Return values
rcReturn status code

Definition at line 221 of file ping.c.

222 {
223 struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer;
224 struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local;
225 struct ping_connection *ping;
226 int port;
227 int rc;
228
229 /* Allocate and initialise structure */
230 ping = zalloc ( sizeof ( *ping ) );
231 if ( ! ping ) {
232 rc = -ENOMEM;
233 goto err_alloc;
234 }
235 DBGC ( ping, "PING %p allocated\n", ping );
236 ref_init ( &ping->refcnt, NULL );
237 intf_init ( &ping->xfer, &ping_xfer_desc, &ping->refcnt );
238 memcpy ( &ping->peer, st_peer, sizeof ( ping->peer ) );
239
240 /* Bind to local port */
241 port = tcpip_bind ( st_local, ping_port_available );
242 if ( port < 0 ) {
243 rc = port;
244 DBGC ( ping, "PING %p could not bind: %s\n",
245 ping, strerror ( rc ) );
246 goto err_bind;
247 }
248 ping->port = port;
249 DBGC ( ping, "PING %p bound to id %#04x\n", ping, port );
250
251 /* Attach parent interface, transfer reference to connection
252 * list, and return
253 */
254 intf_plug_plug ( &ping->xfer, xfer );
255 list_add ( &ping->list, &ping_conns );
256 return 0;
257
258 err_bind:
259 ref_put ( &ping->refcnt );
260 err_alloc:
261 return rc;
262}
#define ENOMEM
Not enough space.
Definition errno.h:578
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
static int ping_port_available(int port)
Check if local port number is available.
Definition ping.c:92
static struct interface_descriptor ping_xfer_desc
Ping data transfer interface descriptor.
Definition ping.c:210
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct interface xfer
Data transfer interface.
Definition ping.c:64
TCP/IP socket address.
Definition tcpip.h:76
int tcpip_bind(struct sockaddr_tcpip *st_local, int(*available)(int port))
Bind to local TCP/IP port.
Definition tcpip.c:215

References DBGC, ENOMEM, intf_init(), intf_plug_plug(), list_add, memcpy(), NULL, peer, ping(), ping_port_available(), ping_xfer_desc, port, rc, ref_init, ref_put, strerror(), tcpip_bind(), ping_connection::xfer, and zalloc().

Variable Documentation

◆ ping_xfer_operations

struct interface_operation ping_xfer_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
static struct io_buffer * ping_alloc_iob(struct ping_connection *ping __unused, size_t len)
Allocate I/O buffer for ping.
Definition ping.c:144
static int ping_deliver(struct ping_connection *ping, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram as I/O buffer.
Definition ping.c:163
static void ping_close(struct ping_connection *ping, int rc)
Close ping connection.
Definition ping.c:190
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

Ping data transfer interface operations.

Definition at line 203 of file ping.c.

◆ ping_xfer_desc

struct interface_descriptor ping_xfer_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation ping_xfer_operations[]
Ping data transfer interface operations.
Definition ping.c:203

Ping data transfer interface descriptor.

Definition at line 210 of file ping.c.

Referenced by ping_open().

◆ __socket_opener

struct socket_opener ping_socket_opener __socket_opener
Initial value:
= {
.semantics = PING_SOCK_ECHO,
.open = ping_open,
}
#define PING_SOCK_ECHO
Definition socket.h:34
static int ping_open(struct interface *xfer, struct sockaddr *peer, struct sockaddr *local)
Open a ping connection.
Definition ping.c:221

Ping socket opener.

Definition at line 265 of file ping.c.

265 {
266 .semantics = PING_SOCK_ECHO,
267 .open = ping_open,
268};