iPXE
Functions | Variables
ipv4.c File Reference

IPv4 protocol. More...

#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/list.h>
#include <ipxe/in.h>
#include <ipxe/arp.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/ip.h>
#include <ipxe/tcpip.h>
#include <ipxe/dhcp.h>
#include <ipxe/settings.h>
#include <ipxe/fragment.h>
#include <ipxe/ipstat.h>
#include <ipxe/profile.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
struct ip_statistics_family ipv4_stats_family __ip_statistics_family (IP_STATISTICS_IPV4)
 IPv4 statistics family. More...
 
static int add_ipv4_miniroute (struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway)
 Add IPv4 minirouting table entry. More...
 
static void del_ipv4_miniroute (struct ipv4_miniroute *miniroute)
 Delete IPv4 minirouting table entry. More...
 
static struct ipv4_minirouteipv4_route (unsigned int scope_id, struct in_addr *dest)
 Perform IPv4 routing. More...
 
static struct net_deviceipv4_netdev (struct sockaddr_tcpip *st_dest)
 Determine transmitting network device. More...
 
static int ipv4_is_fragment (struct fragment *fragment, struct io_buffer *iobuf, size_t hdrlen __unused)
 Check if IPv4 fragment matches fragment reassembly buffer. More...
 
static size_t ipv4_fragment_offset (struct io_buffer *iobuf, size_t hdrlen __unused)
 Get IPv4 fragment offset. More...
 
static int ipv4_more_fragments (struct io_buffer *iobuf, size_t hdrlen __unused)
 Check if more fragments exist. More...
 
static uint16_t ipv4_pshdr_chksum (struct io_buffer *iobuf, uint16_t csum)
 Add IPv4 pseudo-header checksum to existing checksum. More...
 
static int ipv4_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 IP packet. More...
 
int ipv4_has_any_addr (struct net_device *netdev)
 Check if network device has any IPv4 address. More...
 
static int ipv4_has_addr (struct net_device *netdev, struct in_addr addr)
 Check if network device has a specific IPv4 address. More...
 
static int ipv4_rx (struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags)
 Process incoming packets. More...
 
static int ipv4_arp_check (struct net_device *netdev, const void *net_addr)
 Check existence of IPv4 address for ARP. More...
 
int inet_aton (const char *string, struct in_addr *in)
 Parse IPv4 address. More...
 
char * inet_ntoa (struct in_addr in)
 Convert IPv4 address to dotted-quad notation. More...
 
static const char * ipv4_ntoa (const void *net_addr)
 Transcribe IPv4 address. More...
 
static const char * ipv4_sock_ntoa (struct sockaddr *sa)
 Transcribe IPv4 socket address. More...
 
static int ipv4_sock_aton (const char *string, struct sockaddr *sa)
 Parse IPv4 socket address. More...
 
int parse_ipv4_setting (const struct setting_type *type __unused, const char *value, void *buf, size_t len)
 Parse IPv4 address setting value. More...
 
int format_ipv4_setting (const struct setting_type *type __unused, const void *raw, size_t raw_len, char *buf, size_t len)
 Format IPv4 address setting value. More...
 
const struct setting ip_setting __setting (SETTING_IP4, ip)
 IPv4 address setting. More...
 
const struct setting netmask_setting __setting (SETTING_IP4, netmask)
 IPv4 subnet mask setting. More...
 
const struct setting gateway_setting __setting (SETTING_IP4, gateway)
 Default gateway setting. More...
 
static int ipv4_gratuitous_arp (struct net_device *netdev, struct in_addr address, struct in_addr netmask __unused, struct in_addr gateway __unused)
 Send gratuitous ARP, if applicable. More...
 
static int ipv4_settings (int(*apply)(struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway))
 Process IPv4 network device settings. More...
 
static int ipv4_create_routes (void)
 Create IPv4 routing table based on configured settings. More...
 
 REQUIRING_SYMBOL (ipv4_protocol)
 
 REQUIRE_OBJECT (icmpv4)
 

Variables

static uint8_t next_ident_high = 0
 
struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes )
 List of IPv4 miniroutes. More...
 
static struct ip_statistics ipv4_stats
 IPv4 statistics. More...
 
static struct profiler ipv4_tx_profiler __profiler = { .name = "ipv4.tx" }
 Transmit profiler. More...
 
static struct fragment_reassembler ipv4_reassembler
 IPv4 fragment reassembler. More...
 
struct net_protocol ipv4_protocol __net_protocol
 IPv4 protocol. More...
 
struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol
 IPv4 TCPIP net protocol. More...
 
struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol
 IPv4 ARP protocol. More...
 
struct sockaddr_converter ipv4_sockaddr_converter __sockaddr_converter
 IPv4 socket address converter. More...
 
struct settings_applicator ipv4_settings_applicator __settings_applicator
 IPv4 settings applicator. More...
 

Detailed Description

IPv4 protocol.

Definition in file ipv4.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __ip_statistics_family()

struct ip_statistics_family ipv4_stats_family __ip_statistics_family ( IP_STATISTICS_IPV4  )

IPv4 statistics family.

◆ add_ipv4_miniroute()

static int add_ipv4_miniroute ( struct net_device netdev,
struct in_addr  address,
struct in_addr  netmask,
struct in_addr  gateway 
)
static

Add IPv4 minirouting table entry.

Parameters
netdevNetwork device
addressIPv4 address
netmaskSubnet mask
gatewayGateway address (if any)
Return values
rcReturn status code

Definition at line 84 of file ipv4.c.

