Blame view

net/arp.c 5.77 KB
d280d3f43   Joe Hershberger   net: Move ARP out...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  /*
   *	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
   */
  
  #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
  
  IPaddr_t	NetArpWaitPacketIP;
063705908   Kim Phillips   net/: sparse fixes
30
  static IPaddr_t	NetArpWaitReplyIP;
d280d3f43   Joe Hershberger   net: Move ARP out...
31
32
  /* MAC address of waiting packet's destination */
  uchar	       *NetArpWaitPacketMAC;
d280d3f43   Joe Hershberger   net: Move ARP out...
33
  int		NetArpWaitTxPacketSize;
d280d3f43   Joe Hershberger   net: Move ARP out...
34
35
  ulong		NetArpWaitTimerStart;
  int		NetArpWaitTry;
063705908   Kim Phillips   net/: sparse fixes
36
37
  static uchar   *NetArpTxPacket;	/* THE ARP transmit packet */
  static uchar	NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
e94070c44   Joe Hershberger   net: Don't copy e...
38

d280d3f43   Joe Hershberger   net: Move ARP out...
39
40
41
42
43
44
  void ArpInit(void)
  {
  	/* XXX problem with bss workaround */
  	NetArpWaitPacketMAC = NULL;
  	NetArpWaitPacketIP = 0;
  	NetArpWaitReplyIP = 0;
d280d3f43   Joe Hershberger   net: Move ARP out...
45
  	NetArpWaitTxPacketSize = 0;
e94070c44   Joe Hershberger   net: Don't copy e...
46
47
  	NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1);
  	NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN;
d280d3f43   Joe Hershberger   net: Move ARP out...
48
  }
228041893   Joe Hershberger   net: Separate Arp...
49
50
  void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
  	IPaddr_t targetIP)
d280d3f43   Joe Hershberger   net: Move ARP out...
51
52
  {
  	uchar *pkt;
738853bb6   Joe Hershberger   net: cosmetic: Un...
53
  	struct arp_hdr *arp;
00f33268a   Joe Hershberger   net: Refactor pac...
54
  	int eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
55

4ef8d53ca   Joe Hershberger   net: Allow filter...
56
57
  	debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d
  ", NetArpWaitTry);
d280d3f43   Joe Hershberger   net: Move ARP out...
58

e94070c44   Joe Hershberger   net: Don't copy e...
59
  	pkt = NetArpTxPacket;
d280d3f43   Joe Hershberger   net: Move ARP out...
60

00f33268a   Joe Hershberger   net: Refactor pac...
61
62
  	eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP);
  	pkt += eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
63

738853bb6   Joe Hershberger   net: cosmetic: Un...
64
  	arp = (struct arp_hdr *) pkt;
d280d3f43   Joe Hershberger   net: Move ARP out...
65
66
67
  
  	arp->ar_hrd = htons(ARP_ETHER);
  	arp->ar_pro = htons(PROT_IP);
674bb2498   Joe Hershberger   net: cosmetic: Re...
68
69
  	arp->ar_hln = ARP_HLEN;
  	arp->ar_pln = ARP_PLEN;
d280d3f43   Joe Hershberger   net: Move ARP out...
70
  	arp->ar_op = htons(ARPOP_REQUEST);
228041893   Joe Hershberger   net: Separate Arp...
71
72
73
74
75
76
77
78
79
80
  	memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);	/* source ET addr */
  	NetWriteIP(&arp->ar_spa, sourceIP);		/* source IP addr */
  	memcpy(&arp->ar_tha, targetEther, ARP_HLEN);	/* target ET addr */
  	NetWriteIP(&arp->ar_tpa, targetIP);		/* target IP addr */
  
  	NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE);
  }
  
  void ArpRequest(void)
  {
d280d3f43   Joe Hershberger   net: Move ARP out...
81
82
83
84
85
86
87
88
89
90
91
92
  	if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
  	    (NetOurIP & NetOurSubnetMask)) {
  		if (NetOurGatewayIP == 0) {
  			puts("## Warning: gatewayip needed but not set
  ");
  			NetArpWaitReplyIP = NetArpWaitPacketIP;
  		} else {
  			NetArpWaitReplyIP = NetOurGatewayIP;
  		}
  	} else {
  		NetArpWaitReplyIP = NetArpWaitPacketIP;
  	}
228041893   Joe Hershberger   net: Separate Arp...
93
  	arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP);
d280d3f43   Joe Hershberger   net: Move ARP out...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  }
  
  void ArpTimeoutCheck(void)
  {
  	ulong t;
  
  	if (!NetArpWaitPacketIP)
  		return;
  
  	t = get_timer(0);
  
  	/* check for arp timeout */
  	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
  		NetArpWaitTry++;
  
  		if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
  			puts("
  ARP Retry count exceeded; starting again
  ");
  			NetArpWaitTry = 0;
  			NetStartAgain();
  		} else {
  			NetArpWaitTimerStart = t;
  			ArpRequest();
  		}
  	}
  }
cb487f566   Joe Hershberger   net: cosmetic: Un...
121
  void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
