iPXE
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)
 FILE_SECBOOT (PERMITTED)
struct ip_statistics_family ipv4_stats_family __ip_statistics_family (IP_STATISTICS_IPV4)
 IPv4 statistics family.
static int ipv4_add_miniroute (struct net_device *netdev, struct in_addr address, struct in_addr network, struct in_addr netmask, struct in_addr gateway)
 Add IPv4 minirouting table entry.
static int ipv4_add_static (struct net_device *netdev, struct in_addr address, const void *routes, size_t len)
 Add static route minirouting table entries.
static int ipv4_add_miniroutes (struct net_device *netdev, struct in_addr address)
 Add IPv4 minirouting table entries.
static void ipv4_del_miniroute (struct ipv4_miniroute *miniroute)
 Delete IPv4 minirouting table entry.
static void ipv4_del_miniroutes (void)
 Delete IPv4 minirouting table entries.
struct ipv4_minirouteipv4_route (unsigned int scope_id, struct in_addr *dest)
 Perform IPv4 routing.
static struct net_deviceipv4_netdev (struct sockaddr_tcpip *st_dest)
 Determine transmitting network device.
static int ipv4_is_fragment (struct fragment *fragment, struct io_buffer *iobuf, size_t hdrlen __unused)
 Check if IPv4 fragment matches fragment reassembly buffer.
static size_t ipv4_fragment_offset (struct io_buffer *iobuf, size_t hdrlen __unused)
 Get IPv4 fragment offset.
static int ipv4_more_fragments (struct io_buffer *iobuf, size_t hdrlen __unused)
 Check if more fragments exist.
static uint16_t ipv4_pshdr_chksum (struct io_buffer *iobuf, uint16_t csum)
 Add IPv4 pseudo-header checksum to existing checksum.
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.
int ipv4_has_any_addr (struct net_device *netdev)
 Check if network device has any IPv4 address.
static int ipv4_has_addr (struct net_device *netdev, struct in_addr addr)
 Check if network device has a specific IPv4 address.
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.
static int ipv4_arp_check (struct net_device *netdev, const void *net_addr)
 Check existence of IPv4 address for ARP.
int inet_aton (const char *string, struct in_addr *in)
 Parse IPv4 address.
char * inet_ntoa (struct in_addr in)
 Convert IPv4 address to dotted-quad notation.
static const char * ipv4_ntoa (const void *net_addr)
 Transcribe IPv4 address.
static const char * ipv4_sock_ntoa (struct sockaddr *sa)
 Transcribe IPv4 socket address.
static int ipv4_sock_aton (const char *string, struct sockaddr *sa)
 Parse IPv4 socket address.
int parse_ipv4_setting (const struct setting_type *type __unused, const char *value, void *buf, size_t len)
 Parse IPv4 address setting value.
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.
const struct setting ip_setting __setting (SETTING_IP4, ip)
 IPv4 address setting.
const struct setting netmask_setting __setting (SETTING_IP4, netmask)
 IPv4 subnet mask setting.
const struct setting gateway_setting __setting (SETTING_IP4, gateway)
 Default gateway setting.
const struct setting static_route_setting __setting (SETTING_IP4, static_routes)
 Classless static routes setting.
static int ipv4_gratuitous_arp (struct net_device *netdev, struct in_addr address)
 Send gratuitous ARP, if applicable.
static int ipv4_settings (int(*apply)(struct net_device *netdev, struct in_addr address))
 Process IPv4 network device settings.
static int ipv4_apply_routes (void)
 Create IPv4 routing table based on configured settings.
 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.
static struct ip_statistics ipv4_stats
 IPv4 statistics.
static struct profiler ipv4_tx_profiler __profiler = { .name = "ipv4.tx" }
 Transmit profiler.
static struct fragment_reassembler ipv4_reassembler
 IPv4 fragment reassembler.
struct net_protocol ipv4_protocol __net_protocol
 IPv4 protocol.
struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol
 IPv4 TCPIP net protocol.
struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol
 IPv4 ARP protocol.
struct sockaddr_converter ipv4_sockaddr_converter __sockaddr_converter
 IPv4 socket address converter.
struct settings_applicator ipv4_settings_applicator __settings_applicator
 IPv4 settings applicator.

Detailed Description

IPv4 protocol.

Definition in file ipv4.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ __ip_statistics_family()

struct ip_statistics_family ipv4_stats_family __ip_statistics_family ( IP_STATISTICS_IPV4 )

IPv4 statistics family.

References __ip_statistics_family, IP_STATISTICS_IPV4, and ipv4_stats.

◆ ipv4_add_miniroute()

int ipv4_add_miniroute ( struct net_device * netdev,
struct in_addr address,
struct in_addr network,
struct in_addr netmask,
struct in_addr gateway )
static

Add IPv4 minirouting table entry.

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

Definition at line 86 of file ipv4.c.

