Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/sctp_syscalls.c
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
#include <sys/ktrace.h> | #include <sys/ktrace.h> | ||||
#endif | #endif | ||||
#ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
#include <compat/freebsd32/freebsd32.h> | |||||
#include <compat/freebsd32/freebsd32_syscall.h> | |||||
#include <compat/freebsd32/freebsd32_util.h> | #include <compat/freebsd32/freebsd32_util.h> | ||||
#endif | #endif | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <security/audit/audit.h> | #include <security/audit/audit.h> | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <netinet/sctp.h> | #include <netinet/sctp.h> | ||||
#include <netinet/sctp_os_bsd.h> | |||||
#include <netinet/sctp_peeloff.h> | #include <netinet/sctp_peeloff.h> | ||||
static struct syscall_helper_data sctp_syscalls[] = { | static struct syscall_helper_data sctp_syscalls[] = { | ||||
SYSCALL_INIT_HELPER_F(sctp_peeloff, SYF_CAPENABLED), | SYSCALL_INIT_HELPER_F(sctp_peeloff, SYF_CAPENABLED), | ||||
SYSCALL_INIT_HELPER_F(sctp_generic_sendmsg, SYF_CAPENABLED), | SYSCALL_INIT_HELPER_F(sctp_generic_sendmsg, SYF_CAPENABLED), | ||||
SYSCALL_INIT_HELPER_F(sctp_generic_sendmsg_iov, SYF_CAPENABLED), | SYSCALL_INIT_HELPER_F(sctp_generic_sendmsg_iov, SYF_CAPENABLED), | ||||
SYSCALL_INIT_HELPER_F(sctp_generic_recvmsg, SYF_CAPENABLED), | SYSCALL_INIT_HELPER_F(sctp_generic_recvmsg, SYF_CAPENABLED), | ||||
SYSCALL_INIT_LAST | SYSCALL_INIT_LAST | ||||
}; | }; | ||||
static void | #ifdef COMPAT_FREEBSD32 | ||||
sctp_syscalls_init(void *unused __unused) | static struct syscall_helper_data sctp32_syscalls[] = { | ||||
SYSCALL32_INIT_HELPER_COMPAT(sctp_peeloff), | |||||
SYSCALL32_INIT_HELPER_COMPAT(sctp_generic_sendmsg), | |||||
SYSCALL32_INIT_HELPER_COMPAT(sctp_generic_sendmsg_iov), | |||||
SYSCALL32_INIT_HELPER_COMPAT(sctp_generic_recvmsg), | |||||
SYSCALL_INIT_LAST | |||||
}; | |||||
#endif | |||||
int | |||||
sctp_syscalls_init(void) | |||||
{ | { | ||||
int error __unused; | int error; | ||||
error = syscall_helper_register(sctp_syscalls, SY_THR_STATIC); | error = syscall_helper_register(sctp_syscalls, SY_THR_STATIC_KLD); | ||||
KASSERT((error == 0), | if (error != 0) | ||||
("%s: syscall_helper_register failed for sctp syscalls", __func__)); | return (error); | ||||
#ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
error = syscall32_helper_register(sctp_syscalls, SY_THR_STATIC); | error = syscall32_helper_register(sctp32_syscalls, SY_THR_STATIC_KLD); | ||||
KASSERT((error == 0), | if (error != 0) | ||||
("%s: syscall32_helper_register failed for sctp syscalls", | return (error); | ||||
__func__)); | |||||
#endif | #endif | ||||
return (0); | |||||
} | } | ||||
SYSINIT(sctp_syscalls, SI_SUB_SYSCALLS, SI_ORDER_ANY, sctp_syscalls_init, NULL); | |||||
int | |||||
sctp_syscalls_uninit(void) | |||||
{ | |||||
int error; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
error = syscall32_helper_unregister(sctp32_syscalls); | |||||
if (error != 0) | |||||
return (error); | |||||
#endif | |||||
error = syscall_helper_unregister(sctp_syscalls); | |||||
if (error != 0) | |||||
return (error); | |||||
return (0); | |||||
} | |||||
/* | /* | ||||
* SCTP syscalls. | * SCTP syscalls. | ||||
* Functionality only compiled in if SCTP is defined in the kernel Makefile, | * Functionality only compiled in if SCTP is defined in the kernel Makefile, | ||||
* otherwise all return EOPNOTSUPP. | * otherwise all return EOPNOTSUPP. | ||||
* XXX: We should make this loadable one day. | |||||
*/ | */ | ||||
int | int | ||||
sys_sctp_peeloff(td, uap) | sys_sctp_peeloff(td, uap) | ||||
struct thread *td; | struct thread *td; | ||||
struct sctp_peeloff_args /* { | struct sctp_peeloff_args /* { | ||||
int sd; | int sd; | ||||
caddr_t name; | caddr_t name; | ||||
} */ *uap; | } */ *uap; | ||||
{ | { | ||||
#if (defined(INET) || defined(INET6)) && defined(SCTP) | #if defined(INET) || defined(INET6) | ||||
struct file *headfp, *nfp = NULL; | struct file *headfp, *nfp = NULL; | ||||
struct socket *head, *so; | struct socket *head, *so; | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
u_int fflag; | u_int fflag; | ||||
int error, fd; | int error, fd; | ||||
AUDIT_ARG_FD(uap->sd); | AUDIT_ARG_FD(uap->sd); | ||||
error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), | error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | noconnection: | ||||
*/ | */ | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
done: | done: | ||||
if (nfp != NULL) | if (nfp != NULL) | ||||
fdrop(nfp, td); | fdrop(nfp, td); | ||||
fdrop(headfp, td); | fdrop(headfp, td); | ||||
done2: | done2: | ||||
return (error); | return (error); | ||||
#else /* SCTP */ | #endif | ||||
return (EOPNOTSUPP); | |||||
#endif /* SCTP */ | |||||
} | } | ||||
int | int | ||||
sys_sctp_generic_sendmsg (td, uap) | sys_sctp_generic_sendmsg (td, uap) | ||||
struct thread *td; | struct thread *td; | ||||
struct sctp_generic_sendmsg_args /* { | struct sctp_generic_sendmsg_args /* { | ||||
int sd, | int sd, | ||||
caddr_t msg, | caddr_t msg, | ||||
int mlen, | int mlen, | ||||
caddr_t to, | caddr_t to, | ||||
__socklen_t tolen, | __socklen_t tolen, | ||||
struct sctp_sndrcvinfo *sinfo, | struct sctp_sndrcvinfo *sinfo, | ||||
int flags | int flags | ||||
} */ *uap; | } */ *uap; | ||||
{ | { | ||||
#if (defined(INET) || defined(INET6)) && defined(SCTP) | #if defined(INET) || defined(INET6) | ||||
struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; | struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; | ||||
struct socket *so; | struct socket *so; | ||||
struct file *fp = NULL; | struct file *fp = NULL; | ||||
struct sockaddr *to = NULL; | struct sockaddr *to = NULL; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
struct uio *ktruio = NULL; | struct uio *ktruio = NULL; | ||||
#endif | #endif | ||||
struct uio auio; | struct uio auio; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | #ifdef KTRACE | ||||
} | } | ||||
#endif /* KTRACE */ | #endif /* KTRACE */ | ||||
sctp_bad: | sctp_bad: | ||||
if (fp != NULL) | if (fp != NULL) | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
sctp_bad2: | sctp_bad2: | ||||
free(to, M_SONAME); | free(to, M_SONAME); | ||||
return (error); | return (error); | ||||
#else /* SCTP */ | #endif | ||||
return (EOPNOTSUPP); | |||||
#endif /* SCTP */ | |||||
} | } | ||||
int | int | ||||
sys_sctp_generic_sendmsg_iov(td, uap) | sys_sctp_generic_sendmsg_iov(td, uap) | ||||
struct thread *td; | struct thread *td; | ||||
struct sctp_generic_sendmsg_iov_args /* { | struct sctp_generic_sendmsg_iov_args /* { | ||||
int sd, | int sd, | ||||
struct iovec *iov, | struct iovec *iov, | ||||
int iovlen, | int iovlen, | ||||
caddr_t to, | caddr_t to, | ||||
__socklen_t tolen, | __socklen_t tolen, | ||||
struct sctp_sndrcvinfo *sinfo, | struct sctp_sndrcvinfo *sinfo, | ||||
int flags | int flags | ||||
} */ *uap; | } */ *uap; | ||||
{ | { | ||||
#if (defined(INET) || defined(INET6)) && defined(SCTP) | #if defined(INET) || defined(INET6) | ||||
struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; | struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; | ||||
struct socket *so; | struct socket *so; | ||||
struct file *fp = NULL; | struct file *fp = NULL; | ||||
struct sockaddr *to = NULL; | struct sockaddr *to = NULL; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
struct uio *ktruio = NULL; | struct uio *ktruio = NULL; | ||||
#endif | #endif | ||||
struct uio auio; | struct uio auio; | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
sctp_bad: | sctp_bad: | ||||
free(iov, M_IOV); | free(iov, M_IOV); | ||||
sctp_bad1: | sctp_bad1: | ||||
if (fp != NULL) | if (fp != NULL) | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
sctp_bad2: | sctp_bad2: | ||||
free(to, M_SONAME); | free(to, M_SONAME); | ||||
return (error); | return (error); | ||||
#else /* SCTP */ | #endif | ||||
return (EOPNOTSUPP); | |||||
#endif /* SCTP */ | |||||
} | } | ||||
int | int | ||||
sys_sctp_generic_recvmsg(td, uap) | sys_sctp_generic_recvmsg(td, uap) | ||||
struct thread *td; | struct thread *td; | ||||
struct sctp_generic_recvmsg_args /* { | struct sctp_generic_recvmsg_args /* { | ||||
int sd, | int sd, | ||||
struct iovec *iov, | struct iovec *iov, | ||||
int iovlen, | int iovlen, | ||||
struct sockaddr *from, | struct sockaddr *from, | ||||
__socklen_t *fromlenaddr, | __socklen_t *fromlenaddr, | ||||
struct sctp_sndrcvinfo *sinfo, | struct sctp_sndrcvinfo *sinfo, | ||||
int *msg_flags | int *msg_flags | ||||
} */ *uap; | } */ *uap; | ||||
{ | { | ||||
#if (defined(INET) || defined(INET6)) && defined(SCTP) | #if defined(INET) || defined(INET6) | ||||
uint8_t sockbufstore[256]; | uint8_t sockbufstore[256]; | ||||
struct uio auio; | struct uio auio; | ||||
struct iovec *iov, *tiov; | struct iovec *iov, *tiov; | ||||
struct sctp_sndrcvinfo sinfo; | struct sctp_sndrcvinfo sinfo; | ||||
struct socket *so; | struct socket *so; | ||||
struct file *fp = NULL; | struct file *fp = NULL; | ||||
struct sockaddr *fromsa; | struct sockaddr *fromsa; | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
out: | out: | ||||
free(iov, M_IOV); | free(iov, M_IOV); | ||||
out1: | out1: | ||||
if (fp != NULL) | if (fp != NULL) | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
return (error); | return (error); | ||||
#else /* SCTP */ | #endif | ||||
return (EOPNOTSUPP); | |||||
#endif /* SCTP */ | |||||
} | } |