iPXE
ipv4.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 * Copyright (C) 2006 Nikhil Chandru Rao
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 *
20 * You can also choose to distribute this program under the terms of
21 * the Unmodified Binary Distribution Licence (as given in the file
22 * COPYING.UBDL), provided that you have satisfied its requirements.
23 */
24
25#include <string.h>
26#include <stdint.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <errno.h>
30#include <byteswap.h>
31#include <ipxe/list.h>
32#include <ipxe/in.h>
33#include <ipxe/arp.h>
34#include <ipxe/if_ether.h>
35#include <ipxe/iobuf.h>
36#include <ipxe/netdevice.h>
37#include <ipxe/ip.h>
38#include <ipxe/tcpip.h>
39#include <ipxe/dhcp.h>
40#include <ipxe/settings.h>
41#include <ipxe/fragment.h>
42#include <ipxe/ipstat.h>
43#include <ipxe/profile.h>
44
45/** @file
46 *
47 * IPv4 protocol
48 *
49 */
50
51FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
52FILE_SECBOOT ( PERMITTED );
53
54/* Unique IP datagram identification number (high byte) */
56
57/** List of IPv4 miniroutes */
59
60/** IPv4 statistics */
62
63/** IPv4 statistics family */
66 .version = 4,
67 .stats = &ipv4_stats,
68};
69
70/** Transmit profiler */
71static struct profiler ipv4_tx_profiler __profiler = { .name = "ipv4.tx" };
72
73/** Receive profiler */
74static struct profiler ipv4_rx_profiler __profiler = { .name = "ipv4.rx" };
75
76/**
77 * Add IPv4 minirouting table entry
78 *
79 * @v netdev Network device
80 * @v address IPv4 address
81 * @v network Subnet address
82 * @v netmask Subnet mask
83 * @v gateway Gateway address (if any)
84 * @ret rc Return status code
85 */
87 struct in_addr address,
88 struct in_addr network,
89 struct in_addr netmask,
90 struct in_addr gateway ) {
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}
137
138/**
139 * Add static route minirouting table entries
140 *
141 * @v netdev Network device
142 * @v address IPv4 address
143 * @v routes Static routes
144 * @v len Length of static routes
145 * @ret rc Return status code
146 */
147static int ipv4_add_static ( struct net_device *netdev, struct in_addr address,
148 const void *routes, size_t len ) {
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}
204
205/**
206 * Add IPv4 minirouting table entries
207 *
208 * @v netdev Network device
209 * @v address IPv4 address
210 * @ret rc Return status code
211 */
213 struct in_addr address ) {
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}
265
266/**
267 * Delete IPv4 minirouting table entry
268 *
269 * @v miniroute Routing table entry
270 */
271static void ipv4_del_miniroute ( struct ipv4_miniroute *miniroute ) {
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}
285
286/**
287 * Delete IPv4 minirouting table entries
288 *
289 */
290static void ipv4_del_miniroutes ( void ) {
291 struct ipv4_miniroute *miniroute;
292 struct ipv4_miniroute *tmp;
293
294 /* Delete all existing routes */
296 ipv4_del_miniroute ( miniroute );
297}
298
299/**
300 * Perform IPv4 routing
301 *
302 * @v scope_id Destination address scope ID
303 * @v dest Final destination address
304 * @ret dest Next hop destination address
305 * @ret miniroute Routing table entry to use, or NULL if no route
306 *
307 * If the route requires use of a gateway, the next hop destination
308 * address will be overwritten with the gateway address.
309 */
310struct ipv4_miniroute * ipv4_route ( unsigned int scope_id,
311 struct in_addr *dest ) {
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}
347
348/**
349 * Determine transmitting network device
350 *
351 * @v st_dest Destination network-layer address
352 * @ret netdev Transmitting network device, or NULL
353 */
354static struct net_device * ipv4_netdev ( struct sockaddr_tcpip *st_dest ) {
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}
366
367/**
368 * Check if IPv4 fragment matches fragment reassembly buffer
369 *
370 * @v fragment Fragment reassembly buffer
371 * @v iobuf I/O buffer
372 * @v hdrlen Length of non-fragmentable potion of I/O buffer
373 * @ret is_fragment Fragment matches this reassembly buffer
374 */
375static int ipv4_is_fragment ( struct fragment *fragment,
376 struct io_buffer *iobuf,
377 size_t hdrlen __unused ) {
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}
384
385/**
386 * Get IPv4 fragment offset
387 *
388 * @v iobuf I/O buffer
389 * @v hdrlen Length of non-fragmentable potion of I/O buffer
390 * @ret offset Offset
391 */
392static size_t ipv4_fragment_offset ( struct io_buffer *iobuf,
393 size_t hdrlen __unused ) {
394 struct iphdr *iphdr = iobuf->data;
395
396 return ( ( ntohs ( iphdr->frags ) & IP_MASK_OFFSET ) << 3 );
397}
398
399/**
400 * Check if more fragments exist
401 *
402 * @v iobuf I/O buffer
403 * @v hdrlen Length of non-fragmentable potion of I/O buffer
404 * @ret more_frags More fragments exist
405 */
406static int ipv4_more_fragments ( struct io_buffer *iobuf,
407 size_t hdrlen __unused ) {
408 struct iphdr *iphdr = iobuf->data;
409
410 return ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) );
411}
412
413/** IPv4 fragment reassembler */
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};
421
422/**
423 * Add IPv4 pseudo-header checksum to existing checksum
424 *
425 * @v iobuf I/O buffer
426 * @v csum Existing checksum
427 * @ret csum Updated checksum
428 */
429static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) {
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}
444
445/**
446 * Transmit IP packet
447 *
448 * @v iobuf I/O buffer
449 * @v tcpip Transport-layer protocol
450 * @v st_src Source network-layer address
451 * @v st_dest Destination network-layer address
452 * @v netdev Network device to use if no route found, or NULL
453 * @v trans_csum Transport-layer checksum to complete, or NULL
454 * @ret rc Status
455 *
456 * This function expects a transport-layer segment and prepends the IP header
457 */
458static int ipv4_tx ( struct io_buffer *iobuf,
460 struct sockaddr_tcpip *st_src,
461 struct sockaddr_tcpip *st_dest,
462 struct net_device *netdev,
463 uint16_t *trans_csum ) {
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}
582
583/**
584 * Check if network device has any IPv4 address
585 *
586 * @v netdev Network device
587 * @ret has_any_addr Network device has any IPv4 address
588 */
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}
598
599/**
600 * Check if network device has a specific IPv4 address
601 *
602 * @v netdev Network device
603 * @v addr IPv4 address
604 * @ret has_addr Network device has this IPv4 address
605 */
606static int ipv4_has_addr ( struct net_device *netdev, struct in_addr addr ) {
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}
618
619/**
620 * Process incoming packets
621 *
622 * @v iobuf I/O buffer
623 * @v netdev Network device
624 * @v ll_dest Link-layer destination address
625 * @v ll_source Link-layer destination source
626 * @v flags Packet flags
627 * @ret rc Return status code
628 *
629 * This function expects an IP4 network datagram. It processes the headers
630 * and sends it to the transport layer.
631 */
632static int ipv4_rx ( struct io_buffer *iobuf,
633 struct net_device *netdev,
634 const void *ll_dest __unused,
635 const void *ll_source __unused,
636 unsigned int flags ) {
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}
759
760/**
761 * Check existence of IPv4 address for ARP
762 *
763 * @v netdev Network device
764 * @v net_addr Network-layer address
765 * @ret rc Return status code
766 */
767static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
768 const struct in_addr *address = net_addr;
769
770 if ( ipv4_has_addr ( netdev, *address ) )
771 return 0;
772
773 return -ENOENT;
774}
775
776/**
777 * Parse IPv4 address
778 *
779 * @v string IPv4 address string
780 * @ret in IPv4 address to fill in
781 * @ret ok IPv4 address is valid
782 *
783 * Note that this function returns nonzero iff the address is valid,
784 * to match the standard BSD API function of the same name. Unlike
785 * most other iPXE functions, a zero therefore indicates failure.
786 */
787int inet_aton ( const char *string, struct in_addr *in ) {
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}
807
808/**
809 * Convert IPv4 address to dotted-quad notation
810 *
811 * @v in IPv4 address
812 * @ret string IPv4 address in dotted-quad notation
813 */
814char * inet_ntoa ( struct in_addr in ) {
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}
821
822/**
823 * Transcribe IPv4 address
824 *
825 * @v net_addr IPv4 address
826 * @ret string IPv4 address in dotted-quad notation
827 *
828 */
829static const char * ipv4_ntoa ( const void *net_addr ) {
830 return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
831}
832
833/**
834 * Transcribe IPv4 socket address
835 *
836 * @v sa Socket address
837 * @ret string Socket address in standard notation
838 */
839static const char * ipv4_sock_ntoa ( struct sockaddr *sa ) {
840 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) sa );
841
842 return inet_ntoa ( sin->sin_addr );
843}
844
845/**
846 * Parse IPv4 socket address
847 *
848 * @v string Socket address string
849 * @v sa Socket address to fill in
850 * @ret rc Return status code
851 */
852static int ipv4_sock_aton ( const char *string, struct sockaddr *sa ) {
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}
862
863/** IPv4 protocol */
864struct net_protocol ipv4_protocol __net_protocol = {
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};
871
872/** IPv4 TCPIP net protocol */
873struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = {
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};
881
882/** IPv4 ARP protocol */
883struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol = {
884 .net_protocol = &ipv4_protocol,
885 .check = ipv4_arp_check,
886};
887
888/** IPv4 socket address converter */
889struct sockaddr_converter ipv4_sockaddr_converter __sockaddr_converter = {
890 .family = AF_INET,
891 .ntoa = ipv4_sock_ntoa,
892 .aton = ipv4_sock_aton,
893};
894
895/******************************************************************************
896 *
897 * Settings
898 *
899 ******************************************************************************
900 */
901
902/**
903 * Parse IPv4 address setting value
904 *
905 * @v type Setting type
906 * @v value Formatted setting value
907 * @v buf Buffer to contain raw value
908 * @v len Length of buffer
909 * @ret len Length of raw value, or negative error
910 */
912 const char *value, void *buf, size_t len ) {
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}
926
927/**
928 * Format IPv4 address setting value
929 *
930 * @v type Setting type
931 * @v raw Raw setting value
932 * @v raw_len Length of raw setting value
933 * @v buf Buffer to contain formatted value
934 * @v len Length of buffer
935 * @ret len Length of formatted value, or negative error
936 */
938 const void *raw, size_t raw_len, char *buf,
939 size_t len ) {
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}
946
947/** IPv4 address setting */
949 .name = "ip",
950 .description = "IP address",
951 .tag = DHCP_EB_YIADDR,
952 .type = &setting_type_ipv4,
953};
954
955/** IPv4 subnet mask setting */
956const struct setting netmask_setting __setting ( SETTING_IP4, netmask ) = {
957 .name = "netmask",
958 .description = "Subnet mask",
959 .tag = DHCP_SUBNET_MASK,
960 .type = &setting_type_ipv4,
961};
962
963/** Default gateway setting */
964const struct setting gateway_setting __setting ( SETTING_IP4, gateway ) = {
965 .name = "gateway",
966 .description = "Default gateway",
967 .tag = DHCP_ROUTERS,
968 .type = &setting_type_ipv4,
969};
970
971/** Classless static routes setting */
972const struct setting static_route_setting __setting ( SETTING_IP4,
973 static_routes ) = {
974 .name = "static-routes",
975 .description = "Static routes",
976 .tag = DHCP_STATIC_ROUTES,
977 .type = &setting_type_hex,
978};
979
980/**
981 * Send gratuitous ARP, if applicable
982 *
983 * @v netdev Network device
984 * @v address IPv4 address
985 * @ret rc Return status code
986 */
988 struct in_addr address ) {
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}
1007
1008/**
1009 * Process IPv4 network device settings
1010 *
1011 * @v apply Application method
1012 * @ret rc Return status code
1013 */
1014static int ipv4_settings ( int ( * apply ) ( struct net_device *netdev,
1015 struct in_addr address ) ) {
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}
1039
1040/**
1041 * Create IPv4 routing table based on configured settings
1042 *
1043 * @ret rc Return status code
1044 */
1045static int ipv4_apply_routes ( void ) {
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}
1060
1061/** IPv4 settings applicator */
1062struct settings_applicator ipv4_settings_applicator __settings_applicator = {
1063 .apply = ipv4_apply_routes,
1064};
1065
1066/* Drag in objects via ipv4_protocol */
1067REQUIRING_SYMBOL ( ipv4_protocol );
1068
1069/* Drag in ICMPv4 */
@ none
Definition 3c5x9.c:35
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
__be32 raw[7]
Definition CIB_PRM.h:0
__be32 in[4]
Definition CIB_PRM.h:7
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned short uint16_t
Definition stdint.h:11
unsigned char uint8_t
Definition stdint.h:10
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
static const void * src
Definition string.h:48
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
Address Resolution Protocol.
#define __arp_net_protocol
Declare an ARP protocol.
Definition arp.h:36
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
static size_t raw_len
Definition base16.h:54
struct bofm_section_header done
Definition bofm_test.c:46
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
const struct setting ip_setting
const struct setting netmask_setting
const struct setting gateway_setting
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
uint64_t address
Base address.
Definition ena.h:13
Error codes.
struct io_buffer * fragment_reassemble(struct fragment_reassembler *fragments, struct io_buffer *iobuf, size_t *hdrlen)
Reassemble packet.
Definition fragment.c:89
Fragment reassembly.
static struct net_device * netdev
Definition gdbudp.c:53
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define DHCP_STATIC_ROUTES
Classless static routes.
Definition dhcp.h:349
#define DHCP_SUBNET_MASK
Subnet mask.
Definition dhcp.h:66
#define DHCP_EB_YIADDR
"Your" IP address
Definition dhcp.h:374
#define DHCP_ROUTERS
Routers.
Definition dhcp.h:69
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENETUNREACH
Network unreachable.
Definition errno.h:489
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_IP4
IPv4 settings.
Definition settings.h:66
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
uint8_t bytes[64]
Definition ib_mad.h:5
#define ETH_P_IP
Definition if_ether.h:19
#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 INADDR_NONE
Definition in.h:20
#define INADDR_BROADCAST
Definition in.h:22
#define IN_IS_SMALL(mask)
Definition in.h:37
#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
#define IN_IS_MULTICAST(addr)
Definition in.h:34
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
#define __attribute__(x)
Definition compiler.h:10
Dynamic Host Configuration Protocol.
Profiling.
#define __profiler
Declare a profiler.
Definition profile.h:61
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
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
Transport-network layer interface.
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition tcpip.h:58
#define __tcpip_net_protocol
Declare a TCP/IP network-layer protocol.
Definition tcpip.h:189
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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
I/O buffers.
#define iob_push(iobuf, len)
Definition iobuf.h:89
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define iob_unput(iobuf, len)
Definition iobuf.h:140
IP protocol.
#define IP_MASK_MOREFRAGS
Definition ip.h:28
#define IP_TTL
Definition ip.h:33
#define IP_MASK_HLEN
Definition ip.h:25
#define IP_TOS
Definition ip.h:32
#define IP_MASK_VER
Definition ip.h:24
#define IP_MASK_OFFSET
Definition ip.h:26
#define IP_VER
Definition ip.h:23
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition ipv4.c:589
static size_t ipv4_fragment_offset(struct io_buffer *iobuf, size_t hdrlen __unused)
Get IPv4 fragment offset.
Definition ipv4.c:392
int parse_ipv4_setting(const struct setting_type *type __unused, const char *value, void *buf, size_t len)
Parse IPv4 address setting value.
Definition ipv4.c:911
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 int ipv4_arp_check(struct net_device *netdev, const void *net_addr)
Check existence of IPv4 address for ARP.
Definition ipv4.c:767
static uint8_t next_ident_high
Definition ipv4.c:55
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.
Definition ipv4.c:937
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 fragment_reassembler ipv4_reassembler
IPv4 fragment reassembler.
Definition ipv4.c:414
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
static int ipv4_settings(int(*apply)(struct net_device *netdev, struct in_addr address))
Process IPv4 network device settings.
Definition ipv4.c:1014
static const char * ipv4_ntoa(const void *net_addr)
Transcribe IPv4 address.
Definition ipv4.c:829
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
static int ipv4_sock_aton(const char *string, struct sockaddr *sa)
Parse IPv4 socket address.
Definition ipv4.c:852
static int ipv4_gratuitous_arp(struct net_device *netdev, struct in_addr address)
Send gratuitous ARP, if applicable.
Definition ipv4.c:987
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
struct ipv4_miniroute * ipv4_route(unsigned int scope_id, struct in_addr *dest)
Perform IPv4 routing.
Definition ipv4.c:310
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
static void ipv4_del_miniroute(struct ipv4_miniroute *miniroute)
Delete IPv4 minirouting table entry.
Definition ipv4.c:271
struct list_head ipv4_miniroutes
List of IPv4 miniroutes.
Definition ipv4.c:58
static struct net_device * ipv4_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition ipv4.c:354
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
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
Definition ipv4.c:787
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
static void ipv4_del_miniroutes(void)
Delete IPv4 minirouting table entries.
Definition ipv4.c:290
static int ipv4_apply_routes(void)
Create IPv4 routing table based on configured settings.
Definition ipv4.c:1045
static struct ip_statistics ipv4_stats
IPv4 statistics.
Definition ipv4.c:61
static int ipv4_add_miniroutes(struct net_device *netdev, struct in_addr address)
Add IPv4 minirouting table entries.
Definition ipv4.c:212
static const char * ipv4_sock_ntoa(struct sockaddr *sa)
Transcribe IPv4 socket address.
Definition ipv4.c:839
IP statistics.
#define IP_STATISTICS_IPV4
Definition ipstat.h:185
#define __ip_statistics_family(order)
Declare an IP system statistics family.
Definition ipstat.h:182
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#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
#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
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
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
Network device management.
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:547
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
#define LL_MULTICAST
Packet is a multicast (including broadcast) packet.
Definition netdevice.h:106
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
#define LL_BROADCAST
Packet is a broadcast packet.
Definition netdevice.h:109
#define __net_protocol
Declare a network-layer protocol.
Definition netdevice.h:474
#define MAX_LL_ADDR_LEN
Maximum length of a link-layer address.
Definition netdevice.h:37
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
IP4_t ip
Destination IP address.
Definition pxe_api.h:1
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
#define __sockaddr_converter
Declare a socket address converter.
Definition socket.h:142
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485
A network-layer protocol that relies upon ARP.
Definition arp.h:18
A fragment reassembler.
Definition fragment.h:36
A fragment reassembly buffer.
Definition fragment.h:22
struct io_buffer * iobuf
Reassembled packet.
Definition fragment.h:26
IP address structure.
Definition in.h:42
uint32_t s_addr
Definition in.h:43
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
An IP system statistics family.
Definition ipstat.h:170
IP system statistics.
Definition ipstat.h:45
An IPv4 packet header.
Definition ip.h:36
uint8_t service
Definition ip.h:38
uint8_t protocol
Definition ip.h:43
struct in_addr dest
Definition ip.h:46
uint16_t len
Definition ip.h:39
struct in_addr src
Definition ip.h:45
uint8_t ttl
Definition ip.h:42
uint8_t verhdrlen
Definition ip.h:37
uint16_t chksum
Definition ip.h:44
uint16_t frags
Definition ip.h:41
uint16_t ident
Definition ip.h:40
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
An IPv4 pseudo header.
Definition ip.h:50
uint8_t zero_padding
Definition ip.h:53
uint16_t len
Definition ip.h:55
struct in_addr src
Definition ip.h:51
struct in_addr dest
Definition ip.h:52
uint8_t protocol
Definition ip.h:54
A doubly-linked list entry (or list head)
Definition list.h:19
A network device.
Definition netdevice.h:353
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363
unsigned int scope_id
Scope ID.
Definition netdevice.h:361
A network-layer protocol.
Definition netdevice.h:65
A data structure for storing profiling information.
Definition profile.h:27
A setting type.
Definition settings.h:192
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
A settings block.
Definition settings.h:133
Socket address converter.
Definition socket.h:116
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
TCP/IP socket address.
Definition tcpip.h:76
Generalized socket address structure.
Definition socket.h:97
A network-layer protocol of the TCP/IP stack (eg.
Definition tcpip.h:141
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
struct sockaddr_tcpip st
Definition syslog.c:58
struct sockaddr sa
Definition syslog.c:57
struct sockaddr_in sin
Definition syslog.c:59
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition tcpip.c:204
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
int32_t before
Initial microcode version.
Definition ucode.h:5
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition x86_tcpip.c:46