Blame view

net/arp.c 6.06 KB
d280d3f43   Joe Hershberger   net: Move ARP out...
1
2
3
4
5
6
7
8
  /*
   *	Copied from Linux Monitor (LiMon) - Networking.
   *
   *	Copyright 1994 - 2000 Neil Russell.
   *	(See License)
   *	Copyright 2000 Roland Borde
   *	Copyright 2000 Paolo Scaffardi
   *	Copyright 2000-2002 Wolfgang Denk, wd@denx.de
2ea910392   Wolfgang Denk   SPDX License clea...
9
   *	SPDX-License-Identifier:	GPL-2.0
d280d3f43   Joe Hershberger   net: Move ARP out...
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   */
  
  #include <common.h>
  
  #include "arp.h"
  
  #ifndef	CONFIG_ARP_TIMEOUT
  /* Milliseconds before trying ARP again */
  # define ARP_TIMEOUT		5000UL
  #else
  # define ARP_TIMEOUT		CONFIG_ARP_TIMEOUT
  #endif
  
  
  #ifndef	CONFIG_NET_RETRY_COUNT
  # define ARP_TIMEOUT_COUNT	5	/* # of timeouts before giving up  */
  #else
  # define ARP_TIMEOUT_COUNT	CONFIG_NET_RETRY_COUNT
  #endif
049a95a77   Joe Hershberger   net: cosmetic: Ch...
29
30
  struct in_addr net_arp_wait_packet_ip;
  static struct in_addr net_arp_wait_reply_ip;
d280d3f43   Joe Hershberger   net: Move ARP out...
31
  /* MAC address of waiting packet's destination */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
32
33
34
35
  uchar	       *arp_wait_packet_ethaddr;
  int		arp_wait_tx_packet_size;
  ulong		arp_wait_timer_start;
  int		arp_wait_try;
d280d3f43   Joe Hershberger   net: Move ARP out...
36

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
37
38
  static uchar   *arp_tx_packet;	/* THE ARP transmit packet */
  static uchar	arp_tx_packet_buf[PKTSIZE_ALIGN + PKTALIGN];
e94070c44   Joe Hershberger   net: Don't copy e...
39

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
40
  void arp_init(void)
d280d3f43   Joe Hershberger   net: Move ARP out...
41
42
  {
  	/* XXX problem with bss workaround */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
43
  	arp_wait_packet_ethaddr = NULL;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
44
45
  	net_arp_wait_packet_ip.s_addr = 0;
  	net_arp_wait_reply_ip.s_addr = 0;
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
46
47
48
  	arp_wait_tx_packet_size = 0;
  	arp_tx_packet = &arp_tx_packet_buf[0] + (PKTALIGN - 1);
  	arp_tx_packet -= (ulong)arp_tx_packet % PKTALIGN;
d280d3f43   Joe Hershberger   net: Move ARP out...
49
  }
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
50
  void arp_raw_request(struct in_addr source_ip, const uchar *target_ethaddr,
049a95a77   Joe Hershberger   net: cosmetic: Ch...
51
  	struct in_addr target_ip)
d280d3f43   Joe Hershberger   net: Move ARP out...
52
53
  {
  	uchar *pkt;
738853bb6   Joe Hershberger   net: cosmetic: Un...
54
  	struct arp_hdr *arp;
00f33268a   Joe Hershberger   net: Refactor pac...
55
  	int eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
56

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
57
58
  	debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d
  ", arp_wait_try);
d280d3f43   Joe Hershberger   net: Move ARP out...
59

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
60
  	pkt = arp_tx_packet;
d280d3f43   Joe Hershberger   net: Move ARP out...
61

1203fccee   Joe Hershberger   net: cosmetic: Cl...
62
  	eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_ARP);
00f33268a   Joe Hershberger   net: Refactor pac...
63
  	pkt += eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
64

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
65
  	arp = (struct arp_hdr *)pkt;
d280d3f43   Joe Hershberger   net: Move ARP out...
66
67
68
  
  	arp->ar_hrd = htons(ARP_ETHER);
  	arp->ar_pro = htons(PROT_IP);
674bb2498   Joe Hershberger   net: cosmetic: Re...
69
70
  	arp->ar_hln = ARP_HLEN;
  	arp->ar_pln = ARP_PLEN;
d280d3f43   Joe Hershberger   net: Move ARP out...
71
  	arp->ar_op = htons(ARPOP_REQUEST);
0adb5b761   Joe Hershberger   net: cosmetic: Na...
72
  	memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN);	/* source ET addr */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
73
  	net_write_ip(&arp->ar_spa, source_ip);		/* source IP addr */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
74
  	memcpy(&arp->ar_tha, target_ethaddr, ARP_HLEN);	/* target ET addr */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
75
  	net_write_ip(&arp->ar_tpa, target_ip);		/* target IP addr */
228041893   Joe Hershberger   net: Separate Arp...
76

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
77
  	net_send_packet(arp_tx_packet, eth_hdr_size + ARP_HDR_SIZE);
