1 /* 2 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)if_ether.c 7.10 (Berkeley) 04/22/89 18 */ 19 20 /* 21 * Ethernet address resolution protocol. 22 * TODO: 23 * run at splnet (add ARP protocol intr.) 24 * link entries onto hash chains, keep free list 25 * add "inuse/lock" bit (or ref. count) along with valid bit 26 */ 27 28 #include "param.h" 29 #include "systm.h" 30 #include "malloc.h" 31 #include "mbuf.h" 32 #include "socket.h" 33 #include "time.h" 34 #include "kernel.h" 35 #include "errno.h" 36 #include "ioctl.h" 37 #include "syslog.h" 38 39 #include "../net/if.h" 40 #include "in.h" 41 #include "in_systm.h" 42 #include "in_var.h" 43 #include "ip.h" 44 #include "if_ether.h" 45 46 #ifdef GATEWAY 47 #define ARPTAB_BSIZ 16 /* bucket size */ 48 #define ARPTAB_NB 37 /* number of buckets */ 49 #else 50 #define ARPTAB_BSIZ 9 /* bucket size */ 51 #define ARPTAB_NB 19 /* number of buckets */ 52 #endif 53 #define ARPTAB_SIZE (ARPTAB_BSIZ * ARPTAB_NB) 54 struct arptab arptab[ARPTAB_SIZE]; 55 int arptab_size = ARPTAB_SIZE; /* for arp command */ 56 57 /* 58 * ARP trailer negotiation. Trailer protocol is not IP specific, 59 * but ARP request/response use IP addresses. 60 */ 61 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 62 63 #define ARPTAB_HASH(a) \ 64 ((u_long)(a) % ARPTAB_NB) 65 66 #define ARPTAB_LOOK(at,addr) { \ 67 register n; \ 68 at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ]; \ 69 for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) \ 70 if (at->at_iaddr.s_addr == addr) \ 71 break; \ 72 if (n >= ARPTAB_BSIZ) \ 73 at = 0; \ 74 } 75 76 /* timer values */ 77 #define ARPT_AGE (60*1) /* aging timer, 1 min. */ 78 #define ARPT_KILLC 20 /* kill completed entry in 20 mins. */ 79 #define ARPT_KILLI 3 /* kill incomplete entry in 3 minutes */ 80 81 extern struct ifnet loif; 82 83 /* 84 * Timeout routine. Age arp_tab entries once a minute. 85 */ 86 arptimer() 87 { 88 register struct arptab *at; 89 register i; 90 91 timeout(arptimer, (caddr_t)0, ARPT_AGE * hz); 92 at = &arptab[0]; 93 for (i = 0; i < ARPTAB_SIZE; i++, at++) { 94 if (at->at_flags == 0 || (at->at_flags & ATF_PERM)) 95 continue; 96 if (++at->at_timer < ((at->at_flags&ATF_COM) ? 97 ARPT_KILLC : ARPT_KILLI)) 98 continue; 99 /* timer has expired, clear entry */ 100 arptfree(at); 101 } 102 } 103 104 /* 105 * Broadcast an ARP packet, asking who has addr on interface ac. 106 */ 107 arpwhohas(ac, addr) 108 register struct arpcom *ac; 109 struct in_addr *addr; 110 { 111 register struct mbuf *m; 112 register struct ether_header *eh; 113 register struct ether_arp *ea; 114 struct sockaddr sa; 115 116 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 117 return; 118 m->m_len = sizeof(*ea); 119 m->m_pkthdr.len = sizeof(*ea); 120 MH_ALIGN(m, sizeof(*ea)); 121 ea = mtod(m, struct ether_arp *); 122 eh = (struct ether_header *)sa.sa_data; 123 bzero((caddr_t)ea, sizeof (*ea)); 124 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 125 sizeof(eh->ether_dhost)); 126 eh->ether_type = ETHERTYPE_ARP; /* if_output will swap */ 127 ea->arp_hrd = htons(ARPHRD_ETHER); 128 ea->arp_pro = htons(ETHERTYPE_IP); 129 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */ 130 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */ 131 ea->arp_op = htons(ARPOP_REQUEST); 132 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha, 133 sizeof(ea->arp_sha)); 134 bcopy((caddr_t)&ac->ac_ipaddr, (caddr_t)ea->arp_spa, 135 sizeof(ea->arp_spa)); 136 bcopy((caddr_t)addr, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa)); 137 sa.sa_family = AF_UNSPEC; 138 sa.sa_len = sizeof(sa); 139 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa); 140 } 141 142 int useloopback = 1; /* use loopback interface for local traffic */ 143 144 /* 145 * Resolve an IP address into an ethernet address. If success, 146 * desten is filled in. If there is no entry in arptab, 147 * set one up and broadcast a request for the IP address. 148 * Hold onto this mbuf and resend it once the address 149 * is finally resolved. A return value of 1 indicates 150 * that desten has been filled in and the packet should be sent 151 * normally; a 0 return indicates that the packet has been 152 * taken over here, either now or for later transmission. 153 * 154 * We do some (conservative) locking here at splimp, since 155 * arptab is also altered from input interrupt service (ecintr/ilintr 156 * calls arpinput when ETHERTYPE_ARP packets come in). 157 */ 158 arpresolve(ac, m, destip, desten, usetrailers) 159 register struct arpcom *ac; 160 struct mbuf *m; 161 register struct in_addr *destip; 162 register u_char *desten; 163 int *usetrailers; 164 { 165 register struct arptab *at; 166 struct sockaddr_in sin; 167 register struct in_ifaddr *ia; 168 u_long lna; 169 int s; 170 171 *usetrailers = 0; 172 if (m->m_flags & M_BCAST) { /* broadcast */ 173 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten, 174 sizeof(etherbroadcastaddr)); 175 return (1); 176 } 177 lna = in_lnaof(*destip); 178 /* if for us, use software loopback driver if up */ 179 for (ia = in_ifaddr; ia; ia = ia->ia_next) 180 if ((ia->ia_ifp == &ac->ac_if) && 181 (destip->s_addr == ia->ia_addr.sin_addr.s_addr)) { 182 /* 183 * This test used to be 184 * if (loif.if_flags & IFF_UP) 185 * It allowed local traffic to be forced 186 * through the hardware by configuring the loopback down. 187 * However, it causes problems during network configuration 188 * for boards that can't receive packets they send. 189 * It is now necessary to clear "useloopback" 190 * to force traffic out to the hardware. 191 */ 192 if (useloopback) { 193 sin.sin_family = AF_INET; 194 sin.sin_addr = *destip; 195 (void) looutput(&loif, m, (struct sockaddr *)&sin); 196 /* 197 * The packet has already been sent and freed. 198 */ 199 return (0); 200 } else { 201 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)desten, 202 sizeof(ac->ac_enaddr)); 203 return (1); 204 } 205 } 206 s = splimp(); 207 ARPTAB_LOOK(at, destip->s_addr); 208 if (at == 0) { /* not found */ 209 if (ac->ac_if.if_flags & IFF_NOARP) { 210 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)desten, 3); 211 desten[3] = (lna >> 16) & 0x7f; 212 desten[4] = (lna >> 8) & 0xff; 213 desten[5] = lna & 0xff; 214 splx(s); 215 return (1); 216 } else { 217 at = arptnew(destip); 218 if (at == 0) 219 panic("arpresolve: no free entry"); 220 at->at_hold = m; 221 arpwhohas(ac, destip); 222 splx(s); 223 return (0); 224 } 225 } 226 at->at_timer = 0; /* restart the timer */ 227 if (at->at_flags & ATF_COM) { /* entry IS complete */ 228 bcopy((caddr_t)at->at_enaddr, (caddr_t)desten, 229 sizeof(at->at_enaddr)); 230 if (at->at_flags & ATF_USETRAILERS) 231 *usetrailers = 1; 232 splx(s); 233 return (1); 234 } 235 /* 236 * There is an arptab entry, but no ethernet address 237 * response yet. Replace the held mbuf with this 238 * latest one. 239 */ 240 if (at->at_hold) 241 m_freem(at->at_hold); 242 at->at_hold = m; 243 arpwhohas(ac, destip); /* ask again */ 244 splx(s); 245 return (0); 246 } 247 248 /* 249 * Called from 10 Mb/s Ethernet interrupt handlers 250 * when ether packet type ETHERTYPE_ARP 251 * is received. Common length and type checks are done here, 252 * then the protocol-specific routine is called. 253 */ 254 arpinput(ac, m) 255 struct arpcom *ac; 256 struct mbuf *m; 257 { 258 register struct arphdr *ar; 259 260 if (ac->ac_if.if_flags & IFF_NOARP) 261 goto out; 262 if (m->m_len < sizeof(struct arphdr)) 263 goto out; 264 ar = mtod(m, struct arphdr *); 265 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 266 goto out; 267 if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln) 268 goto out; 269 270 switch (ntohs(ar->ar_pro)) { 271 272 case ETHERTYPE_IP: 273 case ETHERTYPE_IPTRAILERS: 274 in_arpinput(ac, m); 275 return; 276 277 default: 278 break; 279 } 280 out: 281 m_freem(m); 282 } 283 284 /* 285 * ARP for Internet protocols on 10 Mb/s Ethernet. 286 * Algorithm is that given in RFC 826. 287 * In addition, a sanity check is performed on the sender 288 * protocol address, to catch impersonators. 289 * We also handle negotiations for use of trailer protocol: 290 * ARP replies for protocol type ETHERTYPE_TRAIL are sent 291 * along with IP replies if we want trailers sent to us, 292 * and also send them in response to IP replies. 293 * This allows either end to announce the desire to receive 294 * trailer packets. 295 * We reply to requests for ETHERTYPE_TRAIL protocol as well, 296 * but don't normally send requests. 297 */ 298 in_arpinput(ac, m) 299 register struct arpcom *ac; 300 struct mbuf *m; 301 { 302 register struct ether_arp *ea; 303 struct ether_header *eh; 304 register struct arptab *at; /* same as "merge" flag */ 305 register struct in_ifaddr *ia; 306 struct in_ifaddr *maybe_ia = 0; 307 struct mbuf *mcopy = 0; 308 struct sockaddr_in sin; 309 struct sockaddr sa; 310 struct in_addr isaddr, itaddr, myaddr; 311 int proto, op, s, completed = 0; 312 313 ea = mtod(m, struct ether_arp *); 314 proto = ntohs(ea->arp_pro); 315 op = ntohs(ea->arp_op); 316 bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr)); 317 bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr)); 318 for (ia = in_ifaddr; ia; ia = ia->ia_next) 319 if (ia->ia_ifp == &ac->ac_if) { 320 maybe_ia = ia; 321 if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) || 322 (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)) 323 break; 324 } 325 if (maybe_ia == 0) 326 goto out; 327 myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr; 328 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr, 329 sizeof (ea->arp_sha))) 330 goto out; /* it's from me, ignore it. */ 331 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr, 332 sizeof (ea->arp_sha))) { 333 log(LOG_ERR, 334 "arp: ether address is broadcast for IP address %x!\n", 335 ntohl(isaddr.s_addr)); 336 goto out; 337 } 338 if (isaddr.s_addr == myaddr.s_addr) { 339 log(LOG_ERR, 340 "duplicate IP address %x!! sent from ethernet address: %s\n", 341 ntohl(isaddr.s_addr), ether_sprintf(ea->arp_sha)); 342 itaddr = myaddr; 343 if (op == ARPOP_REQUEST) 344 goto reply; 345 goto out; 346 } 347 s = splimp(); 348 ARPTAB_LOOK(at, isaddr.s_addr); 349 if (at) { 350 bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr, 351 sizeof(ea->arp_sha)); 352 if ((at->at_flags & ATF_COM) == 0) 353 completed = 1; 354 at->at_flags |= ATF_COM; 355 if (at->at_hold) { 356 sin.sin_family = AF_INET; 357 sin.sin_addr = isaddr; 358 (*ac->ac_if.if_output)(&ac->ac_if, 359 at->at_hold, (struct sockaddr *)&sin); 360 at->at_hold = 0; 361 } 362 } 363 if (at == 0 && itaddr.s_addr == myaddr.s_addr) { 364 /* ensure we have a table entry */ 365 if (at = arptnew(&isaddr)) { 366 bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr, 367 sizeof(ea->arp_sha)); 368 completed = 1; 369 at->at_flags |= ATF_COM; 370 } 371 } 372 splx(s); 373 reply: 374 switch (proto) { 375 376 case ETHERTYPE_IPTRAILERS: 377 /* partner says trailers are OK */ 378 if (at) 379 at->at_flags |= ATF_USETRAILERS; 380 /* 381 * Reply to request iff we want trailers. 382 */ 383 if (op != ARPOP_REQUEST || ac->ac_if.if_flags & IFF_NOTRAILERS) 384 goto out; 385 break; 386 387 case ETHERTYPE_IP: 388 /* 389 * Reply if this is an IP request, 390 * or if we want to send a trailer response. 391 * Send the latter only to the IP response 392 * that completes the current ARP entry. 393 */ 394 if (op != ARPOP_REQUEST && 395 (completed == 0 || ac->ac_if.if_flags & IFF_NOTRAILERS)) 396 goto out; 397 } 398 if (itaddr.s_addr == myaddr.s_addr) { 399 /* I am the target */ 400 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha, 401 sizeof(ea->arp_sha)); 402 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha, 403 sizeof(ea->arp_sha)); 404 } else { 405 ARPTAB_LOOK(at, itaddr.s_addr); 406 if (at == NULL || (at->at_flags & ATF_PUBL) == 0) 407 goto out; 408 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha, 409 sizeof(ea->arp_sha)); 410 bcopy((caddr_t)at->at_enaddr, (caddr_t)ea->arp_sha, 411 sizeof(ea->arp_sha)); 412 } 413 414 bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, 415 sizeof(ea->arp_spa)); 416 bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, 417 sizeof(ea->arp_spa)); 418 ea->arp_op = htons(ARPOP_REPLY); 419 /* 420 * If incoming packet was an IP reply, 421 * we are sending a reply for type IPTRAILERS. 422 * If we are sending a reply for type IP 423 * and we want to receive trailers, 424 * send a trailer reply as well. 425 */ 426 if (op == ARPOP_REPLY) 427 ea->arp_pro = htons(ETHERTYPE_IPTRAILERS); 428 else if (proto == ETHERTYPE_IP && 429 (ac->ac_if.if_flags & IFF_NOTRAILERS) == 0) 430 mcopy = m_copy(m, 0, (int)M_COPYALL); 431 eh = (struct ether_header *)sa.sa_data; 432 bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost, 433 sizeof(eh->ether_dhost)); 434 eh->ether_type = ETHERTYPE_ARP; 435 sa.sa_family = AF_UNSPEC; 436 sa.sa_len = sizeof(sa); 437 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa); 438 if (mcopy) { 439 ea = mtod(mcopy, struct ether_arp *); 440 ea->arp_pro = htons(ETHERTYPE_IPTRAILERS); 441 (*ac->ac_if.if_output)(&ac->ac_if, mcopy, &sa); 442 } 443 return; 444 out: 445 m_freem(m); 446 return; 447 } 448 449 /* 450 * Free an arptab entry. 451 */ 452 arptfree(at) 453 register struct arptab *at; 454 { 455 int s = splimp(); 456 457 if (at->at_hold) 458 m_freem(at->at_hold); 459 at->at_hold = 0; 460 at->at_timer = at->at_flags = 0; 461 at->at_iaddr.s_addr = 0; 462 splx(s); 463 } 464 465 /* 466 * Enter a new address in arptab, pushing out the oldest entry 467 * from the bucket if there is no room. 468 * This always succeeds since no bucket can be completely filled 469 * with permanent entries (except from arpioctl when testing whether 470 * another permanent entry will fit). 471 * MUST BE CALLED AT SPLIMP. 472 */ 473 struct arptab * 474 arptnew(addr) 475 struct in_addr *addr; 476 { 477 register n; 478 int oldest = -1; 479 register struct arptab *at, *ato = NULL; 480 static int first = 1; 481 482 if (first) { 483 first = 0; 484 timeout(arptimer, (caddr_t)0, hz); 485 } 486 at = &arptab[ARPTAB_HASH(addr->s_addr) * ARPTAB_BSIZ]; 487 for (n = 0; n < ARPTAB_BSIZ; n++,at++) { 488 if (at->at_flags == 0) 489 goto out; /* found an empty entry */ 490 if (at->at_flags & ATF_PERM) 491 continue; 492 if ((int) at->at_timer > oldest) { 493 oldest = at->at_timer; 494 ato = at; 495 } 496 } 497 if (ato == NULL) 498 return (NULL); 499 at = ato; 500 arptfree(at); 501 out: 502 at->at_iaddr = *addr; 503 at->at_flags = ATF_INUSE; 504 return (at); 505 } 506 507 arpioctl(cmd, data) 508 int cmd; 509 caddr_t data; 510 { 511 register struct arpreq *ar = (struct arpreq *)data; 512 register struct arptab *at; 513 register struct sockaddr_in *sin; 514 int s; 515 516 sin = (struct sockaddr_in *)&ar->arp_ha; 517 #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN 518 if (sin->sin_family == 0 && sin->sin_len < 16) 519 sin->sin_family = sin->sin_len; 520 #endif 521 sin->sin_len = sizeof(ar->arp_ha); 522 sin = (struct sockaddr_in *)&ar->arp_pa; 523 #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN 524 if (sin->sin_family == 0 && sin->sin_len < 16) 525 sin->sin_family = sin->sin_len; 526 #endif 527 sin->sin_len = sizeof(ar->arp_pa); 528 if (ar->arp_pa.sa_family != AF_INET || 529 ar->arp_ha.sa_family != AF_UNSPEC) 530 return (EAFNOSUPPORT); 531 s = splimp(); 532 ARPTAB_LOOK(at, sin->sin_addr.s_addr); 533 if (at == NULL) { /* not found */ 534 if (cmd != SIOCSARP) { 535 splx(s); 536 return (ENXIO); 537 } 538 if (ifa_ifwithnet(&ar->arp_pa) == NULL) { 539 splx(s); 540 return (ENETUNREACH); 541 } 542 } 543 switch (cmd) { 544 545 case SIOCSARP: /* set entry */ 546 if (at == NULL) { 547 at = arptnew(&sin->sin_addr); 548 if (at == NULL) { 549 splx(s); 550 return (EADDRNOTAVAIL); 551 } 552 if (ar->arp_flags & ATF_PERM) { 553 /* never make all entries in a bucket permanent */ 554 register struct arptab *tat; 555 556 /* try to re-allocate */ 557 tat = arptnew(&sin->sin_addr); 558 if (tat == NULL) { 559 arptfree(at); 560 splx(s); 561 return (EADDRNOTAVAIL); 562 } 563 arptfree(tat); 564 } 565 } 566 bcopy((caddr_t)ar->arp_ha.sa_data, (caddr_t)at->at_enaddr, 567 sizeof(at->at_enaddr)); 568 at->at_flags = ATF_COM | ATF_INUSE | 569 (ar->arp_flags & (ATF_PERM|ATF_PUBL|ATF_USETRAILERS)); 570 at->at_timer = 0; 571 break; 572 573 case SIOCDARP: /* delete entry */ 574 arptfree(at); 575 break; 576 577 case SIOCGARP: /* get entry */ 578 case OSIOCGARP: 579 bcopy((caddr_t)at->at_enaddr, (caddr_t)ar->arp_ha.sa_data, 580 sizeof(at->at_enaddr)); 581 #ifdef COMPAT_43 582 if (cmd == OSIOCGARP) 583 *(u_short *)&ar->arp_ha = ar->arp_ha.sa_family; 584 #endif 585 ar->arp_flags = at->at_flags; 586 break; 587 } 588 splx(s); 589 return (0); 590 } 591