86  {
87  struct ipv4_miniroute *miniroute;
88 
89  DBGC ( netdev, "IPv4 add %s", inet_ntoa ( address ) );
90  DBGC ( netdev, "/%s ", inet_ntoa ( netmask ) );
91  if ( gateway.s_addr )
92  DBGC ( netdev, "gw %s ", inet_ntoa ( gateway ) );
93  DBGC ( netdev, "via %s\n", netdev->name );
94 
95  /* Allocate and populate miniroute structure */
96  miniroute = malloc ( sizeof ( *miniroute ) );
97  if ( ! miniroute ) {
98  DBGC ( netdev, "IPv4 could not add miniroute\n" );
99  return -ENOMEM;
100  }
101 
102  /* Record routing information */
103  miniroute->netdev = netdev_get ( netdev );
104  miniroute->address = address;
105  miniroute->netmask = netmask;
106  miniroute->gateway = gateway;
107 
108  /* Add to end of list if we have a gateway, otherwise
109  * to start of list.
110  */
111  if ( gateway.s_addr ) {
112  list_add_tail ( &miniroute->list, &ipv4_miniroutes );
113  } else {
114  list_add ( &miniroute->list, &ipv4_miniroutes );
115  }
116 
117  return 0;
118 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:68
struct list_head list
List of miniroutes.
Definition: ip.h:60
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
uint64_t address
Base address.
Definition: ena.h:24
struct net_device * netdev
Network device.
Definition: ip.h:63
#define DBGC(...)
Definition: compiler.h:505
struct in_addr address
IPv4 address.
Definition: ip.h:66
#define ENOMEM
Not enough space.
Definition: errno.h:534
An IPv4 address/routing table entry.
Definition: ip.h:58
struct in_addr gateway
Gateway address.
Definition: ip.h:70
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static struct net_device * netdev
Definition: gdbudp.c:52
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition: ipv4.c:57
uint32_t s_addr
Definition: in.h:40
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362

References address, ipv4_miniroute::address, DBGC, ENOMEM, ipv4_miniroute::gateway, inet_ntoa(), ipv4_miniroutes, ipv4_miniroute::list, list_add, list_add_tail, malloc(), net_device::name, netdev, ipv4_miniroute::netdev, netdev_get(), ipv4_miniroute::netmask, and in_addr::s_addr.

Referenced by ipv4_create_routes().

◆ del_ipv4_miniroute()

static void del_ipv4_miniroute ( struct ipv4_miniroute miniroute)
static

Delete IPv4 minirouting table entry.

Parameters
minirouteRouting table entry

Definition at line 125 of file ipv4.c.

125  {
126  struct net_device *netdev = miniroute->netdev;
127 
128  DBGC ( netdev, "IPv4 del %s", inet_ntoa ( miniroute->address ) );
129  DBGC ( netdev, "/%s ", inet_ntoa ( miniroute->netmask ) );
130  if ( miniroute->gateway.s_addr )
131  DBGC ( netdev, "gw %s ", inet_ntoa ( miniroute->gateway ) );
132  DBGC ( netdev, "via %s\n", miniroute->netdev->name );
133 
134  netdev_put ( miniroute->netdev );
135  list_del ( &miniroute->list );
136  free ( miniroute );
137 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:68
struct list_head list
List of miniroutes.
Definition: ip.h:60
struct net_device * netdev
Network device.
Definition: ip.h:63
#define DBGC(...)
Definition: compiler.h:505
struct in_addr address
IPv4 address.
Definition: ip.h:66
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
struct in_addr gateway
Gateway address.
Definition: ip.h:70
static struct net_device * netdev
Definition: gdbudp.c:52
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A network device.
Definition: netdevice.h:352
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
uint32_t s_addr
Definition: in.h:40
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362

References ipv4_miniroute::address, DBGC, free, ipv4_miniroute::gateway, inet_ntoa(), ipv4_miniroute::list, list_del, net_device::name, netdev, ipv4_miniroute::netdev, netdev_put(), ipv4_miniroute::netmask, and in_addr::s_addr.

Referenced by ipv4_create_routes().

◆ ipv4_route()

static struct ipv4_miniroute* ipv4_route ( unsigned int  scope_id,
struct in_addr dest 
)
static

Perform IPv4 routing.

Parameters
scope_idDestination address scope ID
destFinal destination address
Return values
destNext hop destination address
minirouteRouting table entry to use, or NULL if no route

If the route requires use of a gateway, the next hop destination address will be overwritten with the gateway address.

Definition at line 150 of file ipv4.c.

151  {
152  struct ipv4_miniroute *miniroute;
153 
154  /* Find first usable route in routing table */
155  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
156 
157  /* Skip closed network devices */
158  if ( ! netdev_is_open ( miniroute->netdev ) )
159  continue;
160 
161  if ( IN_IS_MULTICAST ( dest->s_addr ) ) {
162 
163  /* If destination is non-global, and the scope ID
164  * matches this network device, then use this route.
165  */
166  if ( miniroute->netdev->scope_id == scope_id )
167  return miniroute;
168 
169  } else {
170 
171  /* If destination is an on-link global
172  * address, then use this route.
173  */
174  if ( ( ( dest->s_addr ^ miniroute->address.s_addr )
175  & miniroute->netmask.s_addr ) == 0 )
176  return miniroute;
177 
178  /* If destination is an off-link global
179  * address, and we have a default gateway,
180  * then use this route.
181  */
182  if ( miniroute->gateway.s_addr ) {
183  *dest = miniroute->gateway;
184  return miniroute;
185  }
186  }
187  }
188 
189  return NULL;
190 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:68
struct list_head list
List of miniroutes.
Definition: ip.h:60
struct net_device * netdev
Network device.
Definition: ip.h:63
struct in_addr address
IPv4 address.
Definition: ip.h:66
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
An IPv4 address/routing table entry.
Definition: ip.h:58
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct in_addr gateway
Gateway address.
Definition: ip.h:70
static void * dest
Definition: strings.h:176
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition: ipv4.c:57
uint32_t s_addr
Definition: in.h:40
#define IN_IS_MULTICAST(addr)
Definition: in.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References ipv4_miniroute::address, dest, ipv4_miniroute::gateway, IN_IS_MULTICAST, ipv4_miniroutes, ipv4_miniroute::list, list_for_each_entry, ipv4_miniroute::netdev, netdev_is_open(), ipv4_miniroute::netmask, NULL, in_addr::s_addr, and net_device::scope_id.

Referenced by ipv4_netdev(), and ipv4_tx().

◆ ipv4_netdev()

static struct net_device* ipv4_netdev ( struct sockaddr_tcpip st_dest)
static

Determine transmitting network device.

Parameters
st_destDestination network-layer address
Return values
netdevTransmitting network device, or NULL

Definition at line 198 of file ipv4.c.

198  {
199  struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
200  struct in_addr dest = sin_dest->sin_addr;
201  struct ipv4_miniroute *miniroute;
202 
203  /* Find routing table entry */
204  miniroute = ipv4_route ( sin_dest->sin_scope_id, &dest );
205  if ( ! miniroute )
206  return NULL;
207 
208  return miniroute->netdev;
209 }
struct net_device * netdev
Network device.
Definition: ip.h:63
IPv4 socket address.
Definition: in.h:82
static struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition: ipv4.c:150
uint16_t sin_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:96
An IPv4 address/routing table entry.
Definition: ip.h:58
static void * dest
Definition: strings.h:176
IP address structure.
Definition: in.h:39
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References dest, ipv4_route(), ipv4_miniroute::netdev, NULL, sockaddr_in::sin_addr, and sockaddr_in::sin_scope_id.

◆ ipv4_is_fragment()

static int ipv4_is_fragment ( struct fragment fragment,
struct io_buffer iobuf,
size_t hdrlen  __unused 
)
static

Check if IPv4 fragment matches fragment reassembly buffer.

Parameters
fragmentFragment reassembly buffer
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
is_fragmentFragment matches this reassembly buffer

Definition at line 219 of file ipv4.c.

221  {
222  struct iphdr *frag_iphdr = fragment->iobuf->data;
223  struct iphdr *iphdr = iobuf->data;
224 
225  return ( ( iphdr->src.s_addr == frag_iphdr->src.s_addr ) &&
226  ( iphdr->ident == frag_iphdr->ident ) );
227 }
struct in_addr src
Definition: ip.h:44
A fragment reassembly buffer.
Definition: fragment.h:21
uint16_t ident
Definition: ip.h:39
An IPv4 packet header.
Definition: ip.h:35
struct io_buffer * iobuf
Reassembled packet.
Definition: fragment.h:25
uint32_t s_addr
Definition: in.h:40
void * data
Start of data.
Definition: iobuf.h:48

References io_buffer::data, iphdr::ident, fragment::iobuf, in_addr::s_addr, and iphdr::src.

◆ ipv4_fragment_offset()

static size_t ipv4_fragment_offset ( struct io_buffer iobuf,
size_t hdrlen  __unused 
)
static

Get IPv4 fragment offset.

Parameters
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
offsetOffset

Definition at line 236 of file ipv4.c.

237  {
238  struct iphdr *iphdr = iobuf->data;
239 
240  return ( ( ntohs ( iphdr->frags ) & IP_MASK_OFFSET ) << 3 );
241 }
#define ntohs(value)
Definition: byteswap.h:136
uint16_t frags
Definition: ip.h:40
An IPv4 packet header.
Definition: ip.h:35
#define IP_MASK_OFFSET
Definition: ip.h:25
void * data
Start of data.
Definition: iobuf.h:48

References io_buffer::data, iphdr::frags, IP_MASK_OFFSET, and ntohs.

◆ ipv4_more_fragments()

static int ipv4_more_fragments ( struct io_buffer iobuf,
size_t hdrlen  __unused 
)
static

Check if more fragments exist.

Parameters
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
more_fragsMore fragments exist

Definition at line 250 of file ipv4.c.

251  {
252  struct iphdr *iphdr = iobuf->data;
253 
254  return ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) );
255 }
uint16_t frags
Definition: ip.h:40
An IPv4 packet header.
Definition: ip.h:35
#define IP_MASK_MOREFRAGS
Definition: ip.h:27
void * data
Start of data.
Definition: iobuf.h:48
#define htons(value)
Definition: byteswap.h:135

