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