90 {
91 struct ipv4_miniroute *miniroute;
92 struct ipv4_miniroute *before;
93 struct in_addr hostmask;
94 struct in_addr broadcast;
95
96 /* Calculate host mask */
97 if ( gateway.s_addr || IN_IS_SMALL ( netmask.s_addr ) ) {
98 hostmask.s_addr = INADDR_NONE;
99 } else {
100 hostmask.s_addr = ~netmask.s_addr;
101 }
102 broadcast.s_addr = ( network.s_addr | hostmask.s_addr );
103
104 /* Print debugging information */
105 DBGC ( netdev, "IPv4 add %s", inet_ntoa ( address ) );
106 DBGC ( netdev, " for %s", inet_ntoa ( network ) );
107 DBGC ( netdev, "/%s ", inet_ntoa ( netmask ) );
108 DBGC ( netdev, "bc %s ", inet_ntoa ( broadcast ) );
109 if ( gateway.s_addr )
110 DBGC ( netdev, "gw %s ", inet_ntoa ( gateway ) );
111 DBGC ( netdev, "via %s\n", netdev->name );
112
113 /* Allocate and populate miniroute structure */
114 miniroute = malloc ( sizeof ( *miniroute ) );
115 if ( ! miniroute ) {
116 DBGC ( netdev, "IPv4 could not add miniroute\n" );
117 return -ENOMEM;
118 }
119
120 /* Record routing information */
121 miniroute->netdev = netdev_get ( netdev );
122 miniroute->address = address;
123 miniroute->network = network;
124 miniroute->netmask = netmask;
125 miniroute->hostmask = hostmask;
126 miniroute->gateway = gateway;
127
128 /* Add to routing table ahead of any less specific routes */
130 if ( netmask.s_addr & ~before->netmask.s_addr )
131 break;
132 }
133 list_add_tail ( &miniroute->list, &before->list );
134
135 return 0;
136}
uint64_t address
Base address.
Definition ena.h:13
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
#define INADDR_NONE
Definition in.h:20
#define IN_IS_SMALL(mask)
Definition in.h:37
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition ipv4.c:58
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
IP address structure.
Definition in.h:42
uint32_t s_addr
Definition in.h:43
An IPv4 address/routing table entry.
Definition ip.h:64
struct in_addr gateway
Gateway address, or zero.
Definition ip.h:109
struct in_addr network
Subnet network address.
Definition ip.h:93
struct in_addr netmask
Subnet mask.
Definition ip.h:99
struct list_head list
List of miniroutes.
Definition ip.h:66
struct net_device * netdev
Network device.
Definition ip.h:73
struct in_addr address
IPv4 address.
Definition ip.h:84
struct in_addr hostmask
Host mask.
Definition ip.h:134
int32_t before
Initial microcode version.
Definition ucode.h:5

References address, ipv4_miniroute::address, before, DBGC, ENOMEM, ipv4_miniroute::gateway, ipv4_miniroute::hostmask, IN_IS_SMALL, INADDR_NONE, inet_ntoa(), ipv4_miniroutes, ipv4_miniroute::list, list_add_tail, list_for_each_entry, malloc(), ipv4_miniroute::netdev, netdev, netdev_get(), ipv4_miniroute::netmask, ipv4_miniroute::network, and in_addr::s_addr.

Referenced by ipv4_add_miniroutes(), and ipv4_add_static().

◆ ipv4_add_static()

int ipv4_add_static ( struct net_device * netdev,
struct in_addr address,
const void * routes,
size_t len )
static

Add static route minirouting table entries.

Parameters
netdevNetwork device
addressIPv4 address
routesStatic routes
lenLength of static routes
Return values
rcReturn status code

Definition at line 147 of file ipv4.c.

148 {
149 const struct {
150 struct in_addr address;
151 } __attribute__ (( packed )) *encoded;
152 struct in_addr netmask;
153 struct in_addr network;
154 struct in_addr gateway;
155 unsigned int width;
156 unsigned int masklen;
157 size_t remaining;
158 const void *data;
159 int rc;
160
161 /* Parse and add static routes */
162 for ( data = routes, remaining = len ; remaining ; ) {
163
164 /* Extract subnet mask width */
165 width = *( ( uint8_t * ) data );
166 data++;
167 remaining--;
168 masklen = ( ( width + 7 ) / 8 );
169
170 /* Check remaining length */
171 if ( ( masklen + sizeof ( gateway ) ) > remaining ) {
172 DBGC ( netdev, "IPv4 invalid static route:\n" );
173 DBGC_HDA ( netdev, 0, routes, len );
174 return -EINVAL;
175 }
176
177 /* Calculate subnet mask */
178 if ( width ) {
179 netmask.s_addr = htonl ( -1UL << ( 32 - width ) );
180 } else {
181 netmask.s_addr = 0;
182 }
183
184 /* Extract network address */
185 encoded = data;
186 network.s_addr = ( encoded->address.s_addr & netmask.s_addr );
187 data += masklen;
188 remaining -= masklen;
189
190 /* Extract gateway address */
191 encoded = data;
192 gateway.s_addr = encoded->address.s_addr;
193 data += sizeof ( gateway );
194 remaining -= sizeof ( gateway );
195
196 /* Add route */
197 if ( ( rc = ipv4_add_miniroute ( netdev, address, network,
198 netmask, gateway ) ) != 0 )
199 return rc;
200 }
201
202 return 0;
203}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
#define htonl(value)
Definition byteswap.h:134
#define __attribute__(x)
Definition compiler.h:10
static int ipv4_add_miniroute(struct net_device *netdev, struct in_addr address, struct in_addr network, struct in_addr netmask, struct in_addr gateway)
Add IPv4 minirouting table entry.
Definition ipv4.c:86

References __attribute__, address, data, DBGC, DBGC_HDA, EINVAL, htonl, ipv4_add_miniroute(), len, netdev, rc, and in_addr::s_addr.

Referenced by ipv4_add_miniroutes().

◆ ipv4_add_miniroutes()

int ipv4_add_miniroutes ( struct net_device * netdev,
struct in_addr address )
static

Add IPv4 minirouting table entries.

