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:530
#define ENOMEM
Not enough space.
Definition errno.h:578
#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:816
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:677
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
IP address structure.
Definition in.h:42
uint32_t s_addr
Definition in.h:43
An IPv4 address/routing table entry.
Definition ip.h:71
struct in_addr gateway
Gateway address, or zero.
Definition ip.h:116
struct in_addr network
Subnet network address.
Definition ip.h:100
struct in_addr netmask
Subnet mask.
Definition ip.h:106
struct list_head list
List of miniroutes.
Definition ip.h:73
struct net_device * netdev
Network device.
Definition ip.h:80
struct in_addr address
IPv4 address.
Definition ip.h:91
struct in_addr hostmask
Host mask.
Definition ip.h:141
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 and mask validity */
171 if ( ( ( masklen + sizeof ( gateway ) ) > remaining ) ||
172 ( width > 32 ) ) {
173 DBGC ( netdev, "IPv4 invalid static route:\n" );
174 DBGC_HDA ( netdev, 0, routes, len );
175 return -EINVAL;
176 }
177
178 /* Calculate subnet mask */
179 if ( width ) {
180 netmask.s_addr = htonl ( -1UL << ( 32 - width ) );
181 } else {
182 netmask.s_addr = 0;
183 }
184
185 /* Extract network address */
186 encoded = data;
187 network.s_addr = ( encoded->address.s_addr & netmask.s_addr );
188 data += masklen;
189 remaining -= masklen;
190
191 /* Extract gateway address */
192 encoded = data;
193 gateway.s_addr = encoded->address.s_addr;
194 data += sizeof ( gateway );
195 remaining -= sizeof ( gateway );
196
197 /* Add route */
198 if ( ( rc = ipv4_add_miniroute ( netdev, address, network,
199 netmask, gateway ) ) != 0 )
200 return rc;
201 }
202
203 return 0;
204}
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:531
#define EINVAL
Invalid argument.
Definition errno.h:472
#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 213 of file ipv4.c.

214 {
216 struct in_addr none = { 0 };
217 struct in_addr netmask;
218 struct in_addr gateway;
219 struct in_addr network;
220 void *routes;
221 int len;
222 int rc;
223
224 /* Get subnet mask */
226
227 /* Calculate default netmask, if necessary */
228 if ( ! netmask.s_addr ) {
229 if ( IN_IS_CLASSA ( address.s_addr ) ) {
230 netmask.s_addr = INADDR_NET_CLASSA;
231 } else if ( IN_IS_CLASSB ( address.s_addr ) ) {
232 netmask.s_addr = INADDR_NET_CLASSB;
233 } else if ( IN_IS_CLASSC ( address.s_addr ) ) {
234 netmask.s_addr = INADDR_NET_CLASSC;
235 }
236 }
237
238 /* Get default gateway, if present */
240
241 /* Get static routes, if present */
242 len = fetch_raw_setting_copy ( settings, &static_route_setting,
243 &routes );
244
245 /* Add local address */
246 network.s_addr = ( address.s_addr & netmask.s_addr );
247 if ( ( rc = ipv4_add_miniroute ( netdev, address, network, netmask,
248 none ) ) != 0 )
249 goto done;
250
251 /* Add static routes or default gateway, as applicable */
252 if ( len >= 0 ) {
253 if ( ( rc = ipv4_add_static ( netdev, address, routes,
254 len ) ) != 0 )
255 goto done;
256 } else if ( gateway.s_addr ) {
258 gateway ) ) != 0 )
259 goto done;
260 }
261
262 done:
263 free ( routes );
264 return rc;
265}
@ 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:590
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 272 of file ipv4.c.

