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