Parameters
netdevNetwork device
addressIPv4 address
Return values
rcReturn status code

Definition at line 212 of file ipv4.c.

213 {
215 struct in_addr none = { 0 };
216 struct in_addr netmask;
217 struct in_addr gateway;
218 struct in_addr network;
219 void *routes;
220 int len;
221 int rc;
222
223 /* Get subnet mask */
225
226 /* Calculate default netmask, if necessary */
227 if ( ! netmask.s_addr ) {
228 if ( IN_IS_CLASSA ( address.s_addr ) ) {
229 netmask.s_addr = INADDR_NET_CLASSA;
230 } else if ( IN_IS_CLASSB ( address.s_addr ) ) {
231 netmask.s_addr = INADDR_NET_CLASSB;
232 } else if ( IN_IS_CLASSC ( address.s_addr ) ) {
233 netmask.s_addr = INADDR_NET_CLASSC;
234 }
235 }
236
237 /* Get default gateway, if present */
239
240 /* Get static routes, if present */
241 len = fetch_raw_setting_copy ( settings, &static_route_setting,
242 &routes );
243
244 /* Add local address */
245 network.s_addr = ( address.s_addr & netmask.s_addr );
246 if ( ( rc = ipv4_add_miniroute ( netdev, address, network, netmask,
247 none ) ) != 0 )
248 goto done;
249
250 /* Add static routes or default gateway, as applicable */
251 if ( len >= 0 ) {
252 if ( ( rc = ipv4_add_static ( netdev, address, routes,
253 len ) ) != 0 )
254 goto done;
255 } else if ( gateway.s_addr ) {
257 gateway ) ) != 0 )
258 goto done;
259 }
260
261 done:
262 free ( routes );
263 return rc;
264}
@ none
Definition 3c5x9.c:35
struct bofm_section_header done
Definition bofm_test.c:46
const struct setting netmask_setting
const struct setting gateway_setting
#define IN_IS_CLASSB(addr)
Definition in.h:30
#define IN_IS_CLASSA(addr)
Definition in.h:28
#define INADDR_NET_CLASSC
Definition in.h:26
#define IN_IS_CLASSC(addr)
Definition in.h:32
#define INADDR_NET_CLASSB
Definition in.h:25
#define INADDR_NET_CLASSA
Definition in.h:24
static int ipv4_add_static(struct net_device *netdev, struct in_addr address, const void *routes, size_t len)
Add static route minirouting table entries.
Definition ipv4.c:147
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition settings.c:822
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913
A settings block.
Definition settings.h:133

References address, done, fetch_ipv4_setting(), fetch_raw_setting_copy(), free, gateway_setting, IN_IS_CLASSA, IN_IS_CLASSB, IN_IS_CLASSC, INADDR_NET_CLASSA, INADDR_NET_CLASSB, INADDR_NET_CLASSC, ipv4_add_miniroute(), ipv4_add_static(), len, netdev, netdev_settings(), netmask_setting, none, rc, and in_addr::s_addr.

Referenced by ipv4_apply_routes().

◆ ipv4_del_miniroute()

void ipv4_del_miniroute ( struct ipv4_miniroute * miniroute)
static

Delete IPv4 minirouting table entry.

Parameters
minirouteRouting table entry

Definition at line 271 of file ipv4.c.

271 {
272 struct net_device *netdev = miniroute->netdev;
273
274 DBGC ( netdev, "IPv4 del %s", inet_ntoa ( miniroute->address ) );
275 DBGC ( netdev, " for %s", inet_ntoa ( miniroute->network ) );
276 DBGC ( netdev, "/%s ", inet_ntoa ( miniroute->netmask ) );
277 if ( miniroute->gateway.s_addr )
278 DBGC ( netdev, "gw %s ", inet_ntoa ( miniroute->gateway ) );
279 DBGC ( netdev, "via %s\n", miniroute->netdev->name );
280
281 netdev_put ( miniroute->netdev );
282 list_del ( &miniroute->list );
283 free ( miniroute );
284}
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
A network device.
Definition netdevice.h:353
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363

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

Referenced by ipv4_del_miniroutes().

◆ ipv4_del_miniroutes()

void ipv4_del_miniroutes ( void )
static

Delete IPv4 minirouting table entries.

Definition at line 290 of file ipv4.c.

290 {
291 struct ipv4_miniroute *miniroute;
292 struct ipv4_miniroute *tmp;
293
294 /* Delete all existing routes */
296 ipv4_del_miniroute ( miniroute );
297}
static void ipv4_del_miniroute(struct ipv4_miniroute *miniroute)
Delete IPv4 minirouting table entry.
Definition ipv4.c:271
unsigned long tmp
Definition linux_pci.h:65
#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:459

References ipv4_del_miniroute(), ipv4_miniroutes, ipv4_miniroute::list, list_for_each_entry_safe, and tmp.

Referenced by ipv4_apply_routes().

◆ ipv4_route()

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

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

311 {
312 struct ipv4_miniroute *miniroute;
313
314 /* Find first usable route in routing table */
315 list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
316
317 /* Skip closed network devices */
318 if ( ! netdev_is_open ( miniroute->netdev ) )
319 continue;
320
321 if ( IN_IS_MULTICAST ( dest->s_addr ) ) {
322
323 /* If destination is non-global, and the scope
324 * ID matches this network device, then use
325 * the first matching route.
326 */
327 if ( miniroute->netdev->scope_id == scope_id )
328 return miniroute;
329
330 } else {
331
332 /* If destination is global, then use the
333 * first matching route (via its gateway if
334 * specified).
335 */
336 if ( ( ( dest->s_addr ^ miniroute->network.s_addr )
337 & miniroute->netmask.s_addr ) == 0 ) {
338 if ( miniroute->gateway.s_addr )
339 *dest = miniroute->gateway;
340 return miniroute;
341 }
342 }
343 }
344
345 return NULL;
346}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define IN_IS_MULTICAST(addr)
Definition in.h:34
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
unsigned int scope_id
Scope ID.
Definition netdevice.h:361

