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.3 (Berkeley) 01/04/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 continue; 177 if (equal(addr, ifa->ifa_dstaddr)) 178 return (ifa); 179 } 180 return ((struct ifaddr *)0); 181 } 182 183 /* 184 * Find an interface on a specific network. If many, choice 185 * is most specific found. 186 */ 187 struct ifaddr * 188 ifa_ifwithnet(addr) 189 struct sockaddr *addr; 190 { 191 register struct ifnet *ifp; 192 register struct ifaddr *ifa; 193 struct ifaddr *ifa_maybe = (struct ifaddr *) 0; 194 u_int af = addr->sa_family; 195 char *addr_data = addr->sa_data, *cplim; 196 197 if (af == AF_LINK) { 198 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; 199 if (sdl->sdl_index && sdl->sdl_index <= if_index) 200 return (ifnet_addrs[sdl->sdl_index - 1]); 201 } 202 for (ifp = ifnet; ifp; ifp = ifp->if_next) 203 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 204 register char *cp, *cp2, *cp3; 205 206 if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0) 207 next: continue; 208 cp = addr_data; 209 cp2 = ifa->ifa_addr->sa_data; 210 cp3 = ifa->ifa_netmask->sa_data; 211 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 212 while (cp3 < cplim) 213 if ((*cp++ ^ *cp2++) & *cp3++) 214 goto next; 215 if (ifa_maybe == 0 || 216 rn_refines((caddr_t)ifa->ifa_netmask, 217 (caddr_t)ifa_maybe->ifa_netmask)) 218 ifa_maybe = ifa; 219 } 220 return (ifa_maybe); 221 } 222 223 /* 224 * Find an interface using a specific address family 225 */ 226 struct ifaddr * 227 ifa_ifwithaf(af) 228 register int af; 229 { 230 register struct ifnet *ifp; 231 register struct ifaddr *ifa; 232 233 for (ifp = ifnet; ifp; ifp = ifp->if_next) 234 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 235 if (ifa->ifa_addr->sa_family == af) 236 return (ifa); 237 return ((struct ifaddr *)0); 238 } 239 240 /* 241 * Find an interface address specific to an interface best matching 242 * a given address. 243 */ 244 struct ifaddr * 245 ifaof_ifpforaddr(addr, ifp) 246 struct sockaddr *addr; 247 register struct ifnet *ifp; 248 { 249 register struct ifaddr *ifa; 250 register char *cp, *cp2, *cp3; 251 register char *cplim; 252 struct ifaddr *ifa_maybe = 0; 253 u_int af = addr->sa_family; 254 255 if (af >= AF_MAX) 256 return (0); 257 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 258 if (ifa->ifa_addr->sa_family != af) 259 continue; 260 ifa_maybe = ifa; 261 if (ifa->ifa_netmask == 0) { 262 if (equal(addr, ifa->ifa_addr) || 263 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) 264 return (ifa); 265 continue; 266 } 267 cp = addr->sa_data; 268 cp2 = ifa->ifa_addr->sa_data; 269 cp3 = ifa->ifa_netmask->sa_data; 270 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 271 for (; cp3 < cplim; cp3++) 272 if ((*cp++ ^ *cp2++) & *cp3) 273 break; 274 if (cp3 == cplim) 275 return (ifa); 276 } 277 return (ifa_maybe); 278 } 279 280 #include <net/route.h> 281 282 /* 283 * Default action when installing a route with a Link Level gateway. 284 * Lookup an appropriate real ifa to point to. 285 * This should be moved to /sys/net/link.c eventually. 286 */ 287 void 288 link_rtrequest(cmd, rt, sa) 289 int cmd; 290 register struct rtentry *rt; 291 struct sockaddr *sa; 292 { 293 register struct ifaddr *ifa; 294 struct sockaddr *dst; 295 struct ifnet *ifp; 296 297 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 298 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 299 return; 300 if (ifa = ifaof_ifpforaddr(dst, ifp)) { 301 IFAFREE(rt->rt_ifa); 302 rt->rt_ifa = ifa; 303 ifa->ifa_refcnt++; 304 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 305 ifa->ifa_rtrequest(cmd, rt, sa); 306 } 307 } 308 309 /* 310 * Mark an interface down and notify protocols of 311 * the transition. 312 * NOTE: must be called at splnet or eqivalent. 313 */ 314 void 315 if_down(ifp) 316 register struct ifnet *ifp; 317 { 318 register struct ifaddr *ifa; 319 320 ifp->if_flags &= ~IFF_UP; 321 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 322 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 323 if_qflush(&ifp->if_snd); 324 rt_ifmsg(ifp); 325 } 326 327 /* 328 * Mark an interface up and notify protocols of 329 * the transition. 330 * NOTE: must be called at splnet or eqivalent. 331 */ 332 void 333 if_up(ifp) 334 register struct ifnet *ifp; 335 { 336 register struct ifaddr *ifa; 337 338 ifp->if_flags |= IFF_UP; 339 #ifdef notyet 340 /* this has no effect on IP, and will kill all iso connections XXX */ 341 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 342 pfctlinput(PRC_IFUP, ifa->ifa_addr); 343 #endif 344 rt_ifmsg(ifp); 345 } 346 347 /* 348 * Flush an interface queue. 349 */ 350 void 351 if_qflush(ifq) 352 register struct ifqueue *ifq; 353 { 354 register struct mbuf *m, *n; 355 356 n = ifq->ifq_head; 357 while (m = n) { 358 n = m->m_act; 359 m_freem(m); 360 } 361 ifq->ifq_head = 0; 362 ifq->ifq_tail = 0; 363 ifq->ifq_len = 0; 364 } 365 366 /* 367 * Handle interface watchdog timer routines. Called 368 * from softclock, we decrement timers (if set) and 369 * call the appropriate interface routine on expiration. 370 */ 371 void 372 if_slowtimo(arg) 373 void *arg; 374 { 375 register struct ifnet *ifp; 376 int s = splimp(); 377 378 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 379 if (ifp->if_timer == 0 || --ifp->if_timer) 380 continue; 381 if (ifp->if_watchdog) 382 (*ifp->if_watchdog)(ifp->if_unit); 383 } 384 splx(s); 385 timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); 386 } 387 388 /* 389 * Map interface name to 390 * interface structure pointer. 391 */ 392 struct ifnet * 393 ifunit(name) 394 register char *name; 395 { 396 register char *cp; 397 register struct ifnet *ifp; 398 int unit; 399 unsigned len; 400 char *ep, c; 401 402 for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) 403 if (*cp >= '0' && *cp <= '9') 404 break; 405 if (*cp == '\0' || cp == name + IFNAMSIZ) 406 return ((struct ifnet *)0); 407 /* 408 * Save first char of unit, and pointer to it, 409 * so we can put a null there to avoid matching 410 * initial substrings of interface names. 411 */ 412 len = cp - name + 1; 413 c = *cp; 414 ep = cp; 415 for (unit = 0; *cp >= '0' && *cp <= '9'; ) 416 unit = unit * 10 + *cp++ - '0'; 417 *ep = 0; 418 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 419 if (bcmp(ifp->if_name, name, len)) 420 continue; 421 if (unit == ifp->if_unit) 422 break; 423 } 424 *ep = c; 425 return (ifp); 426 } 427 428 /* 429 * Interface ioctls. 430 */ 431 int 432 ifioctl(so, cmd, data, p) 433 struct socket *so; 434 int cmd; 435 caddr_t data; 436 struct proc *p; 437 { 438 register struct ifnet *ifp; 439 register struct ifreq *ifr; 440 int error; 441 442 switch (cmd) { 443 444 case SIOCGIFCONF: 445 case OSIOCGIFCONF: 446 return (ifconf(cmd, data)); 447 } 448 ifr = (struct ifreq *)data; 449 ifp = ifunit(ifr->ifr_name); 450 if (ifp == 0) 451 return (ENXIO); 452 switch (cmd) { 453 454 case SIOCGIFFLAGS: 455 ifr->ifr_flags = ifp->if_flags; 456 break; 457 458 case SIOCGIFMETRIC: 459 ifr->ifr_metric = ifp->if_metric; 460 break; 461 462 case SIOCSIFFLAGS: 463 if (error = suser(p->p_ucred, &p->p_acflag)) 464 return (error); 465 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 466 int s = splimp(); 467 if_down(ifp); 468 splx(s); 469 } 470 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 471 int s = splimp(); 472 if_up(ifp); 473 splx(s); 474 } 475 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 476 (ifr->ifr_flags &~ IFF_CANTCHANGE); 477 if (ifp->if_ioctl) 478 (void) (*ifp->if_ioctl)(ifp, cmd, data); 479 break; 480 481 case SIOCSIFMETRIC: 482 if (error = suser(p->p_ucred, &p->p_acflag)) 483 return (error); 484 ifp->if_metric = ifr->ifr_metric; 485 break; 486 487 case SIOCADDMULTI: 488 case SIOCDELMULTI: 489 if (error = suser(p->p_ucred, &p->p_acflag)) 490 return (error); 491 if (ifp->if_ioctl == NULL) 492 return (EOPNOTSUPP); 493 return ((*ifp->if_ioctl)(ifp, cmd, data)); 494 495 default: 496 if (so->so_proto == 0) 497 return (EOPNOTSUPP); 498 #ifndef COMPAT_43 499 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 500 cmd, data, ifp)); 501 #else 502 { 503 int ocmd = cmd; 504 505 switch (cmd) { 506 507 case SIOCSIFDSTADDR: 508 case SIOCSIFADDR: 509 case SIOCSIFBRDADDR: 510 case SIOCSIFNETMASK: 511 #if BYTE_ORDER != BIG_ENDIAN 512 if (ifr->ifr_addr.sa_family == 0 && 513 ifr->ifr_addr.sa_len < 16) { 514 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 515 ifr->ifr_addr.sa_len = 16; 516 } 517 #else 518 if (ifr->ifr_addr.sa_len == 0) 519 ifr->ifr_addr.sa_len = 16; 520 #endif 521 break; 522 523 case OSIOCGIFADDR: 524 cmd = SIOCGIFADDR; 525 break; 526 527 case OSIOCGIFDSTADDR: 528 cmd = SIOCGIFDSTADDR; 529 break; 530 531 case OSIOCGIFBRDADDR: 532 cmd = SIOCGIFBRDADDR; 533 break; 534 535 case OSIOCGIFNETMASK: 536 cmd = SIOCGIFNETMASK; 537 } 538 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 539 cmd, data, ifp)); 540 switch (ocmd) { 541 542 case OSIOCGIFADDR: 543 case OSIOCGIFDSTADDR: 544 case OSIOCGIFBRDADDR: 545 case OSIOCGIFNETMASK: 546 *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 547 } 548 return (error); 549 550 } 551 #endif 552 } 553 return (0); 554 } 555 556 /* 557 * Return interface configuration 558 * of system. List may be used 559 * in later ioctl's (above) to get 560 * other information. 561 */ 562 /*ARGSUSED*/ 563 int 564 ifconf(cmd, data) 565 int cmd; 566 caddr_t data; 567 { 568 register struct ifconf *ifc = (struct ifconf *)data; 569 register struct ifnet *ifp = ifnet; 570 register struct ifaddr *ifa; 571 register char *cp, *ep; 572 struct ifreq ifr, *ifrp; 573 int space = ifc->ifc_len, error = 0; 574 575 ifrp = ifc->ifc_req; 576 ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2; 577 for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { 578 strncpy(ifr.ifr_name, ifp->if_name, sizeof (ifr.ifr_name) - 2); 579 for (cp = ifr.ifr_name; cp < ep && *cp; cp++) 580 continue; 581 *cp++ = '0' + ifp->if_unit; *cp = '\0'; 582 if ((ifa = ifp->if_addrlist) == 0) { 583 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 584 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 585 sizeof (ifr)); 586 if (error) 587 break; 588 space -= sizeof (ifr), ifrp++; 589 } else 590 for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) { 591 register struct sockaddr *sa = ifa->ifa_addr; 592 #ifdef COMPAT_43 593 if (cmd == OSIOCGIFCONF) { 594 struct osockaddr *osa = 595 (struct osockaddr *)&ifr.ifr_addr; 596 ifr.ifr_addr = *sa; 597 osa->sa_family = sa->sa_family; 598 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 599 sizeof (ifr)); 600 ifrp++; 601 } else 602 #endif 603 if (sa->sa_len <= sizeof(*sa)) { 604 ifr.ifr_addr = *sa; 605 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 606 sizeof (ifr)); 607 ifrp++; 608 } else { 609 space -= sa->sa_len - sizeof(*sa); 610 if (space < sizeof (ifr)) 611 break; 612 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 613 sizeof (ifr.ifr_name)); 614 if (error == 0) 615 error = copyout((caddr_t)sa, 616 (caddr_t)&ifrp->ifr_addr, sa->sa_len); 617 ifrp = (struct ifreq *) 618 (sa->sa_len + (caddr_t)&ifrp->ifr_addr); 619 } 620 if (error) 621 break; 622 space -= sizeof (ifr); 623 } 624 } 625 ifc->ifc_len -= space; 626 return (error); 627 } 628 629 static char * 630 sprint_d(n, buf, buflen) 631 u_int n; 632 char *buf; 633 int buflen; 634 { 635 register char *cp = buf + buflen - 1; 636 637 *cp = 0; 638 do { 639 cp--; 640 *cp = "0123456789"[n % 10]; 641 n /= 10; 642 } while (n != 0); 643 return (cp); 644 } 645