rarp.c revision 256281
1228753Smm/* $NetBSD: rarp.c,v 1.16 1997/07/07 15:52:52 drochner Exp $ */ 2228753Smm 3228753Smm/* 4228753Smm * Copyright (c) 1992 Regents of the University of California. 5228753Smm * All rights reserved. 6228753Smm * 7228753Smm * This software was developed by the Computer Systems Engineering group 8228753Smm * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9228753Smm * contributed to Berkeley. 10228753Smm * 11228753Smm * Redistribution and use in source and binary forms, with or without 12228753Smm * modification, are permitted provided that the following conditions 13228753Smm * are met: 14228753Smm * 1. Redistributions of source code must retain the above copyright 15228753Smm * notice, this list of conditions and the following disclaimer. 16228753Smm * 2. Redistributions in binary form must reproduce the above copyright 17228753Smm * notice, this list of conditions and the following disclaimer in the 18228753Smm * documentation and/or other materials provided with the distribution. 19228753Smm * 4. Neither the name of the University nor the names of its contributors 20228753Smm * may be used to endorse or promote products derived from this software 21228753Smm * without specific prior written permission. 22228753Smm * 23228753Smm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24228753Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25228753Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26228753Smm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27228753Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28228753Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29228753Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30228753Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31228753Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32228753Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33228753Smm * SUCH DAMAGE. 34228753Smm * 35228753Smm * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) 36228753Smm */ 37228753Smm 38228753Smm#include <sys/cdefs.h> 39228753Smm__FBSDID("$FreeBSD: stable/10/lib/libstand/rarp.c 165906 2007-01-09 01:02:06Z imp $"); 40228753Smm 41228753Smm#include <sys/param.h> 42228753Smm#include <sys/socket.h> 43228753Smm#include <net/if.h> 44228753Smm#include <netinet/in.h> 45228753Smm#include <netinet/if_ether.h> 46228753Smm 47228753Smm#include <netinet/in_systm.h> 48228753Smm 49228753Smm#include <string.h> 50228753Smm 51228753Smm#include "stand.h" 52228753Smm#include "net.h" 53228753Smm#include "netif.h" 54228753Smm 55228753Smm 56228753Smmstatic ssize_t rarpsend(struct iodesc *, void *, size_t); 57228753Smmstatic ssize_t rarprecv(struct iodesc *, void *, size_t, time_t); 58228753Smm 59228753Smm/* 60228753Smm * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826). 61228753Smm */ 62228753Smmint 63228753Smmrarp_getipaddress(sock) 64228753Smm int sock; 65228753Smm{ 66228753Smm struct iodesc *d; 67228753Smm struct ether_arp *ap; 68228753Smm struct { 69228753Smm u_char header[ETHER_SIZE]; 70228753Smm struct { 71228753Smm struct ether_arp arp; 72228753Smm u_char pad[18]; /* 60 - sizeof(arp) */ 73228753Smm } data; 74228753Smm } wbuf; 75228753Smm struct { 76228753Smm u_char header[ETHER_SIZE]; 77228753Smm struct { 78228753Smm struct ether_arp arp; 79228753Smm u_char pad[24]; /* extra space */ 80228753Smm } data; 81228753Smm } rbuf; 82228753Smm 83228753Smm#ifdef RARP_DEBUG 84228753Smm if (debug) 85228753Smm printf("rarp: socket=%d\n", sock); 86228753Smm#endif 87228753Smm if (!(d = socktodesc(sock))) { 88228753Smm printf("rarp: bad socket. %d\n", sock); 89228753Smm return (-1); 90228753Smm } 91228753Smm#ifdef RARP_DEBUG 92228753Smm if (debug) 93228753Smm printf("rarp: d=%x\n", (u_int)d); 94228753Smm#endif 95228753Smm 96228753Smm bzero((char*)&wbuf.data, sizeof(wbuf.data)); 97228753Smm ap = &wbuf.data.arp; 98228753Smm ap->arp_hrd = htons(ARPHRD_ETHER); 99228753Smm ap->arp_pro = htons(ETHERTYPE_IP); 100228753Smm ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */ 101228753Smm ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */ 102228753Smm ap->arp_op = htons(ARPOP_REVREQUEST); 103228753Smm bcopy(d->myea, ap->arp_sha, 6); 104228753Smm bcopy(d->myea, ap->arp_tha, 6); 105228753Smm 106228753Smm if (sendrecv(d, 107228753Smm rarpsend, &wbuf.data, sizeof(wbuf.data), 108228753Smm rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0) 109228753Smm { 110228753Smm printf("No response for RARP request\n"); 111228753Smm return (-1); 112228753Smm } 113228753Smm 114228753Smm ap = &rbuf.data.arp; 115228753Smm bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip)); 116228753Smm#if 0 117228753Smm /* XXX - Can NOT assume this is our root server! */ 118228753Smm bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip)); 119228753Smm#endif 120228753Smm 121228753Smm /* Compute our "natural" netmask. */ 122228753Smm if (IN_CLASSA(myip.s_addr)) 123228753Smm netmask = IN_CLASSA_NET; 124228753Smm else if (IN_CLASSB(myip.s_addr)) 125228753Smm netmask = IN_CLASSB_NET; 126228753Smm else 127228753Smm netmask = IN_CLASSC_NET; 128228753Smm 129228753Smm d->myip = myip; 130228753Smm return (0); 131228753Smm} 132228753Smm 133228753Smm/* 134228753Smm * Broadcast a RARP request (i.e. who knows who I am) 135228753Smm */ 136228753Smmstatic ssize_t 137228753Smmrarpsend(d, pkt, len) 138228753Smm struct iodesc *d; 139228753Smm void *pkt; 140228753Smm size_t len; 141228753Smm{ 142228753Smm 143228753Smm#ifdef RARP_DEBUG 144228753Smm if (debug) 145228753Smm printf("rarpsend: called\n"); 146228753Smm#endif 147228753Smm 148228753Smm return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP)); 149228753Smm} 150228753Smm 151228753Smm/* 152228753Smm * Returns 0 if this is the packet we're waiting for 153228753Smm * else -1 (and errno == 0) 154228753Smm */ 155228753Smmstatic ssize_t 156228753Smmrarprecv(d, pkt, len, tleft) 157228753Smm struct iodesc *d; 158228753Smm void *pkt; 159228753Smm size_t len; 160228753Smm time_t tleft; 161228753Smm{ 162228753Smm ssize_t n; 163228753Smm struct ether_arp *ap; 164228753Smm u_int16_t etype; /* host order */ 165228753Smm 166228753Smm#ifdef RARP_DEBUG 167228753Smm if (debug) 168228753Smm printf("rarprecv: "); 169228753Smm#endif 170228753Smm 171228753Smm n = readether(d, pkt, len, tleft, &etype); 172228753Smm errno = 0; /* XXX */ 173228753Smm if (n == -1 || n < sizeof(struct ether_arp)) { 174228753Smm#ifdef RARP_DEBUG 175228753Smm if (debug) 176228753Smm printf("bad len=%d\n", n); 177228753Smm#endif 178228753Smm return (-1); 179228753Smm } 180228753Smm 181228753Smm if (etype != ETHERTYPE_REVARP) { 182228753Smm#ifdef RARP_DEBUG 183228753Smm if (debug) 184228753Smm printf("bad type=0x%x\n", etype); 185228753Smm#endif 186228753Smm return (-1); 187228753Smm } 188228753Smm 189228753Smm ap = (struct ether_arp *)pkt; 190228753Smm if (ap->arp_hrd != htons(ARPHRD_ETHER) || 191228753Smm ap->arp_pro != htons(ETHERTYPE_IP) || 192228753Smm ap->arp_hln != sizeof(ap->arp_sha) || 193228753Smm ap->arp_pln != sizeof(ap->arp_spa) ) 194228753Smm { 195228753Smm#ifdef RARP_DEBUG 196228753Smm if (debug) 197228753Smm printf("bad hrd/pro/hln/pln\n"); 198228753Smm#endif 199228753Smm return (-1); 200228753Smm } 201228753Smm 202228753Smm if (ap->arp_op != htons(ARPOP_REVREPLY)) { 203228753Smm#ifdef RARP_DEBUG 204228753Smm if (debug) 205228753Smm printf("bad op=0x%x\n", ntohs(ap->arp_op)); 206228753Smm#endif 207228753Smm return (-1); 208228753Smm } 209228753Smm 210228753Smm /* Is the reply for our Ethernet address? */ 211228753Smm if (bcmp(ap->arp_tha, d->myea, 6)) { 212228753Smm#ifdef RARP_DEBUG 213228753Smm if (debug) 214228753Smm printf("unwanted address\n"); 215228753Smm#endif 216228753Smm return (-1); 217228753Smm } 218228753Smm 219228753Smm /* We have our answer. */ 220228753Smm#ifdef RARP_DEBUG 221228753Smm if (debug) 222228753Smm printf("got it\n"); 223228753Smm#endif 224228753Smm return (n); 225228753Smm} 226228753Smm