References 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, ipv4_miniroute::network, NULL, in_addr::s_addr, and net_device::scope_id.

Referenced by ipv4_netdev(), ipv4_route_okx(), and ipv4_tx().

◆ ipv4_netdev()

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

354 {
355 struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
356 struct in_addr dest = sin_dest->sin_addr;
357 struct ipv4_miniroute *miniroute;
358
359 /* Find routing table entry */
360 miniroute = ipv4_route ( sin_dest->sin_scope_id, &dest );
361 if ( ! miniroute )
362 return NULL;
363
364 return miniroute->netdev;
365}
struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition ipv4.c:310
IPv4 socket address.
Definition in.h:85
uint16_t sin_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition in.h:99
struct in_addr sin_addr
IPv4 address.
Definition in.h:101

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

◆ ipv4_is_fragment()

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

377 {
378 struct iphdr *frag_iphdr = fragment->iobuf->data;
379 struct iphdr *iphdr = iobuf->data;
380
381 return ( ( iphdr->src.s_addr == frag_iphdr->src.s_addr ) &&
382 ( iphdr->ident == frag_iphdr->ident ) );
383}
A fragment reassembly buffer.
Definition fragment.h:22
struct io_buffer * iobuf
Reassembled packet.
Definition fragment.h:26
void * data
Start of data.
Definition iobuf.h:53
An IPv4 packet header.
Definition ip.h:36
struct in_addr src
Definition ip.h:45
uint16_t ident
Definition ip.h:40

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

◆ ipv4_fragment_offset()

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

393 {
394 struct iphdr *iphdr = iobuf->data;
395
396 return ( ( ntohs ( iphdr->frags ) & IP_MASK_OFFSET ) << 3 );
397}
#define ntohs(value)
Definition byteswap.h:137
#define IP_MASK_OFFSET
Definition ip.h:26
uint16_t frags
Definition ip.h:41

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

◆ ipv4_more_fragments()

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

407 {
408 struct iphdr *iphdr = iobuf->data;
409
410 return ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) );
411}
#define htons(value)
Definition byteswap.h:136
#define IP_MASK_MOREFRAGS
Definition ip.h:28

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

◆ ipv4_pshdr_chksum()

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

429 {
430 struct ipv4_pseudo_header pshdr;
431 struct iphdr *iphdr = iobuf->data;
432 size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
433
434 /* Build pseudo-header */
435 pshdr.src = iphdr->src;
436 pshdr.dest = iphdr->dest;
437 pshdr.zero_padding = 0x00;
438 pshdr.protocol = iphdr->protocol;
439 pshdr.len = htons ( iob_len ( iobuf ) - hdrlen );
440
441 /* Update the checksum value */
442 return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
443}
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define IP_MASK_HLEN
Definition ip.h:25
uint8_t protocol
Definition ip.h:43
struct in_addr dest
Definition ip.h:46
uint8_t verhdrlen
Definition ip.h:37
An IPv4 pseudo header.
Definition ip.h:50
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition x86_tcpip.c:46

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

Referenced by ipv4_rx(), and ipv4_tx().

◆ ipv4_tx()

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

