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  struct in_addr hostmask;
89  struct in_addr broadcast;
90 
91  /* Calculate host mask */
92  hostmask.s_addr = ( IN_IS_SMALL ( netmask.s_addr ) ?
93  INADDR_NONE : ~netmask.s_addr );
94  broadcast.s_addr = ( address.s_addr | hostmask.s_addr );
95 
96  /* Print debugging information */
97  DBGC ( netdev, "IPv4 add %s", inet_ntoa ( address ) );
98  DBGC ( netdev, "/%s ", inet_ntoa ( netmask ) );
99  DBGC ( netdev, "bc %s ", inet_ntoa ( broadcast ) );
100  if ( gateway.s_addr )
101  DBGC ( netdev, "gw %s ", inet_ntoa ( gateway ) );
102  DBGC ( netdev, "via %s\n", netdev->name );
103 
104  /* Allocate and populate miniroute structure */
105  miniroute = malloc ( sizeof ( *miniroute ) );
106  if ( ! miniroute ) {
107  DBGC ( netdev, "IPv4 could not add miniroute\n" );
108  return -ENOMEM;
109  }
110 
111  /* Record routing information */
112  miniroute->netdev = netdev_get ( netdev );
113  miniroute->address = address;
114  miniroute->netmask = netmask;
115  miniroute->hostmask = hostmask;
116  miniroute->gateway = gateway;
117 
118  /* Add to end of list if we have a gateway, otherwise
119  * to start of list.
120  */
121  if ( gateway.s_addr ) {
122  list_add_tail ( &miniroute->list, &ipv4_miniroutes );
123  } else {
124  list_add ( &miniroute->list, &ipv4_miniroutes );
125  }
126 
127  return 0;
128 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:72
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
struct in_addr hostmask
Host mask.
Definition: ip.h:86
#define IN_IS_SMALL(mask)
Definition: in.h:36
#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, or zero for no gateway.
Definition: ip.h:88
#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
IP address structure.
Definition: in.h:41
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:668
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:42
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define INADDR_NONE
Definition: in.h:19

References address, ipv4_miniroute::address, DBGC, ENOMEM, ipv4_miniroute::gateway, ipv4_miniroute::hostmask, IN_IS_SMALL, INADDR_NONE, 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 135 of file ipv4.c.

135  {
136  struct net_device *netdev = miniroute->netdev;
137 
138  DBGC ( netdev, "IPv4 del %s", inet_ntoa ( miniroute->address ) );
139  DBGC ( netdev, "/%s ", inet_ntoa ( miniroute->netmask ) );
140  if ( miniroute->gateway.s_addr )
141  DBGC ( netdev, "gw %s ", inet_ntoa ( miniroute->gateway ) );
142  DBGC ( netdev, "via %s\n", miniroute->netdev->name );
143 
144  netdev_put ( miniroute->netdev );
145  list_del ( &miniroute->list );
146  free ( miniroute );
147 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:72
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, or zero for no gateway.
Definition: ip.h:88
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:668
uint32_t s_addr
Definition: in.h:42
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 160 of file ipv4.c.

161  {
162  struct ipv4_miniroute *miniroute;
163 
164  /* Find first usable route in routing table */
165  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
166 
167  /* Skip closed network devices */
168  if ( ! netdev_is_open ( miniroute->netdev ) )
169  continue;
170 
171  if ( IN_IS_MULTICAST ( dest->s_addr ) ) {
172 
173  /* If destination is non-global, and the scope ID
174  * matches this network device, then use this route.
175  */
176  if ( miniroute->netdev->scope_id == scope_id )
177  return miniroute;
178 
179  } else {
180 
181  /* If destination is an on-link global
182  * address, then use this route.
183  */
184  if ( ( ( dest->s_addr ^ miniroute->address.s_addr )
185  & miniroute->netmask.s_addr ) == 0 )
186  return miniroute;
187 
188  /* If destination is an off-link global
189  * address, and we have a default gateway,
190  * then use this route.
191  */
192  if ( miniroute->gateway.s_addr ) {
193  *dest = miniroute->gateway;
194  return miniroute;
195  }
196  }
197  }
198 
199  return NULL;
200 }
struct in_addr netmask
Subnet mask.
Definition: ip.h:72
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, or zero for no gateway.
Definition: ip.h:88
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:42
#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 208 of file ipv4.c.

