1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Lawrence Berkeley Laboratory and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) 38 * $Id: rarp.c,v 1.3 1994/08/04 19:39:37 brezak Exp $ 39 */ 40 #include <sys/param.h> 41 #include <sys/socket.h> 42 #include <net/if.h> 43 #include <netinet/in.h> 44 45 #include <netinet/if_ether.h> 46 #include <netinet/in_systm.h> 47 48 #include <string.h> 49 50 #include "stand.h" 51 #include "net.h" 52 #include "netif.h" 53 54 static int rarpsend(struct iodesc *, void *, int); 55 static int rarprecv(struct iodesc *, void *, int); 56 57 /* 58 * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826). 59 */ 60 n_long 61 rarp_getipaddress(sock) 62 int sock; 63 { 64 struct iodesc *d; 65 register struct ether_arp *ap; 66 register void *pkt; 67 struct { 68 u_char header[HEADER_SIZE]; 69 struct ether_arp wrarp; 70 } wbuf; 71 union { 72 u_char buffer[RECV_SIZE]; 73 struct { 74 u_char header[HEADER_SIZE]; 75 struct ether_arp xrrarp; 76 }xrbuf; 77 #define rrarp xrbuf.xrrarp 78 } rbuf; 79 80 #ifdef RARP_DEBUG 81 if (debug) 82 printf("rarp: socket=%d\n", sock); 83 #endif 84 if (!(d = socktodesc(sock))) { 85 printf("rarp: bad socket. %d\n", sock); 86 return(INADDR_ANY); 87 } 88 #ifdef RARP_DEBUG 89 if (debug) 90 printf("rarp: d=%x\n", (u_int)d); 91 #endif 92 ap = &wbuf.wrarp; 93 pkt = &rbuf.rrarp; 94 pkt -= HEADER_SIZE; 95 96 bzero(ap, sizeof(*ap)); 97 98 ap->arp_hrd = htons(ARPHRD_ETHER); 99 ap->arp_pro = htons(ETHERTYPE_IP); 100 ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */ 101 ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */ 102 ap->arp_op = htons(ARPOP_REQUEST); 103 bcopy(d->myea, ap->arp_sha, 6); 104 bcopy(d->myea, ap->arp_tha, 6); 105 106 if (sendrecv(d, 107 rarpsend, ap, sizeof(*ap), 108 rarprecv, pkt, RECV_SIZE) < 0) { 109 printf("No response for RARP request\n"); 110 return(INADDR_ANY); 111 } 112 113 return(myip); 114 } 115 116 /* 117 * Broadcast a RARP request (i.e. who knows who I am) 118 */ 119 static int 120 rarpsend(d, pkt, len) 121 register struct iodesc *d; 122 register void *pkt; 123 register int len; 124 { 125 #ifdef RARP_DEBUG 126 if (debug) 127 printf("rarpsend: called\n"); 128 #endif 129 return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP)); 130 } 131 132 /* 133 * Called when packet containing RARP is received 134 */ 135 static int 136 rarprecv(d, pkt, len) 137 register struct iodesc *d; 138 register void *pkt; 139 register int len; 140 { 141 register struct ether_header *ep; 142 register struct ether_arp *ap; 143 144 #ifdef RARP_DEBUG 145 if (debug) 146 printf("rarprecv: called\n"); 147 #endif 148 if (len < sizeof(struct ether_header) + sizeof(struct ether_arp)) { 149 errno = 0; 150 return (-1); 151 } 152 153 ep = (struct ether_header *)pkt; 154 if (ntohs(ep->ether_type) != ETHERTYPE_REVARP) { 155 errno = 0; 156 return (-1); 157 } 158 159 ap = (struct ether_arp *)(ep + 1); 160 if (ntohs(ap->arp_op) != ARPOP_REPLY || 161 ntohs(ap->arp_pro) != ETHERTYPE_IP) { 162 errno = 0; 163 return (-1); 164 } 165 166 if (bcmp(ap->arp_tha, d->myea, 6)) { 167 errno = 0; 168 return (-1); 169 } 170 171 bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip)); 172 bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip)); 173 174 return(0); 175 } 176