463 {
464 struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
465 struct sockaddr_in *sin_src = ( ( struct sockaddr_in * ) st_src );
466 struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
467 struct ipv4_miniroute *miniroute;
468 struct in_addr next_hop;
469 struct in_addr hostmask = { .s_addr = INADDR_NONE };
470 uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
471 const void *ll_dest;
472 int rc;
473
474 /* Start profiling */
475 profile_start ( &ipv4_tx_profiler );
476
477 /* Update statistics */
478 ipv4_stats.out_requests++;
479
480 /* Fill up the IP header, except source address */
481 memset ( iphdr, 0, sizeof ( *iphdr ) );
482 iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
484 iphdr->len = htons ( iob_len ( iobuf ) );
485 iphdr->ttl = IP_TTL;
487 iphdr->dest = sin_dest->sin_addr;
488
489 /* Use routing table to identify next hop and transmitting netdev */
490 next_hop = iphdr->dest;
491 if ( sin_src )
492 iphdr->src = sin_src->sin_addr;
493 if ( ( next_hop.s_addr != INADDR_BROADCAST ) &&
494 ( ( miniroute = ipv4_route ( sin_dest->sin_scope_id,
495 &next_hop ) ) != NULL ) ) {
496 iphdr->src = miniroute->address;
497 hostmask = miniroute->hostmask;
498 netdev = miniroute->netdev;
499 }
500 if ( ! netdev ) {
501 DBGC ( sin_dest->sin_addr, "IPv4 has no route to %s\n",
502 inet_ntoa ( iphdr->dest ) );
503 ipv4_stats.out_no_routes++;
504 rc = -ENETUNREACH;
505 goto err;
506 }
507
508 /* (Ab)use the "ident" field to convey metadata about the
509 * network device statistics into packet traces. Useful for
510 * extracting debug information from non-debug builds.
511 */
512 iphdr->ident = htons ( ( (++next_ident_high) << 8 ) |
513 ( ( netdev->rx_stats.bad & 0xf ) << 4 ) |
514 ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
515
516 /* Fix up checksums */
517 if ( trans_csum ) {
518 *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
519 if ( ! *trans_csum )
520 *trans_csum = tcpip_protocol->zero_csum;
521 }
522 iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
523
524 /* Print IP4 header for debugging */
525 DBGC2 ( sin_dest->sin_addr, "IPv4 TX %s->", inet_ntoa ( iphdr->src ) );
526 DBGC2 ( sin_dest->sin_addr, "%s len %d proto %d id %04x csum %04x\n",
527 inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ),
529 ntohs ( iphdr->chksum ) );
530
531 /* Calculate link-layer destination address, if possible */
532 if ( ( ( ~next_hop.s_addr ) & hostmask.s_addr ) == 0 ) {
533 /* Broadcast address */
534 ipv4_stats.out_bcast_pkts++;
535 ll_dest = netdev->ll_broadcast;
536 } else if ( IN_IS_MULTICAST ( next_hop.s_addr ) ) {
537 /* Multicast address */
538 ipv4_stats.out_mcast_pkts++;
539 if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET, &next_hop,
540 ll_dest_buf ) ) !=0){
541 DBGC ( sin_dest->sin_addr, "IPv4 could not hash "
542 "multicast %s: %s\n",
543 inet_ntoa ( next_hop ), strerror ( rc ) );
544 goto err;
545 }
546 ll_dest = ll_dest_buf;
547 } else {
548 /* Unicast address */
549 ll_dest = NULL;
550 }
551
552 /* Update statistics */
553 ipv4_stats.out_transmits++;
554 ipv4_stats.out_octets += iob_len ( iobuf );
555
556 /* Hand off to link layer (via ARP if applicable) */
557 if ( ll_dest ) {
558 if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest,
559 netdev->ll_addr ) ) != 0 ) {
560 DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
561 "packet via %s: %s\n",
562 netdev->name, strerror ( rc ) );
563 return rc;
564 }
565 } else {
566 if ( ( rc = arp_tx ( iobuf, netdev, &ipv4_protocol, &next_hop,
567 &iphdr->src ) ) != 0 ) {
568 DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
569 "packet via %s: %s\n",
570 netdev->name, strerror ( rc ) );
571 return rc;
572 }
573 }
574
575 profile_stop ( &ipv4_tx_profiler );
576 return 0;
577
578 err:
579 free_iob ( iobuf );
580 return rc;
581}
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)
Transmit packet, determining link-layer address via ARP.
Definition arp.h:51
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define DBGC2(...)
Definition compiler.h:522
#define ENETUNREACH
Network unreachable.
Definition errno.h:489
#define INADDR_BROADCAST
Definition in.h:22
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
void * memset(void *dest, int character, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define IP_TTL
Definition ip.h:33
#define IP_TOS
Definition ip.h:32
#define IP_VER
Definition ip.h:23
static uint8_t next_ident_high
Definition ipv4.c:55
static uint16_t ipv4_pshdr_chksum(struct io_buffer *iobuf, uint16_t csum)
Add IPv4 pseudo-header checksum to existing checksum.
Definition ipv4.c:429
static struct ip_statistics ipv4_stats
IPv4 statistics.
Definition ipv4.c:61
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:1074
#define MAX_LL_ADDR_LEN
Maximum length of a link-layer address.
Definition netdevice.h:37
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
uint8_t service
Definition ip.h:38
uint16_t len
Definition ip.h:39
uint8_t ttl
Definition ip.h:42
uint16_t chksum
Definition ip.h:44
A transport-layer protocol of the TCP/IP stack (eg.
Definition tcpip.h:105
uint8_t tcpip_proto
Transport-layer protocol number.
Definition tcpip.h:135
uint16_t zero_csum
Preferred zero checksum value.
Definition tcpip.h:129
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition tcpip.c:204

References ipv4_miniroute::address, AF_INET, arp_tx(), iphdr::chksum, DBGC, DBGC2, iphdr::dest, ENETUNREACH, free_iob(), 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, MAX_LL_ADDR_LEN, memset(), net_tx(), ipv4_miniroute::netdev, netdev, next_ident_high, ntohs, NULL, profile_start(), profile_stop(), iphdr::protocol, rc, 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 589 of file ipv4.c.

589 {
590 struct ipv4_miniroute *miniroute;
591
592 list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
593 if ( miniroute->netdev == netdev )
594 return 1;
595 }
596 return 0;
597}

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

Referenced by dhcp_create_packet(), and ipv4_rx().

◆ ipv4_has_addr()

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

606 {
607 struct ipv4_miniroute *miniroute;
608
609 list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
610 if ( ( miniroute->netdev == netdev ) &&
611 ( miniroute->address.s_addr == addr.s_addr ) ) {
612 /* Found matching address */
613 return 1;
614 }
615 }
616 return 0;
617}
uint32_t addr
Buffer address.
Definition dwmac.h:9

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

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

◆ ipv4_rx()

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