208  {
209  struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
210  struct in_addr dest = sin_dest->sin_addr;
211  struct ipv4_miniroute *miniroute;
212 
213  /* Find routing table entry */
214  miniroute = ipv4_route ( sin_dest->sin_scope_id, &dest );
215  if ( ! miniroute )
216  return NULL;
217 
218  return miniroute->netdev;
219 }
struct net_device * netdev
Network device.
Definition: ip.h:63
IPv4 socket address.
Definition: in.h:84
static struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition: ipv4.c:160
uint16_t sin_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:98
An IPv4 address/routing table entry.
Definition: ip.h:58
static void * dest
Definition: strings.h:176
IP address structure.
Definition: in.h:41
struct in_addr sin_addr
IPv4 address.
Definition: in.h:100
#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 229 of file ipv4.c.

231  {
232  struct iphdr *frag_iphdr = fragment->iobuf->data;
233  struct iphdr *iphdr = iobuf->data;
234 
235  return ( ( iphdr->src.s_addr == frag_iphdr->src.s_addr ) &&
236  ( iphdr->ident == frag_iphdr->ident ) );
237 }
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:42
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 246 of file ipv4.c.

247  {
248  struct iphdr *iphdr = iobuf->data;
249 
250  return ( ( ntohs ( iphdr->frags ) & IP_MASK_OFFSET ) << 3 );
251 }
#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 260 of file ipv4.c.

261  {
262  struct iphdr *iphdr = iobuf->data;
263 
264  return ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) );
265 }
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 283 of file ipv4.c.

283  {
284  struct ipv4_pseudo_header pshdr;
285  struct iphdr *iphdr = iobuf->data;
286  size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
287 
288  /* Build pseudo-header */
289  pshdr.src = iphdr->src;
290  pshdr.dest = iphdr->dest;
291  pshdr.zero_padding = 0x00;
292  pshdr.protocol = iphdr->protocol;
293  pshdr.len = htons ( iob_len ( iobuf ) - hdrlen );
294 
295  /* Update the checksum value */
296  return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
297 }
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 312 of file ipv4.c.

