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