References io_buffer::data, iphdr::frags, htons, and IP_MASK_MOREFRAGS.

◆ ipv4_pshdr_chksum()

static uint16_t ipv4_pshdr_chksum ( struct io_buffer iobuf,
uint16_t  csum 
)
static

Add IPv4 pseudo-header checksum to existing checksum.

Parameters
iobufI/O buffer
csumExisting checksum
Return values
csumUpdated checksum

Definition at line 273 of file ipv4.c.

273  {
274  struct ipv4_pseudo_header pshdr;
275  struct iphdr *iphdr = iobuf->data;
276  size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
277 
278  /* Build pseudo-header */
279  pshdr.src = iphdr->src;
280  pshdr.dest = iphdr->dest;
281  pshdr.zero_padding = 0x00;
282  pshdr.protocol = iphdr->protocol;
283  pshdr.len = htons ( iob_len ( iobuf ) - hdrlen );
284 
285  /* Update the checksum value */
286  return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
287 }
struct in_addr src
Definition: ip.h:44
An IPv4 packet header.
Definition: ip.h:35
uint8_t verhdrlen
Definition: ip.h:36
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
struct in_addr dest
Definition: ip.h:45
An IPv4 pseudo header.
Definition: ip.h:49
#define IP_MASK_HLEN
Definition: ip.h:24
uint8_t protocol
Definition: ip.h:42
void * data
Start of data.
Definition: iobuf.h:48
#define htons(value)
Definition: byteswap.h:135
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: x86_tcpip.c:45

References io_buffer::data, ipv4_pseudo_header::dest, iphdr::dest, htons, iob_len(), IP_MASK_HLEN, ipv4_pseudo_header::len, iphdr::protocol, ipv4_pseudo_header::protocol, ipv4_pseudo_header::src, iphdr::src, tcpip_continue_chksum(), iphdr::verhdrlen, and ipv4_pseudo_header::zero_padding.

Referenced by ipv4_rx(), and ipv4_tx().

◆ ipv4_tx()

static int ipv4_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 
)
static

Transmit IP packet.

Parameters
iobufI/O buffer
tcpipTransport-layer protocol
st_srcSource network-layer address
st_destDestination network-layer address
netdevNetwork device to use if no route found, or NULL
trans_csumTransport-layer checksum to complete, or NULL
Return values
rcStatus

This function expects a transport-layer segment and prepends the IP header

Definition at line 302 of file ipv4.c.