317  {
318  struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
319  struct sockaddr_in *sin_src = ( ( struct sockaddr_in * ) st_src );
320  struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
321  struct ipv4_miniroute *miniroute;
322  struct in_addr next_hop;
323  struct in_addr hostmask = { .s_addr = INADDR_NONE };
324  uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
325  const void *ll_dest;
326  int rc;
327 
328  /* Start profiling */
329  profile_start ( &ipv4_tx_profiler );
330 
331  /* Update statistics */
333 
334  /* Fill up the IP header, except source address */
335  memset ( iphdr, 0, sizeof ( *iphdr ) );
336  iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
337  iphdr->service = IP_TOS;
338  iphdr->len = htons ( iob_len ( iobuf ) );
339  iphdr->ttl = IP_TTL;
341  iphdr->dest = sin_dest->sin_addr;
342 
343  /* Use routing table to identify next hop and transmitting netdev */
344  next_hop = iphdr->dest;
345  if ( sin_src )
346  iphdr->src = sin_src->sin_addr;
347  if ( ( next_hop.s_addr != INADDR_BROADCAST ) &&
348  ( ( miniroute = ipv4_route ( sin_dest->sin_scope_id,
349  &next_hop ) ) != NULL ) ) {
350  iphdr->src = miniroute->address;
351  hostmask = miniroute->hostmask;
352  netdev = miniroute->netdev;
353  }
354  if ( ! netdev ) {
355  DBGC ( sin_dest->sin_addr, "IPv4 has no route to %s\n",
356  inet_ntoa ( iphdr->dest ) );
358  rc = -ENETUNREACH;
359  goto err;
360  }
361 
362  /* (Ab)use the "ident" field to convey metadata about the
363  * network device statistics into packet traces. Useful for
364  * extracting debug information from non-debug builds.
365  */
366  iphdr->ident = htons ( ( (++next_ident_high) << 8 ) |
367  ( ( netdev->rx_stats.bad & 0xf ) << 4 ) |
368  ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
369 
370  /* Fix up checksums */
371  if ( trans_csum ) {
372  *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
373  if ( ! *trans_csum )
374  *trans_csum = tcpip_protocol->zero_csum;
375  }
376  iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
377 
378  /* Print IP4 header for debugging */
379  DBGC2 ( sin_dest->sin_addr, "IPv4 TX %s->", inet_ntoa ( iphdr->src ) );
380  DBGC2 ( sin_dest->sin_addr, "%s len %d proto %d id %04x csum %04x\n",
381  inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ),
382  iphdr->protocol, ntohs ( iphdr->ident ),
383  ntohs ( iphdr->chksum ) );
384 
385  /* Calculate link-layer destination address, if possible */
386  if ( ( ( ~next_hop.s_addr ) & hostmask.s_addr ) == 0 ) {
387  /* Broadcast address */
389  ll_dest = netdev->ll_broadcast;
390  } else if ( IN_IS_MULTICAST ( next_hop.s_addr ) ) {
391  /* Multicast address */
393  if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET, &next_hop,
394  ll_dest_buf ) ) !=0){
395  DBGC ( sin_dest->sin_addr, "IPv4 could not hash "
396  "multicast %s: %s\n",
397  inet_ntoa ( next_hop ), strerror ( rc ) );
398  goto err;
399  }
400  ll_dest = ll_dest_buf;
401  } else {
402  /* Unicast address */
403  ll_dest = NULL;
404  }
405 
406  /* Update statistics */
408  ipv4_stats.out_octets += iob_len ( iobuf );
409 
410  /* Hand off to link layer (via ARP if applicable) */
411  if ( ll_dest ) {
412  if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest,
413  netdev->ll_addr ) ) != 0 ) {
414  DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
415  "packet via %s: %s\n",
416  netdev->name, strerror ( rc ) );
417  return rc;
418  }
419  } else {
420  if ( ( rc = arp_tx ( iobuf, netdev, &ipv4_protocol, &next_hop,
421  &iphdr->src, netdev->ll_addr ) ) != 0 ) {
422  DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
423  "packet via %s: %s\n",
424  netdev->name, strerror ( rc ) );
425  return rc;
426  }
427  }
428 
429  profile_stop ( &ipv4_tx_profiler );
430  return 0;
431 
432  err:
433  free_iob ( iobuf );
434  return rc;
435 }
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:84
#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:160
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
struct in_addr hostmask
Host mask.
Definition: ip.h:86
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:98
#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:283
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP address structure.
Definition: in.h:41
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:668
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:42
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:100
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 INADDR_NONE
Definition: in.h:19
#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, ipv4_miniroute::hostmask, htons, iphdr::ident, IN_IS_MULTICAST, INADDR_BROADCAST, INADDR_NONE, 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, 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 443 of file ipv4.c.

443  {
444  struct ipv4_miniroute *miniroute;
445 
446  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
447  if ( miniroute->netdev == netdev )
448  return 1;
449  }
450  return 0;
451 }
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 460 of file ipv4.c.

460  {
461  struct ipv4_miniroute *miniroute;
462 
463  list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
464  if ( ( miniroute->netdev == netdev ) &&
465  ( miniroute->address.s_addr == addr.s_addr ) ) {
466  /* Found matching address */
467  return 1;
468  }
469  }
470  return 0;
471 }
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:42

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 486 of file ipv4.c.