636 {
637 struct iphdr *iphdr = iobuf->data;
638 size_t hdrlen;
639 size_t len;
640 union {
641 struct sockaddr_in sin;
642 struct sockaddr_tcpip st;
643 } src, dest;
644 uint16_t csum;
645 uint16_t pshdr_csum;
646 int rc;
647
648 /* Start profiling */
649 profile_start ( &ipv4_rx_profiler );
650
651 /* Update statistics */
652 ipv4_stats.in_receives++;
653 ipv4_stats.in_octets += iob_len ( iobuf );
654 if ( flags & LL_BROADCAST ) {
655 ipv4_stats.in_bcast_pkts++;
656 } else if ( flags & LL_MULTICAST ) {
657 ipv4_stats.in_mcast_pkts++;
658 }
659
660 /* Sanity check the IPv4 header */
661 if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) {
662 DBGC ( iphdr->src, "IPv4 packet too short at %zd bytes (min "
663 "%zd bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) );
664 goto err_header;
665 }
666 if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) {
667 DBGC ( iphdr->src, "IPv4 version %#02x not supported\n",
668 iphdr->verhdrlen );
669 goto err_header;
670 }
671 hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
672 if ( hdrlen < sizeof ( *iphdr ) ) {
673 DBGC ( iphdr->src, "IPv4 header too short at %zd bytes (min "
674 "%zd bytes)\n", hdrlen, sizeof ( *iphdr ) );
675 goto err_header;
676 }
677 if ( hdrlen > iob_len ( iobuf ) ) {
678 DBGC ( iphdr->src, "IPv4 header too long at %zd bytes "
679 "(packet is %zd bytes)\n", hdrlen, iob_len ( iobuf ) );
680 goto err_header;
681 }
682 if ( ( csum = tcpip_chksum ( iphdr, hdrlen ) ) != 0 ) {
683 DBGC ( iphdr->src, "IPv4 checksum incorrect (is %04x "
684 "including checksum field, should be 0000)\n", csum );
685 goto err_header;
686 }
687 len = ntohs ( iphdr->len );
688 if ( len < hdrlen ) {
689 DBGC ( iphdr->src, "IPv4 length too short at %zd bytes "
690 "(header is %zd bytes)\n", len, hdrlen );
691 goto err_header;
692 }
693 if ( len > iob_len ( iobuf ) ) {
694 DBGC ( iphdr->src, "IPv4 length too long at %zd bytes "
695 "(packet is %zd bytes)\n", len, iob_len ( iobuf ) );
696 ipv4_stats.in_truncated_pkts++;
697 goto err_other;
698 }
699
700 /* Truncate packet to correct length */
701 iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
702
703 /* Print IPv4 header for debugging */
704 DBGC2 ( iphdr->src, "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) );
705 DBGC2 ( iphdr->src, "%s len %d proto %d id %04x csum %04x\n",
707 ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
708
709 /* Discard unicast packets not destined for us */
710 if ( ( ! ( flags & LL_MULTICAST ) ) &&
713 ( ! ipv4_has_addr ( netdev, iphdr->dest ) ) ) {
714 DBGC ( iphdr->src, "IPv4 discarding non-local unicast packet "
715 "for %s\n", inet_ntoa ( iphdr->dest ) );
716 ipv4_stats.in_addr_errors++;
717 goto err_other;
718 }
719
720 /* Perform fragment reassembly if applicable */
722 /* Pass the fragment to fragment_reassemble() which returns
723 * either a fully reassembled I/O buffer or NULL.
724 */
725 iobuf = fragment_reassemble ( &ipv4_reassembler, iobuf,
726 &hdrlen );
727 if ( ! iobuf )
728 return 0;
729 iphdr = iobuf->data;
730 }
731
732 /* Construct socket addresses, calculate pseudo-header
733 * checksum, and hand off to transport layer
734 */
735 memset ( &src, 0, sizeof ( src ) );
736 src.sin.sin_family = AF_INET;
737 src.sin.sin_addr = iphdr->src;
738 memset ( &dest, 0, sizeof ( dest ) );
739 dest.sin.sin_family = AF_INET;
740 dest.sin.sin_addr = iphdr->dest;
741 pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
742 iob_pull ( iobuf, hdrlen );
743 if ( ( rc = tcpip_rx ( iobuf, netdev, iphdr->protocol, &src.st,
744 &dest.st, pshdr_csum, &ipv4_stats ) ) != 0 ) {
745 DBGC ( src.sin.sin_addr, "IPv4 received packet rejected by "
746 "stack: %s\n", strerror ( rc ) );
747 return rc;
748 }
749
750 profile_stop ( &ipv4_rx_profiler );
751 return 0;
752
753 err_header:
754 ipv4_stats.in_hdr_errors++;
755 err_other:
756 free_iob ( iobuf );
757 return -EINVAL;
758}
unsigned short uint16_t
Definition stdint.h:11
static const void * src
Definition string.h:48
uint8_t flags
Flags.
Definition ena.h:7
struct io_buffer * fragment_reassemble(struct fragment_reassembler *fragments, struct io_buffer *iobuf, size_t *hdrlen)
Reassemble packet.
Definition fragment.c:89
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition tcpip.h:58
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define iob_unput(iobuf, len)
Definition iobuf.h:140
#define IP_MASK_VER
Definition ip.h:24
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition ipv4.c:589
static struct fragment_reassembler ipv4_reassembler
IPv4 fragment reassembler.
Definition ipv4.c:414
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:606
#define LL_MULTICAST
Packet is a multicast (including broadcast) packet.
Definition netdevice.h:106
#define LL_BROADCAST
Packet is a broadcast packet.
Definition netdevice.h:109
struct sockaddr_tcpip st
Definition syslog.c:58
struct sockaddr_in sin
Definition syslog.c:59
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:41

References __unused, AF_INET, iphdr::chksum, io_buffer::data, DBGC, DBGC2, dest, iphdr::dest, EINVAL, flags, fragment_reassemble(), iphdr::frags, free_iob(), htons, iphdr::ident, 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, iphdr::len, 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()

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