307  {
308  struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
309  struct sockaddr_in *sin_src = ( ( struct sockaddr_in * ) st_src );
310  struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
311  struct ipv4_miniroute *miniroute;
312  struct in_addr next_hop;
313  struct in_addr netmask = { .s_addr = 0 };
314  uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
315  const void *ll_dest;
316  int rc;
317 
318  /* Start profiling */
319  profile_start ( &ipv4_tx_profiler );
320 
321  /* Update statistics */
323 
324  /* Fill up the IP header, except source address */
325  memset ( iphdr, 0, sizeof ( *iphdr ) );
326  iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
327  iphdr->service = IP_TOS;
328  iphdr->len = htons ( iob_len ( iobuf ) );
329  iphdr->ttl = IP_TTL;
331  iphdr->dest = sin_dest->sin_addr;
332 
333  /* Use routing table to identify next hop and transmitting netdev */
334  next_hop = iphdr->dest;
335  if ( sin_src )
336  iphdr->src = sin_src->sin_addr;
337  if ( ( next_hop.s_addr != INADDR_BROADCAST ) &&
338  ( ( miniroute = ipv4_route ( sin_dest->sin_scope_id,
339  &next_hop ) ) != NULL ) ) {
340  iphdr->src = miniroute->address;
341  netmask = miniroute->netmask;
342  netdev = miniroute->netdev;
343  }
344  if ( ! netdev ) {
345  DBGC ( sin_dest->sin_addr, "IPv4 has no route to %s\n",
346  inet_ntoa ( iphdr->dest ) );
348  rc = -ENETUNREACH;
349  goto err;
350  }
351 
352  /* (Ab)use the "ident" field to convey metadata about the
353  * network device statistics into packet traces. Useful for
354  * extracting debug information from non-debug builds.
355  */
356  iphdr->ident = htons ( ( (++next_ident_high) << 8 ) |
357  ( ( netdev->rx_stats.bad & 0xf ) << 4 ) |
358  ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
359 
360  /* Fix up checksums */
361  if ( trans_csum ) {
362  *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
363  if ( ! *trans_csum )
364  *trans_csum = tcpip_protocol->zero_csum;
365  }
366  iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
367 
368  /* Print IP4 header for debugging */
369  DBGC2 ( sin_dest->sin_addr, "IPv4 TX %s->", inet_ntoa ( iphdr->src ) );
370  DBGC2 ( sin_dest->sin_addr, "%s len %d proto %d id %04x csum %04x\n",
371  inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ),
372  iphdr->protocol, ntohs ( iphdr->ident ),
373  ntohs ( iphdr->chksum ) );
374 
375  /* Calculate link-layer destination address, if possible */
376  if ( ( ( next_hop.s_addr ^ INADDR_BROADCAST ) & ~netmask.s_addr ) == 0){
377  /* Broadcast address */
379  ll_dest = netdev->ll_broadcast;
380  } else if ( IN_IS_MULTICAST ( next_hop.s_addr ) ) {
381  /* Multicast address */
383  if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET, &next_hop,
384  ll_dest_buf ) ) !=0){
385  DBGC ( sin_dest->sin_addr, "IPv4 could not hash "
386  "multicast %s: %s\n",
387  inet_ntoa ( next_hop ), strerror ( rc ) );
388  goto err;
389  }
390  ll_dest = ll_dest_buf;
391  } else {
392  /* Unicast address */
393  ll_dest = NULL;
394  }
395 
396  /* Update statistics */
398  ipv4_stats.out_octets += iob_len ( iobuf );
399 
400  /* Hand off to link layer (via ARP if applicable) */
401  if ( ll_dest ) {
402  if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest,
403  netdev->ll_addr ) ) != 0 ) {
404  DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
405  "packet via %s: %s\n",
406  netdev->name, strerror ( rc ) );
407  return rc;
408  }
409  } else {
410  if ( ( rc = arp_tx ( iobuf, netdev, &ipv4_protocol, &next_hop,
411  &iphdr->src, netdev->ll_addr ) ) != 0 ) {
412  DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
413  "packet via %s: %s\n",
414  netdev->name, strerror ( rc ) );
415  return rc;
416  }
417  }
418 
419  profile_stop ( &ipv4_tx_profiler );
420  return 0;
421 
422  err:
423  free_iob ( iobuf );
424  return rc;
425 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:68
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define IP_VER
Definition: ip.h:22
struct in_addr src
Definition: ip.h:44
#define iob_push(iobuf, len)
Definition: iobuf.h:84
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
uint8_t tcpip_proto
Transport-layer protocol number.
Definition: tcpip.h:134
struct net_device * netdev
Network device.
Definition: ip.h:63
#define DBGC(...)
Definition: compiler.h:505
const uint8_t * ll_broadcast
Link-layer broadcast address.
Definition: netdevice.h:389
uint16_t chksum
Definition: ip.h:43
IPv4 socket address.
Definition: in.h:82
#define ntohs(value)
Definition: byteswap.h:136
static struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition: ipv4.c:150
uint16_t ident
Definition: ip.h:39
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
An IPv4 packet header.
Definition: ip.h:35
struct in_addr address
IPv4 address.
Definition: ip.h:66
static int arp_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *net_source, const void *ll_source)
Transmit packet, determining link-layer address via ARP.
Definition: arp.h:51
#define IP_TTL
Definition: ip.h:32
uint16_t sin_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:96
#define MAX_LL_ADDR_LEN
Maximum length of a link-layer address.
Definition: netdevice.h:36
unsigned long out_no_routes
ipSystemStatsOutNoRoutes
Definition: ipstat.h:130
An IPv4 address/routing table entry.
Definition: ip.h:58
uint16_t len
Definition: ip.h:38
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t verhdrlen
Definition: ip.h:36
#define INADDR_BROADCAST
Definition: in.h:21
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
static uint16_t ipv4_pshdr_chksum(struct io_buffer *iobuf, uint16_t csum)
Add IPv4 pseudo-header checksum to existing checksum.
Definition: ipv4.c:273
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP address structure.
Definition: in.h:39
struct net_device_stats rx_stats
RX statistics.
Definition: netdevice.h:425
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
static struct ip_statistics ipv4_stats
IPv4 statistics.
Definition: ipv4.c:60
unsigned int bad
Count of error completions.
Definition: netdevice.h:295
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
unsigned char uint8_t
Definition: stdint.h:10
unsigned long out_mcast_pkts
ipSystemStatsOutMcastPkts
Definition: ipstat.h:155
struct in_addr dest
Definition: ip.h:45
int(* mc_hash)(unsigned int af, const void *net_addr, void *ll_addr)
Hash multicast address.
Definition: netdevice.h:172
uint32_t s_addr
Definition: in.h:40
A transport-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:104
unsigned long out_bcast_pkts
ipSystemStatsOutBcastPkts
Definition: ipstat.h:165
uint16_t zero_csum
Preferred zero checksum value.
Definition: tcpip.h:128
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
uint8_t protocol
Definition: ip.h:42
unsigned int good
Count of successful completions.
Definition: netdevice.h:293
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define IP_TOS
Definition: ip.h:31
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition: netdevice.c:1073
#define DBGC2(...)
Definition: compiler.h:522
unsigned long out_requests
ipSystemStatsOutRequests
Definition: ipstat.h:123
#define IN_IS_MULTICAST(addr)
Definition: in.h:33
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint8_t ttl
Definition: ip.h:41
static uint8_t next_ident_high
Definition: ipv4.c:54
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition: tcpip.c:203
uint8_t service
Definition: ip.h:37
#define ENETUNREACH
Network unreachable.
Definition: errno.h:488
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
unsigned long out_octets
ipSystemStatsOutOctets
Definition: ipstat.h:145
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
unsigned long out_transmits
ipSystemStatsOutTransmits
Definition: ipstat.h:138
void * memset(void *dest, int character, size_t len) __nonnull

References ipv4_miniroute::address, AF_INET, arp_tx(), net_device_stats::bad, iphdr::chksum, DBGC, DBGC2, iphdr::dest, ENETUNREACH, free_iob(), net_device_stats::good, htons, iphdr::ident, IN_IS_MULTICAST, INADDR_BROADCAST, inet_ntoa(), iob_len(), iob_push, IP_TOS, IP_TTL, IP_VER, ipv4_pshdr_chksum(), ipv4_route(), ipv4_stats, iphdr::len, net_device::ll_addr, net_device::ll_broadcast, net_device::ll_protocol, MAX_LL_ADDR_LEN, ll_protocol::mc_hash, memset(), net_device::name, net_tx(), netdev, ipv4_miniroute::netdev, ipv4_miniroute::netmask, next_ident_high, ntohs, NULL, ip_statistics::out_bcast_pkts, ip_statistics::out_mcast_pkts, ip_statistics::out_no_routes, ip_statistics::out_octets, ip_statistics::out_requests, ip_statistics::out_transmits, profile_start(), profile_stop(), iphdr::protocol, rc, net_device::rx_stats, in_addr::s_addr, iphdr::service, sockaddr_in::sin_addr, sockaddr_in::sin_scope_id, iphdr::src, strerror(), tcpip_chksum(), tcpip_protocol::tcpip_proto, iphdr::ttl, iphdr::verhdrlen, and tcpip_protocol::zero_csum.

◆ ipv4_has_any_addr()

int ipv4_has_any_addr ( struct net_device netdev)

Check if network device has any IPv4 address.

Parameters
netdevNetwork device
Return values
has_any_addrNetwork device has any IPv4 address

Definition at line 433 of file ipv4.c.

433  {
434  struct ipv4_miniroute *miniroute;
435 
436  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
437  if ( miniroute->netdev == netdev )
438  return 1;
439  }
440  return 0;
441 }
struct list_head list
List of miniroutes.
Definition: ip.h:60
struct net_device * netdev
Network device.
Definition: ip.h:63
An IPv4 address/routing table entry.
Definition: ip.h:58
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition: ipv4.c:57

References ipv4_miniroutes, ipv4_miniroute::list, list_for_each_entry, netdev, and ipv4_miniroute::netdev.

Referenced by dhcp_create_packet(), and ipv4_rx().

◆ ipv4_has_addr()

static int ipv4_has_addr ( struct net_device netdev,
struct in_addr  addr 
)
static

Check if network device has a specific IPv4 address.

Parameters
netdevNetwork device
addrIPv4 address
Return values
has_addrNetwork device has this IPv4 address

Definition at line 450 of file ipv4.c.

450  {
451  struct ipv4_miniroute *miniroute;
452 
453  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
454  if ( ( miniroute->netdev == netdev ) &&
455  ( miniroute->address.s_addr == addr.s_addr ) ) {
456  /* Found matching address */
457  return 1;
458  }
459  }
460  return 0;
461 }
struct list_head list
List of miniroutes.
Definition: ip.h:60
struct net_device * netdev
Network device.
Definition: ip.h:63
struct in_addr address
IPv4 address.
Definition: ip.h:66
An IPv4 address/routing table entry.
Definition: ip.h:58
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
u32 addr
Definition: sky2.h:8
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition: ipv4.c:57
uint32_t s_addr
Definition: in.h:40

