* Fills in @info based on userland-provided @rtm message. * * Returns 0 on success. */
| 618 | * Returns 0 on success. |
| 619 | */ |
| 620 | static int |
| 621 | fill_addrinfo(struct rt_msghdr *rtm, int len, u_int fibnum, struct rt_addrinfo *info) |
| 622 | { |
| 623 | int error; |
| 624 | sa_family_t saf; |
| 625 | |
| 626 | rtm->rtm_pid = curproc->p_pid; |
| 627 | info->rti_addrs = rtm->rtm_addrs; |
| 628 | |
| 629 | info->rti_mflags = rtm->rtm_inits; |
| 630 | info->rti_rmx = &rtm->rtm_rmx; |
| 631 | |
| 632 | /* |
| 633 | * rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6 |
| 634 | * link-local address because rtrequest requires addresses with |
| 635 | * embedded scope id. |
| 636 | */ |
| 637 | if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, info)) |
| 638 | return (EINVAL); |
| 639 | |
| 640 | if (rtm->rtm_flags & RTF_RNH_LOCKED) |
| 641 | return (EINVAL); |
| 642 | info->rti_flags = rtm->rtm_flags; |
| 643 | error = cleanup_xaddrs(info); |
| 644 | if (error != 0) |
| 645 | return (error); |
| 646 | saf = info->rti_info[RTAX_DST]->sa_family; |
| 647 | /* |
| 648 | * Verify that the caller has the appropriate privilege; RTM_GET |
| 649 | * is the only operation the non-superuser is allowed. |
| 650 | */ |
| 651 | if (rtm->rtm_type != RTM_GET) { |
| 652 | error = priv_check(curthread, PRIV_NET_ROUTE); |
| 653 | if (error != 0) |
| 654 | return (error); |
| 655 | } |
| 656 | |
| 657 | /* |
| 658 | * The given gateway address may be an interface address. |
| 659 | * For example, issuing a "route change" command on a route |
| 660 | * entry that was created from a tunnel, and the gateway |
| 661 | * address given is the local end point. In this case the |
| 662 | * RTF_GATEWAY flag must be cleared or the destination will |
| 663 | * not be reachable even though there is no error message. |
| 664 | */ |
| 665 | if (info->rti_info[RTAX_GATEWAY] != NULL && |
| 666 | info->rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) { |
| 667 | struct rt_addrinfo ginfo; |
| 668 | struct sockaddr *gdst; |
| 669 | struct sockaddr_storage ss; |
| 670 | |
| 671 | bzero(&ginfo, sizeof(ginfo)); |
| 672 | bzero(&ss, sizeof(ss)); |
| 673 | ss.ss_len = sizeof(ss); |
| 674 | |
| 675 | ginfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&ss; |
| 676 | gdst = info->rti_info[RTAX_GATEWAY]; |
| 677 |
no test coverage detected