1 /* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)if.c 8.4 (Berkeley) 07/01/94 8 */ 9 10 #include <sys/param.h> 11 #include <sys/mbuf.h> 12 #include <sys/systm.h> 13 #include <sys/proc.h> 14 #include <sys/socket.h> 15 #include <sys/socketvar.h> 16 #include <sys/protosw.h> 17 #include <sys/kernel.h> 18 #include <sys/ioctl.h> 19 20 #include <net/if.h> 21 #include <net/if_dl.h> 22 #include <net/if_types.h> 23 24 int ifqmaxlen = IFQ_MAXLEN; 25 void if_slowtimo __P((void *arg)); 26 27 /* 28 * Network interface utility routines. 29 * 30 * Routines with ifa_ifwith* names take sockaddr *'s as 31 * parameters. 32 */ 33 void 34 ifinit() 35 { 36 register struct ifnet *ifp; 37 38 for (ifp = ifnet; ifp; ifp = ifp->if_next) 39 if (ifp->if_snd.ifq_maxlen == 0) 40 ifp->if_snd.ifq_maxlen = ifqmaxlen; 41 if_slowtimo(0); 42 } 43 44 #ifdef vax 45 /* 46 * Call each interface on a Unibus reset. 47 */ 48 void 49 ifubareset(uban) 50 int uban; 51 { 52 register struct ifnet *ifp; 53 54 for (ifp = ifnet; ifp; ifp = ifp->if_next) 55 if (ifp->if_reset) 56 (*ifp->if_reset)(ifp->if_unit, uban); 57 } 58 #endif 59 60 int if_index = 0; 61 struct ifaddr **ifnet_addrs; 62 static char *sprint_d __P((u_int, char *, int)); 63 64 /* 65 * Attach an interface to the 66 * list of "active" interfaces. 67 */ 68 void 69 if_attach(ifp) 70 struct ifnet *ifp; 71 { 72 unsigned socksize, ifasize; 73 int namelen, unitlen, masklen, ether_output(); 74 char workbuf[12], *unitname; 75 register struct ifnet **p = &ifnet; 76 register struct sockaddr_dl *sdl; 77 register struct ifaddr *ifa; 78 static int if_indexlim = 8; 79 extern void link_rtrequest(); 80 81 while (*p) 82 p = &((*p)->if_next); 83 *p = ifp; 84 ifp->if_index = ++if_index; 85 if (ifnet_addrs == 0 || if_index >= if_indexlim) { 86 unsigned n = (if_indexlim <<= 1) * sizeof(ifa); 87 struct ifaddr **q = (struct ifaddr **) 88 malloc(n, M_IFADDR, M_WAITOK); 89 if (ifnet_addrs) { 90 bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); 91 free((caddr_t)ifnet_addrs, M_IFADDR); 92 } 93 ifnet_addrs = q; 94 } 95 /* 96 * create a Link Level name for this device 97 */ 98 unitname = sprint_d((u_int)ifp->if_unit, workbuf, sizeof(workbuf)); 99 namelen = strlen(ifp->if_name); 100 unitlen = strlen(unitname); 101 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) 102 masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + 103 unitlen + namelen; 104 socksize = masklen + ifp->if_addrlen; 105 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) 106 socksize = ROUNDUP(socksize); 107 if (socksize < sizeof(*sdl)) 108 socksize = sizeof(*sdl); 109 ifasize = sizeof(*ifa) + 2 * socksize; 110 if (ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK)) { 111 bzero((caddr_t)ifa, ifasize); 112 sdl = (struct sockaddr_dl *)(ifa + 1); 113 sdl->sdl_len = socksize; 114 sdl->sdl_family = AF_LINK; 115 bcopy(ifp->if_name, sdl->sdl_data, namelen); 116 bcopy(unitname, namelen + (caddr_t)sdl->sdl_data, unitlen); 117 sdl->sdl_nlen = (namelen += unitlen); 118 sdl->sdl_index = ifp->if_index; 119 sdl->sdl_type = ifp->if_type; 120 ifnet_addrs[if_index - 1] = ifa; 121 ifa->ifa_ifp = ifp; 122 ifa->ifa_next = ifp->if_addrlist; 123 ifa->ifa_rtrequest = link_rtrequest; 124 ifp->if_addrlist = ifa; 125 ifa->ifa_addr = (struct sockaddr *)sdl; 126 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 127 ifa->ifa_netmask = (struct sockaddr *)sdl; 128 sdl->sdl_len = masklen; 129 while (namelen != 0) 130 sdl->sdl_data[--namelen] = 0xff; 131 } 132 /* XXX -- Temporary fix before changing 10 ethernet drivers */ 133 if (ifp->if_output == ether_output) 134 ether_ifattach(ifp); 135 } 136 /* 137 * Locate an interface based on a complete address. 138 */ 139 /*ARGSUSED*/ 140 struct ifaddr * 141 ifa_ifwithaddr(addr) 142 register struct sockaddr *addr; 143 { 144 register struct ifnet *ifp; 145 register struct ifaddr *ifa; 146 147 #define equal(a1, a2) \ 148 (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) 149 for (ifp = ifnet; ifp; ifp = ifp->if_next) 150 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 151 if (ifa->ifa_addr->sa_family != addr->sa_family) 152 continue; 153 if (equal(addr, ifa->ifa_addr)) 154 return (ifa); 155 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && 156 equal(ifa->ifa_broadaddr, addr)) 157 return (ifa); 158 } 159 return ((struct ifaddr *)0); 160 } 161 /* 162 * Locate the point to point interface with a given destination address. 163 */ 164 /*ARGSUSED*/ 165 struct ifaddr * 166 ifa_ifwithdstaddr(addr) 167 register struct sockaddr *addr; 168 { 169 register struct ifnet *ifp; 170 register struct ifaddr *ifa; 171 172 for (ifp = ifnet; ifp; ifp = ifp->if_next) 173 if (ifp->if_flags & IFF_POINTOPOINT) 174 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 175 if (ifa->ifa_addr->sa_family != addr->sa_family || 176 ifa->ifa_dstaddr == NULL) 177 continue; 178 if (equal(addr, ifa->ifa_dstaddr)) 179 return (ifa); 180 } 181 return ((struct ifaddr *)0); 182 } 183 184 /* 185 * Find an interface on a specific network. If many, choice 186 * is most specific found. 187 */ 188 struct ifaddr * 189 ifa_ifwithnet(addr) 190 struct sockaddr *addr; 191 { 192 register struct ifnet *ifp; 193 register struct ifaddr *ifa; 194 struct ifaddr *ifa_maybe = (struct ifaddr *) 0; 195 u_int af = addr->sa_family; 196 char *addr_data = addr->sa_data, *cplim; 197 198 if (af == AF_LINK) { 199 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; 200 if (sdl->sdl_index && sdl->sdl_index <= if_index) 201 return (ifnet_addrs[sdl->sdl_index - 1]); 202 } 203 for (ifp = ifnet; ifp; ifp = ifp->if_next) 204 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 205 register char *cp, *cp2, *cp3; 206 207 if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0) 208 next: continue; 209 cp = addr_data; 210 cp2 = ifa->ifa_addr->sa_data; 211 cp3 = ifa->ifa_netmask->sa_data; 212 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 213 while (cp3 < cplim) 214 if ((*cp++ ^ *cp2++) & *cp3++) 215 goto next; 216 if (ifa_maybe == 0 || 217 rn_refines((caddr_t)ifa->ifa_netmask, 218 (caddr_t)ifa_maybe->ifa_netmask)) 219 ifa_maybe = ifa; 220 } 221 return (ifa_maybe); 222 } 223 224 /* 225 * Find an interface using a specific address family 226 */ 227 struct ifaddr * 228 ifa_ifwithaf(af) 229 register int af; 230 { 231 register struct ifnet *ifp; 232 register struct ifaddr *ifa; 233 234 for (ifp = ifnet; ifp; ifp = ifp->if_next) 235 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 236 if (ifa->ifa_addr->sa_family == af) 237 return (ifa); 238 return ((struct ifaddr *)0); 239 } 240 241 /* 242 * Find an interface address specific to an interface best matching 243 * a given address. 244 */ 245 struct ifaddr * 246 ifaof_ifpforaddr(addr, ifp) 247 struct sockaddr *addr; 248 register struct ifnet *ifp; 249 { 250 register struct ifaddr *ifa; 251 register char *cp, *cp2, *cp3; 252 register char *cplim; 253 struct ifaddr *ifa_maybe = 0; 254 u_int af = addr->sa_family; 255 256 if (af >= AF_MAX) 257 return (0); 258 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 259 if (ifa->ifa_addr->sa_family != af) 260 continue; 261 ifa_maybe = ifa; 262 if (ifa->ifa_netmask == 0) { 263 if (equal(addr, ifa->ifa_addr) || 264 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) 265 return (ifa); 266 continue; 267 } 268 cp = addr->sa_data; 269 cp2 = ifa->ifa_addr->sa_data; 270 cp3 = ifa->ifa_netmask->sa_data; 271 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 272 for (; cp3 < cplim; cp3++) 273 if ((*cp++ ^ *cp2++) & *cp3) 274 break; 275 if (cp3 == cplim) 276 return (ifa); 277 } 278 return (ifa_maybe); 279 } 280 281 #include <net/route.h> 282 283 /* 284 * Default action when installing a route with a Link Level gateway. 285 * Lookup an appropriate real ifa to point to. 286 * This should be moved to /sys/net/link.c eventually. 287 */ 288 void 289 link_rtrequest(cmd, rt, sa) 290 int cmd; 291 register struct rtentry *rt; 292 struct sockaddr *sa; 293 { 294 register struct ifaddr *ifa; 295 struct sockaddr *dst; 296 struct ifnet *ifp; 297 298 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 299 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 300 return; 301 if (ifa = ifaof_ifpforaddr(dst, ifp)) { 302 IFAFREE(rt->rt_ifa); 303 rt->rt_ifa = ifa; 304 ifa->ifa_refcnt++; 305 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 306 ifa->ifa_rtrequest(cmd, rt, sa); 307 } 308 } 309 310 /* 311 * Mark an interface down and notify protocols of 312 * the transition. 313 * NOTE: must be called at splnet or eqivalent. 314 */ 315 void 316 if_down(ifp) 317 register struct ifnet *ifp; 318 { 319 register struct ifaddr *ifa; 320 321 ifp->if_flags &= ~IFF_UP; 322 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 323 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 324 if_qflush(&ifp->if_snd); 325 rt_ifmsg(ifp); 326 } 327 328 /* 329 * Mark an interface up and notify protocols of 330 * the transition. 331 * NOTE: must be called at splnet or eqivalent. 332 */ 333 void 334 if_up(ifp) 335 register struct ifnet *ifp; 336 { 337 register struct ifaddr *ifa; 338 339 ifp->if_flags |= IFF_UP; 340 #ifdef notyet 341 /* this has no effect on IP, and will kill all iso connections XXX */ 342 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 343 pfctlinput(PRC_IFUP, ifa->ifa_addr); 344 #endif 345 rt_ifmsg(ifp); 346 } 347 348 /* 349 * Flush an interface queue. 350 */ 351 void 352 if_qflush(ifq) 353 register struct ifqueue *ifq; 354 { 355 register struct mbuf *m, *n; 356 357 n = ifq->ifq_head; 358 while (m = n) { 359 n = m->m_act; 360 m_freem(m); 361 } 362 ifq->ifq_head = 0; 363 ifq->ifq_tail = 0; 364 ifq->ifq_len = 0; 365 } 366 367 /* 368 * Handle interface watchdog timer routines. Called 369 * from softclock, we decrement timers (if set) and 370 * call the appropriate interface routine on expiration. 371 */ 372 void 373 if_slowtimo(arg) 374 void *arg; 375 { 376 register struct ifnet *ifp; 377 int s = splimp(); 378 379 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 380 if (ifp->if_timer == 0 || --ifp->if_timer) 381 continue; 382 if (ifp->if_watchdog) 383 (*ifp->if_watchdog)(ifp->if_unit); 384 } 385 splx(s); 386 timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); 387 } 388 389 /* 390 * Map interface name to 391 * interface structure pointer. 392 */ 393 struct ifnet * 394 ifunit(name) 395 register char *name; 396 { 397 register char *cp; 398 register struct ifnet *ifp; 399 int unit; 400 unsigned len; 401 char *ep, c; 402 403 for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) 404 if (*cp >= '0' && *cp <= '9') 405 break; 406 if (*cp == '\0' || cp == name + IFNAMSIZ) 407 return ((struct ifnet *)0); 408 /* 409 * Save first char of unit, and pointer to it, 410 * so we can put a null there to avoid matching 411 * initial substrings of interface names. 412 */ 413 len = cp - name + 1; 414 c = *cp; 415 ep = cp; 416 for (unit = 0; *cp >= '0' && *cp <= '9'; ) 417 unit = unit * 10 + *cp++ - '0'; 418 *ep = 0; 419 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 420 if (bcmp(ifp->if_name, name, len)) 421 continue; 422 if (unit == ifp->if_unit) 423 break; 424 } 425 *ep = c; 426 return (ifp); 427 } 428 429 /* 430 * Interface ioctls. 431 */ 432 int 433 ifioctl(so, cmd, data, p) 434 struct socket *so; 435 int cmd; 436 caddr_t data; 437 struct proc *p; 438 { 439 register struct ifnet *ifp; 440 register struct ifreq *ifr; 441 int error; 442 443 switch (cmd) { 444 445 case SIOCGIFCONF: 446 case OSIOCGIFCONF: 447 return (ifconf(cmd, data)); 448 } 449 ifr = (struct ifreq *)data; 450 ifp = ifunit(ifr->ifr_name); 451 if (ifp == 0) 452 return (ENXIO); 453 switch (cmd) { 454 455 case SIOCGIFFLAGS: 456 ifr->ifr_flags = ifp->if_flags; 457 break; 458 459 case SIOCGIFMETRIC: 460 ifr->ifr_metric = ifp->if_metric; 461 break; 462 463 case SIOCSIFFLAGS: 464 if (error = suser(p->p_ucred, &p->p_acflag)) 465 return (error); 466 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 467 int s = splimp(); 468 if_down(ifp); 469 splx(s); 470 } 471 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 472 int s = splimp(); 473 if_up(ifp); 474 splx(s); 475 } 476 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 477 (ifr->ifr_flags &~ IFF_CANTCHANGE); 478 if (ifp->if_ioctl) 479 (void) (*ifp->if_ioctl)(ifp, cmd, data); 480 break; 481 482 case SIOCSIFMETRIC: 483 if (error = suser(p->p_ucred, &p->p_acflag)) 484 return (error); 485 ifp->if_metric = ifr->ifr_metric; 486 break; 487 488 case SIOCADDMULTI: 489 case SIOCDELMULTI: 490 if (error = suser(p->p_ucred, &p->p_acflag)) 491 return (error); 492 if (ifp->if_ioctl == NULL) 493 return (EOPNOTSUPP); 494 return ((*ifp->if_ioctl)(ifp, cmd, data)); 495 496 default: 497 if (so->so_proto == 0) 498 return (EOPNOTSUPP); 499 #ifndef COMPAT_43 500 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 501 cmd, data, ifp)); 502 #else 503 { 504 int ocmd = cmd; 505 506 switch (cmd) { 507 508 case SIOCSIFDSTADDR: 509 case SIOCSIFADDR: 510 case SIOCSIFBRDADDR: 511 case SIOCSIFNETMASK: 512 #if BYTE_ORDER != BIG_ENDIAN 513 if (ifr->ifr_addr.sa_family == 0 && 514 ifr->ifr_addr.sa_len < 16) { 515 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 516 ifr->ifr_addr.sa_len = 16; 517 } 518 #else 519 if (ifr->ifr_addr.sa_len == 0) 520 ifr->ifr_addr.sa_len = 16; 521 #endif 522 break; 523 524 case OSIOCGIFADDR: 525 cmd = SIOCGIFADDR; 526 break; 527 528 case OSIOCGIFDSTADDR: 529 cmd = SIOCGIFDSTADDR; 530 break; 531 532 case OSIOCGIFBRDADDR: 533 cmd = SIOCGIFBRDADDR; 534 break; 535 536 case OSIOCGIFNETMASK: 537 cmd = SIOCGIFNETMASK; 538 } 539 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 540 cmd, data, ifp)); 541 switch (ocmd) { 542 543 case OSIOCGIFADDR: 544 case OSIOCGIFDSTADDR: 545 case OSIOCGIFBRDADDR: 546 case OSIOCGIFNETMASK: 547 *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 548 } 549 return (error); 550 551 } 552 #endif 553 } 554 return (0); 555 } 556 557 /* 558 * Return interface configuration 559 * of system. List may be used 560 * in later ioctl's (above) to get 561 * other information. 562 */ 563 /*ARGSUSED*/ 564 int 565 ifconf(cmd, data) 566 int cmd; 567 caddr_t data; 568 { 569 register struct ifconf *ifc = (struct ifconf *)data; 570 register struct ifnet *ifp = ifnet; 571 register struct ifaddr *ifa; 572 register char *cp, *ep; 573 struct ifreq ifr, *ifrp; 574 int space = ifc->ifc_len, error = 0; 575 576 ifrp = ifc->ifc_req; 577 ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2; 578 for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { 579 strncpy(ifr.ifr_name, ifp->if_name, sizeof (ifr.ifr_name) - 2); 580 for (cp = ifr.ifr_name; cp < ep && *cp; cp++) 581 continue; 582 *cp++ = '0' + ifp->if_unit; *cp = '\0'; 583 if ((ifa = ifp->if_addrlist) == 0) { 584 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 585 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 586 sizeof (ifr)); 587 if (error) 588 break; 589 space -= sizeof (ifr), ifrp++; 590 } else 591 for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) { 592 register struct sockaddr *sa = ifa->ifa_addr; 593 #ifdef COMPAT_43 594 if (cmd == OSIOCGIFCONF) { 595 struct osockaddr *osa = 596 (struct osockaddr *)&ifr.ifr_addr; 597 ifr.ifr_addr = *sa; 598 osa->sa_family = sa->sa_family; 599 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 600 sizeof (ifr)); 601 ifrp++; 602 } else 603 #endif 604 if (sa->sa_len <= sizeof(*sa)) { 605 ifr.ifr_addr = *sa; 606 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 607 sizeof (ifr)); 608 ifrp++; 609 } else { 610 space -= sa->sa_len - sizeof(*sa); 611 if (space < sizeof (ifr)) 612 break; 613 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 614 sizeof (ifr.ifr_name)); 615 if (error == 0) 616 error = copyout((caddr_t)sa, 617 (caddr_t)&ifrp->ifr_addr, sa->sa_len); 618 ifrp = (struct ifreq *) 619 (sa->sa_len + (caddr_t)&ifrp->ifr_addr); 620 } 621 if (error) 622 break; 623 space -= sizeof (ifr); 624 } 625 } 626 ifc->ifc_len -= space; 627 return (error); 628 } 629 630 static char * 631 sprint_d(n, buf, buflen) 632 u_int n; 633 char *buf; 634 int buflen; 635 { 636 register char *cp = buf + buflen - 1; 637 638 *cp = 0; 639 do { 640 cp--; 641 *cp = "0123456789"[n % 10]; 642 n /= 10; 643 } while (n != 0); 644 return (cp); 645 } 646