272 {
273 struct net_device *netdev = miniroute->netdev;
274
275 DBGC ( netdev, "IPv4 del %s", inet_ntoa ( miniroute->address ) );
276 DBGC ( netdev, " for %s", inet_ntoa ( miniroute->network ) );
277 DBGC ( netdev, "/%s ", inet_ntoa ( miniroute->netmask ) );
278 if ( miniroute->gateway.s_addr )
279 DBGC ( netdev, "gw %s ", inet_ntoa ( miniroute->gateway ) );
280 DBGC ( netdev, "via %s\n", miniroute->netdev->name );
281
282 netdev_put ( miniroute->netdev );
283 list_del ( &miniroute->list );
284 free ( miniroute );
285}
#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:579
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 291 of file ipv4.c.

291 {
292 struct ipv4_miniroute *miniroute;
293 struct ipv4_miniroute *tmp;
294
295 /* Delete all existing routes */
297 ipv4_del_miniroute ( miniroute );
298}
static void ipv4_del_miniroute(struct ipv4_miniroute *miniroute)
Delete IPv4 minirouting table entry.
Definition ipv4.c:272
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 311 of file ipv4.c.

312 {
313 struct ipv4_miniroute *miniroute;
314
315 /* Find first usable route in routing table */
316 list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
317
318 /* Skip closed network devices */
319 if ( ! netdev_is_open ( miniroute->netdev ) )
320 continue;
321
322 if ( IN_IS_MULTICAST ( dest->s_addr ) ) {
323
324 /* If destination is non-global, and the scope
325 * ID matches this network device, then use
326 * the first matching route.
327 */
328 if ( miniroute->netdev->scope_id == scope_id )
329 return miniroute;
330
331 } else {
332
333 /* If destination is global, then use the
334 * first matching route (via its gateway if
335 * specified).
336 */
337 if ( ( ( dest->s_addr ^ miniroute->network.s_addr )
338 & miniroute->netmask.s_addr ) == 0 ) {
339 if ( miniroute->gateway.s_addr )
340 *dest = miniroute->gateway;
341 return miniroute;
342 }
343 }
344 }
345
346 return NULL;
347}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
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:665
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 355 of file ipv4.c.

355 {
356 struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
357 struct in_addr dest = sin_dest->sin_addr;
358 struct ipv4_miniroute *miniroute;
359
360 /* Find routing table entry */
361 miniroute = ipv4_route ( sin_dest->sin_scope_id, &dest );
362 if ( ! miniroute )
363 return NULL;
364
365 return miniroute->netdev;
366}
struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition ipv4.c:311
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 376 of file ipv4.c.

378 {
379 struct iphdr *frag_iphdr = fragment->iobuf->data;
380 struct iphdr *iphdr = iobuf->data;
381
382 return ( ( iphdr->src.s_addr == frag_iphdr->src.s_addr ) &&
383 ( iphdr->ident == frag_iphdr->ident ) );
384}
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:113
An IPv4 packet header.
Definition ip.h:43
struct in_addr src
Definition ip.h:52
uint16_t ident
Definition ip.h:47

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

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

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

408 {
409 struct iphdr *iphdr = iobuf->data;
410
411 return ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) );
412}
#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 430 of file ipv4.c.

430 {
431 struct ipv4_pseudo_header pshdr;
432 struct iphdr *iphdr = iobuf->data;
433 size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
434
435 /* Build pseudo-header */
436 pshdr.src = iphdr->src;
437 pshdr.dest = iphdr->dest;
438 pshdr.zero_padding = 0x00;
439 pshdr.protocol = iphdr->protocol;
440 pshdr.len = htons ( iob_len ( iobuf ) - hdrlen );
441
442 /* Update the checksum value */
443 return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
444}
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define IP_MASK_HLEN
Definition ip.h:25
uint8_t protocol
Definition ip.h:50
struct in_addr dest
Definition ip.h:53
uint8_t verhdrlen
Definition ip.h:44
An IPv4 pseudo header.
Definition ip.h:57
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 459 of file ipv4.c.

