254{ 255 int s, error; 256 s = splnet(); 257 error = raw_usrreqs.pru_sockaddr(so, nam); 258 splx(s); 259 return error; 260} 261 262static struct pr_usrreqs route_usrreqs = { 263 rts_abort, pru_accept_notsupp, rts_attach, rts_bind, rts_connect, 264 pru_connect2_notsupp, pru_control_notsupp, rts_detach, rts_disconnect, 265 pru_listen_notsupp, rts_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, 266 rts_send, pru_sense_null, rts_shutdown, rts_sockaddr, 267 sosend, soreceive, soselect 268}; 269 270/*ARGSUSED*/ 271static int 272route_output(m, so) 273 register struct mbuf *m; 274 struct socket *so; 275{ 276 register struct rt_msghdr *rtm = 0; 277 register struct rtentry *rt = 0; 278 struct rtentry *saved_nrt = 0; 279 struct radix_node_head *rnh; 280 struct rt_addrinfo info; 281 int len, error = 0; 282 struct ifnet *ifp = 0; 283 struct ifaddr *ifa = 0; 284 285#define senderr(e) { error = e; goto flush;} 286 if (m == 0 || ((m->m_len < sizeof(long)) && 287 (m = m_pullup(m, sizeof(long))) == 0)) 288 return (ENOBUFS); 289 if ((m->m_flags & M_PKTHDR) == 0) 290 panic("route_output"); 291 len = m->m_pkthdr.len; 292 if (len < sizeof(*rtm) || 293 len != mtod(m, struct rt_msghdr *)->rtm_msglen) { 294 dst = 0; 295 senderr(EINVAL); 296 } 297 R_Malloc(rtm, struct rt_msghdr *, len); 298 if (rtm == 0) { 299 dst = 0; 300 senderr(ENOBUFS); 301 } 302 m_copydata(m, 0, len, (caddr_t)rtm); 303 if (rtm->rtm_version != RTM_VERSION) { 304 dst = 0; 305 senderr(EPROTONOSUPPORT); 306 } 307 rtm->rtm_pid = curproc->p_pid; 308 info.rti_addrs = rtm->rtm_addrs; 309 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 310 dst = 0; 311 senderr(EINVAL); 312 } 313 if (dst == 0 || (dst->sa_family >= AF_MAX) 314 || (gate != 0 && (gate->sa_family >= AF_MAX))) 315 senderr(EINVAL); 316 if (genmask) { 317 struct radix_node *t; 318 t = rn_addmask((caddr_t)genmask, 0, 1); 319 if (t && Bcmp(genmask, t->rn_key, *(u_char *)genmask) == 0) 320 genmask = (struct sockaddr *)(t->rn_key); 321 else 322 senderr(ENOBUFS); 323 } 324 switch (rtm->rtm_type) { 325 326 case RTM_ADD: 327 if (gate == 0) 328 senderr(EINVAL); 329 error = rtrequest(RTM_ADD, dst, gate, netmask, 330 rtm->rtm_flags, &saved_nrt); 331 if (error == 0 && saved_nrt) { 332 rt_setmetrics(rtm->rtm_inits, 333 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 334 saved_nrt->rt_refcnt--; 335 saved_nrt->rt_genmask = genmask; 336 } 337 break; 338 339 case RTM_DELETE: 340 error = rtrequest(RTM_DELETE, dst, gate, netmask, 341 rtm->rtm_flags, &saved_nrt); 342 if (error == 0) { 343 if ((rt = saved_nrt)) 344 rt->rt_refcnt++; 345 goto report; 346 } 347 break; 348 349 case RTM_GET: 350 case RTM_CHANGE: 351 case RTM_LOCK: 352 if ((rnh = rt_tables[dst->sa_family]) == 0) { 353 senderr(EAFNOSUPPORT); 354 } else if (rt = (struct rtentry *) 355 rnh->rnh_lookup(dst, netmask, rnh)) 356 rt->rt_refcnt++; 357 else 358 senderr(ESRCH); 359 switch(rtm->rtm_type) { 360 361 case RTM_GET: 362 report: 363 dst = rt_key(rt); 364 gate = rt->rt_gateway; 365 netmask = rt_mask(rt); 366 genmask = rt->rt_genmask; 367 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 368 ifp = rt->rt_ifp; 369 if (ifp) { 370 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 371 ifaaddr = rt->rt_ifa->ifa_addr; 372 rtm->rtm_index = ifp->if_index; 373 } else { 374 ifpaddr = 0; 375 ifaaddr = 0; 376 } 377 } 378 len = rt_msg2(rtm->rtm_type, &info, (caddr_t)0, 379 (struct walkarg *)0); 380 if (len > rtm->rtm_msglen) { 381 struct rt_msghdr *new_rtm; 382 R_Malloc(new_rtm, struct rt_msghdr *, len); 383 if (new_rtm == 0) 384 senderr(ENOBUFS); 385 Bcopy(rtm, new_rtm, rtm->rtm_msglen); 386 Free(rtm); rtm = new_rtm; 387 } 388 (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, 389 (struct walkarg *)0); 390 rtm->rtm_flags = rt->rt_flags; 391 rtm->rtm_rmx = rt->rt_rmx; 392 rtm->rtm_addrs = info.rti_addrs; 393 break; 394 395 case RTM_CHANGE: 396 if (gate && (error = rt_setgate(rt, rt_key(rt), gate))) 397 senderr(error); 398 399 /* 400 * If they tried to change things but didn't specify 401 * the required gateway, then just use the old one. 402 * This can happen if the user tries to change the 403 * flags on the default route without changing the 404 * default gateway. Changing flags still doesn't work. 405 */ 406 if ((rt->rt_flags & RTF_GATEWAY) && !gate) 407 gate = rt->rt_gateway; 408 409 /* new gateway could require new ifaddr, ifp; 410 flags may also be different; ifp may be specified 411 by ll sockaddr when protocol address is ambiguous */ 412 if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) && 413 (ifp = ifa->ifa_ifp) && (ifaaddr || gate)) 414 ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, 415 ifp); 416 else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) || 417 (gate && (ifa = ifa_ifwithroute(rt->rt_flags, 418 rt_key(rt), gate)))) 419 ifp = ifa->ifa_ifp; 420 if (ifa) { 421 register struct ifaddr *oifa = rt->rt_ifa; 422 if (oifa != ifa) { 423 if (oifa && oifa->ifa_rtrequest) 424 oifa->ifa_rtrequest(RTM_DELETE, 425 rt, gate); 426 IFAFREE(rt->rt_ifa); 427 rt->rt_ifa = ifa; 428 ifa->ifa_refcnt++; 429 rt->rt_ifp = ifp; 430 } 431 } 432 rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 433 &rt->rt_rmx); 434 if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) 435 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate); 436 if (genmask) 437 rt->rt_genmask = genmask; 438 /* 439 * Fall into 440 */ 441 case RTM_LOCK: 442 rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); 443 rt->rt_rmx.rmx_locks |= 444 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); 445 break; 446 } 447 break; 448 449 default: 450 senderr(EOPNOTSUPP); 451 } 452 453flush: 454 if (rtm) { 455 if (error) 456 rtm->rtm_errno = error; 457 else 458 rtm->rtm_flags |= RTF_DONE; 459 } 460 if (rt) 461 rtfree(rt); 462 { 463 register struct rawcb *rp = 0; 464 /* 465 * Check to see if we don't want our own messages. 466 */ 467 if ((so->so_options & SO_USELOOPBACK) == 0) { 468 if (route_cb.any_count <= 1) { 469 if (rtm) 470 Free(rtm); 471 m_freem(m); 472 return (error); 473 } 474 /* There is another listener, so construct message */ 475 rp = sotorawcb(so); 476 } 477 if (rtm) { 478 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 479 Free(rtm); 480 } 481 if (rp) 482 rp->rcb_proto.sp_family = 0; /* Avoid us */ 483 if (dst) 484 route_proto.sp_protocol = dst->sa_family; 485 raw_input(m, &route_proto, &route_src, &route_dst); 486 if (rp) 487 rp->rcb_proto.sp_family = PF_ROUTE; 488 } 489 return (error); 490} 491 492static void 493rt_setmetrics(which, in, out) 494 u_long which; 495 register struct rt_metrics *in, *out; 496{ 497#define metric(f, e) if (which & (f)) out->e = in->e; 498 metric(RTV_RPIPE, rmx_recvpipe); 499 metric(RTV_SPIPE, rmx_sendpipe); 500 metric(RTV_SSTHRESH, rmx_ssthresh); 501 metric(RTV_RTT, rmx_rtt); 502 metric(RTV_RTTVAR, rmx_rttvar); 503 metric(RTV_HOPCOUNT, rmx_hopcount); 504 metric(RTV_MTU, rmx_mtu); 505 metric(RTV_EXPIRE, rmx_expire); 506#undef metric 507} 508 509#define ROUNDUP(a) \ 510 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 511#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 512 513 514/* 515 * Extract the addresses of the passed sockaddrs. 516 * Do a little sanity checking so as to avoid bad memory references. 517 * This data is derived straight from userland. 518 */ 519static int 520rt_xaddrs(cp, cplim, rtinfo) 521 register caddr_t cp, cplim; 522 register struct rt_addrinfo *rtinfo; 523{ 524 register struct sockaddr *sa; 525 register int i; 526 527 bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); 528 for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 529 if ((rtinfo->rti_addrs & (1 << i)) == 0) 530 continue; 531 sa = (struct sockaddr *)cp; 532 /* 533 * It won't fit. 534 */ 535 if ( (cp + sa->sa_len) > cplim ) { 536 return (EINVAL); 537 } 538 539 /* 540 * there are no more.. quit now 541 * If there are more bits, they are in error. 542 * I've seen this. route(1) can evidently generate these. 543 * This causes kernel to core dump. 544 * for compatibility, If we see this, point to a safe address. 545 */ 546 if (sa->sa_len == 0) { 547 rtinfo->rti_info[i] = &sa_zero; 548 return (0); /* should be EINVAL but for compat */ 549 } 550 551 /* accept it */ 552 rtinfo->rti_info[i] = sa; 553 ADVANCE(cp, sa); 554 } 555 return (0); 556} 557 558static struct mbuf * 559rt_msg1(type, rtinfo) 560 int type; 561 register struct rt_addrinfo *rtinfo; 562{ 563 register struct rt_msghdr *rtm; 564 register struct mbuf *m; 565 register int i; 566 register struct sockaddr *sa; 567 int len, dlen; 568 569 m = m_gethdr(M_DONTWAIT, MT_DATA); 570 if (m == 0) 571 return (m); 572 switch (type) { 573 574 case RTM_DELADDR: 575 case RTM_NEWADDR: 576 len = sizeof(struct ifa_msghdr); 577 break; 578 579 case RTM_DELMADDR: 580 case RTM_NEWMADDR: 581 len = sizeof(struct ifma_msghdr); 582 break; 583 584 case RTM_IFINFO: 585 len = sizeof(struct if_msghdr); 586 break; 587 588 default: 589 len = sizeof(struct rt_msghdr); 590 } 591 if (len > MHLEN) 592 panic("rt_msg1"); 593 m->m_pkthdr.len = m->m_len = len; 594 m->m_pkthdr.rcvif = 0; 595 rtm = mtod(m, struct rt_msghdr *); 596 bzero((caddr_t)rtm, len); 597 for (i = 0; i < RTAX_MAX; i++) { 598 if ((sa = rtinfo->rti_info[i]) == NULL) 599 continue; 600 rtinfo->rti_addrs |= (1 << i); 601 dlen = ROUNDUP(sa->sa_len); 602 m_copyback(m, len, dlen, (caddr_t)sa); 603 len += dlen; 604 } 605 if (m->m_pkthdr.len != len) { 606 m_freem(m); 607 return (NULL); 608 } 609 rtm->rtm_msglen = len; 610 rtm->rtm_version = RTM_VERSION; 611 rtm->rtm_type = type; 612 return (m); 613} 614 615static int 616rt_msg2(type, rtinfo, cp, w) 617 int type; 618 register struct rt_addrinfo *rtinfo; 619 caddr_t cp; 620 struct walkarg *w; 621{ 622 register int i; 623 int len, dlen, second_time = 0; 624 caddr_t cp0; 625 626 rtinfo->rti_addrs = 0; 627again: 628 switch (type) { 629 630 case RTM_DELADDR: 631 case RTM_NEWADDR: 632 len = sizeof(struct ifa_msghdr); 633 break; 634 635 case RTM_IFINFO: 636 len = sizeof(struct if_msghdr); 637 break; 638 639 default: 640 len = sizeof(struct rt_msghdr); 641 } 642 cp0 = cp; 643 if (cp0) 644 cp += len; 645 for (i = 0; i < RTAX_MAX; i++) { 646 register struct sockaddr *sa; 647 648 if ((sa = rtinfo->rti_info[i]) == 0) 649 continue; 650 rtinfo->rti_addrs |= (1 << i); 651 dlen = ROUNDUP(sa->sa_len); 652 if (cp) { 653 bcopy((caddr_t)sa, cp, (unsigned)dlen); 654 cp += dlen; 655 } 656 len += dlen; 657 } 658 if (cp == 0 && w != NULL && !second_time) { 659 register struct walkarg *rw = w; 660 661 if (rw->w_req) { 662 if (rw->w_tmemsize < len) { 663 if (rw->w_tmem) 664 free(rw->w_tmem, M_RTABLE); 665 rw->w_tmem = (caddr_t) 666 malloc(len, M_RTABLE, M_NOWAIT); 667 if (rw->w_tmem) 668 rw->w_tmemsize = len; 669 } 670 if (rw->w_tmem) { 671 cp = rw->w_tmem; 672 second_time = 1; 673 goto again; 674 } 675 } 676 } 677 if (cp) { 678 register struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; 679 680 rtm->rtm_version = RTM_VERSION; 681 rtm->rtm_type = type; 682 rtm->rtm_msglen = len; 683 } 684 return (len); 685} 686 687/* 688 * This routine is called to generate a message from the routing 689 * socket indicating that a redirect has occured, a routing lookup 690 * has failed, or that a protocol has detected timeouts to a particular 691 * destination. 692 */ 693void 694rt_missmsg(type, rtinfo, flags, error) 695 int type, flags, error; 696 register struct rt_addrinfo *rtinfo; 697{ 698 register struct rt_msghdr *rtm; 699 register struct mbuf *m; 700 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 701 702 if (route_cb.any_count == 0) 703 return; 704 m = rt_msg1(type, rtinfo); 705 if (m == 0) 706 return; 707 rtm = mtod(m, struct rt_msghdr *); 708 rtm->rtm_flags = RTF_DONE | flags; 709 rtm->rtm_errno = error; 710 rtm->rtm_addrs = rtinfo->rti_addrs; 711 route_proto.sp_protocol = sa ? sa->sa_family : 0; 712 raw_input(m, &route_proto, &route_src, &route_dst); 713} 714 715/* 716 * This routine is called to generate a message from the routing 717 * socket indicating that the status of a network interface has changed. 718 */ 719void 720rt_ifmsg(ifp) 721 register struct ifnet *ifp; 722{ 723 register struct if_msghdr *ifm; 724 struct mbuf *m; 725 struct rt_addrinfo info; 726 727 if (route_cb.any_count == 0) 728 return; 729 bzero((caddr_t)&info, sizeof(info)); 730 m = rt_msg1(RTM_IFINFO, &info); 731 if (m == 0) 732 return; 733 ifm = mtod(m, struct if_msghdr *); 734 ifm->ifm_index = ifp->if_index; 735 ifm->ifm_flags = (u_short)ifp->if_flags; 736 ifm->ifm_data = ifp->if_data; 737 ifm->ifm_addrs = 0; 738 route_proto.sp_protocol = 0; 739 raw_input(m, &route_proto, &route_src, &route_dst); 740} 741 742/* 743 * This is called to generate messages from the routing socket 744 * indicating a network interface has had addresses associated with it. 745 * if we ever reverse the logic and replace messages TO the routing 746 * socket indicate a request to configure interfaces, then it will 747 * be unnecessary as the routing socket will automatically generate 748 * copies of it. 749 */ 750void 751rt_newaddrmsg(cmd, ifa, error, rt) 752 int cmd, error; 753 register struct ifaddr *ifa; 754 register struct rtentry *rt; 755{ 756 struct rt_addrinfo info; 757 struct sockaddr *sa = 0; 758 int pass; 759 struct mbuf *m = 0; 760 struct ifnet *ifp = ifa->ifa_ifp; 761 762 if (route_cb.any_count == 0) 763 return; 764 for (pass = 1; pass < 3; pass++) { 765 bzero((caddr_t)&info, sizeof(info)); 766 if ((cmd == RTM_ADD && pass == 1) || 767 (cmd == RTM_DELETE && pass == 2)) { 768 register struct ifa_msghdr *ifam; 769 int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; 770 771 ifaaddr = sa = ifa->ifa_addr; 772 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 773 netmask = ifa->ifa_netmask; 774 brdaddr = ifa->ifa_dstaddr; 775 if ((m = rt_msg1(ncmd, &info)) == NULL) 776 continue; 777 ifam = mtod(m, struct ifa_msghdr *); 778 ifam->ifam_index = ifp->if_index; 779 ifam->ifam_metric = ifa->ifa_metric; 780 ifam->ifam_flags = ifa->ifa_flags; 781 ifam->ifam_addrs = info.rti_addrs; 782 } 783 if ((cmd == RTM_ADD && pass == 2) || 784 (cmd == RTM_DELETE && pass == 1)) { 785 register struct rt_msghdr *rtm; 786 787 if (rt == 0) 788 continue; 789 netmask = rt_mask(rt); 790 dst = sa = rt_key(rt); 791 gate = rt->rt_gateway; 792 if ((m = rt_msg1(cmd, &info)) == NULL) 793 continue; 794 rtm = mtod(m, struct rt_msghdr *); 795 rtm->rtm_index = ifp->if_index; 796 rtm->rtm_flags |= rt->rt_flags; 797 rtm->rtm_errno = error; 798 rtm->rtm_addrs = info.rti_addrs; 799 } 800 route_proto.sp_protocol = sa ? sa->sa_family : 0; 801 raw_input(m, &route_proto, &route_src, &route_dst); 802 } 803} 804 805/* 806 * This is the analogue to the rt_newaddrmsg which performs the same 807 * function but for multicast group memberhips. This is easier since 808 * there is no route state to worry about. 809 */ 810void 811rt_newmaddrmsg(cmd, ifma) 812 int cmd; 813 struct ifmultiaddr *ifma; 814{ 815 struct rt_addrinfo info; 816 struct mbuf *m = 0; 817 struct ifnet *ifp = ifma->ifma_ifp; 818 struct ifma_msghdr *ifmam; 819 820 if (route_cb.any_count == 0) 821 return; 822 823 bzero((caddr_t)&info, sizeof(info)); 824 ifaaddr = ifma->ifma_addr; 825 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 826 /* 827 * If a link-layer address is present, present it as a ``gateway'' 828 * (similarly to how ARP entries, e.g., are presented). 829 */ 830 gate = ifma->ifma_lladdr; 831 if ((m = rt_msg1(cmd, &info)) == NULL) 832 return; 833 ifmam = mtod(m, struct ifma_msghdr *); 834 ifmam->ifmam_index = ifp->if_index; 835 ifmam->ifmam_addrs = info.rti_addrs; 836 route_proto.sp_protocol = ifma->ifma_addr->sa_family; 837 raw_input(m, &route_proto, &route_src, &route_dst); 838} 839 840/* 841 * This is used in dumping the kernel table via sysctl(). 842 */ 843int 844sysctl_dumpentry(rn, vw) 845 struct radix_node *rn; 846 void *vw; 847{ 848 register struct walkarg *w = vw; 849 register struct rtentry *rt = (struct rtentry *)rn; 850 int error = 0, size; 851 struct rt_addrinfo info; 852 853 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 854 return 0; 855 bzero((caddr_t)&info, sizeof(info)); 856 dst = rt_key(rt); 857 gate = rt->rt_gateway; 858 netmask = rt_mask(rt); 859 genmask = rt->rt_genmask; 860 size = rt_msg2(RTM_GET, &info, 0, w); 861 if (w->w_req && w->w_tmem) { 862 register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 863 864 rtm->rtm_flags = rt->rt_flags; 865 rtm->rtm_use = rt->rt_use; 866 rtm->rtm_rmx = rt->rt_rmx; 867 rtm->rtm_index = rt->rt_ifp->if_index; 868 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 869 rtm->rtm_addrs = info.rti_addrs; 870 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); 871 return (error); 872 } 873 return (error); 874} 875 876int 877sysctl_iflist(af, w) 878 int af; 879 register struct walkarg *w; 880{ 881 register struct ifnet *ifp; 882 register struct ifaddr *ifa; 883 struct rt_addrinfo info; 884 int len, error = 0; 885 886 bzero((caddr_t)&info, sizeof(info)); 887 for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { 888 if (w->w_arg && w->w_arg != ifp->if_index) 889 continue; 890 ifa = ifp->if_addrhead.tqh_first; 891 ifpaddr = ifa->ifa_addr; 892 len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w); 893 ifpaddr = 0; 894 if (w->w_req && w->w_tmem) { 895 register struct if_msghdr *ifm; 896 897 ifm = (struct if_msghdr *)w->w_tmem; 898 ifm->ifm_index = ifp->if_index; 899 ifm->ifm_flags = (u_short)ifp->if_flags; 900 ifm->ifm_data = ifp->if_data; 901 ifm->ifm_addrs = info.rti_addrs; 902 error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); 903 if (error) 904 return (error); 905 } 906 while ((ifa = ifa->ifa_link.tqe_next) != 0) { 907 if (af && af != ifa->ifa_addr->sa_family) 908 continue; 909 ifaaddr = ifa->ifa_addr; 910 netmask = ifa->ifa_netmask; 911 brdaddr = ifa->ifa_dstaddr; 912 len = rt_msg2(RTM_NEWADDR, &info, 0, w); 913 if (w->w_req && w->w_tmem) { 914 register struct ifa_msghdr *ifam; 915 916 ifam = (struct ifa_msghdr *)w->w_tmem; 917 ifam->ifam_index = ifa->ifa_ifp->if_index; 918 ifam->ifam_flags = ifa->ifa_flags; 919 ifam->ifam_metric = ifa->ifa_metric; 920 ifam->ifam_addrs = info.rti_addrs; 921 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 922 if (error) 923 return (error); 924 } 925 } 926 ifaaddr = netmask = brdaddr = 0; 927 } 928 return (0); 929} 930 931static int 932sysctl_rtsock SYSCTL_HANDLER_ARGS 933{ 934 int *name = (int *)arg1; 935 u_int namelen = arg2; 936 register struct radix_node_head *rnh; 937 int i, s, error = EINVAL; 938 u_char af; 939 struct walkarg w; 940 941 name ++; 942 namelen--; 943 if (req->newptr) 944 return (EPERM); 945 if (namelen != 3) 946 return (EINVAL); 947 af = name[0]; 948 Bzero(&w, sizeof(w)); 949 w.w_op = name[1]; 950 w.w_arg = name[2]; 951 w.w_req = req; 952 953 s = splnet(); 954 switch (w.w_op) { 955 956 case NET_RT_DUMP: 957 case NET_RT_FLAGS: 958 for (i = 1; i <= AF_MAX; i++) 959 if ((rnh = rt_tables[i]) && (af == 0 || af == i) && 960 (error = rnh->rnh_walktree(rnh, 961 sysctl_dumpentry, &w))) 962 break; 963 break; 964 965 case NET_RT_IFLIST: 966 error = sysctl_iflist(af, &w); 967 } 968 splx(s); 969 if (w.w_tmem) 970 free(w.w_tmem, M_RTABLE); 971 return (error); 972} 973 974SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); 975 976/* 977 * Definitions of protocols supported in the ROUTE domain. 978 */ 979 980extern struct domain routedomain; /* or at least forward */ 981 982static struct protosw routesw[] = { 983{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR, 984 0, route_output, raw_ctlinput, 0, 985 0, 986 raw_init, 0, 0, 0, 987 &route_usrreqs 988} 989}; 990 991static struct domain routedomain = 992 { PF_ROUTE, "route", route_init, 0, 0, 993 routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] }; 994 995DOMAIN_SET(route);
| 254{ 255 int s, error; 256 s = splnet(); 257 error = raw_usrreqs.pru_sockaddr(so, nam); 258 splx(s); 259 return error; 260} 261 262static struct pr_usrreqs route_usrreqs = { 263 rts_abort, pru_accept_notsupp, rts_attach, rts_bind, rts_connect, 264 pru_connect2_notsupp, pru_control_notsupp, rts_detach, rts_disconnect, 265 pru_listen_notsupp, rts_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, 266 rts_send, pru_sense_null, rts_shutdown, rts_sockaddr, 267 sosend, soreceive, soselect 268}; 269 270/*ARGSUSED*/ 271static int 272route_output(m, so) 273 register struct mbuf *m; 274 struct socket *so; 275{ 276 register struct rt_msghdr *rtm = 0; 277 register struct rtentry *rt = 0; 278 struct rtentry *saved_nrt = 0; 279 struct radix_node_head *rnh; 280 struct rt_addrinfo info; 281 int len, error = 0; 282 struct ifnet *ifp = 0; 283 struct ifaddr *ifa = 0; 284 285#define senderr(e) { error = e; goto flush;} 286 if (m == 0 || ((m->m_len < sizeof(long)) && 287 (m = m_pullup(m, sizeof(long))) == 0)) 288 return (ENOBUFS); 289 if ((m->m_flags & M_PKTHDR) == 0) 290 panic("route_output"); 291 len = m->m_pkthdr.len; 292 if (len < sizeof(*rtm) || 293 len != mtod(m, struct rt_msghdr *)->rtm_msglen) { 294 dst = 0; 295 senderr(EINVAL); 296 } 297 R_Malloc(rtm, struct rt_msghdr *, len); 298 if (rtm == 0) { 299 dst = 0; 300 senderr(ENOBUFS); 301 } 302 m_copydata(m, 0, len, (caddr_t)rtm); 303 if (rtm->rtm_version != RTM_VERSION) { 304 dst = 0; 305 senderr(EPROTONOSUPPORT); 306 } 307 rtm->rtm_pid = curproc->p_pid; 308 info.rti_addrs = rtm->rtm_addrs; 309 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 310 dst = 0; 311 senderr(EINVAL); 312 } 313 if (dst == 0 || (dst->sa_family >= AF_MAX) 314 || (gate != 0 && (gate->sa_family >= AF_MAX))) 315 senderr(EINVAL); 316 if (genmask) { 317 struct radix_node *t; 318 t = rn_addmask((caddr_t)genmask, 0, 1); 319 if (t && Bcmp(genmask, t->rn_key, *(u_char *)genmask) == 0) 320 genmask = (struct sockaddr *)(t->rn_key); 321 else 322 senderr(ENOBUFS); 323 } 324 switch (rtm->rtm_type) { 325 326 case RTM_ADD: 327 if (gate == 0) 328 senderr(EINVAL); 329 error = rtrequest(RTM_ADD, dst, gate, netmask, 330 rtm->rtm_flags, &saved_nrt); 331 if (error == 0 && saved_nrt) { 332 rt_setmetrics(rtm->rtm_inits, 333 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 334 saved_nrt->rt_refcnt--; 335 saved_nrt->rt_genmask = genmask; 336 } 337 break; 338 339 case RTM_DELETE: 340 error = rtrequest(RTM_DELETE, dst, gate, netmask, 341 rtm->rtm_flags, &saved_nrt); 342 if (error == 0) { 343 if ((rt = saved_nrt)) 344 rt->rt_refcnt++; 345 goto report; 346 } 347 break; 348 349 case RTM_GET: 350 case RTM_CHANGE: 351 case RTM_LOCK: 352 if ((rnh = rt_tables[dst->sa_family]) == 0) { 353 senderr(EAFNOSUPPORT); 354 } else if (rt = (struct rtentry *) 355 rnh->rnh_lookup(dst, netmask, rnh)) 356 rt->rt_refcnt++; 357 else 358 senderr(ESRCH); 359 switch(rtm->rtm_type) { 360 361 case RTM_GET: 362 report: 363 dst = rt_key(rt); 364 gate = rt->rt_gateway; 365 netmask = rt_mask(rt); 366 genmask = rt->rt_genmask; 367 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 368 ifp = rt->rt_ifp; 369 if (ifp) { 370 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 371 ifaaddr = rt->rt_ifa->ifa_addr; 372 rtm->rtm_index = ifp->if_index; 373 } else { 374 ifpaddr = 0; 375 ifaaddr = 0; 376 } 377 } 378 len = rt_msg2(rtm->rtm_type, &info, (caddr_t)0, 379 (struct walkarg *)0); 380 if (len > rtm->rtm_msglen) { 381 struct rt_msghdr *new_rtm; 382 R_Malloc(new_rtm, struct rt_msghdr *, len); 383 if (new_rtm == 0) 384 senderr(ENOBUFS); 385 Bcopy(rtm, new_rtm, rtm->rtm_msglen); 386 Free(rtm); rtm = new_rtm; 387 } 388 (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, 389 (struct walkarg *)0); 390 rtm->rtm_flags = rt->rt_flags; 391 rtm->rtm_rmx = rt->rt_rmx; 392 rtm->rtm_addrs = info.rti_addrs; 393 break; 394 395 case RTM_CHANGE: 396 if (gate && (error = rt_setgate(rt, rt_key(rt), gate))) 397 senderr(error); 398 399 /* 400 * If they tried to change things but didn't specify 401 * the required gateway, then just use the old one. 402 * This can happen if the user tries to change the 403 * flags on the default route without changing the 404 * default gateway. Changing flags still doesn't work. 405 */ 406 if ((rt->rt_flags & RTF_GATEWAY) && !gate) 407 gate = rt->rt_gateway; 408 409 /* new gateway could require new ifaddr, ifp; 410 flags may also be different; ifp may be specified 411 by ll sockaddr when protocol address is ambiguous */ 412 if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) && 413 (ifp = ifa->ifa_ifp) && (ifaaddr || gate)) 414 ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, 415 ifp); 416 else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) || 417 (gate && (ifa = ifa_ifwithroute(rt->rt_flags, 418 rt_key(rt), gate)))) 419 ifp = ifa->ifa_ifp; 420 if (ifa) { 421 register struct ifaddr *oifa = rt->rt_ifa; 422 if (oifa != ifa) { 423 if (oifa && oifa->ifa_rtrequest) 424 oifa->ifa_rtrequest(RTM_DELETE, 425 rt, gate); 426 IFAFREE(rt->rt_ifa); 427 rt->rt_ifa = ifa; 428 ifa->ifa_refcnt++; 429 rt->rt_ifp = ifp; 430 } 431 } 432 rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 433 &rt->rt_rmx); 434 if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) 435 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate); 436 if (genmask) 437 rt->rt_genmask = genmask; 438 /* 439 * Fall into 440 */ 441 case RTM_LOCK: 442 rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); 443 rt->rt_rmx.rmx_locks |= 444 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); 445 break; 446 } 447 break; 448 449 default: 450 senderr(EOPNOTSUPP); 451 } 452 453flush: 454 if (rtm) { 455 if (error) 456 rtm->rtm_errno = error; 457 else 458 rtm->rtm_flags |= RTF_DONE; 459 } 460 if (rt) 461 rtfree(rt); 462 { 463 register struct rawcb *rp = 0; 464 /* 465 * Check to see if we don't want our own messages. 466 */ 467 if ((so->so_options & SO_USELOOPBACK) == 0) { 468 if (route_cb.any_count <= 1) { 469 if (rtm) 470 Free(rtm); 471 m_freem(m); 472 return (error); 473 } 474 /* There is another listener, so construct message */ 475 rp = sotorawcb(so); 476 } 477 if (rtm) { 478 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 479 Free(rtm); 480 } 481 if (rp) 482 rp->rcb_proto.sp_family = 0; /* Avoid us */ 483 if (dst) 484 route_proto.sp_protocol = dst->sa_family; 485 raw_input(m, &route_proto, &route_src, &route_dst); 486 if (rp) 487 rp->rcb_proto.sp_family = PF_ROUTE; 488 } 489 return (error); 490} 491 492static void 493rt_setmetrics(which, in, out) 494 u_long which; 495 register struct rt_metrics *in, *out; 496{ 497#define metric(f, e) if (which & (f)) out->e = in->e; 498 metric(RTV_RPIPE, rmx_recvpipe); 499 metric(RTV_SPIPE, rmx_sendpipe); 500 metric(RTV_SSTHRESH, rmx_ssthresh); 501 metric(RTV_RTT, rmx_rtt); 502 metric(RTV_RTTVAR, rmx_rttvar); 503 metric(RTV_HOPCOUNT, rmx_hopcount); 504 metric(RTV_MTU, rmx_mtu); 505 metric(RTV_EXPIRE, rmx_expire); 506#undef metric 507} 508 509#define ROUNDUP(a) \ 510 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 511#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 512 513 514/* 515 * Extract the addresses of the passed sockaddrs. 516 * Do a little sanity checking so as to avoid bad memory references. 517 * This data is derived straight from userland. 518 */ 519static int 520rt_xaddrs(cp, cplim, rtinfo) 521 register caddr_t cp, cplim; 522 register struct rt_addrinfo *rtinfo; 523{ 524 register struct sockaddr *sa; 525 register int i; 526 527 bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); 528 for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 529 if ((rtinfo->rti_addrs & (1 << i)) == 0) 530 continue; 531 sa = (struct sockaddr *)cp; 532 /* 533 * It won't fit. 534 */ 535 if ( (cp + sa->sa_len) > cplim ) { 536 return (EINVAL); 537 } 538 539 /* 540 * there are no more.. quit now 541 * If there are more bits, they are in error. 542 * I've seen this. route(1) can evidently generate these. 543 * This causes kernel to core dump. 544 * for compatibility, If we see this, point to a safe address. 545 */ 546 if (sa->sa_len == 0) { 547 rtinfo->rti_info[i] = &sa_zero; 548 return (0); /* should be EINVAL but for compat */ 549 } 550 551 /* accept it */ 552 rtinfo->rti_info[i] = sa; 553 ADVANCE(cp, sa); 554 } 555 return (0); 556} 557 558static struct mbuf * 559rt_msg1(type, rtinfo) 560 int type; 561 register struct rt_addrinfo *rtinfo; 562{ 563 register struct rt_msghdr *rtm; 564 register struct mbuf *m; 565 register int i; 566 register struct sockaddr *sa; 567 int len, dlen; 568 569 m = m_gethdr(M_DONTWAIT, MT_DATA); 570 if (m == 0) 571 return (m); 572 switch (type) { 573 574 case RTM_DELADDR: 575 case RTM_NEWADDR: 576 len = sizeof(struct ifa_msghdr); 577 break; 578 579 case RTM_DELMADDR: 580 case RTM_NEWMADDR: 581 len = sizeof(struct ifma_msghdr); 582 break; 583 584 case RTM_IFINFO: 585 len = sizeof(struct if_msghdr); 586 break; 587 588 default: 589 len = sizeof(struct rt_msghdr); 590 } 591 if (len > MHLEN) 592 panic("rt_msg1"); 593 m->m_pkthdr.len = m->m_len = len; 594 m->m_pkthdr.rcvif = 0; 595 rtm = mtod(m, struct rt_msghdr *); 596 bzero((caddr_t)rtm, len); 597 for (i = 0; i < RTAX_MAX; i++) { 598 if ((sa = rtinfo->rti_info[i]) == NULL) 599 continue; 600 rtinfo->rti_addrs |= (1 << i); 601 dlen = ROUNDUP(sa->sa_len); 602 m_copyback(m, len, dlen, (caddr_t)sa); 603 len += dlen; 604 } 605 if (m->m_pkthdr.len != len) { 606 m_freem(m); 607 return (NULL); 608 } 609 rtm->rtm_msglen = len; 610 rtm->rtm_version = RTM_VERSION; 611 rtm->rtm_type = type; 612 return (m); 613} 614 615static int 616rt_msg2(type, rtinfo, cp, w) 617 int type; 618 register struct rt_addrinfo *rtinfo; 619 caddr_t cp; 620 struct walkarg *w; 621{ 622 register int i; 623 int len, dlen, second_time = 0; 624 caddr_t cp0; 625 626 rtinfo->rti_addrs = 0; 627again: 628 switch (type) { 629 630 case RTM_DELADDR: 631 case RTM_NEWADDR: 632 len = sizeof(struct ifa_msghdr); 633 break; 634 635 case RTM_IFINFO: 636 len = sizeof(struct if_msghdr); 637 break; 638 639 default: 640 len = sizeof(struct rt_msghdr); 641 } 642 cp0 = cp; 643 if (cp0) 644 cp += len; 645 for (i = 0; i < RTAX_MAX; i++) { 646 register struct sockaddr *sa; 647 648 if ((sa = rtinfo->rti_info[i]) == 0) 649 continue; 650 rtinfo->rti_addrs |= (1 << i); 651 dlen = ROUNDUP(sa->sa_len); 652 if (cp) { 653 bcopy((caddr_t)sa, cp, (unsigned)dlen); 654 cp += dlen; 655 } 656 len += dlen; 657 } 658 if (cp == 0 && w != NULL && !second_time) { 659 register struct walkarg *rw = w; 660 661 if (rw->w_req) { 662 if (rw->w_tmemsize < len) { 663 if (rw->w_tmem) 664 free(rw->w_tmem, M_RTABLE); 665 rw->w_tmem = (caddr_t) 666 malloc(len, M_RTABLE, M_NOWAIT); 667 if (rw->w_tmem) 668 rw->w_tmemsize = len; 669 } 670 if (rw->w_tmem) { 671 cp = rw->w_tmem; 672 second_time = 1; 673 goto again; 674 } 675 } 676 } 677 if (cp) { 678 register struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; 679 680 rtm->rtm_version = RTM_VERSION; 681 rtm->rtm_type = type; 682 rtm->rtm_msglen = len; 683 } 684 return (len); 685} 686 687/* 688 * This routine is called to generate a message from the routing 689 * socket indicating that a redirect has occured, a routing lookup 690 * has failed, or that a protocol has detected timeouts to a particular 691 * destination. 692 */ 693void 694rt_missmsg(type, rtinfo, flags, error) 695 int type, flags, error; 696 register struct rt_addrinfo *rtinfo; 697{ 698 register struct rt_msghdr *rtm; 699 register struct mbuf *m; 700 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 701 702 if (route_cb.any_count == 0) 703 return; 704 m = rt_msg1(type, rtinfo); 705 if (m == 0) 706 return; 707 rtm = mtod(m, struct rt_msghdr *); 708 rtm->rtm_flags = RTF_DONE | flags; 709 rtm->rtm_errno = error; 710 rtm->rtm_addrs = rtinfo->rti_addrs; 711 route_proto.sp_protocol = sa ? sa->sa_family : 0; 712 raw_input(m, &route_proto, &route_src, &route_dst); 713} 714 715/* 716 * This routine is called to generate a message from the routing 717 * socket indicating that the status of a network interface has changed. 718 */ 719void 720rt_ifmsg(ifp) 721 register struct ifnet *ifp; 722{ 723 register struct if_msghdr *ifm; 724 struct mbuf *m; 725 struct rt_addrinfo info; 726 727 if (route_cb.any_count == 0) 728 return; 729 bzero((caddr_t)&info, sizeof(info)); 730 m = rt_msg1(RTM_IFINFO, &info); 731 if (m == 0) 732 return; 733 ifm = mtod(m, struct if_msghdr *); 734 ifm->ifm_index = ifp->if_index; 735 ifm->ifm_flags = (u_short)ifp->if_flags; 736 ifm->ifm_data = ifp->if_data; 737 ifm->ifm_addrs = 0; 738 route_proto.sp_protocol = 0; 739 raw_input(m, &route_proto, &route_src, &route_dst); 740} 741 742/* 743 * This is called to generate messages from the routing socket 744 * indicating a network interface has had addresses associated with it. 745 * if we ever reverse the logic and replace messages TO the routing 746 * socket indicate a request to configure interfaces, then it will 747 * be unnecessary as the routing socket will automatically generate 748 * copies of it. 749 */ 750void 751rt_newaddrmsg(cmd, ifa, error, rt) 752 int cmd, error; 753 register struct ifaddr *ifa; 754 register struct rtentry *rt; 755{ 756 struct rt_addrinfo info; 757 struct sockaddr *sa = 0; 758 int pass; 759 struct mbuf *m = 0; 760 struct ifnet *ifp = ifa->ifa_ifp; 761 762 if (route_cb.any_count == 0) 763 return; 764 for (pass = 1; pass < 3; pass++) { 765 bzero((caddr_t)&info, sizeof(info)); 766 if ((cmd == RTM_ADD && pass == 1) || 767 (cmd == RTM_DELETE && pass == 2)) { 768 register struct ifa_msghdr *ifam; 769 int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; 770 771 ifaaddr = sa = ifa->ifa_addr; 772 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 773 netmask = ifa->ifa_netmask; 774 brdaddr = ifa->ifa_dstaddr; 775 if ((m = rt_msg1(ncmd, &info)) == NULL) 776 continue; 777 ifam = mtod(m, struct ifa_msghdr *); 778 ifam->ifam_index = ifp->if_index; 779 ifam->ifam_metric = ifa->ifa_metric; 780 ifam->ifam_flags = ifa->ifa_flags; 781 ifam->ifam_addrs = info.rti_addrs; 782 } 783 if ((cmd == RTM_ADD && pass == 2) || 784 (cmd == RTM_DELETE && pass == 1)) { 785 register struct rt_msghdr *rtm; 786 787 if (rt == 0) 788 continue; 789 netmask = rt_mask(rt); 790 dst = sa = rt_key(rt); 791 gate = rt->rt_gateway; 792 if ((m = rt_msg1(cmd, &info)) == NULL) 793 continue; 794 rtm = mtod(m, struct rt_msghdr *); 795 rtm->rtm_index = ifp->if_index; 796 rtm->rtm_flags |= rt->rt_flags; 797 rtm->rtm_errno = error; 798 rtm->rtm_addrs = info.rti_addrs; 799 } 800 route_proto.sp_protocol = sa ? sa->sa_family : 0; 801 raw_input(m, &route_proto, &route_src, &route_dst); 802 } 803} 804 805/* 806 * This is the analogue to the rt_newaddrmsg which performs the same 807 * function but for multicast group memberhips. This is easier since 808 * there is no route state to worry about. 809 */ 810void 811rt_newmaddrmsg(cmd, ifma) 812 int cmd; 813 struct ifmultiaddr *ifma; 814{ 815 struct rt_addrinfo info; 816 struct mbuf *m = 0; 817 struct ifnet *ifp = ifma->ifma_ifp; 818 struct ifma_msghdr *ifmam; 819 820 if (route_cb.any_count == 0) 821 return; 822 823 bzero((caddr_t)&info, sizeof(info)); 824 ifaaddr = ifma->ifma_addr; 825 ifpaddr = ifp->if_addrhead.tqh_first->ifa_addr; 826 /* 827 * If a link-layer address is present, present it as a ``gateway'' 828 * (similarly to how ARP entries, e.g., are presented). 829 */ 830 gate = ifma->ifma_lladdr; 831 if ((m = rt_msg1(cmd, &info)) == NULL) 832 return; 833 ifmam = mtod(m, struct ifma_msghdr *); 834 ifmam->ifmam_index = ifp->if_index; 835 ifmam->ifmam_addrs = info.rti_addrs; 836 route_proto.sp_protocol = ifma->ifma_addr->sa_family; 837 raw_input(m, &route_proto, &route_src, &route_dst); 838} 839 840/* 841 * This is used in dumping the kernel table via sysctl(). 842 */ 843int 844sysctl_dumpentry(rn, vw) 845 struct radix_node *rn; 846 void *vw; 847{ 848 register struct walkarg *w = vw; 849 register struct rtentry *rt = (struct rtentry *)rn; 850 int error = 0, size; 851 struct rt_addrinfo info; 852 853 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 854 return 0; 855 bzero((caddr_t)&info, sizeof(info)); 856 dst = rt_key(rt); 857 gate = rt->rt_gateway; 858 netmask = rt_mask(rt); 859 genmask = rt->rt_genmask; 860 size = rt_msg2(RTM_GET, &info, 0, w); 861 if (w->w_req && w->w_tmem) { 862 register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 863 864 rtm->rtm_flags = rt->rt_flags; 865 rtm->rtm_use = rt->rt_use; 866 rtm->rtm_rmx = rt->rt_rmx; 867 rtm->rtm_index = rt->rt_ifp->if_index; 868 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 869 rtm->rtm_addrs = info.rti_addrs; 870 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); 871 return (error); 872 } 873 return (error); 874} 875 876int 877sysctl_iflist(af, w) 878 int af; 879 register struct walkarg *w; 880{ 881 register struct ifnet *ifp; 882 register struct ifaddr *ifa; 883 struct rt_addrinfo info; 884 int len, error = 0; 885 886 bzero((caddr_t)&info, sizeof(info)); 887 for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { 888 if (w->w_arg && w->w_arg != ifp->if_index) 889 continue; 890 ifa = ifp->if_addrhead.tqh_first; 891 ifpaddr = ifa->ifa_addr; 892 len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w); 893 ifpaddr = 0; 894 if (w->w_req && w->w_tmem) { 895 register struct if_msghdr *ifm; 896 897 ifm = (struct if_msghdr *)w->w_tmem; 898 ifm->ifm_index = ifp->if_index; 899 ifm->ifm_flags = (u_short)ifp->if_flags; 900 ifm->ifm_data = ifp->if_data; 901 ifm->ifm_addrs = info.rti_addrs; 902 error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); 903 if (error) 904 return (error); 905 } 906 while ((ifa = ifa->ifa_link.tqe_next) != 0) { 907 if (af && af != ifa->ifa_addr->sa_family) 908 continue; 909 ifaaddr = ifa->ifa_addr; 910 netmask = ifa->ifa_netmask; 911 brdaddr = ifa->ifa_dstaddr; 912 len = rt_msg2(RTM_NEWADDR, &info, 0, w); 913 if (w->w_req && w->w_tmem) { 914 register struct ifa_msghdr *ifam; 915 916 ifam = (struct ifa_msghdr *)w->w_tmem; 917 ifam->ifam_index = ifa->ifa_ifp->if_index; 918 ifam->ifam_flags = ifa->ifa_flags; 919 ifam->ifam_metric = ifa->ifa_metric; 920 ifam->ifam_addrs = info.rti_addrs; 921 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 922 if (error) 923 return (error); 924 } 925 } 926 ifaaddr = netmask = brdaddr = 0; 927 } 928 return (0); 929} 930 931static int 932sysctl_rtsock SYSCTL_HANDLER_ARGS 933{ 934 int *name = (int *)arg1; 935 u_int namelen = arg2; 936 register struct radix_node_head *rnh; 937 int i, s, error = EINVAL; 938 u_char af; 939 struct walkarg w; 940 941 name ++; 942 namelen--; 943 if (req->newptr) 944 return (EPERM); 945 if (namelen != 3) 946 return (EINVAL); 947 af = name[0]; 948 Bzero(&w, sizeof(w)); 949 w.w_op = name[1]; 950 w.w_arg = name[2]; 951 w.w_req = req; 952 953 s = splnet(); 954 switch (w.w_op) { 955 956 case NET_RT_DUMP: 957 case NET_RT_FLAGS: 958 for (i = 1; i <= AF_MAX; i++) 959 if ((rnh = rt_tables[i]) && (af == 0 || af == i) && 960 (error = rnh->rnh_walktree(rnh, 961 sysctl_dumpentry, &w))) 962 break; 963 break; 964 965 case NET_RT_IFLIST: 966 error = sysctl_iflist(af, &w); 967 } 968 splx(s); 969 if (w.w_tmem) 970 free(w.w_tmem, M_RTABLE); 971 return (error); 972} 973 974SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); 975 976/* 977 * Definitions of protocols supported in the ROUTE domain. 978 */ 979 980extern struct domain routedomain; /* or at least forward */ 981 982static struct protosw routesw[] = { 983{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR, 984 0, route_output, raw_ctlinput, 0, 985 0, 986 raw_init, 0, 0, 0, 987 &route_usrreqs 988} 989}; 990 991static struct domain routedomain = 992 { PF_ROUTE, "route", route_init, 0, 0, 993 routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] }; 994 995DOMAIN_SET(route);
|