References addr, ipv4_miniroute::address, ipv4_miniroutes, ipv4_miniroute::list, list_for_each_entry, netdev, ipv4_miniroute::netdev, and in_addr::s_addr.

Referenced by ipv4_arp_check(), ipv4_gratuitous_arp(), and ipv4_rx().

◆ ipv4_rx()

static int ipv4_rx ( struct io_buffer iobuf,
struct net_device netdev,
const void *ll_dest  __unused,
const void *ll_source  __unused,
unsigned int  flags 
)
static

Process incoming packets.

Parameters
iobufI/O buffer
netdevNetwork device
ll_destLink-layer destination address
ll_sourceLink-layer destination source
flagsPacket flags
Return values
rcReturn status code

This function expects an IP4 network datagram. It processes the headers and sends it to the transport layer.

Definition at line 476 of file ipv4.c.

480  {
481  struct iphdr *iphdr = iobuf->data;
482  size_t hdrlen;
483  size_t len;
484  union {
485  struct sockaddr_in sin;
486  struct sockaddr_tcpip st;
487  } src, dest;
488  uint16_t csum;
489  uint16_t pshdr_csum;
490  int rc;
491 
492  /* Start profiling */
493  profile_start ( &ipv4_rx_profiler );
494 
495  /* Update statistics */
497  ipv4_stats.in_octets += iob_len ( iobuf );
498  if ( flags & LL_BROADCAST ) {
500  } else if ( flags & LL_MULTICAST ) {
502  }
503 
504  /* Sanity check the IPv4 header */
505  if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) {
506  DBGC ( iphdr->src, "IPv4 packet too short at %zd bytes (min "
507  "%zd bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) );
508  goto err_header;
509  }
510  if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) {
511  DBGC ( iphdr->src, "IPv4 version %#02x not supported\n",
512  iphdr->verhdrlen );
513  goto err_header;
514  }
515  hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
516  if ( hdrlen < sizeof ( *iphdr ) ) {
517  DBGC ( iphdr->src, "IPv4 header too short at %zd bytes (min "
518  "%zd bytes)\n", hdrlen, sizeof ( *iphdr ) );
519  goto err_header;
520  }
521  if ( hdrlen > iob_len ( iobuf ) ) {
522  DBGC ( iphdr->src, "IPv4 header too long at %zd bytes "
523  "(packet is %zd bytes)\n", hdrlen, iob_len ( iobuf ) );
524  goto err_header;
525  }
526  if ( ( csum = tcpip_chksum ( iphdr, hdrlen ) ) != 0 ) {
527  DBGC ( iphdr->src, "IPv4 checksum incorrect (is %04x "
528  "including checksum field, should be 0000)\n", csum );
529  goto err_header;
530  }
531  len = ntohs ( iphdr->len );
532  if ( len < hdrlen ) {
533  DBGC ( iphdr->src, "IPv4 length too short at %zd bytes "
534  "(header is %zd bytes)\n", len, hdrlen );
535  goto err_header;
536  }
537  if ( len > iob_len ( iobuf ) ) {
538  DBGC ( iphdr->src, "IPv4 length too long at %zd bytes "
539  "(packet is %zd bytes)\n", len, iob_len ( iobuf ) );
541  goto err_other;
542  }
543 
544  /* Truncate packet to correct length */
545  iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
546 
547  /* Print IPv4 header for debugging */
548  DBGC2 ( iphdr->src, "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) );
549  DBGC2 ( iphdr->src, "%s len %d proto %d id %04x csum %04x\n",
551  ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
552 
553  /* Discard unicast packets not destined for us */
554  if ( ( ! ( flags & LL_MULTICAST ) ) &&
555  ( iphdr->dest.s_addr != INADDR_BROADCAST ) &&
557  ( ! ipv4_has_addr ( netdev, iphdr->dest ) ) ) {
558  DBGC ( iphdr->src, "IPv4 discarding non-local unicast packet "
559  "for %s\n", inet_ntoa ( iphdr->dest ) );
561  goto err_other;
562  }
563 
564  /* Perform fragment reassembly if applicable */
566  /* Pass the fragment to fragment_reassemble() which returns
567  * either a fully reassembled I/O buffer or NULL.
568  */
569  iobuf = fragment_reassemble ( &ipv4_reassembler, iobuf,
570  &hdrlen );
571  if ( ! iobuf )
572  return 0;
573  iphdr = iobuf->data;
574  }
575 
576  /* Construct socket addresses, calculate pseudo-header
577  * checksum, and hand off to transport layer
578  */
579  memset ( &src, 0, sizeof ( src ) );
580  src.sin.sin_family = AF_INET;
581  src.sin.sin_addr = iphdr->src;
582  memset ( &dest, 0, sizeof ( dest ) );
583  dest.sin.sin_family = AF_INET;
584  dest.sin.sin_addr = iphdr->dest;
585  pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
586  iob_pull ( iobuf, hdrlen );
587  if ( ( rc = tcpip_rx ( iobuf, netdev, iphdr->protocol, &src.st,
588  &dest.st, pshdr_csum, &ipv4_stats ) ) != 0 ) {
589  DBGC ( src.sin.sin_addr, "IPv4 received packet rejected by "
590  "stack: %s\n", strerror ( rc ) );
591  return rc;
592  }
593 
594  profile_stop ( &ipv4_rx_profiler );
595  return 0;
596 
597  err_header:
599  err_other:
600  free_iob ( iobuf );
601  return -EINVAL;
602 }
#define LL_MULTICAST
Packet is a multicast (including broadcast) packet.
Definition: netdevice.h:105
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#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 ipv4_has_addr(struct net_device *netdev, struct in_addr addr)
Check if network device has a specific IPv4 address.
Definition: ipv4.c:450
unsigned long in_receives
ipSystemStatsInReceives
Definition: ipstat.h:50
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition: tcpip.h:57
#define IP_VER
Definition: ip.h:22
struct in_addr src
Definition: ip.h:44
unsigned long in_addr_errors
ipSystemStatsInAddrErrors
Definition: ipstat.h:76
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.
Definition: tcpip.c:40
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static void const void * src
Definition: crypto.h:244
#define DBGC(...)
Definition: compiler.h:505
uint16_t chksum
Definition: ip.h:43
IPv4 socket address.
Definition: in.h:82
#define ntohs(value)
Definition: byteswap.h:136
uint16_t ident
Definition: ip.h:39
uint16_t frags
Definition: ip.h:40
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
An IPv4 packet header.
Definition: ip.h:35
struct sockaddr_tcpip st
Definition: syslog.c:56
unsigned long in_mcast_pkts
ipSystemStatsInMcastPkts
Definition: ipstat.h:150
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition: ipv4.c:433
struct io_buffer * fragment_reassemble(struct fragment_reassembler *fragments, struct io_buffer *iobuf, size_t *hdrlen)
Reassemble packet.
Definition: fragment.c:88
uint16_t len
Definition: ip.h:38
unsigned long in_truncated_pkts
ipSystemStatsInTruncatedPkts
Definition: ipstat.h:89
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t verhdrlen
Definition: ip.h:36
static struct fragment_reassembler ipv4_reassembler
IPv4 fragment reassembler.
Definition: ipv4.c:258
#define INADDR_BROADCAST
Definition: in.h:21
#define IP_MASK_MOREFRAGS
Definition: ip.h:27
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
static uint16_t ipv4_pshdr_chksum(struct io_buffer *iobuf, uint16_t csum)
Add IPv4 pseudo-header checksum to existing checksum.
Definition: ipv4.c:273
static void * dest
Definition: strings.h:176
#define iob_unput(iobuf, len)
Definition: iobuf.h:135
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
static struct ip_statistics ipv4_stats
IPv4 statistics.
Definition: ipv4.c:60
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define IP_MASK_VER
Definition: ip.h:23
struct in_addr dest
Definition: ip.h:45
#define IP_MASK_OFFSET
Definition: ip.h:25
#define LL_BROADCAST
Packet is a broadcast packet.
Definition: netdevice.h:108
uint32_t s_addr
Definition: in.h:40
#define IP_MASK_HLEN
Definition: ip.h:24
uint8_t protocol
Definition: ip.h:42
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
struct sockaddr_in sin
Definition: syslog.c:57
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition: tcpip.c:203
unsigned long in_hdr_errors
ipSystemStatsInHdrErrors
Definition: ipstat.h:65
unsigned long in_bcast_pkts
ipSystemStatsInBcastPkts
Definition: ipstat.h:160
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
unsigned long in_octets
ipSystemStatsInOctets
Definition: ipstat.h:57
void * memset(void *dest, int character, size_t len) __nonnull
uint8_t flags
Flags.
Definition: ena.h:18

