| 7375 | |
| 7376 | #ifdef INET |
| 7377 | int |
| 7378 | sctp_ingetaddr(struct socket *so, struct sockaddr **addr) |
| 7379 | { |
| 7380 | struct sockaddr_in *sin; |
| 7381 | uint32_t vrf_id; |
| 7382 | struct sctp_inpcb *inp; |
| 7383 | struct sctp_ifa *sctp_ifa; |
| 7384 | |
| 7385 | /* |
| 7386 | * Do the malloc first in case it blocks. |
| 7387 | */ |
| 7388 | SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); |
| 7389 | if (sin == NULL) |
| 7390 | return (ENOMEM); |
| 7391 | sin->sin_family = AF_INET; |
| 7392 | sin->sin_len = sizeof(*sin); |
| 7393 | inp = (struct sctp_inpcb *)so->so_pcb; |
| 7394 | if (!inp) { |
| 7395 | SCTP_FREE_SONAME(sin); |
| 7396 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); |
| 7397 | return (ECONNRESET); |
| 7398 | } |
| 7399 | SCTP_INP_RLOCK(inp); |
| 7400 | sin->sin_port = inp->sctp_lport; |
| 7401 | if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { |
| 7402 | if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { |
| 7403 | struct sctp_tcb *stcb; |
| 7404 | struct sockaddr_in *sin_a; |
| 7405 | struct sctp_nets *net; |
| 7406 | int fnd; |
| 7407 | |
| 7408 | stcb = LIST_FIRST(&inp->sctp_asoc_list); |
| 7409 | if (stcb == NULL) { |
| 7410 | goto notConn; |
| 7411 | } |
| 7412 | fnd = 0; |
| 7413 | sin_a = NULL; |
| 7414 | SCTP_TCB_LOCK(stcb); |
| 7415 | TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { |
| 7416 | sin_a = (struct sockaddr_in *)&net->ro._l_addr; |
| 7417 | if (sin_a == NULL) |
| 7418 | /* this will make coverity happy */ |
| 7419 | continue; |
| 7420 | |
| 7421 | if (sin_a->sin_family == AF_INET) { |
| 7422 | fnd = 1; |
| 7423 | break; |
| 7424 | } |
| 7425 | } |
| 7426 | if ((!fnd) || (sin_a == NULL)) { |
| 7427 | /* punt */ |
| 7428 | SCTP_TCB_UNLOCK(stcb); |
| 7429 | goto notConn; |
| 7430 | } |
| 7431 | |
| 7432 | vrf_id = inp->def_vrf_id; |
| 7433 | sctp_ifa = sctp_source_address_selection(inp, |
| 7434 | stcb, |
no test coverage detected