228041893   Joe Hershberger   net: Separate Arp...
78
  }
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
79
  void arp_request(void)
228041893   Joe Hershberger   net: Separate Arp...
80
  {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
81
82
83
  	if ((net_arp_wait_packet_ip.s_addr & net_netmask.s_addr) !=
  	    (net_ip.s_addr & net_netmask.s_addr)) {
  		if (net_gateway.s_addr == 0) {
d280d3f43   Joe Hershberger   net: Move ARP out...
84
85
  			puts("## Warning: gatewayip needed but not set
  ");
049a95a77   Joe Hershberger   net: cosmetic: Ch...
86
  			net_arp_wait_reply_ip = net_arp_wait_packet_ip;
d280d3f43   Joe Hershberger   net: Move ARP out...
87
  		} else {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
88
  			net_arp_wait_reply_ip = net_gateway;
d280d3f43   Joe Hershberger   net: Move ARP out...
89
90
  		}
  	} else {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
91
  		net_arp_wait_reply_ip = net_arp_wait_packet_ip;
d280d3f43   Joe Hershberger   net: Move ARP out...
92
  	}
0adb5b761   Joe Hershberger   net: cosmetic: Na...
93
  	arp_raw_request(net_ip, net_null_ethaddr, net_arp_wait_reply_ip);
d280d3f43   Joe Hershberger   net: Move ARP out...
94
  }
45b47734a   Stefan Brüns   net/arp: account ...
95
  int arp_timeout_check(void)
d280d3f43   Joe Hershberger   net: Move ARP out...
96
97
  {
  	ulong t;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
98
  	if (!net_arp_wait_packet_ip.s_addr)
45b47734a   Stefan Brüns   net/arp: account ...
99
  		return 0;
d280d3f43   Joe Hershberger   net: Move ARP out...
100
101
102
103
  
  	t = get_timer(0);
  
  	/* check for arp timeout */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
104
105
  	if ((t - arp_wait_timer_start) > ARP_TIMEOUT) {
  		arp_wait_try++;
d280d3f43   Joe Hershberger   net: Move ARP out...
106

85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
107
  		if (arp_wait_try >= ARP_TIMEOUT_COUNT) {
d280d3f43   Joe Hershberger   net: Move ARP out...
108
109
110
  			puts("
  ARP Retry count exceeded; starting again
  ");
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
111
  			arp_wait_try = 0;
943231119   Stefan Brüns   net/arp: Do not r...
112
  			net_set_state(NETLOOP_FAIL);
d280d3f43   Joe Hershberger   net: Move ARP out...
113
  		} else {
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
114
115
  			arp_wait_timer_start = t;
  			arp_request();
d280d3f43   Joe Hershberger   net: Move ARP out...
116
117
  		}
  	}
45b47734a   Stefan Brüns   net/arp: account ...
118
  	return 1;
d280d3f43   Joe Hershberger   net: Move ARP out...
119
  }
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
120
  void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
d280d3f43   Joe Hershberger   net: Move ARP out...
121
  {
738853bb6   Joe Hershberger   net: cosmetic: Un...
122
  	struct arp_hdr *arp;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
123
  	struct in_addr reply_ip_addr;
00f33268a   Joe Hershberger   net: Refactor pac...
124
  	int eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
125
126
127
128
129
130
131
132
133
134
  
  	/*
  	 * We have to deal with two types of ARP packets:
  	 * - REQUEST packets will be answered by sending  our
  	 *   IP address - if we know it.
  	 * - REPLY packates are expected only after we asked
  	 *   for the TFTP server's or the gateway's ethernet
  	 *   address; so if we receive such a packet, we set
  	 *   the server ethernet address
  	 */
4ef8d53ca   Joe Hershberger   net: Allow filter...
135
136
  	debug_cond(DEBUG_NET_PKT, "Got ARP
  ");
d280d3f43   Joe Hershberger   net: Move ARP out...
137

738853bb6   Joe Hershberger   net: cosmetic: Un...
138
  	arp = (struct arp_hdr *)ip;
d280d3f43   Joe Hershberger   net: Move ARP out...
139
140
141
142
143
144
145
146
147
  	if (len < ARP_HDR_SIZE) {
  		printf("bad length %d < %d
  ", len, ARP_HDR_SIZE);
  		return;
  	}
  	if (ntohs(arp->ar_hrd) != ARP_ETHER)
  		return;
  	if (ntohs(arp->ar_pro) != PROT_IP)
  		return;
674bb2498   Joe Hershberger   net: cosmetic: Re...
148
  	if (arp->ar_hln != ARP_HLEN)
d280d3f43   Joe Hershberger   net: Move ARP out...
149
  		return;
674bb2498   Joe Hershberger   net: cosmetic: Re...
150
  	if (arp->ar_pln != ARP_PLEN)
d280d3f43   Joe Hershberger   net: Move ARP out...
151
  		return;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
152
  	if (net_ip.s_addr == 0)
d280d3f43   Joe Hershberger   net: Move ARP out...
153
  		return;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
154
  	if (net_read_ip(&arp->ar_tpa).s_addr != net_ip.s_addr)
d280d3f43   Joe Hershberger   net: Move ARP out...
155
156
157
158
159
  		return;
  
  	switch (ntohs(arp->ar_op)) {
  	case ARPOP_REQUEST:
  		/* reply with our IP address */
4ef8d53ca   Joe Hershberger   net: Allow filter...
160
161
  		debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP
  ");
e71110158   Joe Hershberger   net: Add net_upda...
162
  		eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP);
d280d3f43   Joe Hershberger   net: Move ARP out...
163
  		arp->ar_op = htons(ARPOP_REPLY);
674bb2498   Joe Hershberger   net: cosmetic: Re...
164
  		memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN);
049a95a77   Joe Hershberger   net: cosmetic: Ch...
165
  		net_copy_ip(&arp->ar_tpa, &arp->ar_spa);
0adb5b761   Joe Hershberger   net: cosmetic: Na...
166
  		memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN);
049a95a77   Joe Hershberger   net: cosmetic: Ch...
167
  		net_copy_ip(&arp->ar_spa, &net_ip);
c69757626   Joe Hershberger   net: Work-around ...
168
169
170
171
172
173
174
175
176
177
  
  #ifdef CONFIG_CMD_LINK_LOCAL
  		/*
  		 * Work-around for brain-damaged Cisco equipment with
  		 *   arp-proxy enabled.
  		 *
  		 *   If the requesting IP is not on our subnet, wait 5ms to
  		 *   reply to ARP request so that our reply will overwrite
  		 *   the arp-proxy's instead of the other way around.
  		 */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
178
179
  		if ((net_read_ip(&arp->ar_tpa).s_addr & net_netmask.s_addr) !=
  		    (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr))
c69757626   Joe Hershberger   net: Work-around ...
180
181
  			udelay(5000);
  #endif
1203fccee   Joe Hershberger   net: cosmetic: Cl...
182
  		net_send_packet((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
d280d3f43   Joe Hershberger   net: Move ARP out...
183
184
185
186
  		return;
  
  	case ARPOP_REPLY:		/* arp reply */
  		/* are we waiting for a reply */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
187
  		if (!net_arp_wait_packet_ip.s_addr)
d280d3f43   Joe Hershberger   net: Move ARP out...
188
189
190
  			break;
  
  #ifdef CONFIG_KEEP_SERVERADDR
049a95a77   Joe Hershberger   net: cosmetic: Ch...
191
  		if (net_server_ip.s_addr == net_arp_wait_packet_ip.s_addr) {
d280d3f43   Joe Hershberger   net: Move ARP out...
192
  			char buf[20];
a0bc44e68   Mike Frysinger   net: fix typo in ...
193
  			sprintf(buf, "%pM", &arp->ar_sha);
382bee57f   Simon Glass   env: Rename seten...
194
  			env_set("serveraddr", buf);
d280d3f43   Joe Hershberger   net: Move ARP out...
195
196
  		}
  #endif
049a95a77   Joe Hershberger   net: cosmetic: Ch...
197
  		reply_ip_addr = net_read_ip(&arp->ar_spa);
d280d3f43   Joe Hershberger   net: Move ARP out...
198
199
  
  		/* matched waiting packet's address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
200
  		if (reply_ip_addr.s_addr == net_arp_wait_reply_ip.s_addr) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
201
  			debug_cond(DEBUG_DEV_PKT,
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
202
203
204
  				   "Got ARP REPLY, set eth addr (%pM)
  ",
  				   arp->ar_data);
d280d3f43   Joe Hershberger   net: Move ARP out...
205
206
  
  			/* save address for later use */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
207
208
  			if (arp_wait_packet_ethaddr != NULL)
  				memcpy(arp_wait_packet_ethaddr,
f1d2d2846   Joe Hershberger   net: Remove stati...
209
  				       &arp->ar_sha, ARP_HLEN);
d280d3f43   Joe Hershberger   net: Move ARP out...
210

ece223b52   Joe Hershberger   net: Refactor to ...
211
  			net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr,
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
212
  					      0, len);
ece223b52   Joe Hershberger   net: Refactor to ...
213

e94070c44   Joe Hershberger   net: Don't copy e...
214
215
  			/* set the mac address in the waiting packet's header
  			   and transmit it */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
216
217
  			memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest,
  			       &arp->ar_sha, ARP_HLEN);
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
218
  			net_send_packet(net_tx_packet, arp_wait_tx_packet_size);
d280d3f43   Joe Hershberger   net: Move ARP out...
219
220
  
  			/* no arp request pending now */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
221
  			net_arp_wait_packet_ip.s_addr = 0;
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
222
223
  			arp_wait_tx_packet_size = 0;
  			arp_wait_packet_ethaddr = NULL;
d280d3f43   Joe Hershberger   net: Move ARP out...
224
225
226
227
228
229
230
231
232
  		}
  		return;
  	default:
  		debug("Unexpected ARP opcode 0x%x
  ",
  		      ntohs(arp->ar_op));
  		return;
  	}
  }