References AF_INET, iphdr::chksum, io_buffer::data, DBGC, DBGC2, iphdr::dest, dest, EINVAL, flags, fragment_reassemble(), iphdr::frags, free_iob(), htons, iphdr::ident, ip_statistics::in_addr_errors, ip_statistics::in_bcast_pkts, ip_statistics::in_hdr_errors, ip_statistics::in_mcast_pkts, ip_statistics::in_octets, ip_statistics::in_receives, ip_statistics::in_truncated_pkts, INADDR_BROADCAST, inet_ntoa(), iob_len(), iob_pull, iob_unput, IP_MASK_HLEN, IP_MASK_MOREFRAGS, IP_MASK_OFFSET, IP_MASK_VER, IP_VER, ipv4_has_addr(), ipv4_has_any_addr(), ipv4_pshdr_chksum(), ipv4_reassembler, ipv4_stats, len, iphdr::len, LL_BROADCAST, LL_MULTICAST, memset(), netdev, ntohs, profile_start(), profile_stop(), iphdr::protocol, rc, in_addr::s_addr, sin, iphdr::src, src, st, strerror(), tcpip_chksum(), TCPIP_EMPTY_CSUM, tcpip_rx(), and iphdr::verhdrlen.

◆ ipv4_arp_check()

static int ipv4_arp_check ( struct net_device netdev,
const void *  net_addr 
)
static

Check existence of IPv4 address for ARP.

Parameters
netdevNetwork device
net_addrNetwork-layer address
Return values
rcReturn status code

Definition at line 611 of file ipv4.c.

611  {
612  const struct in_addr *address = net_addr;
613 
614  if ( ipv4_has_addr ( netdev, *address ) )
615  return 0;
616 
617  return -ENOENT;
618 }
static int ipv4_has_addr(struct net_device *netdev, struct in_addr addr)
Check if network device has a specific IPv4 address.
Definition: ipv4.c:450
uint64_t address
Base address.
Definition: ena.h:24
#define ENOENT
No such file or directory.
Definition: errno.h:514
static struct net_device * netdev
Definition: gdbudp.c:52
IP address structure.
Definition: in.h:39

References address, ENOENT, ipv4_has_addr(), and netdev.

◆ inet_aton()

int inet_aton ( const char *  string,
struct in_addr in 
)

Parse IPv4 address.

Parameters
stringIPv4 address string
Return values
inIPv4 address to fill in
okIPv4 address is valid

Note that this function returns nonzero iff the address is valid, to match the standard BSD API function of the same name. Unlike most other iPXE functions, a zero therefore indicates failure.

Definition at line 631 of file ipv4.c.

