Deleted Added
full compact
sctp_pcb.c (171440) sctp_pcb.c (171477)
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 171440 2007-07-14 09:36:28Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 171477 2007-07-17 20:58:26Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>

--- 2077 unchanged lines hidden (view full) ---

2120 }
2121 return (0);
2122}
2123
2124
2125
2126int
2127sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>

--- 2077 unchanged lines hidden (view full) ---

2120 }
2121 return (0);
2122}
2123
2124
2125
2126int
2127sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
2128 struct sctp_ifa *sctp_ifap, struct thread *p)
2128 struct thread *p)
2129{
2130 /* bind a ep to a socket address */
2131 struct sctppcbhead *head;
2132 struct sctp_inpcb *inp, *inp_tmp;
2133 struct inpcb *ip_inp;
2134 int bindall;
2129{
2130 /* bind a ep to a socket address */
2131 struct sctppcbhead *head;
2132 struct sctp_inpcb *inp, *inp_tmp;
2133 struct inpcb *ip_inp;
2134 int bindall;
2135 int prison = 0;
2135 uint16_t lport;
2136 int error;
2137 uint32_t vrf_id;
2138
2139 lport = 0;
2140 error = 0;
2141 bindall = 1;
2142 inp = (struct sctp_inpcb *)so->so_pcb;

--- 5 unchanged lines hidden (view full) ---

2148 SCTPDBG(SCTP_DEBUG_PCB1, "Addr :");
2149 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
2150 }
2151#endif
2152 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
2153 /* already did a bind, subsequent binds NOT allowed ! */
2154 return (EINVAL);
2155 }
2136 uint16_t lport;
2137 int error;
2138 uint32_t vrf_id;
2139
2140 lport = 0;
2141 error = 0;
2142 bindall = 1;
2143 inp = (struct sctp_inpcb *)so->so_pcb;

--- 5 unchanged lines hidden (view full) ---

2149 SCTPDBG(SCTP_DEBUG_PCB1, "Addr :");
2150 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
2151 }
2152#endif
2153 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
2154 /* already did a bind, subsequent binds NOT allowed ! */
2155 return (EINVAL);
2156 }
2157 if (jailed(p->td_ucred)) {
2158 prison = 1;
2159 }
2156 if (addr != NULL) {
2157 if (addr->sa_family == AF_INET) {
2158 struct sockaddr_in *sin;
2159
2160 /* IPV6_V6ONLY socket? */
2161 if (SCTP_IPV6_V6ONLY(ip_inp)) {
2162 return (EINVAL);
2163 }
2164 if (addr->sa_len != sizeof(*sin))
2165 return (EINVAL);
2166
2167 sin = (struct sockaddr_in *)addr;
2168 lport = sin->sin_port;
2160 if (addr != NULL) {
2161 if (addr->sa_family == AF_INET) {
2162 struct sockaddr_in *sin;
2163
2164 /* IPV6_V6ONLY socket? */
2165 if (SCTP_IPV6_V6ONLY(ip_inp)) {
2166 return (EINVAL);
2167 }
2168 if (addr->sa_len != sizeof(*sin))
2169 return (EINVAL);
2170
2171 sin = (struct sockaddr_in *)addr;
2172 lport = sin->sin_port;
2169
2173 if (prison) {
2174 /*
2175 * For INADDR_ANY and LOOPBACK the
2176 * prison_ip() call will tranmute the ip
2177 * address to the proper valie.
2178 */
2179 if (prison_ip(p->td_ucred, 0, &sin->sin_addr.s_addr))
2180 return (EINVAL);
2181 }
2170 if (sin->sin_addr.s_addr != INADDR_ANY) {
2171 bindall = 0;
2172 }
2173 } else if (addr->sa_family == AF_INET6) {
2174 /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
2175 struct sockaddr_in6 *sin6;
2176
2177 sin6 = (struct sockaddr_in6 *)addr;
2178
2179 if (addr->sa_len != sizeof(*sin6))
2180 return (EINVAL);
2181
2182 lport = sin6->sin6_port;
2182 if (sin->sin_addr.s_addr != INADDR_ANY) {
2183 bindall = 0;
2184 }
2185 } else if (addr->sa_family == AF_INET6) {
2186 /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
2187 struct sockaddr_in6 *sin6;
2188
2189 sin6 = (struct sockaddr_in6 *)addr;
2190
2191 if (addr->sa_len != sizeof(*sin6))
2192 return (EINVAL);
2193
2194 lport = sin6->sin6_port;
2195 /*
2196 * Jail checks for IPv6 should go HERE! i.e. add the
2197 * prison_ip() equivilant in this postion to
2198 * transmute the addresses to the proper one jailed.
2199 */
2183 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2184 bindall = 0;
2185 /* KAME hack: embed scopeid */
2186 if (sa6_embedscope(sin6, ip6_use_defzone) != 0)
2187 return (EINVAL);
2188 }
2189 /* this must be cleared for ifa_ifwithaddr() */
2190 sin6->sin6_scope_id = 0;

--- 179 unchanged lines hidden (view full) ---

2370 memcpy(sin6, addr, sizeof(struct sockaddr_in6));
2371 sin6->sin6_port = 0;
2372 }
2373 /*
2374 * first find the interface with the bound address need to
2375 * zero out the port to find the address! yuck! can't do
2376 * this earlier since need port for sctp_pcb_findep()
2377 */
2200 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2201 bindall = 0;
2202 /* KAME hack: embed scopeid */
2203 if (sa6_embedscope(sin6, ip6_use_defzone) != 0)
2204 return (EINVAL);
2205 }
2206 /* this must be cleared for ifa_ifwithaddr() */
2207 sin6->sin6_scope_id = 0;

--- 179 unchanged lines hidden (view full) ---

2387 memcpy(sin6, addr, sizeof(struct sockaddr_in6));
2388 sin6->sin6_port = 0;
2389 }
2390 /*
2391 * first find the interface with the bound address need to
2392 * zero out the port to find the address! yuck! can't do
2393 * this earlier since need port for sctp_pcb_findep()
2394 */
2378 if (sctp_ifap)
2379 ifa = sctp_ifap;
2380 else
2381 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa,
2382 vrf_id, 0);
2395 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa,
2396 vrf_id, 0);
2383 if (ifa == NULL) {
2384 /* Can't find an interface with that address */
2385 SCTP_INP_WUNLOCK(inp);
2386 SCTP_INP_INFO_WUNLOCK();
2387 return (EADDRNOTAVAIL);
2388 }
2389 if (addr->sa_family == AF_INET6) {
2390 /* GAK, more FIXME IFA lock? */

--- 982 unchanged lines hidden (view full) ---

3373 }
3374 SCTP_INP_RUNLOCK(inp);
3375 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3376 /*
3377 * If you have not performed a bind, then we need to do the
3378 * ephemerial bind for you.
3379 */
3380 if ((err = sctp_inpcb_bind(inp->sctp_socket,
2397 if (ifa == NULL) {
2398 /* Can't find an interface with that address */
2399 SCTP_INP_WUNLOCK(inp);
2400 SCTP_INP_INFO_WUNLOCK();
2401 return (EADDRNOTAVAIL);
2402 }
2403 if (addr->sa_family == AF_INET6) {
2404 /* GAK, more FIXME IFA lock? */

--- 982 unchanged lines hidden (view full) ---

3387 }
3388 SCTP_INP_RUNLOCK(inp);
3389 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3390 /*
3391 * If you have not performed a bind, then we need to do the
3392 * ephemerial bind for you.
3393 */
3394 if ((err = sctp_inpcb_bind(inp->sctp_socket,
3381 (struct sockaddr *)NULL, (struct sctp_ifa *)NULL,
3395 (struct sockaddr *)NULL,
3382 (struct thread *)NULL
3383 ))) {
3384 /* bind error, probably perm */
3385 *error = err;
3386 return (NULL);
3387 }
3388 }
3389 stcb = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_asoc, struct sctp_tcb);

--- 1142 unchanged lines hidden (view full) ---

4532 * the INP during its work often times. This must be since we don't
4533 * want other proc's looking up things while what they are looking
4534 * up is changing :-D
4535 */
4536
4537 inp = stcb->sctp_ep;
4538 /* if subset bound and don't allow ASCONF's, can't delete last */
4539 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
3396 (struct thread *)NULL
3397 ))) {
3398 /* bind error, probably perm */
3399 *error = err;
3400 return (NULL);
3401 }
3402 }
3403 stcb = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_asoc, struct sctp_tcb);

