* Set the IP multicast options in response to user setsockopt(). * * Many of the socket options handled in this function duplicate the * functionality of socket options in the regular unicast API. However, * it is not possible to merge the duplicate code, because the idempotence * of the IPv4 multicast part of the BSD Sockets API must be preserved; * the effects of these options must be trea
| 2759 | * is refactored to no longer use vifs. |
| 2760 | */ |
| 2761 | int |
| 2762 | inp_setmoptions(struct inpcb *inp, struct sockopt *sopt) |
| 2763 | { |
| 2764 | struct ip_moptions *imo; |
| 2765 | int error; |
| 2766 | |
| 2767 | error = 0; |
| 2768 | |
| 2769 | /* |
| 2770 | * If socket is neither of type SOCK_RAW or SOCK_DGRAM, |
| 2771 | * or is a divert socket, reject it. |
| 2772 | */ |
| 2773 | if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || |
| 2774 | (inp->inp_socket->so_proto->pr_type != SOCK_RAW && |
| 2775 | inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) |
| 2776 | return (EOPNOTSUPP); |
| 2777 | |
| 2778 | switch (sopt->sopt_name) { |
| 2779 | case IP_MULTICAST_VIF: { |
| 2780 | int vifi; |
| 2781 | /* |
| 2782 | * Select a multicast VIF for transmission. |
| 2783 | * Only useful if multicast forwarding is active. |
| 2784 | */ |
| 2785 | if (legal_vif_num == NULL) { |
| 2786 | error = EOPNOTSUPP; |
| 2787 | break; |
| 2788 | } |
| 2789 | error = sooptcopyin(sopt, &vifi, sizeof(int), sizeof(int)); |
| 2790 | if (error) |
| 2791 | break; |
| 2792 | if (!legal_vif_num(vifi) && (vifi != -1)) { |
| 2793 | error = EINVAL; |
| 2794 | break; |
| 2795 | } |
| 2796 | imo = inp_findmoptions(inp); |
| 2797 | imo->imo_multicast_vif = vifi; |
| 2798 | INP_WUNLOCK(inp); |
| 2799 | break; |
| 2800 | } |
| 2801 | |
| 2802 | case IP_MULTICAST_IF: |
| 2803 | error = inp_set_multicast_if(inp, sopt); |
| 2804 | break; |
| 2805 | |
| 2806 | case IP_MULTICAST_TTL: { |
| 2807 | u_char ttl; |
| 2808 | |
| 2809 | /* |
| 2810 | * Set the IP time-to-live for outgoing multicast packets. |
| 2811 | * The original multicast API required a char argument, |
| 2812 | * which is inconsistent with the rest of the socket API. |
| 2813 | * We allow either a char or an int. |
| 2814 | */ |
| 2815 | if (sopt->sopt_valsize == sizeof(u_char)) { |
| 2816 | error = sooptcopyin(sopt, &ttl, sizeof(u_char), |
| 2817 | sizeof(u_char)); |
| 2818 | if (error) |
no test coverage detected