1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <command.h> 10 #include <net.h> 11 #include "nfs.h" 12 #include "bootp.h" 13 #include "rarp.h" 14 #include "tftp.h" 15 16 #define TIMEOUT 5000UL /* Milliseconds before trying BOOTP again */ 17 #ifndef CONFIG_NET_RETRY_COUNT 18 #define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ 19 #else 20 #define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) 21 #endif 22 23 int RarpTry; 24 25 /* 26 * Handle a RARP received packet. 27 */ 28 void rarp_receive(struct ip_udp_hdr *ip, unsigned len) 29 { 30 struct arp_hdr *arp; 31 32 debug_cond(DEBUG_NET_PKT, "Got RARP\n"); 33 arp = (struct arp_hdr *)ip; 34 if (len < ARP_HDR_SIZE) { 35 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 36 return; 37 } 38 39 if ((ntohs(arp->ar_op) != RARPOP_REPLY) || 40 (ntohs(arp->ar_hrd) != ARP_ETHER) || 41 (ntohs(arp->ar_pro) != PROT_IP) || 42 (arp->ar_hln != 6) || (arp->ar_pln != 4)) { 43 44 puts("invalid RARP header\n"); 45 } else { 46 NetCopyIP(&NetOurIP, &arp->ar_data[16]); 47 if (NetServerIP == 0) 48 NetCopyIP(&NetServerIP, &arp->ar_data[6]); 49 memcpy(NetServerEther, &arp->ar_data[0], 6); 50 debug_cond(DEBUG_DEV_PKT, "Got good RARP\n"); 51 net_auto_load(); 52 } 53 } 54 55 56 /* 57 * Timeout on BOOTP request. 58 */ 59 static void RarpTimeout(void) 60 { 61 if (RarpTry >= TIMEOUT_COUNT) { 62 puts("\nRetry count exceeded; starting again\n"); 63 NetStartAgain(); 64 } else { 65 NetSetTimeout(TIMEOUT, RarpTimeout); 66 RarpRequest(); 67 } 68 } 69 70 71 void RarpRequest(void) 72 { 73 uchar *pkt; 74 struct arp_hdr *rarp; 75 int eth_hdr_size; 76 77 printf("RARP broadcast %d\n", ++RarpTry); 78 pkt = NetTxPacket; 79 80 eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_RARP); 81 pkt += eth_hdr_size; 82 83 rarp = (struct arp_hdr *)pkt; 84 85 rarp->ar_hrd = htons(ARP_ETHER); 86 rarp->ar_pro = htons(PROT_IP); 87 rarp->ar_hln = 6; 88 rarp->ar_pln = 4; 89 rarp->ar_op = htons(RARPOP_REQUEST); 90 memcpy(&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */ 91 memcpy(&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */ 92 /* dest ET addr = source ET addr ??*/ 93 memcpy(&rarp->ar_data[10], NetOurEther, 6); 94 /* dest IP addr set to broadcast */ 95 memset(&rarp->ar_data[16], 0xff, 4); 96 97 NetSendPacket(NetTxPacket, eth_hdr_size + ARP_HDR_SIZE); 98 99 NetSetTimeout(TIMEOUT, RarpTimeout); 100 } 101