sctp_usrreq.c (184030) | sctp_usrreq.c (185435) |
---|---|
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_usrreq.c,v 1.48 2005/03/07 23:26:08 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_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 184030 2008-10-18 15:56:12Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 185435 2008-11-29 14:32:14Z bz $"); |
35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#endif 42#include <netinet/sctp_sysctl.h> --- 459 unchanged lines hidden (view full) --- 502 503static int 504sctp_attach(struct socket *so, int proto, struct thread *p) 505{ 506 struct sctp_inpcb *inp; 507 struct inpcb *ip_inp; 508 int error; 509 uint32_t vrf_id = SCTP_DEFAULT_VRFID; | 35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#endif 42#include <netinet/sctp_sysctl.h> --- 459 unchanged lines hidden (view full) --- 502 503static int 504sctp_attach(struct socket *so, int proto, struct thread *p) 505{ 506 struct sctp_inpcb *inp; 507 struct inpcb *ip_inp; 508 int error; 509 uint32_t vrf_id = SCTP_DEFAULT_VRFID; |
510 | |
511#ifdef IPSEC 512 uint32_t flags; | 510#ifdef IPSEC 511 uint32_t flags; |
513 | |
514#endif | 512#endif |
513 |
|
515 inp = (struct sctp_inpcb *)so->so_pcb; 516 if (inp != 0) { 517 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 518 return EINVAL; 519 } 520 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 521 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 522 if (error) { --- 3423 unchanged lines hidden (view full) --- 3946 3947 } 3948 break; 3949 case SCTP_BINDX_ADD_ADDR: 3950 { 3951 struct sctp_getaddresses *addrs; 3952 size_t sz; 3953 struct thread *td; | 514 inp = (struct sctp_inpcb *)so->so_pcb; 515 if (inp != 0) { 516 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 517 return EINVAL; 518 } 519 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 520 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 521 if (error) { --- 3423 unchanged lines hidden (view full) --- 3945 3946 } 3947 break; 3948 case SCTP_BINDX_ADD_ADDR: 3949 { 3950 struct sctp_getaddresses *addrs; 3951 size_t sz; 3952 struct thread *td; |
3954 int prison = 0; | |
3955 3956 td = (struct thread *)p; | 3953 3954 td = (struct thread *)p; |
3957 if (jailed(td->td_ucred)) { 3958 prison = 1; 3959 } | |
3960 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 3961 optsize); 3962 if (addrs->addr->sa_family == AF_INET) { 3963 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 3964 if (optsize < sz) { 3965 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3966 error = EINVAL; 3967 break; 3968 } | 3955 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 3956 optsize); 3957 if (addrs->addr->sa_family == AF_INET) { 3958 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 3959 if (optsize < sz) { 3960 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3961 error = EINVAL; 3962 break; 3963 } |
3969 if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) { | 3964 if (td != NULL && prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr))) { |
3970 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 3971 error = EADDRNOTAVAIL; | 3965 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 3966 error = EADDRNOTAVAIL; |
3967 break; |
|
3972 } | 3968 } |
3969#ifdef INET6 |
|
3973 } else if (addrs->addr->sa_family == AF_INET6) { 3974 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 3975 if (optsize < sz) { 3976 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3977 error = EINVAL; 3978 break; 3979 } | 3970 } else if (addrs->addr->sa_family == AF_INET6) { 3971 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 3972 if (optsize < sz) { 3973 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3974 error = EINVAL; 3975 break; 3976 } |
3980 /* JAIL XXXX Add else here for V6 */ | 3977 if (td != NULL && prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 3978 (SCTP_IPV6_V6ONLY(inp) != 0)) != 0) { 3979 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 3980 error = EADDRNOTAVAIL; 3981 break; 3982 } 3983#endif 3984 } else { 3985 error = EAFNOSUPPORT; 3986 break; |
3981 } 3982 sctp_bindx_add_address(so, inp, addrs->addr, 3983 addrs->sget_assoc_id, vrf_id, 3984 &error, p); 3985 } 3986 break; 3987 case SCTP_BINDX_REM_ADDR: 3988 { 3989 struct sctp_getaddresses *addrs; 3990 size_t sz; 3991 struct thread *td; | 3987 } 3988 sctp_bindx_add_address(so, inp, addrs->addr, 3989 addrs->sget_assoc_id, vrf_id, 3990 &error, p); 3991 } 3992 break; 3993 case SCTP_BINDX_REM_ADDR: 3994 { 3995 struct sctp_getaddresses *addrs; 3996 size_t sz; 3997 struct thread *td; |
3992 int prison = 0; | |
3993 3994 td = (struct thread *)p; | 3998 3999 td = (struct thread *)p; |
3995 if (jailed(td->td_ucred)) { 3996 prison = 1; 3997 } | 4000 |
3998 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 3999 if (addrs->addr->sa_family == AF_INET) { 4000 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 4001 if (optsize < sz) { 4002 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4003 error = EINVAL; 4004 break; 4005 } | 4001 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 4002 if (addrs->addr->sa_family == AF_INET) { 4003 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 4004 if (optsize < sz) { 4005 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4006 error = EINVAL; 4007 break; 4008 } |
4006 if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) { | 4009 if (td != NULL && prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr))) { |
4007 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 4008 error = EADDRNOTAVAIL; | 4010 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 4011 error = EADDRNOTAVAIL; |
4012 break; |
|
4009 } | 4013 } |
4014#ifdef INET6 |
|
4010 } else if (addrs->addr->sa_family == AF_INET6) { 4011 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 4012 if (optsize < sz) { 4013 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4014 error = EINVAL; 4015 break; 4016 } | 4015 } else if (addrs->addr->sa_family == AF_INET6) { 4016 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 4017 if (optsize < sz) { 4018 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4019 error = EINVAL; 4020 break; 4021 } |
4017 /* JAIL XXXX Add else here for V6 */ | 4022 if (td != NULL && prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 4023 (SCTP_IPV6_V6ONLY(inp) != 0)) != 0) { 4024 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 4025 error = EADDRNOTAVAIL; 4026 break; 4027 } 4028#endif 4029 } else { 4030 error = EAFNOSUPPORT; 4031 break; |
4018 } 4019 sctp_bindx_delete_address(so, inp, addrs->addr, 4020 addrs->sget_assoc_id, vrf_id, 4021 &error); 4022 } 4023 break; 4024 default: 4025 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); --- 75 unchanged lines hidden (view full) --- 4101 /* I made the same as TCP since we are not setup? */ 4102 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4103 return (ECONNRESET); 4104 } 4105 if (addr == NULL) { 4106 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4107 return EINVAL; 4108 } | 4032 } 4033 sctp_bindx_delete_address(so, inp, addrs->addr, 4034 addrs->sget_assoc_id, vrf_id, 4035 &error); 4036 } 4037 break; 4038 default: 4039 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); --- 75 unchanged lines hidden (view full) --- 4115 /* I made the same as TCP since we are not setup? */ 4116 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4117 return (ECONNRESET); 4118 } 4119 if (addr == NULL) { 4120 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4121 return EINVAL; 4122 } |
4109 if ((addr->sa_family == AF_INET6) && (addr->sa_len != sizeof(struct sockaddr_in6))) { 4110 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4111 return (EINVAL); | 4123#ifdef INET6 4124 if (addr->sa_family == AF_INET6) { 4125 struct sockaddr_in6 *sin6p; 4126 if (addr->sa_len != sizeof(struct sockaddr_in6)) { 4127 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4128 return (EINVAL); 4129 } 4130 sin6p = (struct sockaddr_in6 *)addr; 4131 if (p != NULL && prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr) != 0) { 4132 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4133 return (EINVAL); 4134 } 4135 } else 4136#endif 4137 if (addr->sa_family == AF_INET) { 4138 struct sockaddr_in *sinp; 4139 if (addr->sa_len != sizeof(struct sockaddr_in)) { 4140 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4141 return (EINVAL); 4142 } 4143 sinp = (struct sockaddr_in *)addr; 4144 if (p != NULL && prison_remote_ip4(p->td_ucred, &sinp->sin_addr) != 0) { 4145 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4146 return (EINVAL); 4147 } 4148 } else { 4149 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 4150 return (EAFNOSUPPORT); |
4112 } | 4151 } |
4113 if ((addr->sa_family == AF_INET) && (addr->sa_len != sizeof(struct sockaddr_in))) { 4114 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4115 return (EINVAL); 4116 } | |
4117 SCTP_INP_INCR_REF(inp); 4118 SCTP_ASOC_CREATE_LOCK(inp); 4119 create_lock_on = 1; 4120 4121 4122 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 4123 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 4124 /* Should I really unlock ? */ --- 507 unchanged lines hidden --- | 4152 SCTP_INP_INCR_REF(inp); 4153 SCTP_ASOC_CREATE_LOCK(inp); 4154 create_lock_on = 1; 4155 4156 4157 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 4158 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 4159 /* Should I really unlock ? */ --- 507 unchanged lines hidden --- |