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