* Copyright 2000 Roland Borde
* Copyright 2000 Paolo Scaffardi
* Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#endif
IPaddr_t NetArpWaitPacketIP;
-IPaddr_t NetArpWaitReplyIP;
+static IPaddr_t NetArpWaitReplyIP;
/* MAC address of waiting packet's destination */
uchar *NetArpWaitPacketMAC;
int NetArpWaitTxPacketSize;
ulong NetArpWaitTimerStart;
int NetArpWaitTry;
-uchar *NetArpTxPacket; /* THE ARP transmit packet */
-uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+static uchar *NetArpTxPacket; /* THE ARP transmit packet */
+static uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
void ArpInit(void)
{
struct arp_hdr *arp;
int eth_hdr_size;
- debug("ARP broadcast %d\n", NetArpWaitTry);
+ debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry);
pkt = NetArpTxPacket;
* address; so if we receive such a packet, we set
* the server ethernet address
*/
- debug("Got ARP\n");
+ debug_cond(DEBUG_NET_PKT, "Got ARP\n");
arp = (struct arp_hdr *)ip;
if (len < ARP_HDR_SIZE) {
switch (ntohs(arp->ar_op)) {
case ARPOP_REQUEST:
/* reply with our IP address */
- debug("Got ARP REQUEST, return our IP\n");
+ debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP\n");
pkt = (uchar *)et;
eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP);
pkt += eth_hdr_size;
NetCopyIP(&arp->ar_tpa, &arp->ar_spa);
memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);
NetCopyIP(&arp->ar_spa, &NetOurIP);
+
+#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
NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
return;
#ifdef CONFIG_KEEP_SERVERADDR
if (NetServerIP == NetArpWaitPacketIP) {
char buf[20];
- sprintf(buf, "%pM", arp->ar_sha);
+ sprintf(buf, "%pM", &arp->ar_sha);
setenv("serveraddr", buf);
}
#endif
/* matched waiting packet's address */
if (reply_ip_addr == NetArpWaitReplyIP) {
- debug("Got ARP REPLY, set eth addr (%pM)\n",
+ debug_cond(DEBUG_DEV_PKT,
+ "Got ARP REPLY, set eth addr (%pM)\n",
arp->ar_data);
/* save address for later use */