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