631  {
632  const char *separator = "...";
633  uint8_t *byte = ( ( uint8_t * ) in );
634  char *endp;
635  unsigned long value;
636 
637  while ( 1 ) {
638  value = strtoul ( string, &endp, 0 );
639  if ( string == endp )
640  return 0;
641  if ( value > 0xff )
642  return 0;
643  *(byte++) = value;
644  if ( *endp != *separator )
645  return 0;
646  if ( ! *(separator++) )
647  return 1;
648  string = ( endp + 1 );
649  }
650 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:471
__be32 in[4]
Definition: CIB_PRM.h:35
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
unsigned char uint8_t
Definition: stdint.h:10

References in, strtoul(), and value.

Referenced by inet_aton_fail_okx(), inet_aton_okx(), ipv4_sock_aton(), parse_ipv4_setting(), and tftp_process_multicast().

◆ inet_ntoa()

char* inet_ntoa ( struct in_addr  in)

Convert IPv4 address to dotted-quad notation.

Parameters
inIPv4 address
Return values
stringIPv4 address in dotted-quad notation

Definition at line 658 of file ipv4.c.

658  {
659  static char buf[16]; /* "xxx.xxx.xxx.xxx" */
660  uint8_t *bytes = ( uint8_t * ) &in;
661 
662  sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
663  return buf;
664 }
__be32 in[4]
Definition: CIB_PRM.h:35
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:36
unsigned char uint8_t
Definition: stdint.h:10
uint8_t bytes[64]
Definition: ib_mad.h:16

References bytes, in, and sprintf.

Referenced by add_ipv4_miniroute(), del_ipv4_miniroute(), dhcp_deliver(), dhcp_discovery_rx(), dhcp_proxy_rx(), dhcp_proxy_tx(), dhcp_pxebs_accept(), dhcp_pxebs_rx(), dhcp_pxebs_tx(), dhcp_request_rx(), dhcp_request_tx(), efi_snp_mcast_ip_to_mac(), fetch_next_server_and_filename(), format_ipv4_setting(), ibft_ipaddr(), inet_aton_okx(), inet_ntoa_okx(), ipoib_transmit(), ipv4_gratuitous_arp(), ipv4_ntoa(), ipv4_rx(), ipv4_sock_ntoa(), ipv4_tx(), pxenv_udp_open(), pxenv_udp_read(), pxenv_udp_write(), pxenv_undi_get_mcast_address(), route_ipv4_print(), start_pxebs(), tftp_apply_settings(), and tftp_process_multicast().

◆ ipv4_ntoa()

static const char* ipv4_ntoa ( const void *  net_addr)
static

Transcribe IPv4 address.

Parameters
net_addrIPv4 address
Return values
stringIPv4 address in dotted-quad notation

Definition at line 673 of file ipv4.c.

673  {
674  return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
675 }
IP address structure.
Definition: in.h:39
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658

References inet_ntoa().

◆ ipv4_sock_ntoa()

static const char* ipv4_sock_ntoa ( struct sockaddr sa)
static

Transcribe IPv4 socket address.

Parameters
saSocket address
Return values
stringSocket address in standard notation

Definition at line 683 of file ipv4.c.

683  {
684  struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
685 
686  return inet_ntoa ( sin->sin_addr );
687 }
IPv4 socket address.
Definition: in.h:82
struct sockaddr sa
Definition: syslog.c:55
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
struct sockaddr_in sin
Definition: syslog.c:57

References inet_ntoa(), sa, sin, and sockaddr_in::sin_addr.

◆ ipv4_sock_aton()

static int ipv4_sock_aton ( const char *  string,
struct sockaddr sa 
)
static

Parse IPv4 socket address.

Parameters
stringSocket address string
saSocket address to fill in
Return values
rcReturn status code

Definition at line 696 of file ipv4.c.

696  {
697  struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
698  struct in_addr in;
699 
700  if ( inet_aton ( string, &in ) ) {
701  sin->sin_addr = in;
702  return 0;
703  }
704  return -EINVAL;
705 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
__be32 in[4]
Definition: CIB_PRM.h:35
IPv4 socket address.
Definition: in.h:82
struct sockaddr sa
Definition: syslog.c:55
IP address structure.
Definition: in.h:39
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition: ipv4.c:631
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
struct sockaddr_in sin
Definition: syslog.c:57

References EINVAL, in, inet_aton(), sa, sin, and sockaddr_in::sin_addr.

◆ parse_ipv4_setting()

int parse_ipv4_setting ( const struct setting_type *type  __unused,
const char *  value,
void *  buf,
size_t  len 
)

Parse IPv4 address setting value.

Parameters
typeSetting type
valueFormatted setting value
bufBuffer to contain raw value
lenLength of buffer
Return values
lenLength of raw value, or negative error

Definition at line 755 of file ipv4.c.

756  {
757  struct in_addr ipv4;
758 
759  /* Parse IPv4 address */
760  if ( inet_aton ( value, &ipv4 ) == 0 )
761  return -EINVAL;
762 
763  /* Copy to buffer */
764  if ( len > sizeof ( ipv4 ) )
765  len = sizeof ( ipv4 );
766  memcpy ( buf, &ipv4, len );
767 
768  return ( sizeof ( ipv4 ) );
769 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
void * memcpy(void *dest, const void *src, size_t len) __nonnull
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
IP address structure.
Definition: in.h:39
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition: ipv4.c:631
uint32_t len
Length.
Definition: ena.h:14

References EINVAL, inet_aton(), len, memcpy(), and value.

◆ format_ipv4_setting()

int format_ipv4_setting ( const struct setting_type *type  __unused,
const void *  raw,
size_t  raw_len,
char *  buf,
size_t  len 
)

Format IPv4 address setting value.

Parameters
typeSetting type
rawRaw setting value
raw_lenLength of raw setting value
bufBuffer to contain formatted value
lenLength of buffer
Return values
lenLength of formatted value, or negative error

Definition at line 781 of file ipv4.c.

783  {
784  const struct in_addr *ipv4 = raw;
785 
786  if ( raw_len < sizeof ( *ipv4 ) )
787  return -EINVAL;
788  return snprintf ( buf, len, "%s", inet_ntoa ( *ipv4 ) );
789 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static size_t raw_len
Definition: base16.h:53
IP address structure.
Definition: in.h:39
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
uint32_t len
Length.
Definition: ena.h:14
__be32 raw[7]
Definition: CIB_PRM.h:28
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

References EINVAL, inet_ntoa(), len, raw, raw_len, and snprintf().

◆ __setting() [1/3]

const struct setting ip_setting __setting ( SETTING_IP4  ,
ip   
)

IPv4 address setting.

◆ __setting() [2/3]

const struct setting netmask_setting __setting ( SETTING_IP4  ,
netmask   
)

IPv4 subnet mask setting.

◆ __setting() [3/3]

const struct setting gateway_setting __setting ( SETTING_IP4  ,
gateway   
)

Default gateway setting.

◆ ipv4_gratuitous_arp()

static int ipv4_gratuitous_arp ( struct net_device netdev,
struct in_addr  address,
struct in_addr netmask  __unused,
struct in_addr gateway  __unused 
)
static

Send gratuitous ARP, if applicable.

Parameters
netdevNetwork device
addressIPv4 address
netmaskSubnet mask
gatewayGateway address (if any)
Return values
rcReturn status code

Definition at line 824 of file ipv4.c.

827  {
828  int rc;
829 
830  /* Do nothing if network device already has this IPv4 address */
831  if ( ipv4_has_addr ( netdev, address ) )
832  return 0;
833 
834  /* Transmit gratuitous ARP */
835  DBGC ( netdev, "IPv4 sending gratuitous ARP for %s via %s\n",
836  inet_ntoa ( address ), netdev->name );
837  if ( ( rc = arp_tx_request ( netdev, &ipv4_protocol, &address,
838  &address ) ) != 0 ) {
839  DBGC ( netdev, "IPv4 could not transmit gratuitous ARP: %s\n",
840  strerror ( rc ) );
841  /* Treat failures as non-fatal */
842  }
843 
844  return 0;
845 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int ipv4_has_addr(struct net_device *netdev, struct in_addr addr)
Check if network device has a specific IPv4 address.
Definition: ipv4.c:450
uint64_t address
Base address.
Definition: ena.h:24
#define DBGC(...)
Definition: compiler.h:505
static struct net_device * netdev
Definition: gdbudp.c:52
int arp_tx_request(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *net_source)
Transmit ARP request.
Definition: arp.c:59
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362

References address, arp_tx_request(), DBGC, inet_ntoa(), ipv4_has_addr(), net_device::name, netdev, rc, and strerror().

Referenced by ipv4_create_routes().

◆ ipv4_settings()

static int ipv4_settings ( int(*)(struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway)  apply)
static

Process IPv4 network device settings.

Parameters
applyApplication method
Return values
rcReturn status code

Definition at line 853 of file ipv4.c.

856  {
857  struct net_device *netdev;
858  struct settings *settings;
859  struct in_addr address = { 0 };
860  struct in_addr netmask = { 0 };
861  struct in_addr gateway = { 0 };
862  int rc;
863 
864  /* Process settings for each network device */
865  for_each_netdev ( netdev ) {
866 
867  /* Get network device settings */
869 
870  /* Get IPv4 address */
871  address.s_addr = 0;
872  fetch_ipv4_setting ( settings, &ip_setting, &address );
873  if ( ! address.s_addr )
874  continue;
875 
876  /* Get subnet mask */
877  fetch_ipv4_setting ( settings, &netmask_setting, &netmask );
878 
879  /* Calculate default netmask, if necessary */
880  if ( ! netmask.s_addr ) {
881  if ( IN_IS_CLASSA ( address.s_addr ) ) {
882  netmask.s_addr = INADDR_NET_CLASSA;
883  } else if ( IN_IS_CLASSB ( address.s_addr ) ) {
884  netmask.s_addr = INADDR_NET_CLASSB;
885  } else if ( IN_IS_CLASSC ( address.s_addr ) ) {
886  netmask.s_addr = INADDR_NET_CLASSC;
887  }
888  }
889 
890  /* Get default gateway, if present */
891  fetch_ipv4_setting ( settings, &gateway_setting, &gateway );
892 
893  /* Apply settings */
894  if ( ( rc = apply ( netdev, address, netmask, gateway ) ) != 0 )
895  return rc;
896  }
897 
898  return 0;
899 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define IN_IS_CLASSA(addr)
Definition: in.h:27
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
uint64_t address
Base address.
Definition: ena.h:24
#define IN_IS_CLASSB(addr)
Definition: in.h:29
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
#define INADDR_NET_CLASSC
Definition: in.h:25
static struct net_device * netdev
Definition: gdbudp.c:52
IP address structure.
Definition: in.h:39
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:543
A network device.
Definition: netdevice.h:352
A settings block.
Definition: settings.h:132
uint32_t s_addr
Definition: in.h:40
#define INADDR_NET_CLASSA
Definition: in.h:23
#define INADDR_NET_CLASSB
Definition: in.h:24
#define IN_IS_CLASSC(addr)
Definition: in.h:31

References address, fetch_ipv4_setting(), for_each_netdev, IN_IS_CLASSA, IN_IS_CLASSB, IN_IS_CLASSC, INADDR_NET_CLASSA, INADDR_NET_CLASSB, INADDR_NET_CLASSC, netdev, netdev_settings(), rc, and in_addr::s_addr.

Referenced by ipv4_create_routes().

◆ ipv4_create_routes()

static int ipv4_create_routes ( void  )
static

Create IPv4 routing table based on configured settings.

Return values
rcReturn status code

Definition at line 906 of file ipv4.c.

906  {
907  struct ipv4_miniroute *miniroute;
908  struct ipv4_miniroute *tmp;
909  int rc;
910 
911  /* Send gratuitous ARPs for any new IPv4 addresses */
913 
914  /* Delete all existing routes */
916  del_ipv4_miniroute ( miniroute );
917 
918  /* Create a route for each configured network device */
919  if ( ( rc = ipv4_settings ( add_ipv4_miniroute ) ) != 0 )
920  return rc;
921 
922  return 0;
923 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of miniroutes.
Definition: ip.h:60
static void del_ipv4_miniroute(struct ipv4_miniroute *miniroute)
Delete IPv4 minirouting table entry.
Definition: ipv4.c:125
static int ipv4_gratuitous_arp(struct net_device *netdev, struct in_addr address, struct in_addr netmask __unused, struct in_addr gateway __unused)
Send gratuitous ARP, if applicable.
Definition: ipv4.c:824
unsigned long tmp
Definition: linux_pci.h:53
An IPv4 address/routing table entry.
Definition: ip.h:58
static int ipv4_settings(int(*apply)(struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway))
Process IPv4 network device settings.
Definition: ipv4.c:853
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition: ipv4.c:57
static int add_ipv4_miniroute(struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway)
Add IPv4 minirouting table entry.
Definition: ipv4.c:84

References add_ipv4_miniroute(), del_ipv4_miniroute(), ipv4_gratuitous_arp(), ipv4_miniroutes, ipv4_settings(), ipv4_miniroute::list, list_for_each_entry_safe, rc, and tmp.

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( ipv4_protocol  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( icmpv4  )

Variable Documentation

◆ next_ident_high

uint8_t next_ident_high = 0
static

Definition at line 54 of file ipv4.c.

Referenced by ipv4_tx().

◆ ipv4_miniroutes

struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes )

List of IPv4 miniroutes.

Definition at line 57 of file ipv4.c.

Referenced by add_ipv4_miniroute(), ipv4_create_routes(), ipv4_has_addr(), ipv4_has_any_addr(), ipv4_route(), and route_ipv4_print().

◆ ipv4_stats

struct ip_statistics ipv4_stats
static

IPv4 statistics.

Definition at line 60 of file ipv4.c.

Referenced by ipv4_rx(), and ipv4_tx().

◆ __profiler

struct profiler ipv4_rx_profiler __profiler = { .name = "ipv4.tx" }
static

Transmit profiler.

Receive profiler.

Definition at line 70 of file ipv4.c.

◆ ipv4_reassembler

struct fragment_reassembler ipv4_reassembler
static
Initial value:
= {
.is_fragment = ipv4_is_fragment,
.fragment_offset = ipv4_fragment_offset,
.more_fragments = ipv4_more_fragments,
.stats = &ipv4_stats,
}
static int ipv4_more_fragments(struct io_buffer *iobuf, size_t hdrlen __unused)
Check if more fragments exist.
Definition: ipv4.c:250
static size_t ipv4_fragment_offset(struct io_buffer *iobuf, size_t hdrlen __unused)
Get IPv4 fragment offset.
Definition: ipv4.c:236
static struct fragment_reassembler ipv4_reassembler
IPv4 fragment reassembler.
Definition: ipv4.c:258
static struct ip_statistics ipv4_stats
IPv4 statistics.
Definition: ipv4.c:60
static int ipv4_is_fragment(struct fragment *fragment, struct io_buffer *iobuf, size_t hdrlen __unused)
Check if IPv4 fragment matches fragment reassembly buffer.
Definition: ipv4.c:219
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
struct list_head list
List of fragment reassembly buffers.
Definition: fragment.h:37

IPv4 fragment reassembler.

Definition at line 258 of file ipv4.c.

Referenced by ipv4_rx().

◆ __net_protocol

struct net_protocol ipv4_protocol __net_protocol
Initial value:
= {
.name = "IP",
.net_proto = htons ( ETH_P_IP ),
.net_addr_len = sizeof ( struct in_addr ),
.rx = ipv4_rx,
.ntoa = ipv4_ntoa,
}
#define ETH_P_IP
Definition: if_ether.h:18
static const char * ipv4_ntoa(const void *net_addr)
Transcribe IPv4 address.
Definition: ipv4.c:673
IP address structure.
Definition: in.h:39
static int ipv4_rx(struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags)
Process incoming packets.
Definition: ipv4.c:476
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
#define htons(value)
Definition: byteswap.h:135

IPv4 protocol.

AoE protocol.

Definition at line 708 of file ipv4.c.

◆ __tcpip_net_protocol

struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol
Initial value:
= {
.name = "IPv4",
.sa_family = AF_INET,
.header_len = sizeof ( struct iphdr ),
.net_protocol = &ipv4_protocol,
.tx = ipv4_tx,
.netdev = ipv4_netdev,
}
An IPv4 packet header.
Definition: ip.h:35
static struct net_device * ipv4_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition: ipv4.c:198
A network-layer protocol.
Definition: netdevice.h:64
static int ipv4_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 IP packet.
Definition: ipv4.c:302
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

IPv4 TCPIP net protocol.

Definition at line 717 of file ipv4.c.

◆ __arp_net_protocol

struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol
Initial value:
= {
.net_protocol = &ipv4_protocol,
.check = ipv4_arp_check,
}
static int ipv4_arp_check(struct net_device *netdev, const void *net_addr)
Check existence of IPv4 address for ARP.
Definition: ipv4.c:611

IPv4 ARP protocol.

Definition at line 727 of file ipv4.c.

◆ __sockaddr_converter

struct sockaddr_converter ipv4_sockaddr_converter __sockaddr_converter
Initial value:
= {
.family = AF_INET,
.ntoa = ipv4_sock_ntoa,
.aton = ipv4_sock_aton,
}
static const char * ipv4_sock_ntoa(struct sockaddr *sa)
Transcribe IPv4 socket address.
Definition: ipv4.c:683
static int ipv4_sock_aton(const char *string, struct sockaddr *sa)
Parse IPv4 socket address.
Definition: ipv4.c:696
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

IPv4 socket address converter.

Definition at line 733 of file ipv4.c.

◆ __settings_applicator

struct settings_applicator ipv4_settings_applicator __settings_applicator
Initial value:
= {
}
static int ipv4_create_routes(void)
Create IPv4 routing table based on configured settings.
Definition: ipv4.c:906

IPv4 settings applicator.

Definition at line 926 of file ipv4.c.