767 {
768 const struct in_addr *address = net_addr;
769
770 if ( ipv4_has_addr ( netdev, *address ) )
771 return 0;
772
773 return -ENOENT;
774}
#define ENOENT
No such file or directory.
Definition errno.h:515

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

787 {
788 const char *separator = "...";
789 uint8_t *byte = ( ( uint8_t * ) in );
790 char *endp;
791 unsigned long value;
792
793 while ( 1 ) {
794 value = strtoul ( string, &endp, 0 );
795 if ( string == endp )
796 return 0;
797 if ( value > 0xff )
798 return 0;
799 *(byte++) = value;
800 if ( *endp != *separator )
801 return 0;
802 if ( ! *(separator++) )
803 return 1;
804 string = ( endp + 1 );
805 }
806}
__be32 in[4]
Definition CIB_PRM.h:7
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485

References in, strtoul(), and value.

Referenced by inet_aton_fail_okx(), inet_aton_okx(), ipv4_route_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 814 of file ipv4.c.

814 {
815 static char buf[16]; /* "xxx.xxx.xxx.xxx" */
816 uint8_t *bytes = ( uint8_t * ) &in;
817
818 sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
819 return buf;
820}
uint8_t bytes[64]
Definition ib_mad.h:5
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37

References bytes, in, and sprintf.

Referenced by 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_add_miniroute(), ipv4_del_miniroute(), ipv4_gratuitous_arp(), ipv4_ntoa(), ipv4_route_okx(), 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()

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

829 {
830 return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
831}

References inet_ntoa().

◆ ipv4_sock_ntoa()

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

839 {
840 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
841
842 return inet_ntoa ( sin->sin_addr );
843}
struct sockaddr sa
Definition syslog.c:57

References inet_ntoa(), sa, and sin.

◆ ipv4_sock_aton()

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

852 {
853 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
854 struct in_addr in;
855
856 if ( inet_aton ( string, &in ) ) {
857 sin->sin_addr = in;
858 return 0;
859 }
860 return -EINVAL;
861}
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition ipv4.c:787

References EINVAL, in, inet_aton(), sa, and sin.

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

912 {
913 struct in_addr ipv4;
914
915 /* Parse IPv4 address */
916 if ( inet_aton ( value, &ipv4 ) == 0 )
917 return -EINVAL;
918
919 /* Copy to buffer */
920 if ( len > sizeof ( ipv4 ) )
921 len = sizeof ( ipv4 );
922 memcpy ( buf, &ipv4, len );
923
924 return ( sizeof ( ipv4 ) );
925}
void * memcpy(void *dest, const void *src, size_t len) __nonnull

References __unused, EINVAL, inet_aton(), len, memcpy(), type, 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 937 of file ipv4.c.

939 {
940 const struct in_addr *ipv4 = raw;
941
942 if ( raw_len < sizeof ( *ipv4 ) )
943 return -EINVAL;
944 return snprintf ( buf, len, "%s", inet_ntoa ( *ipv4 ) );
945}
__be32 raw[7]
Definition CIB_PRM.h:0
static size_t raw_len
Definition base16.h:54
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

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

◆ __setting() [1/4]

const struct setting ip_setting __setting ( SETTING_IP4 ,
ip  )

IPv4 address setting.

References __setting, DHCP_EB_YIADDR, ip, ip_setting, and SETTING_IP4.

◆ __setting() [2/4]

const struct setting netmask_setting __setting ( SETTING_IP4 ,
netmask  )

IPv4 subnet mask setting.

References __setting, DHCP_SUBNET_MASK, netmask_setting, and SETTING_IP4.

◆ __setting() [3/4]

const struct setting gateway_setting __setting ( SETTING_IP4 ,
gateway  )

Default gateway setting.

References __setting, DHCP_ROUTERS, gateway_setting, and SETTING_IP4.

◆ __setting() [4/4]

const struct setting static_route_setting __setting ( SETTING_IP4 ,
static_routes  )

Classless static routes setting.

References __setting, DHCP_STATIC_ROUTES, and SETTING_IP4.

◆ ipv4_gratuitous_arp()

int ipv4_gratuitous_arp ( struct net_device * netdev,
struct in_addr address )
static

Send gratuitous ARP, if applicable.

Parameters
netdevNetwork device
addressIPv4 address
Return values
rcReturn status code

Definition at line 987 of file ipv4.c.

988 {
989 int rc;
990
991 /* Do nothing if network device already has this IPv4 address */
992 if ( ipv4_has_addr ( netdev, address ) )
993 return 0;
994
995 /* Transmit gratuitous ARP */
996 DBGC ( netdev, "IPv4 sending gratuitous ARP for %s via %s\n",
997 inet_ntoa ( address ), netdev->name );
998 if ( ( rc = arp_tx_request ( netdev, &ipv4_protocol, &address,
999 &address ) ) != 0 ) {
1000 DBGC ( netdev, "IPv4 could not transmit gratuitous ARP: %s\n",
1001 strerror ( rc ) );
1002 /* Treat failures as non-fatal */
1003 }
1004
1005 return 0;
1006}
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:60

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

Referenced by ipv4_apply_routes().

◆ ipv4_settings()

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

Process IPv4 network device settings.

Parameters
applyApplication method
Return values
rcReturn status code

Definition at line 1014 of file ipv4.c.

