* Fills in @info based on userland-provided @rtm message. * * Returns 0 on success. */
| 503 | * Returns 0 on success. |
| 504 | */ |
| 505 | static int |
| 506 | fill_addrinfo(struct rt_msghdr *rtm, int len, u_int fibnum, struct rt_addrinfo *info) |
| 507 | { |
| 508 | int error; |
| 509 | sa_family_t saf; |
| 510 | |
| 511 | rtm->rtm_pid = curproc->p_pid; |
| 512 | info->rti_addrs = rtm->rtm_addrs; |
| 513 | |
| 514 | info->rti_mflags = rtm->rtm_inits; |
| 515 | info->rti_rmx = &rtm->rtm_rmx; |
| 516 | |
| 517 | /* |
| 518 | * rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6 |
| 519 | * link-local address because rtrequest requires addresses with |
| 520 | * embedded scope id. |
| 521 | */ |
| 522 | if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, info)) |
| 523 | return (EINVAL); |
| 524 | |
| 525 | if (rtm->rtm_flags & RTF_RNH_LOCKED) |
| 526 | return (EINVAL); |
| 527 | info->rti_flags = rtm->rtm_flags; |
| 528 | error = cleanup_xaddrs(info); |
| 529 | if (error != 0) |
| 530 | return (error); |
| 531 | saf = info->rti_info[RTAX_DST]->sa_family; |
| 532 | /* |
| 533 | * Verify that the caller has the appropriate privilege; RTM_GET |
| 534 | * is the only operation the non-superuser is allowed. |
| 535 | */ |
| 536 | if (rtm->rtm_type != RTM_GET) { |
| 537 | error = priv_check(curthread, PRIV_NET_ROUTE); |
| 538 | if (error != 0) |
| 539 | return (error); |
| 540 | } |
| 541 | |
| 542 | /* |
| 543 | * The given gateway address may be an interface address. |
| 544 | * For example, issuing a "route change" command on a route |
| 545 | * entry that was created from a tunnel, and the gateway |
| 546 | * address given is the local end point. In this case the |
| 547 | * RTF_GATEWAY flag must be cleared or the destination will |
| 548 | * not be reachable even though there is no error message. |
| 549 | */ |
| 550 | if (info->rti_info[RTAX_GATEWAY] != NULL && |
| 551 | info->rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) { |
| 552 | struct rt_addrinfo ginfo; |
| 553 | struct sockaddr *gdst; |
| 554 | struct sockaddr_storage ss; |
| 555 | |
| 556 | bzero(&ginfo, sizeof(ginfo)); |
| 557 | bzero(&ss, sizeof(ss)); |
| 558 | ss.ss_len = sizeof(ss); |
| 559 | |
| 560 | ginfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&ss; |
| 561 | gdst = info->rti_info[RTAX_GATEWAY]; |
| 562 |
no test coverage detected