--- 1142 unchanged lines hidden (view full) ---

4546 * the INP during its work often times. This must be since we don't
4547 * want other proc's looking up things while what they are looking
4548 * up is changing :-D
4549 */
4550
4551 inp = stcb->sctp_ep;
4552 /* if subset bound and don't allow ASCONF's, can't delete last */
4553 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4540 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4541 if (stcb->asoc.numnets < 2) {
4554 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
4555 if (stcb->sctp_ep->laddr_count < 2) {
4542 /* can't delete last address */
4543 return;
4544 }
4545 }
4546 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
4547 /* remove the address if it exists */
4548 if (laddr->ifa == NULL)
4549 continue;

--- 268 unchanged lines hidden (view full) ---

4818 SCTP_TCB_UNLOCK(stcb_tmp);
4819 return (-3);
4820 }
4821 }
4822 if (stcb->asoc.state == 0) {
4823 /* the assoc was freed? */
4824 return (-4);
4825 }
4556 /* can't delete last address */
4557 return;
4558 }
4559 }
4560 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
4561 /* remove the address if it exists */
4562 if (laddr->ifa == NULL)
4563 continue;

--- 268 unchanged lines hidden (view full) ---

4832 SCTP_TCB_UNLOCK(stcb_tmp);
4833 return (-3);
4834 }
4835 }
4836 if (stcb->asoc.state == 0) {
4837 /* the assoc was freed? */
4838 return (-4);
4839 }
4840 /*
4841 * peer must explicitly turn this on. This may have been initialized
4842 * to be "on" in order to allow local addr changes while INIT's are
4843 * in flight.
4844 */
4845 stcb->asoc.peer_supports_asconf = 0;
4826 /* now we must go through each of the params. */
4827 phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
4828 while (phdr) {
4829 ptype = ntohs(phdr->param_type);
4830 plen = ntohs(phdr->param_length);
4831 /*
4832 * printf("ptype => %0x, plen => %d\n", (uint32_t)ptype,
4833 * (int)plen);

--- 847 unchanged lines hidden ---
4846 /* now we must go through each of the params. */
4847 phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
4848 while (phdr) {
4849 ptype = ntohs(phdr->param_type);
4850 plen = ntohs(phdr->param_length);
4851 /*
4852 * printf("ptype => %0x, plen => %d\n", (uint32_t)ptype,
4853 * (int)plen);

--- 847 unchanged lines hidden ---