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