1 /* $Id: uipc_syscalls.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
2 /* $OpenBSD: uipc_syscalls.c,v 1.28 1999/07/13 15:17:51 provos Exp $ */
3 /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
6 * Copyright (c) 1982, 1986, 1989, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/filedesc.h>
46 #include <sys/malloc.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/signalvar.h>
56 #include <sys/ktrace.h>
60 #include <sys/mount.h>
62 #include <sys/syscallargs.h>
65 * System call interface to the socket abstraction.
67 extern struct fileops socketops
;
70 sys_socket(p
, v
, retval
)
75 register struct sys_socket_args
/* {
76 syscallarg(int) domain;
78 syscallarg(int) protocol;
80 struct filedesc
*fdp
= p
->p_fd
;
85 if ((error
= falloc(p
, &fp
, &fd
)) != 0)
87 fp
->f_flag
= FREAD
|FWRITE
;
88 fp
->f_type
= DTYPE_SOCKET
;
89 fp
->f_ops
= &socketops
;
90 error
= socreate(SCARG(uap
, domain
), &so
, SCARG(uap
, type
),
91 SCARG(uap
, protocol
));
96 fp
->f_data
= (caddr_t
)so
;
104 sys_bind(p
, v
, retval
)
109 register struct sys_bind_args
/* {
111 syscallarg(struct sockaddr *) name;
112 syscallarg(socklen_t) namelen;
118 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
120 error
= sockargs(&nam
, (caddr_t
)SCARG(uap
, name
), SCARG(uap
, namelen
),
124 error
= sobind((struct socket
*)fp
->f_data
, nam
);
131 sys_listen(p
, v
, retval
)
136 register struct sys_listen_args
/* {
138 syscallarg(int) backlog;
143 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
145 return (solisten((struct socket
*)fp
->f_data
, SCARG(uap
, backlog
)));
149 sys_accept(p
, v
, retval
)
154 register struct sys_accept_args
/* {
156 syscallarg(struct sockaddr *) name;
157 syscallarg(socklen_t *) anamelen;
163 register struct socket
*so
;
165 if (SCARG(uap
, name
) && (error
= copyin((caddr_t
)SCARG(uap
, anamelen
),
166 (caddr_t
)&namelen
, sizeof (namelen
))))
168 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
171 so
= (struct socket
*)fp
->f_data
;
172 if ((so
->so_options
& SO_ACCEPTCONN
) == 0) {
176 if ((so
->so_state
& SS_NBIO
) && so
->so_qlen
== 0) {
178 return (EWOULDBLOCK
);
180 while (so
->so_qlen
== 0 && so
->so_error
== 0) {
181 if (so
->so_state
& SS_CANTRCVMORE
) {
182 so
->so_error
= ECONNABORTED
;
185 error
= tsleep((caddr_t
)&so
->so_timeo
, PSOCK
| PCATCH
,
193 error
= so
->so_error
;
198 if ((error
= falloc(p
, &fp
, &tmpfd
)) != 0) {
203 { struct socket
*aso
= so
->so_q
;
204 if (soqremque(aso
, 1) == 0)
208 fp
->f_type
= DTYPE_SOCKET
;
209 fp
->f_flag
= FREAD
|FWRITE
;
210 fp
->f_ops
= &socketops
;
211 fp
->f_data
= (caddr_t
)so
;
212 nam
= m_get(M_WAIT
, MT_SONAME
);
213 (void) soaccept(so
, nam
);
214 if (SCARG(uap
, name
)) {
215 if (namelen
> nam
->m_len
)
216 namelen
= nam
->m_len
;
217 /* SHOULD COPY OUT A CHAIN HERE */
218 if ((error
= copyout(mtod(nam
, caddr_t
),
219 (caddr_t
)SCARG(uap
, name
), namelen
)) == 0)
220 error
= copyout((caddr_t
)&namelen
,
221 (caddr_t
)SCARG(uap
, anamelen
),
222 sizeof (*SCARG(uap
, anamelen
)));
231 sys_connect(p
, v
, retval
)
236 register struct sys_connect_args
/* {
238 syscallarg(struct sockaddr *) name;
239 syscallarg(socklen_t) namelen;
242 register struct socket
*so
;
246 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
248 so
= (struct socket
*)fp
->f_data
;
249 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
))
251 error
= sockargs(&nam
, (caddr_t
)SCARG(uap
, name
), SCARG(uap
, namelen
),
255 error
= soconnect(so
, nam
);
258 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
260 return (EINPROGRESS
);
263 while ((so
->so_state
& SS_ISCONNECTING
) && so
->so_error
== 0) {
264 error
= tsleep((caddr_t
)&so
->so_timeo
, PSOCK
| PCATCH
,
270 error
= so
->so_error
;
275 so
->so_state
&= ~SS_ISCONNECTING
;
277 if (error
== ERESTART
)
282 #ifdef NOTUSED_BY_PMON
284 sys_socketpair(p
, v
, retval
)
289 register struct sys_socketpair_args
/* {
290 syscallarg(int) domain;
291 syscallarg(int) type;
292 syscallarg(int) protocol;
293 syscallarg(int *) rsv;
295 register struct filedesc
*fdp
= p
->p_fd
;
296 struct file
*fp1
, *fp2
;
297 struct socket
*so1
, *so2
;
298 int fd
, error
, sv
[2];
300 error
= socreate(SCARG(uap
, domain
), &so1
, SCARG(uap
, type
),
301 SCARG(uap
, protocol
));
304 error
= socreate(SCARG(uap
, domain
), &so2
, SCARG(uap
, type
),
305 SCARG(uap
, protocol
));
308 if ((error
= falloc(p
, &fp1
, &fd
)) != 0)
311 fp1
->f_flag
= FREAD
|FWRITE
;
312 fp1
->f_type
= DTYPE_SOCKET
;
313 fp1
->f_ops
= &socketops
;
314 fp1
->f_data
= (caddr_t
)so1
;
315 if ((error
= falloc(p
, &fp2
, &fd
)) != 0)
317 fp2
->f_flag
= FREAD
|FWRITE
;
318 fp2
->f_type
= DTYPE_SOCKET
;
319 fp2
->f_ops
= &socketops
;
320 fp2
->f_data
= (caddr_t
)so2
;
322 if ((error
= soconnect2(so1
, so2
)) != 0)
324 if (SCARG(uap
, type
) == SOCK_DGRAM
) {
326 * Datagram socket connection is asymmetric.
328 if ((error
= soconnect2(so2
, so1
)) != 0)
331 error
= copyout((caddr_t
)sv
, (caddr_t
)SCARG(uap
, rsv
),
337 fdremove(fdp
, sv
[1]);
340 fdremove(fdp
, sv
[0]);
347 #endif /* NOTUSED_BU_PMON */
350 sys_sendto(p
, v
, retval
)
355 register struct sys_sendto_args
/* {
357 syscallarg(caddr_t) buf;
358 syscallarg(size_t) len;
359 syscallarg(int) flags;
360 syscallarg(struct sockaddr *) to;
361 syscallarg(socklen_t) tolen;
366 msg
.msg_name
= (caddr_t
)SCARG(uap
, to
);
367 msg
.msg_namelen
= SCARG(uap
, tolen
);
371 #ifdef COMPAT_OLDSOCK
374 aiov
.iov_base
= (char *)SCARG(uap
, buf
);
375 aiov
.iov_len
= SCARG(uap
, len
);
376 return (sendit(p
, SCARG(uap
, s
), &msg
, SCARG(uap
, flags
), retval
));
380 sys_sendmsg(p
, v
, retval
)
385 register struct sys_sendmsg_args
/* {
387 syscallarg(caddr_t) msg;
388 syscallarg(int) flags;
391 struct iovec aiov
[UIO_SMALLIOV
], *iov
;
394 error
= copyin(SCARG(uap
, msg
), (caddr_t
)&msg
, sizeof (msg
));
397 if (msg
.msg_iovlen
<= 0 || msg
.msg_iovlen
> IOV_MAX
)
399 if (msg
.msg_iovlen
> UIO_SMALLIOV
)
400 MALLOC(iov
, struct iovec
*,
401 sizeof(struct iovec
) * msg
.msg_iovlen
, M_IOV
, M_WAITOK
);
404 if (msg
.msg_iovlen
&&
405 (error
= copyin((caddr_t
)msg
.msg_iov
, (caddr_t
)iov
,
406 (unsigned)(msg
.msg_iovlen
* sizeof (struct iovec
)))))
409 #ifdef COMPAT_OLDSOCK
412 error
= sendit(p
, SCARG(uap
, s
), &msg
, SCARG(uap
, flags
), retval
);
420 sendit(p
, s
, mp
, flags
, retsize
)
421 register struct proc
*p
;
423 register struct msghdr
*mp
;
429 register struct iovec
*iov
;
431 struct mbuf
*to
, *control
;
434 struct iovec
*ktriov
= NULL
;
437 if ((error
= getsock(p
->p_fd
, s
, &fp
)) != 0)
439 auio
.uio_iov
= mp
->msg_iov
;
440 auio
.uio_iovcnt
= mp
->msg_iovlen
;
441 auio
.uio_segflg
= UIO_USERSPACE
;
442 auio
.uio_rw
= UIO_WRITE
;
444 auio
.uio_offset
= 0; /* XXX */
447 for (i
= 0; i
< mp
->msg_iovlen
; i
++, iov
++) {
448 /* Don't allow sum > SSIZE_MAX */
449 if (iov
->iov_len
> SSIZE_MAX
||
450 (auio
.uio_resid
+= iov
->iov_len
) > SSIZE_MAX
)
454 error
= sockargs(&to
, mp
->msg_name
, mp
->msg_namelen
,
460 if (mp
->msg_control
) {
461 if (mp
->msg_controllen
< sizeof(struct cmsghdr
)
462 #ifdef COMPAT_OLDSOCK
463 && mp
->msg_flags
!= MSG_COMPAT
469 error
= sockargs(&control
, mp
->msg_control
,
470 mp
->msg_controllen
, MT_CONTROL
);
473 #ifdef COMPAT_OLDSOCK
474 if (mp
->msg_flags
== MSG_COMPAT
) {
475 register struct cmsghdr
*cm
;
477 M_PREPEND(control
, sizeof(*cm
), M_WAIT
);
482 cm
= mtod(control
, struct cmsghdr
*);
483 cm
->cmsg_len
= control
->m_len
;
484 cm
->cmsg_level
= SOL_SOCKET
;
485 cm
->cmsg_type
= SCM_RIGHTS
;
492 if (KTRPOINT(p
, KTR_GENIO
)) {
493 int iovlen
= auio
.uio_iovcnt
* sizeof (struct iovec
);
495 MALLOC(ktriov
, struct iovec
*, iovlen
, M_TEMP
, M_WAITOK
);
496 bcopy((caddr_t
)auio
.uio_iov
, (caddr_t
)ktriov
, iovlen
);
499 len
= auio
.uio_resid
;
500 error
= sosend((struct socket
*)fp
->f_data
, to
, &auio
,
501 NULL
, control
, flags
);
503 if (auio
.uio_resid
!= len
&& (error
== ERESTART
||
504 error
== EINTR
|| error
== EWOULDBLOCK
))
510 *retsize
= len
- auio
.uio_resid
;
512 if (ktriov
!= NULL
) {
514 ktrgenio(p
->p_tracep
, s
, UIO_WRITE
,
515 ktriov
, *retsize
, error
);
516 FREE(ktriov
, M_TEMP
);
526 sys_recvfrom(p
, v
, retval
)
531 register struct sys_recvfrom_args
/* {
533 syscallarg(caddr_t) buf;
534 syscallarg(size_t) len;
535 syscallarg(int) flags;
536 syscallarg(struct sockaddr *) from;
537 syscallarg(socklen_t *) fromlenaddr;
543 if (SCARG(uap
, fromlenaddr
)) {
544 error
= copyin((caddr_t
)SCARG(uap
, fromlenaddr
),
545 (caddr_t
)&msg
.msg_namelen
,
546 sizeof (msg
.msg_namelen
));
551 msg
.msg_name
= (caddr_t
)SCARG(uap
, from
);
554 aiov
.iov_base
= SCARG(uap
, buf
);
555 aiov
.iov_len
= SCARG(uap
, len
);
557 msg
.msg_flags
= SCARG(uap
, flags
);
558 return (recvit(p
, SCARG(uap
, s
), &msg
,
559 (caddr_t
)SCARG(uap
, fromlenaddr
), retval
));
563 sys_recvmsg(p
, v
, retval
)
568 register struct sys_recvmsg_args
/* {
570 syscallarg(struct msghdr *) msg;
571 syscallarg(int) flags;
574 struct iovec aiov
[UIO_SMALLIOV
], *uiov
, *iov
;
577 error
= copyin((caddr_t
)SCARG(uap
, msg
), (caddr_t
)&msg
,
581 if (msg
.msg_iovlen
<= 0 || msg
.msg_iovlen
> IOV_MAX
)
583 if (msg
.msg_iovlen
> UIO_SMALLIOV
)
584 MALLOC(iov
, struct iovec
*,
585 sizeof(struct iovec
) * msg
.msg_iovlen
, M_IOV
, M_WAITOK
);
588 #ifdef COMPAT_OLDSOCK
589 msg
.msg_flags
= SCARG(uap
, flags
) &~ MSG_COMPAT
;
591 msg
.msg_flags
= SCARG(uap
, flags
);
595 error
= copyin((caddr_t
)uiov
, (caddr_t
)iov
,
596 (unsigned)(msg
.msg_iovlen
* sizeof (struct iovec
)));
599 if ((error
= recvit(p
, SCARG(uap
, s
), &msg
, (caddr_t
)0, retval
)) == 0) {
601 error
= copyout((caddr_t
)&msg
, (caddr_t
)SCARG(uap
, msg
),
611 recvit(p
, s
, mp
, namelenp
, retsize
)
612 register struct proc
*p
;
614 register struct msghdr
*mp
;
620 register struct iovec
*iov
;
624 struct mbuf
*from
= 0, *control
= 0;
626 struct iovec
*ktriov
= NULL
;
629 if ((error
= getsock(p
->p_fd
, s
, &fp
)) != 0)
631 auio
.uio_iov
= mp
->msg_iov
;
632 auio
.uio_iovcnt
= mp
->msg_iovlen
;
633 auio
.uio_segflg
= UIO_USERSPACE
;
634 auio
.uio_rw
= UIO_READ
;
636 auio
.uio_offset
= 0; /* XXX */
639 for (i
= 0; i
< mp
->msg_iovlen
; i
++, iov
++) {
640 /* Don't allow sum > SSIZE_MAX */
641 if (iov
->iov_len
> SSIZE_MAX
||
642 (auio
.uio_resid
+= iov
->iov_len
) > SSIZE_MAX
)
646 if (KTRPOINT(p
, KTR_GENIO
)) {
647 int iovlen
= auio
.uio_iovcnt
* sizeof (struct iovec
);
649 MALLOC(ktriov
, struct iovec
*, iovlen
, M_TEMP
, M_WAITOK
);
650 bcopy((caddr_t
)auio
.uio_iov
, (caddr_t
)ktriov
, iovlen
);
653 len
= auio
.uio_resid
;
654 error
= soreceive((struct socket
*)fp
->f_data
, &from
, &auio
,
655 NULL
, mp
->msg_control
? &control
: NULL
,
658 if (auio
.uio_resid
!= len
&& (error
== ERESTART
||
659 error
== EINTR
|| error
== EWOULDBLOCK
))
663 if (ktriov
!= NULL
) {
665 ktrgenio(p
->p_tracep
, s
, UIO_READ
,
666 ktriov
, len
- auio
.uio_resid
, error
);
667 FREE(ktriov
, M_TEMP
);
672 *retsize
= len
- auio
.uio_resid
;
674 len
= mp
->msg_namelen
;
675 if (len
<= 0 || from
== 0)
678 /* save sa_len before it is destroyed by MSG_COMPAT */
679 if (len
> from
->m_len
)
681 /* else if len < from->m_len ??? */
682 #ifdef COMPAT_OLDSOCK
683 if (mp
->msg_flags
& MSG_COMPAT
)
684 mtod(from
, struct osockaddr
*)->sa_family
=
685 mtod(from
, struct sockaddr
*)->sa_family
;
687 error
= copyout(mtod(from
, caddr_t
),
688 (caddr_t
)mp
->msg_name
, (unsigned)len
);
692 mp
->msg_namelen
= len
;
694 (error
= copyout((caddr_t
)&len
, namelenp
, sizeof (int)))) {
695 #ifdef COMPAT_OLDSOCK
696 if (mp
->msg_flags
& MSG_COMPAT
)
697 error
= 0; /* old recvfrom didn't check */
703 if (mp
->msg_control
) {
704 #ifdef COMPAT_OLDSOCK
706 * We assume that old recvmsg calls won't receive access
707 * rights and other control info, esp. as control info
708 * is always optional and those options didn't exist in 4.3.
709 * If we receive rights, trim the cmsghdr; anything else
712 if (control
&& mp
->msg_flags
& MSG_COMPAT
) {
713 if (mtod(control
, struct cmsghdr
*)->cmsg_level
!=
715 mtod(control
, struct cmsghdr
*)->cmsg_type
!=
717 mp
->msg_controllen
= 0;
720 control
->m_len
-= sizeof (struct cmsghdr
);
721 control
->m_data
+= sizeof (struct cmsghdr
);
724 len
= mp
->msg_controllen
;
725 if (len
<= 0 || control
== 0)
728 if (len
>= control
->m_len
)
729 len
= control
->m_len
;
731 mp
->msg_flags
|= MSG_CTRUNC
;
732 error
= copyout((caddr_t
)mtod(control
, caddr_t
),
733 (caddr_t
)mp
->msg_control
, (unsigned)len
);
735 mp
->msg_controllen
= len
;
747 sys_shutdown(p
, v
, retval
)
752 register struct sys_shutdown_args
/* {
759 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
761 return (soshutdown((struct socket
*)fp
->f_data
, SCARG(uap
, how
)));
766 sys_setsockopt(p
, v
, retval
)
771 register struct sys_setsockopt_args
/* {
773 syscallarg(int) level;
774 syscallarg(int) name;
775 syscallarg(caddr_t) val;
776 syscallarg(socklen_t) valsize;
779 struct mbuf
*m
= NULL
;
782 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
784 if (SCARG(uap
, valsize
) > MLEN
)
786 if (SCARG(uap
, val
)) {
787 m
= m_get(M_WAIT
, MT_SOOPTS
);
790 error
= copyin(SCARG(uap
, val
), mtod(m
, caddr_t
),
791 SCARG(uap
, valsize
));
796 m
->m_len
= SCARG(uap
, valsize
);
798 return (sosetopt((struct socket
*)fp
->f_data
, SCARG(uap
, level
),
799 SCARG(uap
, name
), m
));
804 sys_getsockopt(p
, v
, retval
)
809 register struct sys_getsockopt_args
/* {
811 syscallarg(int) level;
812 syscallarg(int) name;
813 syscallarg(caddr_t) val;
814 syscallarg(socklen_t *) avalsize;
817 struct mbuf
*m
= NULL
;
821 if ((error
= getsock(p
->p_fd
, SCARG(uap
, s
), &fp
)) != 0)
823 if (SCARG(uap
, val
)) {
824 error
= copyin((caddr_t
)SCARG(uap
, avalsize
),
825 (caddr_t
)&valsize
, sizeof (valsize
));
830 if ((error
= sogetopt((struct socket
*)fp
->f_data
, SCARG(uap
, level
),
831 SCARG(uap
, name
), &m
)) == 0 && SCARG(uap
, val
) && valsize
&&
833 if (valsize
> m
->m_len
)
835 error
= copyout(mtod(m
, caddr_t
), SCARG(uap
, val
), valsize
);
837 error
= copyout((caddr_t
)&valsize
,
838 (caddr_t
)SCARG(uap
, avalsize
), sizeof (valsize
));
845 #ifdef NOTUSED_BY_PMON
847 sys_pipe(p
, v
, retval
)
852 register struct sys_pipe_args
/* {
853 syscallarg(int *) fdp;
858 if ((error
= sys_opipe(p
, v
, rval
)) == -1)
863 error
= copyout((caddr_t
)fds
, (caddr_t
)SCARG(uap
, fdp
),
866 fdrelease(p
, retval
[0]);
867 fdrelease(p
, retval
[1]);
876 sys_opipe(p
, v
, retval
)
881 register struct filedesc
*fdp
= p
->p_fd
;
882 struct file
*rf
, *wf
;
883 struct socket
*rso
, *wso
;
886 if ((error
= socreate(AF_UNIX
, &rso
, SOCK_STREAM
, 0)) != 0)
888 if ((error
= socreate(AF_UNIX
, &wso
, SOCK_STREAM
, 0)) != 0)
890 if ((error
= falloc(p
, &rf
, &fd
)) != 0)
894 rf
->f_type
= DTYPE_SOCKET
;
895 rf
->f_ops
= &socketops
;
896 rf
->f_data
= (caddr_t
)rso
;
897 if ((error
= falloc(p
, &wf
, &fd
)) != 0)
900 wf
->f_type
= DTYPE_SOCKET
;
901 wf
->f_ops
= &socketops
;
902 wf
->f_data
= (caddr_t
)wso
;
904 if ((error
= unp_connect2(wso
, rso
)) != 0)
909 fdremove(fdp
, retval
[1]);
912 fdremove(fdp
, retval
[0]);
920 #endif /* NOTUSED_BY_PMON */
927 sys_getsockname(p
, v
, retval
)
932 register struct sys_getsockname_args
/* {
933 syscallarg(int) fdes;
934 syscallarg(caddr_t) asa;
935 syscallarg(socklen_t *) alen;
938 register struct socket
*so
;
943 if ((error
= getsock(p
->p_fd
, SCARG(uap
, fdes
), &fp
)) != 0)
945 error
= copyin((caddr_t
)SCARG(uap
, alen
), (caddr_t
)&len
, sizeof (len
));
948 so
= (struct socket
*)fp
->f_data
;
949 m
= m_getclr(M_WAIT
, MT_SONAME
);
952 error
= (*so
->so_proto
->pr_usrreq
)(so
, PRU_SOCKADDR
, 0, m
, 0);
957 error
= copyout(mtod(m
, caddr_t
), (caddr_t
)SCARG(uap
, asa
), len
);
959 error
= copyout((caddr_t
)&len
, (caddr_t
)SCARG(uap
, alen
),
967 * Get name of peer for connected socket.
971 sys_getpeername(p
, v
, retval
)
976 register struct sys_getpeername_args
/* {
977 syscallarg(int) fdes;
978 syscallarg(caddr_t) asa;
979 syscallarg(socklen_t *) alen;
982 register struct socket
*so
;
987 if ((error
= getsock(p
->p_fd
, SCARG(uap
, fdes
), &fp
)) != 0)
989 so
= (struct socket
*)fp
->f_data
;
990 if ((so
->so_state
& (SS_ISCONNECTED
|SS_ISCONFIRMING
)) == 0)
992 error
= copyin((caddr_t
)SCARG(uap
, alen
), (caddr_t
)&len
, sizeof (len
));
995 m
= m_getclr(M_WAIT
, MT_SONAME
);
998 error
= (*so
->so_proto
->pr_usrreq
)(so
, PRU_PEERADDR
, 0, m
, 0);
1003 error
= copyout(mtod(m
, caddr_t
), (caddr_t
)SCARG(uap
, asa
), len
);
1005 error
= copyout((caddr_t
)&len
, (caddr_t
)SCARG(uap
, alen
),
1013 sockargs(mp
, buf
, buflen
, type
)
1019 register struct sockaddr
*sa
;
1020 register struct mbuf
*m
;
1023 if (buflen
> MLEN
) {
1024 #ifdef COMPAT_OLDSOCK
1025 if (type
== MT_SONAME
&& buflen
<= 112)
1026 buflen
= MLEN
; /* unix domain compat. hack */
1031 m
= m_get(M_WAIT
, type
);
1035 error
= copyin(buf
, mtod(m
, caddr_t
), buflen
);
1041 if (type
== MT_SONAME
) {
1042 sa
= mtod(m
, struct sockaddr
*);
1044 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1045 if (sa
->sa_family
== 0 && sa
->sa_len
< AF_MAX
)
1046 sa
->sa_family
= sa
->sa_len
;
1048 sa
->sa_len
= buflen
;
1054 getsock(fdp
, fdes
, fpp
)
1055 struct filedesc
*fdp
;
1059 register struct file
*fp
;
1061 if ((unsigned)fdes
>= fdp
->fd_nfiles
||
1062 (fp
= fdp
->fd_ofiles
[fdes
]) == NULL
)
1064 if (fp
->f_type
!= DTYPE_SOCKET
)