1 //==========================================================================
3 // sys/kern/uipc_syscalls.c
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
10 // -------------------------------------------
12 // Portions of this software may have been derived from OpenBSD or other sources,
13 // and are covered by the appropriate copyright disclaimers included herein.
15 // -------------------------------------------
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
22 // Contributors: gthomas
28 //####DESCRIPTIONEND####
30 //==========================================================================
33 /* $OpenBSD: uipc_syscalls.c,v 1.29 1999/12/08 06:50:17 itojun Exp $ */
34 /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
37 * Copyright (c) 1982, 1986, 1989, 1990, 1993
38 * The Regents of the University of California. All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
71 #include <sys/param.h>
73 #include <cyg/io/file.h>
74 static int ecos_getsock(int fdes, struct file **fpp);
75 #define getsock(fdp, fdes, fpp) ecos_getsock(fdes, fpp)
77 #include <sys/systm.h>
79 #include <sys/filedesc.h>
83 #include <sys/malloc.h>
85 #include <sys/protosw.h>
86 #include <sys/socket.h>
87 #include <sys/socketvar.h>
89 #include <sys/signalvar.h>
93 #include <sys/ktrace.h>
97 #include <sys/mount.h>
99 #include <sys/syscallargs.h>
102 * System call interface to the socket abstraction.
104 extern struct fileops socketops;
108 sys_socket(struct sys_socket_args *uap, register_t *retval)
112 sys_socket(p, v, retval)
117 register struct sys_socket_args /* {
118 syscallarg(int) domain;
119 syscallarg(int) type;
120 syscallarg(int) protocol;
122 struct filedesc *fdp = p->p_fd;
129 if ((error = falloc(&fp, &fd)) != 0)
131 if ((error = falloc(p, &fp, &fd)) != 0)
134 fp->f_flag = FREAD|FWRITE;
135 fp->f_type = DTYPE_SOCKET;
136 fp->f_ops = &socketops;
137 error = socreate(SCARG(uap, domain), &so, SCARG(uap, type),
138 SCARG(uap, protocol));
146 fp->f_data = (CYG_ADDRWORD)so;
148 fp->f_data = (caddr_t)so;
157 sys_bind(struct sys_bind_args *uap, register_t *retval)
162 sys_bind(p, v, retval)
167 register struct sys_bind_args /* {
169 syscallarg(struct sockaddr *) name;
170 syscallarg(socklen_t) namelen;
177 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
179 error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),
183 error = sobind((struct socket *)fp->f_data, nam);
191 sys_listen(struct sys_listen_args *uap, register_t *retval)
195 sys_listen(p, v, retval)
200 register struct sys_listen_args /* {
202 syscallarg(int) backlog;
208 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
210 return (solisten((struct socket *)fp->f_data, SCARG(uap, backlog)));
215 sys_accept(struct sys_accept_args *uap, register_t *retval)
219 sys_accept(p, v, retval)
224 register struct sys_accept_args /* {
226 syscallarg(struct sockaddr *) name;
227 syscallarg(socklen_t *) anamelen;
234 register struct socket *so;
236 if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, anamelen),
237 (caddr_t)&namelen, sizeof (namelen))))
239 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
242 so = (struct socket *)fp->f_data;
243 if ((so->so_options & SO_ACCEPTCONN) == 0) {
247 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
249 return (EWOULDBLOCK);
251 while (so->so_qlen == 0 && so->so_error == 0) {
252 if (so->so_state & SS_CANTRCVMORE) {
253 so->so_error = ECONNABORTED;
256 error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
264 error = so->so_error;
270 if ((error = falloc(&fp, &tmpfd)) != 0) {
272 if ((error = falloc(p, &fp, &tmpfd)) != 0) {
278 { struct socket *aso = so->so_q;
279 if (soqremque(aso, 1) == 0)
283 fp->f_type = DTYPE_SOCKET;
284 fp->f_flag = FREAD|FWRITE;
285 fp->f_ops = &socketops;
287 fp->f_data = (CYG_ADDRWORD)so;
289 fp->f_data = (caddr_t)so;
291 nam = m_get(M_WAIT, MT_SONAME);
292 (void) soaccept(so, nam);
293 if (SCARG(uap, name)) {
294 if (namelen > nam->m_len)
295 namelen = nam->m_len;
296 /* SHOULD COPY OUT A CHAIN HERE */
297 if ((error = copyout(mtod(nam, caddr_t),
298 (caddr_t)SCARG(uap, name), namelen)) == 0)
299 error = copyout((caddr_t)&namelen,
300 (caddr_t)SCARG(uap, anamelen),
301 sizeof (*SCARG(uap, anamelen)));
310 sys_connect(struct sys_connect_args *uap, register_t *retval)
315 sys_connect(p, v, retval)
320 register struct sys_connect_args /* {
322 syscallarg(struct sockaddr *) name;
323 syscallarg(socklen_t) namelen;
327 register struct socket *so;
331 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
333 so = (struct socket *)fp->f_data;
334 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
336 error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),
340 error = soconnect(so, nam);
343 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
345 return (EINPROGRESS);
348 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
349 error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
355 error = so->so_error;
360 so->so_state &= ~SS_ISCONNECTING;
363 if (error == ERESTART)
371 sys_socketpair(p, v, retval)
376 register struct sys_socketpair_args /* {
377 syscallarg(int) domain;
378 syscallarg(int) type;
379 syscallarg(int) protocol;
380 syscallarg(int *) rsv;
382 register struct filedesc *fdp = p->p_fd;
383 struct file *fp1, *fp2;
384 struct socket *so1, *so2;
385 int fd, error, sv[2];
387 error = socreate(SCARG(uap, domain), &so1, SCARG(uap, type),
388 SCARG(uap, protocol));
391 error = socreate(SCARG(uap, domain), &so2, SCARG(uap, type),
392 SCARG(uap, protocol));
395 if ((error = falloc(p, &fp1, &fd)) != 0)
398 fp1->f_flag = FREAD|FWRITE;
399 fp1->f_type = DTYPE_SOCKET;
400 fp1->f_ops = &socketops;
401 fp1->f_data = (caddr_t)so1;
402 if ((error = falloc(p, &fp2, &fd)) != 0)
404 fp2->f_flag = FREAD|FWRITE;
405 fp2->f_type = DTYPE_SOCKET;
406 fp2->f_ops = &socketops;
407 fp2->f_data = (caddr_t)so2;
409 if ((error = soconnect2(so1, so2)) != 0)
411 if (SCARG(uap, type) == SOCK_DGRAM) {
413 * Datagram socket connection is asymmetric.
415 if ((error = soconnect2(so2, so1)) != 0)
418 error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, rsv),
424 fdremove(fdp, sv[1]);
427 fdremove(fdp, sv[0]);
438 sys_sendto(struct sys_sendto_args *uap, register_t *retval)
442 sys_sendto(p, v, retval)
447 register struct sys_sendto_args /* {
449 syscallarg(caddr_t) buf;
450 syscallarg(size_t) len;
451 syscallarg(int) flags;
452 syscallarg(struct sockaddr *) to;
453 syscallarg(socklen_t) tolen;
459 msg.msg_name = (caddr_t)SCARG(uap, to);
460 msg.msg_namelen = SCARG(uap, tolen);
464 #ifdef COMPAT_OLDSOCK
467 aiov.iov_base = (char *)SCARG(uap, buf);
468 aiov.iov_len = SCARG(uap, len);
470 return (sendit(SCARG(uap, s), &msg, SCARG(uap, flags), retval));
472 return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
478 sys_sendmsg(p, v, retval)
483 register struct sys_sendmsg_args /* {
485 syscallarg(caddr_t) msg;
486 syscallarg(int) flags;
489 struct iovec aiov[UIO_SMALLIOV], *iov;
492 error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof (msg));
495 if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
497 if (msg.msg_iovlen > UIO_SMALLIOV)
498 MALLOC(iov, struct iovec *,
499 sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
502 if (msg.msg_iovlen &&
503 (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
504 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
507 #ifdef COMPAT_OLDSOCK
510 error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
520 sendit(int s, struct msghdr *mp, int flags, register_t *retsize)
524 sendit(p, s, mp, flags, retsize)
525 register struct proc *p;
527 register struct msghdr *mp;
534 register struct iovec *iov;
536 struct mbuf *to, *control;
539 struct iovec *ktriov = NULL;
542 if ((error = getsock(p->p_fd, s, &fp)) != 0)
544 auio.uio_iov = mp->msg_iov;
545 auio.uio_iovcnt = mp->msg_iovlen;
546 auio.uio_segflg = UIO_USERSPACE;
547 auio.uio_rw = UIO_WRITE;
551 auio.uio_offset = 0; /* XXX */
554 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
555 /* Don't allow sum > SSIZE_MAX */
556 if (iov->iov_len > SSIZE_MAX ||
557 (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
561 error = sockargs(&to, mp->msg_name, mp->msg_namelen,
567 if (mp->msg_control) {
568 if (mp->msg_controllen < sizeof(struct cmsghdr)
569 #ifdef COMPAT_OLDSOCK
570 && mp->msg_flags != MSG_COMPAT
576 error = sockargs(&control, mp->msg_control,
577 mp->msg_controllen, MT_CONTROL);
580 #ifdef COMPAT_OLDSOCK
581 if (mp->msg_flags == MSG_COMPAT) {
582 register struct cmsghdr *cm;
584 M_PREPEND(control, sizeof(*cm), M_WAIT);
589 cm = mtod(control, struct cmsghdr *);
590 cm->cmsg_len = control->m_len;
591 cm->cmsg_level = SOL_SOCKET;
592 cm->cmsg_type = SCM_RIGHTS;
599 if (KTRPOINT(p, KTR_GENIO)) {
600 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
602 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
603 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
606 len = auio.uio_resid;
607 error = sosend((struct socket *)fp->f_data, to, &auio,
608 NULL, control, flags);
611 if (auio.uio_resid != len &&
612 (error == EINTR || error == EWOULDBLOCK))
614 if (auio.uio_resid != len && (error == ERESTART ||
615 error == EINTR || error == EWOULDBLOCK))
624 *retsize = len - auio.uio_resid;
626 if (ktriov != NULL) {
628 ktrgenio(p->p_tracep, s, UIO_WRITE,
629 ktriov, *retsize, error);
630 FREE(ktriov, M_TEMP);
641 sys_recvfrom(struct sys_recvfrom_args *uap, register_t *retval)
645 sys_recvfrom(p, v, retval)
650 register struct sys_recvfrom_args /* {
652 syscallarg(caddr_t) buf;
653 syscallarg(size_t) len;
654 syscallarg(int) flags;
655 syscallarg(struct sockaddr *) from;
656 syscallarg(socklen_t *) fromlenaddr;
663 if (SCARG(uap, fromlenaddr)) {
664 error = copyin((caddr_t)SCARG(uap, fromlenaddr),
665 (caddr_t)&msg.msg_namelen,
666 sizeof (msg.msg_namelen));
671 msg.msg_name = (caddr_t)SCARG(uap, from);
674 aiov.iov_base = SCARG(uap, buf);
675 aiov.iov_len = SCARG(uap, len);
677 msg.msg_flags = SCARG(uap, flags);
679 return (recvit(SCARG(uap, s), &msg,
680 (caddr_t)SCARG(uap, fromlenaddr), retval));
682 return (recvit(p, SCARG(uap, s), &msg,
683 (caddr_t)SCARG(uap, fromlenaddr), retval));
689 sys_recvmsg(p, v, retval)
694 register struct sys_recvmsg_args /* {
696 syscallarg(struct msghdr *) msg;
697 syscallarg(int) flags;
700 struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
703 error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
707 if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
709 if (msg.msg_iovlen > UIO_SMALLIOV)
710 MALLOC(iov, struct iovec *,
711 sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
714 #ifdef COMPAT_OLDSOCK
715 msg.msg_flags = SCARG(uap, flags) &~ MSG_COMPAT;
717 msg.msg_flags = SCARG(uap, flags);
721 error = copyin((caddr_t)uiov, (caddr_t)iov,
722 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
725 if ((error = recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval)) == 0) {
727 error = copyout((caddr_t)&msg, (caddr_t)SCARG(uap, msg),
739 recvit(int s, struct msghdr *mp, caddr_t namelenp, register_t *retsize)
743 recvit(p, s, mp, namelenp, retsize)
744 register struct proc *p;
746 register struct msghdr *mp;
753 register struct iovec *iov;
757 struct mbuf *from = 0, *control = 0;
759 struct iovec *ktriov = NULL;
762 if ((error = getsock(p->p_fd, s, &fp)) != 0)
764 auio.uio_iov = mp->msg_iov;
765 auio.uio_iovcnt = mp->msg_iovlen;
766 auio.uio_segflg = UIO_USERSPACE;
767 auio.uio_rw = UIO_READ;
771 auio.uio_offset = 0; /* XXX */
774 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
775 /* Don't allow sum > SSIZE_MAX */
776 if (iov->iov_len > SSIZE_MAX ||
777 (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
781 if (KTRPOINT(p, KTR_GENIO)) {
782 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
784 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
785 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
788 len = auio.uio_resid;
789 error = soreceive((struct socket *)fp->f_data, &from, &auio,
790 NULL, mp->msg_control ? &control : NULL,
794 if (auio.uio_resid != len &&
795 (error == EINTR || error == EWOULDBLOCK))
797 if (auio.uio_resid != len && (error == ERESTART ||
798 error == EINTR || error == EWOULDBLOCK))
803 if (ktriov != NULL) {
805 ktrgenio(p->p_tracep, s, UIO_READ,
806 ktriov, len - auio.uio_resid, error);
807 FREE(ktriov, M_TEMP);
812 *retsize = len - auio.uio_resid;
814 len = mp->msg_namelen;
815 if (len <= 0 || from == 0)
818 /* save sa_len before it is destroyed by MSG_COMPAT */
819 if (len > from->m_len)
821 /* else if len < from->m_len ??? */
822 #ifdef COMPAT_OLDSOCK
823 if (mp->msg_flags & MSG_COMPAT)
824 mtod(from, struct osockaddr *)->sa_family =
825 mtod(from, struct sockaddr *)->sa_family;
827 error = copyout(mtod(from, caddr_t),
828 (caddr_t)mp->msg_name, (unsigned)len);
832 mp->msg_namelen = len;
834 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
835 #ifdef COMPAT_OLDSOCK
836 if (mp->msg_flags & MSG_COMPAT)
837 error = 0; /* old recvfrom didn't check */
843 if (mp->msg_control) {
844 #ifdef COMPAT_OLDSOCK
846 * We assume that old recvmsg calls won't receive access
847 * rights and other control info, esp. as control info
848 * is always optional and those options didn't exist in 4.3.
849 * If we receive rights, trim the cmsghdr; anything else
852 if (control && mp->msg_flags & MSG_COMPAT) {
853 if (mtod(control, struct cmsghdr *)->cmsg_level !=
855 mtod(control, struct cmsghdr *)->cmsg_type !=
857 mp->msg_controllen = 0;
860 control->m_len -= sizeof (struct cmsghdr);
861 control->m_data += sizeof (struct cmsghdr);
864 len = mp->msg_controllen;
865 if (len <= 0 || control == 0)
868 struct mbuf *m = control;
869 caddr_t p = (caddr_t)mp->msg_control;
874 mp->msg_flags |= MSG_CTRUNC;
877 error = copyout(mtod(m, caddr_t), p,
883 if (error != 0 || len <= 0)
885 } while ((m = m->m_next) != NULL);
886 len = p - (caddr_t)mp->msg_control;
888 mp->msg_controllen = len;
901 sys_shutdown(struct sys_shutdown_args *uap, register_t *retval)
905 sys_shutdown(p, v, retval)
910 register struct sys_shutdown_args /* {
918 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
920 return (soshutdown((struct socket *)fp->f_data, SCARG(uap, how)));
925 sys_setsockopt(struct sys_setsockopt_args *uap, register_t *retval)
930 sys_setsockopt(p, v, retval)
935 register struct sys_setsockopt_args /* {
937 syscallarg(int) level;
938 syscallarg(int) name;
939 syscallarg(caddr_t) val;
940 syscallarg(socklen_t) valsize;
944 struct mbuf *m = NULL;
947 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
949 if (SCARG(uap, valsize) > MCLBYTES)
951 if (SCARG(uap, val)) {
952 m = m_get(M_WAIT, MT_SOOPTS);
953 if (SCARG(uap, valsize) > MLEN) {
954 MCLGET(m, M_DONTWAIT);
955 if ((m->m_flags & M_EXT) == 0) {
962 error = copyin(SCARG(uap, val), mtod(m, caddr_t),
963 SCARG(uap, valsize));
968 m->m_len = SCARG(uap, valsize);
970 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
971 SCARG(uap, name), m));
976 sys_getsockopt(struct sys_getsockopt_args *uap, register_t *retval)
981 sys_getsockopt(p, v, retval)
986 register struct sys_getsockopt_args /* {
988 syscallarg(int) level;
989 syscallarg(int) name;
990 syscallarg(caddr_t) val;
991 syscallarg(socklen_t *) avalsize;
995 struct mbuf *m = NULL;
999 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
1001 if (SCARG(uap, val)) {
1002 error = copyin((caddr_t)SCARG(uap, avalsize),
1003 (caddr_t)&valsize, sizeof (valsize));
1008 if ((error = sogetopt((struct socket *)fp->f_data, SCARG(uap, level),
1009 SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize &&
1011 if (valsize > m->m_len)
1013 error = copyout(mtod(m, caddr_t), SCARG(uap, val), valsize);
1015 error = copyout((caddr_t)&valsize,
1016 (caddr_t)SCARG(uap, avalsize), sizeof (valsize));
1025 sys_pipe(p, v, retval)
1030 register struct sys_pipe_args /* {
1031 syscallarg(int *) fdp;
1036 if ((error = sys_opipe(p, v, rval)) == -1)
1041 error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
1044 fdrelease(p, retval[0]);
1045 fdrelease(p, retval[1]);
1054 sys_opipe(p, v, retval)
1059 register struct filedesc *fdp = p->p_fd;
1060 struct file *rf, *wf;
1061 struct socket *rso, *wso;
1064 if ((error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) != 0)
1066 if ((error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) != 0)
1068 if ((error = falloc(p, &rf, &fd)) != 0)
1072 rf->f_type = DTYPE_SOCKET;
1073 rf->f_ops = &socketops;
1074 rf->f_data = (caddr_t)rso;
1075 if ((error = falloc(p, &wf, &fd)) != 0)
1077 wf->f_flag = FWRITE;
1078 wf->f_type = DTYPE_SOCKET;
1079 wf->f_ops = &socketops;
1080 wf->f_data = (caddr_t)wso;
1082 if ((error = unp_connect2(wso, rso)) != 0)
1087 fdremove(fdp, retval[1]);
1090 fdremove(fdp, retval[0]);
1105 sys_getsockname(struct sys_getsockname_args *uap, register_t *retval)
1110 sys_getsockname(p, v, retval)
1115 register struct sys_getsockname_args /* {
1116 syscallarg(int) fdes;
1117 syscallarg(caddr_t) asa;
1118 syscallarg(socklen_t *) alen;
1122 register struct socket *so;
1127 if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
1129 error = copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len, sizeof (len));
1132 so = (struct socket *)fp->f_data;
1133 m = m_getclr(M_WAIT, MT_SONAME);
1136 error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
1141 error = copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), len);
1143 error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen),
1151 * Get name of peer for connected socket.
1156 sys_getpeername(struct sys_getpeername_args *uap, register_t *retval)
1160 sys_getpeername(p, v, retval)
1165 register struct sys_getpeername_args /* {
1166 syscallarg(int) fdes;
1167 syscallarg(caddr_t) asa;
1168 syscallarg(socklen_t *) alen;
1172 register struct socket *so;
1177 if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
1179 so = (struct socket *)fp->f_data;
1180 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
1182 error = copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len, sizeof (len));
1185 m = m_getclr(M_WAIT, MT_SONAME);
1188 error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0);
1193 error = copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), len);
1195 error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen),
1203 sockargs(mp, buf, buflen, type)
1209 register struct sockaddr *sa;
1210 register struct mbuf *m;
1213 if (buflen > MLEN) {
1214 #ifdef COMPAT_OLDSOCK
1215 if (type == MT_SONAME && buflen <= 112)
1216 buflen = MLEN; /* unix domain compat. hack */
1221 m = m_get(M_WAIT, type);
1225 error = copyin(buf, mtod(m, caddr_t), buflen);
1231 if (type == MT_SONAME) {
1232 sa = mtod(m, struct sockaddr *);
1234 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1235 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1236 sa->sa_family = sa->sa_len;
1238 sa->sa_len = buflen;
1245 ecos_getsock(int fdes, struct file **fpp)
1248 if (getfp(fdes, &fp))
1250 if (fp->f_type != DTYPE_SOCKET)
1257 getsock(fdp, fdes, fpp)
1258 struct filedesc *fdp;
1262 register struct file *fp;
1264 if ((unsigned)fdes >= fdp->fd_nfiles ||
1265 (fp = fdp->fd_ofiles[fdes]) == NULL)
1267 if (fp->f_type != DTYPE_SOCKET)