| 747 | } |
| 748 | |
| 749 | static int |
| 750 | rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) |
| 751 | { |
| 752 | struct epoch_tracker et; |
| 753 | struct inpcb *inp; |
| 754 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; |
| 755 | struct ifaddr *ifa = NULL; |
| 756 | int error = 0; |
| 757 | |
| 758 | inp = sotoinpcb(so); |
| 759 | KASSERT(inp != NULL, ("rip6_bind: inp == NULL")); |
| 760 | |
| 761 | if (nam->sa_len != sizeof(*addr)) |
| 762 | return (EINVAL); |
| 763 | if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0) |
| 764 | return (error); |
| 765 | if (CK_STAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6) |
| 766 | return (EADDRNOTAVAIL); |
| 767 | if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0) |
| 768 | return (error); |
| 769 | |
| 770 | NET_EPOCH_ENTER(et); |
| 771 | if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && |
| 772 | (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) { |
| 773 | NET_EPOCH_EXIT(et); |
| 774 | return (EADDRNOTAVAIL); |
| 775 | } |
| 776 | if (ifa != NULL && |
| 777 | ((struct in6_ifaddr *)ifa)->ia6_flags & |
| 778 | (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| |
| 779 | IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) { |
| 780 | NET_EPOCH_EXIT(et); |
| 781 | return (EADDRNOTAVAIL); |
| 782 | } |
| 783 | NET_EPOCH_EXIT(et); |
| 784 | INP_INFO_WLOCK(&V_ripcbinfo); |
| 785 | INP_WLOCK(inp); |
| 786 | inp->in6p_laddr = addr->sin6_addr; |
| 787 | INP_WUNLOCK(inp); |
| 788 | INP_INFO_WUNLOCK(&V_ripcbinfo); |
| 789 | return (0); |
| 790 | } |
| 791 | |
| 792 | static int |
| 793 | rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) |
nothing calls this directly
no test coverage detected