| 549 | } |
| 550 | |
| 551 | static int |
| 552 | sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p) |
| 553 | { |
| 554 | struct sctp_inpcb *inp; |
| 555 | int error; |
| 556 | u_char vflagsav; |
| 557 | |
| 558 | inp = (struct sctp_inpcb *)so->so_pcb; |
| 559 | if (inp == NULL) { |
| 560 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); |
| 561 | return (EINVAL); |
| 562 | } |
| 563 | |
| 564 | if (addr) { |
| 565 | switch (addr->sa_family) { |
| 566 | #ifdef INET |
| 567 | case AF_INET: |
| 568 | if (addr->sa_len != sizeof(struct sockaddr_in)) { |
| 569 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); |
| 570 | return (EINVAL); |
| 571 | } |
| 572 | break; |
| 573 | #endif |
| 574 | #ifdef INET6 |
| 575 | case AF_INET6: |
| 576 | if (addr->sa_len != sizeof(struct sockaddr_in6)) { |
| 577 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); |
| 578 | return (EINVAL); |
| 579 | } |
| 580 | break; |
| 581 | #endif |
| 582 | default: |
| 583 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); |
| 584 | return (EINVAL); |
| 585 | } |
| 586 | } |
| 587 | vflagsav = inp->ip_inp.inp.inp_vflag; |
| 588 | inp->ip_inp.inp.inp_vflag &= ~INP_IPV4; |
| 589 | inp->ip_inp.inp.inp_vflag |= INP_IPV6; |
| 590 | if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp) == 0)) { |
| 591 | switch (addr->sa_family) { |
| 592 | #ifdef INET |
| 593 | case AF_INET: |
| 594 | /* binding v4 addr to v6 socket, so reset flags */ |
| 595 | inp->ip_inp.inp.inp_vflag |= INP_IPV4; |
| 596 | inp->ip_inp.inp.inp_vflag &= ~INP_IPV6; |
| 597 | break; |
| 598 | #endif |
| 599 | #ifdef INET6 |
| 600 | case AF_INET6: |
| 601 | { |
| 602 | struct sockaddr_in6 *sin6_p; |
| 603 | |
| 604 | sin6_p = (struct sockaddr_in6 *)addr; |
| 605 | |
| 606 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) { |
| 607 | inp->ip_inp.inp.inp_vflag |= INP_IPV4; |
| 608 | } |
no test coverage detected