| 921 | } |
| 922 | |
| 923 | static int |
| 924 | sctp6_getaddr(struct socket *so, struct sockaddr **addr) |
| 925 | { |
| 926 | struct sockaddr_in6 *sin6; |
| 927 | struct sctp_inpcb *inp; |
| 928 | uint32_t vrf_id; |
| 929 | struct sctp_ifa *sctp_ifa; |
| 930 | |
| 931 | int error; |
| 932 | |
| 933 | /* |
| 934 | * Do the malloc first in case it blocks. |
| 935 | */ |
| 936 | SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6)); |
| 937 | if (sin6 == NULL) |
| 938 | return (ENOMEM); |
| 939 | sin6->sin6_family = AF_INET6; |
| 940 | sin6->sin6_len = sizeof(*sin6); |
| 941 | |
| 942 | inp = (struct sctp_inpcb *)so->so_pcb; |
| 943 | if (inp == NULL) { |
| 944 | SCTP_FREE_SONAME(sin6); |
| 945 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET); |
| 946 | return (ECONNRESET); |
| 947 | } |
| 948 | SCTP_INP_RLOCK(inp); |
| 949 | sin6->sin6_port = inp->sctp_lport; |
| 950 | if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { |
| 951 | /* For the bound all case you get back 0 */ |
| 952 | if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { |
| 953 | struct sctp_tcb *stcb; |
| 954 | struct sockaddr_in6 *sin_a6; |
| 955 | struct sctp_nets *net; |
| 956 | int fnd; |
| 957 | |
| 958 | stcb = LIST_FIRST(&inp->sctp_asoc_list); |
| 959 | if (stcb == NULL) { |
| 960 | SCTP_INP_RUNLOCK(inp); |
| 961 | SCTP_FREE_SONAME(sin6); |
| 962 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); |
| 963 | return (ENOENT); |
| 964 | } |
| 965 | fnd = 0; |
| 966 | sin_a6 = NULL; |
| 967 | TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { |
| 968 | sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr; |
| 969 | if (sin_a6 == NULL) |
| 970 | /* this will make coverity happy */ |
| 971 | continue; |
| 972 | |
| 973 | if (sin_a6->sin6_family == AF_INET6) { |
| 974 | fnd = 1; |
| 975 | break; |
| 976 | } |
| 977 | } |
| 978 | if ((!fnd) || (sin_a6 == NULL)) { |
| 979 | /* punt */ |
| 980 | SCTP_INP_RUNLOCK(inp); |
no test coverage detected