iPXE
arp.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30#include <byteswap.h>
31#include <errno.h>
32#include <ipxe/if_ether.h>
33#include <ipxe/if_arp.h>
34#include <ipxe/iobuf.h>
35#include <ipxe/netdevice.h>
36#include <ipxe/neighbour.h>
37#include <ipxe/arp.h>
38
39/** @file
40 *
41 * Address Resolution Protocol
42 *
43 * This file implements the address resolution protocol as defined in
44 * RFC826. The implementation is media-independent and
45 * protocol-independent; it is not limited to Ethernet or to IPv4.
46 *
47 */
48
49struct net_protocol arp_protocol __net_protocol;
50
51/**
52 * Transmit ARP request
53 *
54 * @v netdev Network device
55 * @v net_protocol Network-layer protocol
56 * @v net_dest Destination network-layer address
57 * @v net_source Source network-layer address
58 * @ret rc Return status code
59 */
62 const void *net_dest, const void *net_source ) {
63 struct ll_protocol *ll_protocol = netdev->ll_protocol;
64 struct io_buffer *iobuf;
65 struct arphdr *arphdr;
66 int rc;
67
68 /* Allocate ARP packet */
69 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
70 ( 2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) ) );
71 if ( ! iobuf )
72 return -ENOMEM;
74
75 /* Build up ARP request */
76 arphdr = iob_put ( iobuf, sizeof ( *arphdr ) );
83 netdev->ll_addr, ll_protocol->ll_addr_len );
85 net_source, net_protocol->net_addr_len );
89 net_dest, net_protocol->net_addr_len );
90
91 /* Transmit ARP request */
92 if ( ( rc = net_tx ( iobuf, netdev, &arp_protocol,
93 netdev->ll_broadcast, netdev->ll_addr ) ) != 0 ) {
94 DBGC ( netdev, "ARP %s %s %s could not transmit request: %s\n",
95 netdev->name, net_protocol->name,
96 net_protocol->ntoa ( net_dest ), strerror ( rc ) );
97 return rc;
98 }
99
100 return 0;
101}
102
103/** ARP neighbour discovery protocol */
105 .name = "ARP",
106 .tx_request = arp_tx_request,
107};
108
109/**
110 * Identify ARP protocol
111 *
112 * @v net_proto Network-layer protocol, in network-endian order
113 * @ret arp_net_protocol ARP protocol, or NULL
114 *
115 */
116static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) {
118
120 if ( arp_net_protocol->net_protocol->net_proto == net_proto )
121 return arp_net_protocol;
122 }
123 return NULL;
124}
125
126/**
127 * Process incoming ARP packets
128 *
129 * @v iobuf I/O buffer
130 * @v netdev Network device
131 * @v ll_source Link-layer source address
132 * @v flags Packet flags
133 * @ret rc Return status code
134 */
135static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
136 const void *ll_dest __unused,
137 const void *ll_source __unused,
138 unsigned int flags __unused ) {
139 struct arphdr *arphdr = iobuf->data;
142 struct ll_protocol *ll_protocol;
143 size_t len = iob_len ( iobuf );
144 int rc;
145
146 /* Sanity check */
147 if ( ( len < sizeof ( *arphdr ) ) || ( len < arp_len ( arphdr ) ) ) {
148 rc = -EINVAL;
149 goto done;
150 }
151
152 /* Identify network-layer and link-layer protocols */
154 if ( ! arp_net_protocol ) {
156 goto done;
157 }
159 ll_protocol = netdev->ll_protocol;
160
161 /* Sanity checks */
162 if ( ( arphdr->ar_hrd != ll_protocol->ll_proto ) ||
165 rc = -EINVAL;
166 goto done;
167 }
168
169 /* Update neighbour cache entry for this sender, if any */
171 arp_sender_ha ( arphdr ) );
172
173 /* If it's not a request, there's nothing more to do */
174 if ( arphdr->ar_op != htons ( ARPOP_REQUEST ) ) {
175 rc = 0;
176 goto done;
177 }
178
179 /* See if we own the target protocol address */
180 if ( arp_net_protocol->check ( netdev, arp_target_pa ( arphdr ) ) != 0){
181 rc = 0;
182 goto done;
183 }
184
185 /* Change request to a reply */
186 DBGC2 ( netdev, "ARP %s %s %s reply => %s %s\n",
187 netdev->name, net_protocol->name,
189 ll_protocol->name, ll_protocol->ntoa ( netdev->ll_addr ) );
193 memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
194
195 /* Send reply */
196 if ( ( rc = net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
198 netdev->ll_addr ) ) != 0 ) {
199 DBGC ( netdev, "ARP %s %s %s could not transmit reply: %s\n",
200 netdev->name, net_protocol->name,
202 strerror ( rc ) );
203 goto done;
204 }
205
206 /* Success */
207 rc = 0;
208
209 done:
210 free_iob ( iobuf );
211 return rc;
212}
213
214/**
215 * Transcribe ARP address
216 *
217 * @v net_addr ARP address
218 * @ret string "<ARP>"
219 *
220 * This operation is meaningless for the ARP protocol.
221 */
222static const char * arp_ntoa ( const void *net_addr __unused ) {
223 return "<ARP>";
224}
225
226/** ARP network protocol */
227struct net_protocol arp_protocol __net_protocol = {
228 .name = "ARP",
229 .net_proto = htons ( ETH_P_ARP ),
230 .rx = arp_rx,
231 .ntoa = arp_ntoa,
232};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
static const char * arp_ntoa(const void *net_addr __unused)
Transcribe ARP address.
Definition arp.c:222
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
static struct arp_net_protocol * arp_find_protocol(uint16_t net_proto)
Identify ARP protocol.
Definition arp.c:116
struct neighbour_discovery arp_discovery
ARP neighbour discovery protocol.
Definition arp.c:104
static int arp_rx(struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused)
Process incoming ARP packets.
Definition arp.c:135
Address Resolution Protocol.
#define ARP_NET_PROTOCOLS
ARP protocol table.
Definition arp.h:32
struct bofm_section_header done
Definition bofm_test.c:46
ring len
Length.
Definition dwmac.h:226
uint8_t flags
Flags.
Definition ena.h:7
Error codes.
static struct net_device * netdev
Definition gdbudp.c:53
#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 FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EPROTONOSUPPORT
Protocol not supported.
Definition errno.h:630
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
Address Resolution Protocol constants and types.
static void * arp_sender_pa(struct arphdr *arphdr)
ARP packet sender protocol address.
Definition if_arp.h:81
static void * arp_target_ha(struct arphdr *arphdr)
ARP packet target hardware address.
Definition if_arp.h:90
#define ARPOP_REQUEST
ARP request.
Definition if_arp.h:33
static void * arp_target_pa(struct arphdr *arphdr)
ARP packet target protocol address.
Definition if_arp.h:99
#define ARPOP_REPLY
ARP reply.
Definition if_arp.h:34
static size_t arp_len(struct arphdr *arphdr)
ARP packet length.
Definition if_arp.h:108
static void * arp_sender_ha(struct arphdr *arphdr)
ARP packet sender hardware address.
Definition if_arp.h:72
#define ETH_P_ARP
Definition if_ether.h:20
#define htons(value)
Definition byteswap.h:136
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
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
I/O buffers.
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
int neighbour_update(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Update existing neighbour cache entry.
Definition neighbour.c:441
Neighbour discovery.
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 MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition netdevice.h:46
#define MAX_NET_ADDR_LEN
Maximum length of a network-layer address.
Definition netdevice.h:49
#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
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition string.c:154
A network-layer protocol that relies upon ARP.
Definition arp.h:18
struct net_protocol * net_protocol
Network-layer protocol.
Definition arp.h:20
int(* check)(struct net_device *netdev, const void *net_addr)
Check existence of address.
Definition arp.h:27
An ARP header.
Definition if_arp.h:48
uint8_t ar_hln
Link-layer address length.
Definition if_arp.h:60
uint16_t ar_op
ARP opcode.
Definition if_arp.h:64
uint16_t ar_pro
Network-layer protocol.
Definition if_arp.h:58
uint8_t ar_pln
Network-layer address length.
Definition if_arp.h:62
uint16_t ar_hrd
Link-layer protocol.
Definition if_arp.h:53
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A link-layer protocol.
Definition netdevice.h:115
const char * name
Protocol name.
Definition netdevice.h:117
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition netdevice.h:164
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
uint16_t ll_proto
Link-layer protocol.
Definition netdevice.h:195
A neighbour discovery protocol.
Definition neighbour.h:20
A network device.
Definition netdevice.h:353
A network-layer protocol.
Definition netdevice.h:65
const char * name
Protocol name.
Definition netdevice.h:67
uint16_t net_proto
Network-layer protocol.
Definition netdevice.h:100
uint8_t net_addr_len
Network-layer address length.
Definition netdevice.h:102
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition netdevice.h:95
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386