iPXE
tcpip.c File Reference

Transport-network layer interface. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/tables.h>
#include <ipxe/ipstat.h>
#include <ipxe/netdevice.h>
#include <ipxe/tcpip.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
int tcpip_rx (struct io_buffer *iobuf, struct net_device *netdev, uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum, struct ip_statistics *stats)
 Process a received TCP/IP packet.
struct tcpip_net_protocol * tcpip_net_protocol (sa_family_t sa_family)
 Find TCP/IP network-layer protocol.
int tcpip_tx (struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum)
 Transmit a TCP/IP packet.
struct net_devicetcpip_netdev (struct sockaddr_tcpip *st_dest)
 Determine transmitting network device.
size_t tcpip_mtu (struct sockaddr_tcpip *st_dest)
 Determine maximum transmission unit.
uint16_t generic_tcpip_continue_chksum (uint16_t partial, const void *data, size_t len)
 Calculate continued TCP/IP checkum.
uint16_t tcpip_chksum (const void *data, size_t len)
 Calculate TCP/IP checkum.
int tcpip_bind (struct sockaddr_tcpip *st_local, int(*available)(int port))
 Bind to local TCP/IP port.

Detailed Description

Transport-network layer interface.

This file contains functions and utilities for the TCP/IP transport-network layer interface

Definition in file tcpip.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ tcpip_rx()

int tcpip_rx ( struct io_buffer * iobuf,
struct net_device * netdev,
uint8_t tcpip_proto,
struct sockaddr_tcpip * st_src,
struct sockaddr_tcpip * st_dest,
uint16_t pshdr_csum,
struct ip_statistics * stats )

Process a received TCP/IP packet.

Parameters
iobufI/O buffer
netdevNetwork device
tcpip_protoTransport-layer protocol number
st_srcPartially-filled source address
st_destPartially-filled destination address
pshdr_csumPseudo-header checksum
statsIP statistics
Return values
rcReturn status code

This function expects a transport-layer segment from the network layer. The network layer should fill in as much as it can of the source and destination addresses (i.e. it should fill in the address family and the network-layer addresses, but leave the ports and the rest of the structures as zero).

Definition at line 41 of file tcpip.c.

44 {
45 struct tcpip_protocol *tcpip;
46
47 /* Hand off packet to the appropriate transport-layer protocol */
49 if ( tcpip->tcpip_proto == tcpip_proto ) {
50 DBG ( "TCP/IP received %s packet\n", tcpip->name );
51 stats->in_delivers++;
52 return tcpip->rx ( iobuf, netdev, st_src, st_dest,
53 pshdr_csum );
54 }
55 }
56
57 DBG ( "Unrecognised TCP/IP protocol %d\n", tcpip_proto );
58 stats->in_unknown_protos++;
59 free_iob ( iobuf );
60 return -EPROTONOSUPPORT;
61}
static struct net_device * netdev
Definition gdbudp.c:53
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define EPROTONOSUPPORT
Protocol not supported.
Definition errno.h:630
#define TCPIP_PROTOCOLS
TCP/IP transport-layer protocol table.
Definition tcpip.h:179
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
unsigned long in_unknown_protos
ipSystemStatsInUnknownProtos
Definition ipstat.h:84
unsigned long in_delivers
ipSystemStatsInDelivers
Definition ipstat.h:117
A transport-layer protocol of the TCP/IP stack (eg.
Definition tcpip.h:105
uint8_t tcpip_proto
Transport-layer protocol number.
Definition tcpip.h:135
const char * name
Protocol name.
Definition tcpip.h:107
int(* rx)(struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum)
Process received packet.
Definition tcpip.h:120
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References DBG, EPROTONOSUPPORT, for_each_table_entry, free_iob(), ip_statistics::in_delivers, ip_statistics::in_unknown_protos, tcpip_protocol::name, netdev, tcpip_protocol::rx, tcpip_protocol::tcpip_proto, and TCPIP_PROTOCOLS.

Referenced by ipv4_rx(), and ipv6_rx().

◆ tcpip_net_protocol()

struct tcpip_net_protocol * tcpip_net_protocol ( sa_family_t sa_family)

Find TCP/IP network-layer protocol.

Parameters
sa_familyAddress family
Return values
tcpip_netTCP/IP network-layer protocol, or NULL if not found

Definition at line 69 of file tcpip.c.

69 {
70 struct tcpip_net_protocol *tcpip_net;
71
73 if ( tcpip_net->sa_family == sa_family )
74 return tcpip_net;
75 }
76
77 DBG ( "Unrecognised TCP/IP address family %d\n", sa_family );
78 return NULL;
79}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define TCPIP_NET_PROTOCOLS
TCP/IP network-layer protocol table.
Definition tcpip.h:185
A network-layer protocol of the TCP/IP stack (eg.
Definition tcpip.h:141
sa_family_t sa_family
Network address family.
Definition tcpip.h:145

References DBG, for_each_table_entry, NULL, tcpip_net_protocol::sa_family, and TCPIP_NET_PROTOCOLS.

Referenced by efi_pxe_install(), efi_pxe_start(), efi_pxe_udp_deliver(), tcpip_mtu(), tcpip_netdev(), and tcpip_tx().

◆ tcpip_tx()

int tcpip_tx ( struct io_buffer * iobuf,
struct tcpip_protocol * tcpip_protocol,
struct sockaddr_tcpip * st_src,
struct sockaddr_tcpip * st_dest,
struct net_device * netdev,
uint16_t * trans_csum )

Transmit a TCP/IP packet.

Parameters
iobufI/O buffer
tcpip_protocolTransport-layer protocol
st_srcSource address, or NULL to use route default
st_destDestination address
netdevNetwork device to use if no route found, or NULL
trans_csumTransport-layer checksum to complete, or NULL
Return values
rcReturn status code

Definition at line 92 of file tcpip.c.

94 {
95 struct tcpip_net_protocol *tcpip_net;
96
97 /* Hand off packet to the appropriate network-layer protocol */
98 tcpip_net = tcpip_net_protocol ( st_dest->st_family );
99 if ( tcpip_net ) {
100 DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
101 return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest,
102 netdev, trans_csum );
103 }
104
105 free_iob ( iobuf );
106 return -EAFNOSUPPORT;
107}
#define EAFNOSUPPORT
Address family not supported.
Definition errno.h:314
sa_family_t st_family
Socket address family (part of struct sockaddr)
Definition tcpip.h:78
int(* tx)(struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum)
Transmit packet.
Definition tcpip.h:163
const char * name
Protocol name.
Definition tcpip.h:143
struct tcpip_net_protocol * tcpip_net_protocol(sa_family_t sa_family)
Find TCP/IP network-layer protocol.
Definition tcpip.c:69