1015 {
1016 struct net_device *netdev;
1017 struct settings *settings;
1018 struct in_addr address;
1019 int rc;
1020
1021 /* Process settings for each network device */
1023
1024 /* Get network device settings */
1026
1027 /* Get IPv4 address */
1029 if ( ! address.s_addr )
1030 continue;
1031
1032 /* Apply settings */
1033 if ( ( rc = apply ( netdev, address ) ) != 0 )
1034 return rc;
1035 }
1036
1037 return 0;
1038}
const struct setting ip_setting
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:547

References address, fetch_ipv4_setting(), for_each_netdev, ip_setting, netdev, netdev_settings(), and rc.

Referenced by ipv4_apply_routes().

◆ ipv4_apply_routes()

int ipv4_apply_routes ( void )
static

Create IPv4 routing table based on configured settings.

Return values
rcReturn status code

Definition at line 1045 of file ipv4.c.

1045 {
1046 int rc;
1047
1048 /* Send gratuitous ARPs for any new IPv4 addresses */
1050
1051 /* Delete all existing routes */
1053
1054 /* Create routes for each configured network device */
1055 if ( ( rc = ipv4_settings ( ipv4_add_miniroutes ) ) != 0 )
1056 return rc;
1057
1058 return 0;
1059}
static int ipv4_settings(int(*apply)(struct net_device *netdev, struct in_addr address))
Process IPv4 network device settings.
Definition ipv4.c:1014
static int ipv4_gratuitous_arp(struct net_device *netdev, struct in_addr address)
Send gratuitous ARP, if applicable.
Definition ipv4.c:987
static void ipv4_del_miniroutes(void)
Delete IPv4 minirouting table entries.
Definition ipv4.c:290
static int ipv4_add_miniroutes(struct net_device *netdev, struct in_addr address)
Add IPv4 minirouting table entries.
Definition ipv4.c:212

References ipv4_add_miniroutes(), ipv4_del_miniroutes(), ipv4_gratuitous_arp(), ipv4_settings(), and rc.

◆ 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 55 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 58 of file ipv4.c.

Referenced by ipv4_add_miniroute(), ipv4_del_miniroutes(), 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 61 of file ipv4.c.

Referenced by __ip_statistics_family(), ipv4_rx(), and ipv4_tx().

◆ __profiler

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

Transmit profiler.

Receive profiler.

Definition at line 71 of file ipv4.c.

71{ .name = "ipv4.tx" };

◆ ipv4_reassembler

struct fragment_reassembler ipv4_reassembler
static
Initial value:
= {
.list = LIST_HEAD_INIT ( ipv4_reassembler.list ),
.is_fragment = ipv4_is_fragment,
.fragment_offset = ipv4_fragment_offset,
.more_fragments = ipv4_more_fragments,
.stats = &ipv4_stats,
}
static size_t ipv4_fragment_offset(struct io_buffer *iobuf, size_t hdrlen __unused)
Get IPv4 fragment offset.
Definition ipv4.c:392
static int ipv4_more_fragments(struct io_buffer *iobuf, size_t hdrlen __unused)
Check if more fragments exist.
Definition ipv4.c:406
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:375
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31

IPv4 fragment reassembler.

Definition at line 414 of file ipv4.c.

414 {
415 .list = LIST_HEAD_INIT ( ipv4_reassembler.list ),
416 .is_fragment = ipv4_is_fragment,
417 .fragment_offset = ipv4_fragment_offset,
418 .more_fragments = ipv4_more_fragments,
419 .stats = &ipv4_stats,
420};

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:19
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:632
static const char * ipv4_ntoa(const void *net_addr)
Transcribe IPv4 address.
Definition ipv4.c:829
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1

IPv4 protocol.

AoE protocol.

Definition at line 864 of file ipv4.c.

864 {
865 .name = "IP",
866 .net_proto = htons ( ETH_P_IP ),
867 .net_addr_len = sizeof ( struct in_addr ),
868 .rx = ipv4_rx,
869 .ntoa = ipv4_ntoa,
870};

◆ __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,
}
static struct net_device * ipv4_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition ipv4.c:354
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:458
A network-layer protocol.
Definition netdevice.h:65

IPv4 TCPIP net protocol.

Definition at line 873 of file ipv4.c.

873 {
874 .name = "IPv4",
875 .sa_family = AF_INET,
876 .header_len = sizeof ( struct iphdr ),
877 .net_protocol = &ipv4_protocol,
878 .tx = ipv4_tx,
879 .netdev = ipv4_netdev,
880};

◆ __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:767

IPv4 ARP protocol.

Definition at line 883 of file ipv4.c.

883 {
884 .net_protocol = &ipv4_protocol,
885 .check = ipv4_arp_check,
886};

◆ __sockaddr_converter

struct sockaddr_converter ipv4_sockaddr_converter __sockaddr_converter
Initial value:
= {
.family = AF_INET,
.ntoa = ipv4_sock_ntoa,
.aton = ipv4_sock_aton,
}
static int ipv4_sock_aton(const char *string, struct sockaddr *sa)
Parse IPv4 socket address.
Definition ipv4.c:852
static const char * ipv4_sock_ntoa(struct sockaddr *sa)
Transcribe IPv4 socket address.
Definition ipv4.c:839

IPv4 socket address converter.

Definition at line 889 of file ipv4.c.

889 {
890 .family = AF_INET,
891 .ntoa = ipv4_sock_ntoa,
892 .aton = ipv4_sock_aton,
893};

◆ __settings_applicator

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

IPv4 settings applicator.

Definition at line 1062 of file ipv4.c.

1062 {
1063 .apply = ipv4_apply_routes,
1064};