PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

sys/lib/libsa/rarp.c

http://www.minix3.org/
C | 240 lines | 155 code | 25 blank | 60 comment | 28 complexity | 28d5b14b6650ae9527bb0a995627103e MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. /* $NetBSD: rarp.c,v 1.31 2011/05/11 16:23:40 zoltan Exp $ */
  2. /*
  3. * Copyright (c) 1992 Regents of the University of California.
  4. * All rights reserved.
  5. *
  6. * This software was developed by the Computer Systems Engineering group
  7. * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
  8. * contributed to Berkeley.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. All advertising materials mentioning features or use of this software
  19. * must display the following acknowledgement:
  20. * This product includes software developed by the University of
  21. * California, Lawrence Berkeley Laboratory and its contributors.
  22. * 4. Neither the name of the University nor the names of its contributors
  23. * may be used to endorse or promote products derived from this software
  24. * without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36. * SUCH DAMAGE.
  37. *
  38. * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL)
  39. */
  40. #include <sys/param.h>
  41. #include <sys/socket.h>
  42. #include <net/if.h>
  43. #include <net/if_ether.h>
  44. #include <netinet/in.h>
  45. #include <netinet/in_systm.h>
  46. #ifdef _STANDALONE
  47. #include <lib/libkern/libkern.h>
  48. #else
  49. #include <string.h>
  50. #endif
  51. #include "stand.h"
  52. #include "net.h"
  53. /*
  54. * Ethernet Address Resolution Protocol.
  55. *
  56. * See RFC 826 for protocol description. Structure below is adapted
  57. * to resolving internet addresses. Field names used correspond to
  58. * RFC 826.
  59. */
  60. struct ether_arp {
  61. struct arphdr ea_hdr; /* fixed-size header */
  62. u_int8_t arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
  63. u_int8_t arp_spa[4]; /* sender protocol address */
  64. u_int8_t arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
  65. u_int8_t arp_tpa[4]; /* target protocol address */
  66. };
  67. #define arp_hrd ea_hdr.ar_hrd
  68. #define arp_pro ea_hdr.ar_pro
  69. #define arp_hln ea_hdr.ar_hln
  70. #define arp_pln ea_hdr.ar_pln
  71. #define arp_op ea_hdr.ar_op
  72. static ssize_t rarpsend(struct iodesc *, void *, size_t);
  73. static ssize_t rarprecv(struct iodesc *, void *, size_t, saseconds_t);
  74. /*
  75. * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
  76. */
  77. int
  78. rarp_getipaddress(int sock)
  79. {
  80. struct iodesc *d;
  81. struct ether_arp *ap;
  82. struct {
  83. u_char header[ETHERNET_HEADER_SIZE];
  84. struct {
  85. struct ether_arp arp;
  86. u_char pad[18]; /* 60 - sizeof(arp) */
  87. } data;
  88. } wbuf;
  89. struct {
  90. u_char header[ETHERNET_HEADER_SIZE];
  91. struct {
  92. struct ether_arp arp;
  93. u_char pad[24]; /* extra space */
  94. } data;
  95. } rbuf;
  96. #ifdef RARP_DEBUG
  97. if (debug)
  98. printf("rarp: socket=%d\n", sock);
  99. #endif
  100. if (!(d = socktodesc(sock))) {
  101. printf("rarp: bad socket. %d\n", sock);
  102. return -1;
  103. }
  104. #ifdef RARP_DEBUG
  105. if (debug)
  106. printf("rarp: d=%lx\n", (u_long)d);
  107. #endif
  108. (void)memset(&wbuf.data, 0, sizeof(wbuf.data));
  109. ap = &wbuf.data.arp;
  110. ap->arp_hrd = htons(ARPHRD_ETHER);
  111. ap->arp_pro = htons(ETHERTYPE_IP);
  112. ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */
  113. ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */
  114. ap->arp_op = htons(ARPOP_REVREQUEST);
  115. (void)memcpy(ap->arp_sha, d->myea, 6);
  116. (void)memcpy(ap->arp_tha, d->myea, 6);
  117. if (sendrecv(d,
  118. rarpsend, &wbuf.data, sizeof(wbuf.data),
  119. rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0)
  120. {
  121. printf("No response for RARP request\n");
  122. return -1;
  123. }
  124. ap = &rbuf.data.arp;
  125. (void)memcpy(&myip, ap->arp_tpa, sizeof(myip));
  126. #if 0
  127. /* XXX - Can NOT assume this is our root server! */
  128. (void)memcpy(&rootip, ap->arp_spa, sizeof(rootip));
  129. #endif
  130. /* Compute our "natural" netmask. */
  131. if (IN_CLASSA(myip.s_addr))
  132. netmask = IN_CLASSA_NET;
  133. else if (IN_CLASSB(myip.s_addr))
  134. netmask = IN_CLASSB_NET;
  135. else
  136. netmask = IN_CLASSC_NET;
  137. d->myip = myip;
  138. return 0;
  139. }
  140. /*
  141. * Broadcast a RARP request (i.e. who knows who I am)
  142. */
  143. static ssize_t
  144. rarpsend(struct iodesc *d, void *pkt, size_t len)
  145. {
  146. #ifdef RARP_DEBUG
  147. if (debug)
  148. printf("rarpsend: called\n");
  149. #endif
  150. return sendether(d, pkt, len, bcea, ETHERTYPE_REVARP);
  151. }
  152. /*
  153. * Returns 0 if this is the packet we're waiting for
  154. * else -1 (and errno == 0)
  155. */
  156. static ssize_t
  157. rarprecv(struct iodesc *d, void *pkt, size_t len, saseconds_t tleft)
  158. {
  159. ssize_t n;
  160. struct ether_arp *ap;
  161. u_int16_t etype; /* host order */
  162. #ifdef RARP_DEBUG
  163. if (debug)
  164. printf("rarprecv: ");
  165. #endif
  166. n = readether(d, pkt, len, tleft, &etype);
  167. errno = 0; /* XXX */
  168. if (n == -1 || (size_t)n < sizeof(struct ether_arp)) {
  169. #ifdef RARP_DEBUG
  170. if (debug)
  171. printf("bad len=%d\n", (int)n);
  172. #endif
  173. return -1;
  174. }
  175. if (etype != ETHERTYPE_REVARP) {
  176. #ifdef RARP_DEBUG
  177. if (debug)
  178. printf("bad type=0x%x\n", etype);
  179. #endif
  180. return -1;
  181. }
  182. ap = (struct ether_arp *)pkt;
  183. if (ap->arp_hrd != htons(ARPHRD_ETHER) ||
  184. ap->arp_pro != htons(ETHERTYPE_IP) ||
  185. ap->arp_hln != sizeof(ap->arp_sha) ||
  186. ap->arp_pln != sizeof(ap->arp_spa) )
  187. {
  188. #ifdef RARP_DEBUG
  189. if (debug)
  190. printf("bad hrd/pro/hln/pln\n");
  191. #endif
  192. return -1;
  193. }
  194. if (ap->arp_op != htons(ARPOP_REVREPLY)) {
  195. #ifdef RARP_DEBUG
  196. if (debug)
  197. printf("bad op=0x%x\n", ntohs(ap->arp_op));
  198. #endif
  199. return -1;
  200. }
  201. /* Is the reply for our Ethernet address? */
  202. if (memcmp(ap->arp_tha, d->myea, 6)) {
  203. #ifdef RARP_DEBUG
  204. if (debug)
  205. printf("unwanted address\n");
  206. #endif
  207. return -1;
  208. }
  209. /* We have our answer. */
  210. #ifdef RARP_DEBUG
  211. if (debug)
  212. printf("got it\n");
  213. #endif
  214. return n;
  215. }