d280d3f43   Joe Hershberger   net: Move ARP out...
122
  {
738853bb6   Joe Hershberger   net: cosmetic: Un...
123
  	struct arp_hdr *arp;
1256793b1   Joe Hershberger   net: cosmetic: Re...
124
  	IPaddr_t reply_ip_addr;
d280d3f43   Joe Hershberger   net: Move ARP out...
125
  	uchar *pkt;
00f33268a   Joe Hershberger   net: Refactor pac...
126
  	int eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
127
128
129
130
131
132
133
134
135
136
  
  	/*
  	 * 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...
137
138
  	debug_cond(DEBUG_NET_PKT, "Got ARP
  ");
d280d3f43   Joe Hershberger   net: Move ARP out...
139

738853bb6   Joe Hershberger   net: cosmetic: Un...
140
  	arp = (struct arp_hdr *)ip;
d280d3f43   Joe Hershberger   net: Move ARP out...
141
142
143
144
145
146
147
148
149
  	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...
150
  	if (arp->ar_hln != ARP_HLEN)
d280d3f43   Joe Hershberger   net: Move ARP out...
151
  		return;
674bb2498   Joe Hershberger   net: cosmetic: Re...
152
  	if (arp->ar_pln != ARP_PLEN)
d280d3f43   Joe Hershberger   net: Move ARP out...
153
154
155
156
  		return;
  
  	if (NetOurIP == 0)
  		return;
674bb2498   Joe Hershberger   net: cosmetic: Re...
157
  	if (NetReadIP(&arp->ar_tpa) != NetOurIP)
d280d3f43   Joe Hershberger   net: Move ARP out...
158
159
160
161
162
  		return;
  
  	switch (ntohs(arp->ar_op)) {
  	case ARPOP_REQUEST:
  		/* reply with our IP address */
4ef8d53ca   Joe Hershberger   net: Allow filter...
163
164
  		debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP
  ");
d280d3f43   Joe Hershberger   net: Move ARP out...
165
  		pkt = (uchar *)et;
e71110158   Joe Hershberger   net: Add net_upda...
166
  		eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP);
00f33268a   Joe Hershberger   net: Refactor pac...
167
  		pkt += eth_hdr_size;
d280d3f43   Joe Hershberger   net: Move ARP out...
168
  		arp->ar_op = htons(ARPOP_REPLY);
674bb2498   Joe Hershberger   net: cosmetic: Re...
169
170
171
172
  		memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN);
  		NetCopyIP(&arp->ar_tpa, &arp->ar_spa);
  		memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);
  		NetCopyIP(&arp->ar_spa, &NetOurIP);
c69757626   Joe Hershberger   net: Work-around ...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  
  #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.
  		 */
  		if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) !=
  		    (NetReadIP(&arp->ar_spa) & NetOurSubnetMask))
  			udelay(5000);
  #endif
adf5d93e4   Joe Hershberger   net: Refactor to ...
187
  		NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
d280d3f43   Joe Hershberger   net: Move ARP out...
188
189
190
191
  		return;
  
  	case ARPOP_REPLY:		/* arp reply */
  		/* are we waiting for a reply */
f1d2d2846   Joe Hershberger   net: Remove stati...
192
  		if (!NetArpWaitPacketIP)
d280d3f43   Joe Hershberger   net: Move ARP out...
193
194
195
196
197
  			break;
  
  #ifdef CONFIG_KEEP_SERVERADDR
  		if (NetServerIP == NetArpWaitPacketIP) {
  			char buf[20];
a0bc44e68   Mike Frysinger   net: fix typo in ...
198
  			sprintf(buf, "%pM", &arp->ar_sha);
d280d3f43   Joe Hershberger   net: Move ARP out...
199
200
201
  			setenv("serveraddr", buf);
  		}
  #endif
674bb2498   Joe Hershberger   net: cosmetic: Re...
202
  		reply_ip_addr = NetReadIP(&arp->ar_spa);
d280d3f43   Joe Hershberger   net: Move ARP out...
203
204
  
  		/* matched waiting packet's address */
1256793b1   Joe Hershberger   net: cosmetic: Re...
205
  		if (reply_ip_addr == NetArpWaitReplyIP) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
206
207
208
  			debug_cond(DEBUG_DEV_PKT,
  				"Got ARP REPLY, set eth addr (%pM)
  ",
d280d3f43   Joe Hershberger   net: Move ARP out...
209
210
211
  				arp->ar_data);
  
  			/* save address for later use */
f1d2d2846   Joe Hershberger   net: Remove stati...
212
213
214
  			if (NetArpWaitPacketMAC != NULL)
  				memcpy(NetArpWaitPacketMAC,
  				       &arp->ar_sha, ARP_HLEN);
d280d3f43   Joe Hershberger   net: Move ARP out...
215

ece223b52   Joe Hershberger   net: Refactor to ...
216
217
  			net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr,
  				0, len);
e94070c44   Joe Hershberger   net: Don't copy e...
218
219
220
221
222
  			/* set the mac address in the waiting packet's header
  			   and transmit it */
  			memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest,
  				&arp->ar_sha, ARP_HLEN);
  			NetSendPacket(NetTxPacket, NetArpWaitTxPacketSize);
d280d3f43   Joe Hershberger   net: Move ARP out...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
  
  			/* no arp request pending now */
  			NetArpWaitPacketIP = 0;
  			NetArpWaitTxPacketSize = 0;
  			NetArpWaitPacketMAC = NULL;
  
  		}
  		return;
  	default:
  		debug("Unexpected ARP opcode 0x%x
  ",
  		      ntohs(arp->ar_op));
  		return;
  	}
  }