* sctp_bindx(DELETE) for one address. * assumes all arguments are valid/checked by caller. */
| 6822 | * assumes all arguments are valid/checked by caller. |
| 6823 | */ |
| 6824 | void |
| 6825 | sctp_bindx_delete_address(struct sctp_inpcb *inp, |
| 6826 | struct sockaddr *sa, uint32_t vrf_id, int *error) |
| 6827 | { |
| 6828 | struct sockaddr *addr_to_use; |
| 6829 | #if defined(INET) && defined(INET6) |
| 6830 | struct sockaddr_in6 *sin6; |
| 6831 | struct sockaddr_in sin; |
| 6832 | #endif |
| 6833 | |
| 6834 | /* see if we're bound all already! */ |
| 6835 | if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { |
| 6836 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); |
| 6837 | *error = EINVAL; |
| 6838 | return; |
| 6839 | } |
| 6840 | switch (sa->sa_family) { |
| 6841 | #ifdef INET6 |
| 6842 | case AF_INET6: |
| 6843 | if (sa->sa_len != sizeof(struct sockaddr_in6)) { |
| 6844 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); |
| 6845 | *error = EINVAL; |
| 6846 | return; |
| 6847 | } |
| 6848 | if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { |
| 6849 | /* can only bind v6 on PF_INET6 sockets */ |
| 6850 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); |
| 6851 | *error = EINVAL; |
| 6852 | return; |
| 6853 | } |
| 6854 | #ifdef INET |
| 6855 | sin6 = (struct sockaddr_in6 *)sa; |
| 6856 | if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { |
| 6857 | if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && |
| 6858 | SCTP_IPV6_V6ONLY(inp)) { |
| 6859 | /* can't bind mapped-v4 on PF_INET sockets */ |
| 6860 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); |
| 6861 | *error = EINVAL; |
| 6862 | return; |
| 6863 | } |
| 6864 | in6_sin6_2_sin(&sin, sin6); |
| 6865 | addr_to_use = (struct sockaddr *)&sin; |
| 6866 | } else { |
| 6867 | addr_to_use = sa; |
| 6868 | } |
| 6869 | #else |
| 6870 | addr_to_use = sa; |
| 6871 | #endif |
| 6872 | break; |
| 6873 | #endif |
| 6874 | #ifdef INET |
| 6875 | case AF_INET: |
| 6876 | if (sa->sa_len != sizeof(struct sockaddr_in)) { |
| 6877 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); |
| 6878 | *error = EINVAL; |
| 6879 | return; |
| 6880 | } |
| 6881 | if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && |
no test coverage detected