490  {
491  struct iphdr *iphdr = iobuf->data;
492  size_t hdrlen;
493  size_t len;
494  union {
495  struct sockaddr_in sin;
496  struct sockaddr_tcpip st;
497  } src, dest;
498  uint16_t csum;
499  uint16_t pshdr_csum;
500  int rc;
501 
502  /* Start profiling */
503  profile_start ( &ipv4_rx_profiler );
504 
505  /* Update statistics */
507  ipv4_stats.in_octets += iob_len ( iobuf );
508  if ( flags & LL_BROADCAST ) {
510  } else if ( flags & LL_MULTICAST ) {
512  }
513 
514  /* Sanity check the IPv4 header */
515  if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) {
516  DBGC ( iphdr->src, "IPv4 packet too short at %zd bytes (min "
517  "%zd bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) );
518  goto err_header;
519  }
520  if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) {
521  DBGC ( iphdr->src, "IPv4 version %#02x not supported\n",
522  iphdr->verhdrlen );
523  goto err_header;
524  }
525  hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
526  if ( hdrlen < sizeof ( *iphdr ) ) {
527  DBGC ( iphdr->src, "IPv4 header too short at %zd bytes (min "
528  "%zd bytes)\n", hdrlen, sizeof ( *iphdr ) );
529  goto err_header;
530  }
531  if ( hdrlen > iob_len ( iobuf ) ) {
532  DBGC ( iphdr->src, "IPv4 header too long at %zd bytes "
533  "(packet is %zd bytes)\n", hdrlen, iob_len ( iobuf ) );
534  goto err_header;
535  }
536  if ( ( csum = tcpip_chksum ( iphdr, hdrlen ) ) != 0 ) {
537  DBGC ( iphdr->src, "IPv4 checksum incorrect (is %04x "
538  "including checksum field, should be 0000)\n", csum );
539  goto err_header;
540  }
541  len = ntohs ( iphdr->len );
542  if ( len < hdrlen ) {
543  DBGC ( iphdr->src, "IPv4 length too short at %zd bytes "
544  "(header is %zd bytes)\n", len, hdrlen );
545  goto err_header;
546  }
547  if ( len > iob_len ( iobuf ) ) {
548  DBGC ( iphdr->src, "IPv4 length too long at %zd bytes "
549  "(packet is %zd bytes)\n", len, iob_len ( iobuf ) );
551  goto err_other;
552  }
553 
554  /* Truncate packet to correct length */
555  iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
556 
557  /* Print IPv4 header for debugging */
558  DBGC2 ( iphdr->src, "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) );
559  DBGC2 ( iphdr->src, "%s len %d proto %d id %04x csum %04x\n",
561  ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
562 
563  /* Discard unicast packets not destined for us */
564  if ( ( ! ( flags & LL_MULTICAST ) ) &&
565  ( iphdr->dest.s_addr != INADDR_BROADCAST ) &&
567  ( ! ipv4_has_addr ( netdev, iphdr->dest ) ) ) {
568  DBGC ( iphdr->src, "IPv4 discarding non-local unicast packet "
569  "for %s\n", inet_ntoa ( iphdr->dest ) );
571  goto err_other;
572  }
573 
574  /* Perform fragment reassembly if applicable */
576  /* Pass the fragment to fragment_reassemble() which returns
577  * either a fully reassembled I/O buffer or NULL.
578  */
579  iobuf = fragment_reassemble ( &ipv4_reassembler, iobuf,
580  &hdrlen );
581  if ( ! iobuf )
582  return 0;
583  iphdr = iobuf->data;
584  }
585 
586  /* Construct socket addresses, calculate pseudo-header
587  * checksum, and hand off to transport layer
588  */
589  memset ( &src, 0, sizeof ( src ) );
590  src.sin.sin_family = AF_INET;
591  src.sin.sin_addr = iphdr->src;
592  memset ( &dest, 0, sizeof ( dest ) );
593  dest.sin.sin_family = AF_INET;
594  dest.sin.sin_addr = iphdr->dest;
595  pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
596  iob_pull ( iobuf, hdrlen );
597  if ( ( rc = tcpip_rx ( iobuf, netdev, iphdr->protocol, &src.st,
598  &dest.st, pshdr_csum, &ipv4_stats ) ) != 0 ) {
599  DBGC ( src.sin.sin_addr, "IPv4 received packet rejected by "
600  "stack: %s\n", strerror ( rc ) );
601  return rc;
602  }
603 
604  profile_stop ( &ipv4_rx_profiler );
605  return 0;
606 
607  err_header:
609  err_other:
610  free_iob ( iobuf );
611  return -EINVAL;
612 }
#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:460
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:84
#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:443
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:268
#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:283
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:668
#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:42
#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 621 of file ipv4.c.