464 {
465 struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
466 struct sockaddr_in *sin_src = ( ( struct sockaddr_in * ) st_src );
467 struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
468 struct ipv4_miniroute *miniroute;
469 struct in_addr next_hop;
470 struct in_addr hostmask = { .s_addr = INADDR_NONE };
471 uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
472 const void *ll_dest;
473 int rc;
474
475 /* Start profiling */
476 profile_start ( &ipv4_tx_profiler );
477
478 /* Update statistics */
479 ipv4_stats.out_requests++;
480
481 /* Fill up the IP header, except source address */
482 memset ( iphdr, 0, sizeof ( *iphdr ) );
483 iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
485 iphdr->len = htons ( iob_len ( iobuf ) );
486 iphdr->ttl = IP_TTL;
488 iphdr->dest = sin_dest->sin_addr;
489
490 /* Use routing table to identify next hop and transmitting netdev */
491 next_hop = iphdr->dest;
492 if ( sin_src )
493 iphdr->src = sin_src->sin_addr;
494 if ( ( next_hop.s_addr != INADDR_BROADCAST ) &&
495 ( ( miniroute = ipv4_route ( sin_dest->sin_scope_id,
496 &next_hop ) ) != NULL ) ) {
497 iphdr->src = miniroute->address;
498 hostmask = miniroute->hostmask;
499 netdev = miniroute->netdev;
500 }
501 if ( ! netdev ) {
502 DBGC ( sin_dest->sin_addr, "IPv4 has no route to %s\n",
503 inet_ntoa ( iphdr->dest ) );
504 ipv4_stats.out_no_routes++;
505 rc = -ENETUNREACH;
506 goto err;
507 }
508
509 /* (Ab)use the "ident" field to convey metadata about the
510 * network device statistics into packet traces. Useful for
511 * extracting debug information from non-debug builds.
512 */
513 iphdr->ident = htons ( ( (++next_ident_high) << 8 ) |
514 ( ( netdev->rx_stats.bad & 0xf ) << 4 ) |
515 ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
516
517 /* Fix up checksums */
518 if ( trans_csum ) {
519 *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
520 if ( ! *trans_csum )
521 *trans_csum = tcpip_protocol->zero_csum;
522 }
523 iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
524
525 /* Print IP4 header for debugging */
526 DBGC2 ( sin_dest->sin_addr, "IPv4 TX %s->", inet_ntoa ( iphdr->src ) );
527 DBGC2 ( sin_dest->sin_addr, "%s len %d proto %d id %04x csum %04x\n",
528 inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ),
530 ntohs ( iphdr->chksum ) );
531
532 /* Calculate link-layer destination address, if possible */
533 if ( ( ( ~next_hop.s_addr ) & hostmask.s_addr ) == 0 ) {
534 /* Broadcast address */
535 ipv4_stats.out_bcast_pkts++;
536 ll_dest = netdev->ll_broadcast;
537 } else if ( IN_IS_MULTICAST ( next_hop.s_addr ) ) {
538 /* Multicast address */
539 ipv4_stats.out_mcast_pkts++;
540 if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET, &next_hop,
541 ll_dest_buf ) ) !=0){
542 DBGC ( sin_dest->sin_addr, "IPv4 could not hash "
543 "multicast %s: %s\n",
544 inet_ntoa ( next_hop ), strerror ( rc ) );
545 goto err;
546 }
547 ll_dest = ll_dest_buf;
548 } else {
549 /* Unicast address */
550 ll_dest = NULL;
551 }
552
553 /* Update statistics */
554 ipv4_stats.out_transmits++;
555 ipv4_stats.out_octets += iob_len ( iobuf );
556
557 /* Hand off to link layer (via ARP if applicable) */
558 if ( ll_dest ) {
559 if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest,
560 netdev->ll_addr ) ) != 0 ) {
561 DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
562 "packet via %s: %s\n",
563 netdev->name, strerror ( rc ) );
564 return rc;
565 }
566 } else {
567 if ( ( rc = arp_tx ( iobuf, netdev, &ipv4_protocol, &next_hop,
568 &iphdr->src ) ) != 0 ) {
569 DBGC ( sin_dest->sin_addr, "IPv4 could not transmit "
570 "packet via %s: %s\n",
571 netdev->name, strerror ( rc ) );
572 return rc;
573 }
574 }
575
576 profile_stop ( &ipv4_tx_profiler );
577 return 0;
578
579 err:
580 free_iob ( iobuf );
581 return rc;
582}
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:547
#define ENETUNREACH
Network unreachable.
Definition errno.h:532
#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:149
#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:430
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:1078
#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:45
uint16_t len
Definition ip.h:46
uint8_t ttl
Definition ip.h:49
uint16_t chksum
Definition ip.h:51
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 590 of file ipv4.c.

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

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

