1 #include <sys/param.h> 2 #include <sys/socket.h> 3 #include <net/if.h> 4 #include <netinet/in.h> 5 6 #include <netinet/if_ether.h> 7 #include <netinet/in_systm.h> 8 9 #include <errno.h> 10 #include <string.h> 11 12 #include "stand.h" 13 #include "net.h" 14 #include "netif.h" 15 16 static int rarpsend(struct iodesc *, void *, int); 17 static int rarprecv(struct iodesc *, void *, int); 18 19 /* 20 * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826). 21 */ 22 n_long 23 rarp_getipaddress(sock) 24 int sock; 25 { 26 struct iodesc *d; 27 register struct ether_arp *ap; 28 register void *pkt; 29 struct { 30 u_char header[HEADER_SIZE]; 31 struct ether_arp wrarp; 32 } wbuf; 33 union { 34 u_char buffer[RECV_SIZE]; 35 struct { 36 u_char header[HEADER_SIZE]; 37 struct ether_arp xrrarp; 38 }xrbuf; 39 #define rrarp xrbuf.xrrarp 40 } rbuf; 41 42 #ifdef RARP_DEBUG 43 if (debug) 44 printf("rarp: socket=%d\n", sock); 45 #endif 46 if (!(d = socktodesc(sock))) { 47 printf("rarp: bad socket. %d\n", sock); 48 return(INADDR_ANY); 49 } 50 #ifdef RARP_DEBUG 51 if (debug) 52 printf("rarp: d=%x\n", (u_int)d); 53 #endif 54 ap = &wbuf.wrarp; 55 pkt = &rbuf.rrarp; 56 pkt -= HEADER_SIZE; 57 58 bzero(ap, sizeof(*ap)); 59 60 ap->arp_hrd = htons(ARPHRD_ETHER); 61 ap->arp_pro = htons(ETHERTYPE_IP); 62 ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */ 63 ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */ 64 ap->arp_op = htons(ARPOP_REQUEST); 65 bcopy(d->myea, ap->arp_sha, 6); 66 bcopy(d->myea, ap->arp_tha, 6); 67 68 if (sendrecv(d, 69 rarpsend, ap, sizeof(*ap), 70 rarprecv, pkt, RECV_SIZE) < 0) { 71 printf("No response for RARP request\n"); 72 return(INADDR_ANY); 73 } 74 75 return(myip); 76 } 77 78 /* 79 * Broadcast a RARP request (i.e. who knows who I am) 80 */ 81 static int 82 rarpsend(d, pkt, len) 83 register struct iodesc *d; 84 register void *pkt; 85 register int len; 86 { 87 #ifdef RARP_DEBUG 88 if (debug) 89 printf("rarpsend: called\n"); 90 #endif 91 return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP)); 92 } 93 94 /* 95 * Called when packet containing RARP is received 96 */ 97 static int 98 rarprecv(d, pkt, len) 99 register struct iodesc *d; 100 register void *pkt; 101 register int len; 102 { 103 register struct ether_header *ep; 104 register struct ether_arp *ap; 105 106 #ifdef RARP_DEBUG 107 if (debug) 108 printf("rarprecv: called\n"); 109 #endif 110 if (len < sizeof(struct ether_header) + sizeof(struct ether_arp)) { 111 errno = 0; 112 return (-1); 113 } 114 115 ep = (struct ether_header *)pkt; 116 if (ntohs(ep->ether_type) != ETHERTYPE_REVARP) { 117 errno = 0; 118 return (-1); 119 } 120 121 ap = (struct ether_arp *)(ep + 1); 122 if (ntohs(ap->arp_op) != ARPOP_REPLY || 123 ntohs(ap->arp_pro) != ETHERTYPE_IP) { 124 errno = 0; 125 return (-1); 126 } 127 128 if (bcmp(ap->arp_tha, d->myea, 6)) { 129 errno = 0; 130 return (-1); 131 } 132 133 bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip)); 134 bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip)); 135 136 return(0); 137 } 138