621  {
622  const struct in_addr *address = net_addr;
623 
624  if ( ipv4_has_addr ( netdev, *address ) )
625  return 0;
626 
627  return -ENOENT;
628 }
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:460
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:41

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 641 of file ipv4.c.

641  {
642  const char *separator = "...";
643  uint8_t *byte = ( ( uint8_t * ) in );
644  char *endp;
645  unsigned long value;
646 
647  while ( 1 ) {
648  value = strtoul ( string, &endp, 0 );
649  if ( string == endp )
650  return 0;
651  if ( value > 0xff )
652  return 0;
653  *(byte++) = value;
654  if ( *endp != *separator )
655  return 0;
656  if ( ! *(separator++) )
657  return 1;
658  string = ( endp + 1 );
659  }
660 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
__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 668 of file ipv4.c.

668  {
669  static char buf[16]; /* "xxx.xxx.xxx.xxx" */
670  uint8_t *bytes = ( uint8_t * ) &in;
671 
672  sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
673  return buf;
674 }
__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(), gve_describe(), 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 683 of file ipv4.c.

683  {
684  return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
685 }
IP address structure.
Definition: in.h:41
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:668

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 693 of file ipv4.c.

693  {
694  struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
695 
696  return inet_ntoa ( sin->sin_addr );
697 }
IPv4 socket address.
Definition: in.h:84
struct sockaddr sa
Definition: syslog.c:55
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:668
struct in_addr sin_addr
IPv4 address.
Definition: in.h:100
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 706 of file ipv4.c.

706  {
707  struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
708  struct in_addr in;
709 
710  if ( inet_aton ( string, &in ) ) {
711  sin->sin_addr = in;
712  return 0;
713  }
714  return -EINVAL;
715 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
__be32 in[4]
Definition: CIB_PRM.h:35
IPv4 socket address.
Definition: in.h:84
struct sockaddr sa
Definition: syslog.c:55
IP address structure.
Definition: in.h:41
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition: ipv4.c:641
struct in_addr sin_addr
IPv4 address.
Definition: in.h:100
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 765 of file ipv4.c.

766  {
767  struct in_addr ipv4;
768 
769  /* Parse IPv4 address */
770  if ( inet_aton ( value, &ipv4 ) == 0 )
771  return -EINVAL;
772 
773  /* Copy to buffer */
774  if ( len > sizeof ( ipv4 ) )
775  len = sizeof ( ipv4 );
776  memcpy ( buf, &ipv4, len );
777 
778  return ( sizeof ( ipv4 ) );
779 }
#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:41
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition: ipv4.c:641
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 791 of file ipv4.c.

793  {
794  const struct in_addr *ipv4 = raw;
795 
796  if ( raw_len < sizeof ( *ipv4 ) )
797  return -EINVAL;
798  return snprintf ( buf, len, "%s", inet_ntoa ( *ipv4 ) );
799 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static size_t raw_len
Definition: base16.h:53
IP address structure.
Definition: in.h:41
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:668
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 834 of file ipv4.c.

837  {
838  int rc;
839 
840  /* Do nothing if network device already has this IPv4 address */
841  if ( ipv4_has_addr ( netdev, address ) )
842  return 0;
843 
844  /* Transmit gratuitous ARP */
845  DBGC ( netdev, "IPv4 sending gratuitous ARP for %s via %s\n",
846  inet_ntoa ( address ), netdev->name );
847  if ( ( rc = arp_tx_request ( netdev, &ipv4_protocol, &address,
848  &address ) ) != 0 ) {
849  DBGC ( netdev, "IPv4 could not transmit gratuitous ARP: %s\n",
850  strerror ( rc ) );
851  /* Treat failures as non-fatal */
852  }
853 
854  return 0;
855 }
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:460
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:668
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 863 of file ipv4.c.

866  {
867  struct net_device *netdev;
868  struct settings *settings;
869  struct in_addr address = { 0 };
870  struct in_addr netmask = { 0 };
871  struct in_addr gateway = { 0 };
872  int rc;
873 
874  /* Process settings for each network device */
875  for_each_netdev ( netdev ) {
876 
877  /* Get network device settings */
879 
880  /* Get IPv4 address */
881  address.s_addr = 0;
882  fetch_ipv4_setting ( settings, &ip_setting, &address );
883  if ( ! address.s_addr )
884  continue;
885 
886  /* Get subnet mask */
887  fetch_ipv4_setting ( settings, &netmask_setting, &netmask );
888 
889  /* Calculate default netmask, if necessary */
890  if ( ! netmask.s_addr ) {
891  if ( IN_IS_CLASSA ( address.s_addr ) ) {
892  netmask.s_addr = INADDR_NET_CLASSA;
893  } else if ( IN_IS_CLASSB ( address.s_addr ) ) {
894  netmask.s_addr = INADDR_NET_CLASSB;
895  } else if ( IN_IS_CLASSC ( address.s_addr ) ) {
896  netmask.s_addr = INADDR_NET_CLASSC;
897  }
898  }
899 
900  /* Get default gateway, if present */
901  fetch_ipv4_setting ( settings, &gateway_setting, &gateway );
902 
903  /* Apply settings */
904  if ( ( rc = apply ( netdev, address, netmask, gateway ) ) != 0 )
905  return rc;
906  }
907 
908  return 0;
909 }
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:41
#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:42
#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 916 of file ipv4.c.

916  {
917  struct ipv4_miniroute *miniroute;
918  struct ipv4_miniroute *tmp;
919  int rc;
920 
921  /* Send gratuitous ARPs for any new IPv4 addresses */
923 
924  /* Delete all existing routes */
926  del_ipv4_miniroute ( miniroute );
927 
928  /* Create a route for each configured network device */
929  if ( ( rc = ipv4_settings ( add_ipv4_miniroute ) ) != 0 )
930  return rc;
931 
932  return 0;
933 }
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:135
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:834
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:863
#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:260
static size_t ipv4_fragment_offset(struct io_buffer *iobuf, size_t hdrlen __unused)
Get IPv4 fragment offset.
Definition: ipv4.c:246
static struct fragment_reassembler ipv4_reassembler
IPv4 fragment reassembler.
Definition: ipv4.c:268
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:229
#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 268 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:683
IP address structure.
Definition: in.h:41
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:486
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 718 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:208
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:312
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

IPv4 TCPIP net protocol.

Definition at line 727 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:621

IPv4 ARP protocol.

Definition at line 737 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:693
static int ipv4_sock_aton(const char *string, struct sockaddr *sa)
Parse IPv4 socket address.
Definition: ipv4.c:706
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

IPv4 socket address converter.

Definition at line 743 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:916

IPv4 settings applicator.

Definition at line 936 of file ipv4.c.