References DBG, EAFNOSUPPORT, free_iob(), tcpip_net_protocol::name, netdev, sockaddr_tcpip::st_family, tcpip_net_protocol(), and tcpip_net_protocol::tx.

Referenced by icmp_tx_echo(), ndp_tx_ll_addr(), tcp_xmit_reset(), tcp_xmit_sack(), and udp_tx().

◆ tcpip_netdev()

struct net_device * tcpip_netdev ( struct sockaddr_tcpip * st_dest)

Determine transmitting network device.

Parameters
st_destDestination address
Return values
netdevNetwork device, or NULL

Definition at line 115 of file tcpip.c.

115 {
116 struct tcpip_net_protocol *tcpip_net;
117
118 /* Hand off to the appropriate network-layer protocol */
119 tcpip_net = tcpip_net_protocol ( st_dest->st_family );
120 if ( tcpip_net )
121 return tcpip_net->netdev ( st_dest );
122
123 return NULL;
124}
struct net_device *(* netdev)(struct sockaddr_tcpip *dest)
Determine transmitting network device.
Definition tcpip.h:175

References tcpip_net_protocol::netdev, NULL, sockaddr_tcpip::st_family, and tcpip_net_protocol().

Referenced by efi_iscsi_path(), ibft_fill_target_nic_association(), and ibft_netdev_is_required().

◆ tcpip_mtu()

size_t tcpip_mtu ( struct sockaddr_tcpip * st_dest)

Determine maximum transmission unit.

Parameters
st_destDestination address
Return values
mtuMaximum transmission unit

Definition at line 132 of file tcpip.c.

132 {
133 struct tcpip_net_protocol *tcpip_net;
134 struct net_device *netdev;
135 size_t mtu;
136
137 /* Find appropriate network-layer protocol */
138 tcpip_net = tcpip_net_protocol ( st_dest->st_family );
139 if ( ! tcpip_net )
140 return 0;
141
142 /* Find transmitting network device */
143 netdev = tcpip_net->netdev ( st_dest );
144 if ( ! netdev )
145 return 0;
146
147 /* Calculate MTU */
148 mtu = ( netdev->mtu - tcpip_net->header_len );
149
150 return mtu;
151}
uint32_t mtu
Maximum MTU.
Definition ena.h:17
A network device.
Definition netdevice.h:353
size_t header_len
Fixed header length.
Definition tcpip.h:147

References tcpip_net_protocol::header_len, mtu, netdev, tcpip_net_protocol::netdev, sockaddr_tcpip::st_family, and tcpip_net_protocol().

