1 /* 2 * (C) Copyright 2000 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <command.h> 26 #include <net.h> 27 #include "bootp.h" 28 #include "tftp.h" 29 #include "arp.h" 30 31 #if (CONFIG_COMMANDS & CFG_CMD_NET) 32 33 #define TIMEOUT 5 /* Seconds before trying ARP again */ 34 #ifndef CONFIG_NET_RETRY_COUNT 35 # define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ 36 #else 37 # define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) 38 #endif 39 40 static void ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len); 41 static void ArpTimeout(void); 42 43 int ArpTry = 0; 44 45 /* 46 * Handle a ARP received packet. 47 */ 48 static void 49 ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len) 50 { 51 /* Check if the frame is really an ARP reply */ 52 if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) { 53 #ifdef DEBUG 54 printf("Got good ARP - start TFTP\n"); 55 #endif 56 TftpStart (); 57 } 58 } 59 60 61 /* 62 * Timeout on ARP request. 63 */ 64 static void 65 ArpTimeout(void) 66 { 67 if (ArpTry >= TIMEOUT_COUNT) { 68 puts ("\nRetry count exceeded; starting again\n"); 69 NetStartAgain (); 70 } else { 71 NetSetTimeout (TIMEOUT * CFG_HZ, ArpTimeout); 72 ArpRequest (); 73 } 74 } 75 76 77 void 78 ArpRequest (void) 79 { 80 int i; 81 volatile uchar *pkt; 82 ARP_t * arp; 83 84 printf("ARP broadcast %d\n", ++ArpTry); 85 pkt = NetTxPacket; 86 87 NetSetEther(pkt, NetBcastAddr, PROT_ARP); 88 pkt += ETHER_HDR_SIZE; 89 90 arp = (ARP_t *)pkt; 91 92 arp->ar_hrd = htons(ARP_ETHER); 93 arp->ar_pro = htons(PROT_IP); 94 arp->ar_hln = 6; 95 arp->ar_pln = 4; 96 arp->ar_op = htons(ARPOP_REQUEST); 97 98 memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ 99 NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ 100 for (i=10; i<16; ++i) { 101 arp->ar_data[i] = 0; /* dest ET addr = 0 */ 102 } 103 104 if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { 105 if (NetOurGatewayIP == 0) { 106 puts ("## Warning: gatewayip needed but not set\n"); 107 } 108 NetWriteIP((uchar*)&arp->ar_data[16], NetOurGatewayIP); 109 } else { 110 NetWriteIP((uchar*)&arp->ar_data[16], NetServerIP); 111 } 112 113 114 NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); 115 116 NetSetTimeout(TIMEOUT * CFG_HZ, ArpTimeout); 117 NetSetHandler(ArpHandler); 118 } 119 120 #endif /* CFG_CMD_NET */ 121