607 {
608 struct ipv4_miniroute *miniroute;
609
610 list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
611 if ( ( miniroute->netdev == netdev ) &&
612 ( miniroute->address.s_addr == addr.s_addr ) ) {
613 /* Found matching address */
614 return 1;
615 }
616 }
617 return 0;
618}
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 633 of file ipv4.c.

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

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

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

789 {
790 const char *separator = "...";
791 uint8_t *byte = ( ( uint8_t * ) in );
792 char *endp;
793 unsigned long value;
794
795 while ( 1 ) {
796 value = strtoul ( string, &endp, 0 );
797 if ( string == endp )
798 return 0;
799 if ( value > 0xff )
800 return 0;
801 *(byte++) = value;
802 if ( *endp != *separator )
803 return 0;
804 if ( ! *(separator++) )
805 return 1;
806 string = ( endp + 1 );
807 }
808}
__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:516

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

816 {
817 static char buf[16]; /* "xxx.xxx.xxx.xxx" */
818 uint8_t *bytes = ( uint8_t * ) &in;
819
820 sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
821 return buf;
822}
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 cachedhcp_uri(), 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 831 of file ipv4.c.

831 {
832 return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
833}

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

841 {
842 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
843
844 return inet_ntoa ( sin->sin_addr );
845}
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 854 of file ipv4.c.

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

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

914 {
915 struct in_addr ipv4;
916
917 /* Parse IPv4 address */
918 if ( inet_aton ( value, &ipv4 ) == 0 )
919 return -EINVAL;
920
921 /* Copy to buffer */
922 if ( len > sizeof ( ipv4 ) )
923 len = sizeof ( ipv4 );
924 memcpy ( buf, &ipv4, len );
925
926 return ( sizeof ( ipv4 ) );
927}
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 939 of file ipv4.c.

941 {
942 const struct in_addr *ipv4 = raw;
943
944 if ( raw_len < sizeof ( *ipv4 ) )
945 return -EINVAL;
946 return snprintf ( buf, len, "%s", inet_ntoa ( *ipv4 ) );
947}
__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 989 of file ipv4.c.

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

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

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

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

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:393
static int ipv4_more_fragments(struct io_buffer *iobuf, size_t hdrlen __unused)
Check if more fragments exist.
Definition ipv4.c:407
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:376
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31

IPv4 fragment reassembler.

Definition at line 415 of file ipv4.c.

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

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:633
static const char * ipv4_ntoa(const void *net_addr)
Transcribe IPv4 address.
Definition ipv4.c:831
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 866 of file ipv4.c.

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

◆ __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:355
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:459
A network-layer protocol.
Definition netdevice.h:65

IPv4 TCPIP net protocol.

Definition at line 875 of file ipv4.c.

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

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

IPv4 ARP protocol.

Definition at line 885 of file ipv4.c.

885 {
886 .net_protocol = &ipv4_protocol,
887 .check = ipv4_arp_check,
888};

◆ __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:854
static const char * ipv4_sock_ntoa(struct sockaddr *sa)
Transcribe IPv4 socket address.
Definition ipv4.c:841

IPv4 socket address converter.

Definition at line 891 of file ipv4.c.

891 {
892 .family = AF_INET,
893 .ntoa = ipv4_sock_ntoa,
894 .aton = ipv4_sock_aton,
895};

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

IPv4 settings applicator.

Definition at line 1064 of file ipv4.c.

1064 {
1065 .apply = ipv4_apply_routes,
1066};