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 rarp_try; 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 puts("invalid RARP header\n"); 44 } else { 45 net_copy_ip(&net_ip, &arp->ar_data[16]); 46 if (net_server_ip.s_addr == 0) 47 net_copy_ip(&net_server_ip, &arp->ar_data[6]); 48 memcpy(net_server_ethaddr, &arp->ar_data[0], 6); 49 debug_cond(DEBUG_DEV_PKT, "Got good RARP\n"); 50 net_auto_load(); 51 } 52 } 53 54 55 /* 56 * Timeout on BOOTP request. 57 */ 58 static void rarp_timeout_handler(void) 59 { 60 if (rarp_try >= TIMEOUT_COUNT) { 61 puts("\nRetry count exceeded; starting again\n"); 62 net_start_again(); 63 } else { 64 net_set_timeout_handler(TIMEOUT, rarp_timeout_handler); 65 rarp_request(); 66 } 67 } 68 69 70 void rarp_request(void) 71 { 72 uchar *pkt; 73 struct arp_hdr *rarp; 74 int eth_hdr_size; 75 76 printf("RARP broadcast %d\n", ++rarp_try); 77 pkt = net_tx_packet; 78 79 eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_RARP); 80 pkt += eth_hdr_size; 81 82 rarp = (struct arp_hdr *)pkt; 83 84 rarp->ar_hrd = htons(ARP_ETHER); 85 rarp->ar_pro = htons(PROT_IP); 86 rarp->ar_hln = 6; 87 rarp->ar_pln = 4; 88 rarp->ar_op = htons(RARPOP_REQUEST); 89 memcpy(&rarp->ar_data[0], net_ethaddr, 6); /* source ET addr */ 90 memcpy(&rarp->ar_data[6], &net_ip, 4); /* source IP addr */ 91 /* dest ET addr = source ET addr ??*/ 92 memcpy(&rarp->ar_data[10], net_ethaddr, 6); 93 /* dest IP addr set to broadcast */ 94 memset(&rarp->ar_data[16], 0xff, 4); 95 96 net_send_packet(net_tx_packet, eth_hdr_size + ARP_HDR_SIZE); 97 98 net_set_timeout_handler(TIMEOUT, rarp_timeout_handler); 99 } 100