diff options
author | rrs <rrs@FreeBSD.org> | 2007-06-13 14:39:41 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-06-13 14:39:41 +0000 |
commit | 94bb7c7cd57a398c31a87b976b9b7b2d920e138c (patch) | |
tree | 44fd92cfa433c070637b94ce79ca679f8ac35b16 /sys/netinet/sctputil.c | |
parent | 20ee7c7a9b5f1194697b9fc673b37c2575903f60 (diff) | |
download | FreeBSD-src-94bb7c7cd57a398c31a87b976b9b7b2d920e138c.zip FreeBSD-src-94bb7c7cd57a398c31a87b976b9b7b2d920e138c.tar.gz |
- fix bindx to check addresses against socket's protocol family
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index b2f9f99..b777333 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -5906,8 +5906,19 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, *error = EINVAL; return; } + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { + /* can only bind v6 on PF_INET6 sockets */ + *error = EINVAL; + return; + } sin6 = (struct sockaddr_in6 *)addr_touse; if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* can't bind v4-mapped on PF_INET sockets */ + *error = EINVAL; + return; + } in6_sin6_2_sin(&sin, sin6); addr_touse = (struct sockaddr *)&sin; } @@ -5918,6 +5929,12 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, *error = EINVAL; return; } + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* can't bind v4 on PF_INET sockets */ + *error = EINVAL; + return; + } } if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { if (p == NULL) { @@ -5993,8 +6010,19 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp, *error = EINVAL; return; } + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { + /* can only bind v6 on PF_INET6 sockets */ + *error = EINVAL; + return; + } sin6 = (struct sockaddr_in6 *)addr_touse; if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* can't bind mapped-v4 on PF_INET sockets */ + *error = EINVAL; + return; + } in6_sin6_2_sin(&sin, sin6); addr_touse = (struct sockaddr *)&sin; } @@ -6005,6 +6033,12 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp, *error = EINVAL; return; } + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* can't bind v4 on PF_INET sockets */ + *error = EINVAL; + return; + } } /* * No lock required mgmt_ep_sa does its own locking. If the FIX: |