Referenced by tcp_open().

◆ generic_tcpip_continue_chksum()

uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
const void * data,
size_t len )

Calculate continued TCP/IP checkum.

Parameters
partialChecksum of already-summed data, in network byte order
dataData buffer
lenLength of data buffer
Return values
cksumUpdated checksum, in network byte order

Calculates a TCP/IP-style 16-bit checksum over the data block. The checksum is returned in network byte order.

This function may be used to add new data to an existing checksum. The function assumes that both the old data and the new data start on even byte offsets; if this is not the case then you will need to byte-swap either the input partial checksum, the output checksum, or both. Deciding which to swap is left as an exercise for the interested reader.

Definition at line 171 of file tcpip.c.

172 {
173 unsigned int cksum = ( ( ~partial ) & 0xffff );
174 unsigned int value;
175 unsigned int i;
176
177 for ( i = 0 ; i < len ; i++ ) {
178 value = * ( ( uint8_t * ) data + i );
179 if ( i & 1 ) {
180 /* Odd bytes: swap on little-endian systems */
181 value = be16_to_cpu ( value );
182 } else {
183 /* Even bytes: swap on big-endian systems */
184 value = le16_to_cpu ( value );
185 }
186 cksum += value;
187 if ( cksum > 0xffff )
188 cksum -= 0xffff;
189 }
190
191 return ( ~cksum );
192}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define le16_to_cpu(value)
Definition byteswap.h:113
#define be16_to_cpu(value)
Definition byteswap.h:116

References be16_to_cpu, data, le16_to_cpu, len, and value.

Referenced by tcpip_okx(), and tcpip_random_okx().

◆ tcpip_chksum()

uint16_t tcpip_chksum ( const void * data,
size_t len )

Calculate TCP/IP checkum.

Parameters
dataData buffer
lenLength of data buffer
Return values
cksumChecksum, in network byte order

Calculates a TCP/IP-style 16-bit checksum over the data block. The checksum is returned in network byte order.

Definition at line 204 of file tcpip.c.

204 {
206}
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition tcpip.h:58
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 data, len, tcpip_continue_chksum(), and TCPIP_EMPTY_CSUM.

Referenced by gdbudp_send(), icmp_tx_echo(), icmpv4_rx(), ipv4_rx(), ipv4_tx(), ndp_tx_ll_addr(), tcp_xmit_reset(), tcp_xmit_sack(), and udp_tx().

◆ tcpip_bind()

int tcpip_bind ( struct sockaddr_tcpip * st_local,
int(* available )(int port) )

Bind to local TCP/IP port.

Parameters
st_localLocal TCP/IP socket address, or NULL
availableFunction to check port availability
Return values
portLocal port number, or negative error

Definition at line 215 of file tcpip.c.

216 {
217 uint16_t flags = 0;
218 uint16_t try_port = 0;
219 uint16_t min_port;
220 uint16_t max_port;
221 unsigned int offset;
222 unsigned int i;
223
224 /* Extract parameters from local socket address */
225 if ( st_local ) {
226 flags = st_local->st_flags;
227 try_port = ntohs ( st_local->st_port );
228 }
229
230 /* If an explicit port is specified, check its availability */
231 if ( try_port )
232 return available ( try_port );
233
234 /* Otherwise, find an available port in the range [1,1023] or
235 * [1025,65535] as appropriate.
236 */
237 min_port = ( ( ( ~flags ) & TCPIP_BIND_PRIVILEGED ) + 1 );
238 max_port = ( ( flags & TCPIP_BIND_PRIVILEGED ) - 1 );
239 offset = random();
240 for ( i = 0 ; i <= max_port ; i++ ) {
241 try_port = ( ( i + offset ) & max_port );
242 if ( try_port < min_port )
243 continue;
244 if ( available ( try_port ) < 0 )
245 continue;
246 return try_port;
247 }
248 return -EADDRINUSE;
249}
unsigned short uint16_t
Definition stdint.h:11
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint8_t flags
Flags.
Definition ena.h:7
#define EADDRINUSE
Address already in use.
Definition errno.h:304
#define ntohs(value)
Definition byteswap.h:137
@ TCPIP_BIND_PRIVILEGED
Bind to a privileged port (less than 1024)
Definition tcpip.h:67
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
uint16_t st_flags
Flags.
Definition tcpip.h:80
uint16_t st_port
TCP/IP port.
Definition tcpip.h:82

References EADDRINUSE, flags, ntohs, offset, port, random(), sockaddr_tcpip::st_flags, sockaddr_tcpip::st_port, and TCPIP_BIND_PRIVILEGED.

Referenced by ping_open(), tcp_open(), and udp_open_common().