]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/uipc_syscalls.c
MFV r304732.
[FreeBSD/FreeBSD.git] / sys / kern / uipc_syscalls.c
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *      @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include "opt_capsicum.h"
36 #include "opt_inet.h"
37 #include "opt_inet6.h"
38 #include "opt_compat.h"
39 #include "opt_ktrace.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/capsicum.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/sysproto.h>
48 #include <sys/malloc.h>
49 #include <sys/filedesc.h>
50 #include <sys/proc.h>
51 #include <sys/filio.h>
52 #include <sys/jail.h>
53 #include <sys/mbuf.h>
54 #include <sys/protosw.h>
55 #include <sys/rwlock.h>
56 #include <sys/socket.h>
57 #include <sys/socketvar.h>
58 #include <sys/syscallsubr.h>
59 #ifdef KTRACE
60 #include <sys/ktrace.h>
61 #endif
62 #ifdef COMPAT_FREEBSD32
63 #include <compat/freebsd32/freebsd32_util.h>
64 #endif
65
66 #include <net/vnet.h>
67
68 #include <security/audit/audit.h>
69 #include <security/mac/mac_framework.h>
70
71 /*
72  * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
73  * and SOCK_NONBLOCK.
74  */
75 #define ACCEPT4_INHERIT 0x1
76 #define ACCEPT4_COMPAT  0x2
77
78 static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
79 static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
80
81 static int accept1(struct thread *td, int s, struct sockaddr *uname,
82                    socklen_t *anamelen, int flags);
83 static int getsockname1(struct thread *td, struct getsockname_args *uap,
84                         int compat);
85 static int getpeername1(struct thread *td, struct getpeername_args *uap,
86                         int compat);
87 static int sockargs(struct mbuf **, char *, socklen_t, int);
88
89 /*
90  * Convert a user file descriptor to a kernel file entry and check if required
91  * capability rights are present.
92  * A reference on the file entry is held upon returning.
93  */
94 int
95 getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
96     struct file **fpp, u_int *fflagp)
97 {
98         struct file *fp;
99         int error;
100
101         error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
102         if (error != 0)
103                 return (error);
104         if (fp->f_type != DTYPE_SOCKET) {
105                 fdrop(fp, td);
106                 return (ENOTSOCK);
107         }
108         if (fflagp != NULL)
109                 *fflagp = fp->f_flag;
110         *fpp = fp;
111         return (0);
112 }
113
114 /*
115  * System call interface to the socket abstraction.
116  */
117 #if defined(COMPAT_43)
118 #define COMPAT_OLDSOCK
119 #endif
120
121 int
122 sys_socket(td, uap)
123         struct thread *td;
124         struct socket_args /* {
125                 int     domain;
126                 int     type;
127                 int     protocol;
128         } */ *uap;
129 {
130         struct socket *so;
131         struct file *fp;
132         int fd, error, type, oflag, fflag;
133
134         AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol);
135
136         type = uap->type;
137         oflag = 0;
138         fflag = 0;
139         if ((type & SOCK_CLOEXEC) != 0) {
140                 type &= ~SOCK_CLOEXEC;
141                 oflag |= O_CLOEXEC;
142         }
143         if ((type & SOCK_NONBLOCK) != 0) {
144                 type &= ~SOCK_NONBLOCK;
145                 fflag |= FNONBLOCK;
146         }
147
148 #ifdef MAC
149         error = mac_socket_check_create(td->td_ucred, uap->domain, type,
150             uap->protocol);
151         if (error != 0)
152                 return (error);
153 #endif
154         error = falloc(td, &fp, &fd, oflag);
155         if (error != 0)
156                 return (error);
157         /* An extra reference on `fp' has been held for us by falloc(). */
158         error = socreate(uap->domain, &so, type, uap->protocol,
159             td->td_ucred, td);
160         if (error != 0) {
161                 fdclose(td, fp, fd);
162         } else {
163                 finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
164                 if ((fflag & FNONBLOCK) != 0)
165                         (void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
166                 td->td_retval[0] = fd;
167         }
168         fdrop(fp, td);
169         return (error);
170 }
171
172 /* ARGSUSED */
173 int
174 sys_bind(td, uap)
175         struct thread *td;
176         struct bind_args /* {
177                 int     s;
178                 caddr_t name;
179                 int     namelen;
180         } */ *uap;
181 {
182         struct sockaddr *sa;
183         int error;
184
185         error = getsockaddr(&sa, uap->name, uap->namelen);
186         if (error == 0) {
187                 error = kern_bindat(td, AT_FDCWD, uap->s, sa);
188                 free(sa, M_SONAME);
189         }
190         return (error);
191 }
192
193 int
194 kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
195 {
196         struct socket *so;
197         struct file *fp;
198         cap_rights_t rights;
199         int error;
200
201         AUDIT_ARG_FD(fd);
202         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
203         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
204             &fp, NULL);
205         if (error != 0)
206                 return (error);
207         so = fp->f_data;
208 #ifdef KTRACE
209         if (KTRPOINT(td, KTR_STRUCT))
210                 ktrsockaddr(sa);
211 #endif
212 #ifdef MAC
213         error = mac_socket_check_bind(td->td_ucred, so, sa);
214         if (error == 0) {
215 #endif
216                 if (dirfd == AT_FDCWD)
217                         error = sobind(so, sa, td);
218                 else
219                         error = sobindat(dirfd, so, sa, td);
220 #ifdef MAC
221         }
222 #endif
223         fdrop(fp, td);
224         return (error);
225 }
226
227 /* ARGSUSED */
228 int
229 sys_bindat(td, uap)
230         struct thread *td;
231         struct bindat_args /* {
232                 int     fd;
233                 int     s;
234                 caddr_t name;
235                 int     namelen;
236         } */ *uap;
237 {
238         struct sockaddr *sa;
239         int error;
240
241         error = getsockaddr(&sa, uap->name, uap->namelen);
242         if (error == 0) {
243                 error = kern_bindat(td, uap->fd, uap->s, sa);
244                 free(sa, M_SONAME);
245         }
246         return (error);
247 }
248
249 /* ARGSUSED */
250 int
251 sys_listen(td, uap)
252         struct thread *td;
253         struct listen_args /* {
254                 int     s;
255                 int     backlog;
256         } */ *uap;
257 {
258         struct socket *so;
259         struct file *fp;
260         cap_rights_t rights;
261         int error;
262
263         AUDIT_ARG_FD(uap->s);
264         error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
265             &fp, NULL);
266         if (error == 0) {
267                 so = fp->f_data;
268 #ifdef MAC
269                 error = mac_socket_check_listen(td->td_ucred, so);
270                 if (error == 0)
271 #endif
272                         error = solisten(so, uap->backlog, td);
273                 fdrop(fp, td);
274         }
275         return(error);
276 }
277
278 /*
279  * accept1()
280  */
281 static int
282 accept1(td, s, uname, anamelen, flags)
283         struct thread *td;
284         int s;
285         struct sockaddr *uname;
286         socklen_t *anamelen;
287         int flags;
288 {
289         struct sockaddr *name;
290         socklen_t namelen;
291         struct file *fp;
292         int error;
293
294         if (uname == NULL)
295                 return (kern_accept4(td, s, NULL, NULL, flags, NULL));
296
297         error = copyin(anamelen, &namelen, sizeof (namelen));
298         if (error != 0)
299                 return (error);
300
301         error = kern_accept4(td, s, &name, &namelen, flags, &fp);
302
303         if (error != 0)
304                 return (error);
305
306         if (error == 0 && uname != NULL) {
307 #ifdef COMPAT_OLDSOCK
308                 if (flags & ACCEPT4_COMPAT)
309                         ((struct osockaddr *)name)->sa_family =
310                             name->sa_family;
311 #endif
312                 error = copyout(name, uname, namelen);
313         }
314         if (error == 0)
315                 error = copyout(&namelen, anamelen,
316                     sizeof(namelen));
317         if (error != 0)
318                 fdclose(td, fp, td->td_retval[0]);
319         fdrop(fp, td);
320         free(name, M_SONAME);
321         return (error);
322 }
323
324 int
325 kern_accept(struct thread *td, int s, struct sockaddr **name,
326     socklen_t *namelen, struct file **fp)
327 {
328         return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
329 }
330
331 int
332 kern_accept4(struct thread *td, int s, struct sockaddr **name,
333     socklen_t *namelen, int flags, struct file **fp)
334 {
335         struct file *headfp, *nfp = NULL;
336         struct sockaddr *sa = NULL;
337         struct socket *head, *so;
338         cap_rights_t rights;
339         u_int fflag;
340         pid_t pgid;
341         int error, fd, tmp;
342
343         if (name != NULL)
344                 *name = NULL;
345
346         AUDIT_ARG_FD(s);
347         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
348             &headfp, &fflag);
349         if (error != 0)
350                 return (error);
351         head = headfp->f_data;
352         if ((head->so_options & SO_ACCEPTCONN) == 0) {
353                 error = EINVAL;
354                 goto done;
355         }
356 #ifdef MAC
357         error = mac_socket_check_accept(td->td_ucred, head);
358         if (error != 0)
359                 goto done;
360 #endif
361         error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0);
362         if (error != 0)
363                 goto done;
364         ACCEPT_LOCK();
365         if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
366                 ACCEPT_UNLOCK();
367                 error = EWOULDBLOCK;
368                 goto noconnection;
369         }
370         while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
371                 if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
372                         head->so_error = ECONNABORTED;
373                         break;
374                 }
375                 error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH,
376                     "accept", 0);
377                 if (error != 0) {
378                         ACCEPT_UNLOCK();
379                         goto noconnection;
380                 }
381         }
382         if (head->so_error) {
383                 error = head->so_error;
384                 head->so_error = 0;
385                 ACCEPT_UNLOCK();
386                 goto noconnection;
387         }
388         so = TAILQ_FIRST(&head->so_comp);
389         KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
390         KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
391
392         /*
393          * Before changing the flags on the socket, we have to bump the
394          * reference count.  Otherwise, if the protocol calls sofree(),
395          * the socket will be released due to a zero refcount.
396          */
397         SOCK_LOCK(so);                  /* soref() and so_state update */
398         soref(so);                      /* file descriptor reference */
399
400         TAILQ_REMOVE(&head->so_comp, so, so_list);
401         head->so_qlen--;
402         if (flags & ACCEPT4_INHERIT)
403                 so->so_state |= (head->so_state & SS_NBIO);
404         else
405                 so->so_state |= (flags & SOCK_NONBLOCK) ? SS_NBIO : 0;
406         so->so_qstate &= ~SQ_COMP;
407         so->so_head = NULL;
408
409         SOCK_UNLOCK(so);
410         ACCEPT_UNLOCK();
411
412         /* An extra reference on `nfp' has been held for us by falloc(). */
413         td->td_retval[0] = fd;
414
415         /* connection has been removed from the listen queue */
416         KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
417
418         if (flags & ACCEPT4_INHERIT) {
419                 pgid = fgetown(&head->so_sigio);
420                 if (pgid != 0)
421                         fsetown(pgid, &so->so_sigio);
422         } else {
423                 fflag &= ~(FNONBLOCK | FASYNC);
424                 if (flags & SOCK_NONBLOCK)
425                         fflag |= FNONBLOCK;
426         }
427
428         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
429         /* Sync socket nonblocking/async state with file flags */
430         tmp = fflag & FNONBLOCK;
431         (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
432         tmp = fflag & FASYNC;
433         (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
434         sa = NULL;
435         error = soaccept(so, &sa);
436         if (error != 0)
437                 goto noconnection;
438         if (sa == NULL) {
439                 if (name)
440                         *namelen = 0;
441                 goto done;
442         }
443         AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
444         if (name) {
445                 /* check sa_len before it is destroyed */
446                 if (*namelen > sa->sa_len)
447                         *namelen = sa->sa_len;
448 #ifdef KTRACE
449                 if (KTRPOINT(td, KTR_STRUCT))
450                         ktrsockaddr(sa);
451 #endif
452                 *name = sa;
453                 sa = NULL;
454         }
455 noconnection:
456         free(sa, M_SONAME);
457
458         /*
459          * close the new descriptor, assuming someone hasn't ripped it
460          * out from under us.
461          */
462         if (error != 0)
463                 fdclose(td, nfp, fd);
464
465         /*
466          * Release explicitly held references before returning.  We return
467          * a reference on nfp to the caller on success if they request it.
468          */
469 done:
470         if (fp != NULL) {
471                 if (error == 0) {
472                         *fp = nfp;
473                         nfp = NULL;
474                 } else
475                         *fp = NULL;
476         }
477         if (nfp != NULL)
478                 fdrop(nfp, td);
479         fdrop(headfp, td);
480         return (error);
481 }
482
483 int
484 sys_accept(td, uap)
485         struct thread *td;
486         struct accept_args *uap;
487 {
488
489         return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT));
490 }
491
492 int
493 sys_accept4(td, uap)
494         struct thread *td;
495         struct accept4_args *uap;
496 {
497
498         if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
499                 return (EINVAL);
500
501         return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags));
502 }
503
504 #ifdef COMPAT_OLDSOCK
505 int
506 oaccept(td, uap)
507         struct thread *td;
508         struct accept_args *uap;
509 {
510
511         return (accept1(td, uap->s, uap->name, uap->anamelen,
512             ACCEPT4_INHERIT | ACCEPT4_COMPAT));
513 }
514 #endif /* COMPAT_OLDSOCK */
515
516 /* ARGSUSED */
517 int
518 sys_connect(td, uap)
519         struct thread *td;
520         struct connect_args /* {
521                 int     s;
522                 caddr_t name;
523                 int     namelen;
524         } */ *uap;
525 {
526         struct sockaddr *sa;
527         int error;
528
529         error = getsockaddr(&sa, uap->name, uap->namelen);
530         if (error == 0) {
531                 error = kern_connectat(td, AT_FDCWD, uap->s, sa);
532                 free(sa, M_SONAME);
533         }
534         return (error);
535 }
536
537 int
538 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
539 {
540         struct socket *so;
541         struct file *fp;
542         cap_rights_t rights;
543         int error, interrupted = 0;
544
545         AUDIT_ARG_FD(fd);
546         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
547         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
548             &fp, NULL);
549         if (error != 0)
550                 return (error);
551         so = fp->f_data;
552         if (so->so_state & SS_ISCONNECTING) {
553                 error = EALREADY;
554                 goto done1;
555         }
556 #ifdef KTRACE
557         if (KTRPOINT(td, KTR_STRUCT))
558                 ktrsockaddr(sa);
559 #endif
560 #ifdef MAC
561         error = mac_socket_check_connect(td->td_ucred, so, sa);
562         if (error != 0)
563                 goto bad;
564 #endif
565         if (dirfd == AT_FDCWD)
566                 error = soconnect(so, sa, td);
567         else
568                 error = soconnectat(dirfd, so, sa, td);
569         if (error != 0)
570                 goto bad;
571         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
572                 error = EINPROGRESS;
573                 goto done1;
574         }
575         SOCK_LOCK(so);
576         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
577                 error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
578                     "connec", 0);
579                 if (error != 0) {
580                         if (error == EINTR || error == ERESTART)
581                                 interrupted = 1;
582                         break;
583                 }
584         }
585         if (error == 0) {
586                 error = so->so_error;
587                 so->so_error = 0;
588         }
589         SOCK_UNLOCK(so);
590 bad:
591         if (!interrupted)
592                 so->so_state &= ~SS_ISCONNECTING;
593         if (error == ERESTART)
594                 error = EINTR;
595 done1:
596         fdrop(fp, td);
597         return (error);
598 }
599
600 /* ARGSUSED */
601 int
602 sys_connectat(td, uap)
603         struct thread *td;
604         struct connectat_args /* {
605                 int     fd;
606                 int     s;
607                 caddr_t name;
608                 int     namelen;
609         } */ *uap;
610 {
611         struct sockaddr *sa;
612         int error;
613
614         error = getsockaddr(&sa, uap->name, uap->namelen);
615         if (error == 0) {
616                 error = kern_connectat(td, uap->fd, uap->s, sa);
617                 free(sa, M_SONAME);
618         }
619         return (error);
620 }
621
622 int
623 kern_socketpair(struct thread *td, int domain, int type, int protocol,
624     int *rsv)
625 {
626         struct file *fp1, *fp2;
627         struct socket *so1, *so2;
628         int fd, error, oflag, fflag;
629
630         AUDIT_ARG_SOCKET(domain, type, protocol);
631
632         oflag = 0;
633         fflag = 0;
634         if ((type & SOCK_CLOEXEC) != 0) {
635                 type &= ~SOCK_CLOEXEC;
636                 oflag |= O_CLOEXEC;
637         }
638         if ((type & SOCK_NONBLOCK) != 0) {
639                 type &= ~SOCK_NONBLOCK;
640                 fflag |= FNONBLOCK;
641         }
642 #ifdef MAC
643         /* We might want to have a separate check for socket pairs. */
644         error = mac_socket_check_create(td->td_ucred, domain, type,
645             protocol);
646         if (error != 0)
647                 return (error);
648 #endif
649         error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
650         if (error != 0)
651                 return (error);
652         error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
653         if (error != 0)
654                 goto free1;
655         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
656         error = falloc(td, &fp1, &fd, oflag);
657         if (error != 0)
658                 goto free2;
659         rsv[0] = fd;
660         fp1->f_data = so1;      /* so1 already has ref count */
661         error = falloc(td, &fp2, &fd, oflag);
662         if (error != 0)
663                 goto free3;
664         fp2->f_data = so2;      /* so2 already has ref count */
665         rsv[1] = fd;
666         error = soconnect2(so1, so2);
667         if (error != 0)
668                 goto free4;
669         if (type == SOCK_DGRAM) {
670                 /*
671                  * Datagram socket connection is asymmetric.
672                  */
673                  error = soconnect2(so2, so1);
674                  if (error != 0)
675                         goto free4;
676         }
677         finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
678             &socketops);
679         finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
680             &socketops);
681         if ((fflag & FNONBLOCK) != 0) {
682                 (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
683                 (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
684         }
685         fdrop(fp1, td);
686         fdrop(fp2, td);
687         return (0);
688 free4:
689         fdclose(td, fp2, rsv[1]);
690         fdrop(fp2, td);
691 free3:
692         fdclose(td, fp1, rsv[0]);
693         fdrop(fp1, td);
694 free2:
695         if (so2 != NULL)
696                 (void)soclose(so2);
697 free1:
698         if (so1 != NULL)
699                 (void)soclose(so1);
700         return (error);
701 }
702
703 int
704 sys_socketpair(struct thread *td, struct socketpair_args *uap)
705 {
706         int error, sv[2];
707
708         error = kern_socketpair(td, uap->domain, uap->type,
709             uap->protocol, sv);
710         if (error != 0)
711                 return (error);
712         error = copyout(sv, uap->rsv, 2 * sizeof(int));
713         if (error != 0) {
714                 (void)kern_close(td, sv[0]);
715                 (void)kern_close(td, sv[1]);
716         }
717         return (error);
718 }
719
720 static int
721 sendit(td, s, mp, flags)
722         struct thread *td;
723         int s;
724         struct msghdr *mp;
725         int flags;
726 {
727         struct mbuf *control;
728         struct sockaddr *to;
729         int error;
730
731 #ifdef CAPABILITY_MODE
732         if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
733                 return (ECAPMODE);
734 #endif
735
736         if (mp->msg_name != NULL) {
737                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
738                 if (error != 0) {
739                         to = NULL;
740                         goto bad;
741                 }
742                 mp->msg_name = to;
743         } else {
744                 to = NULL;
745         }
746
747         if (mp->msg_control) {
748                 if (mp->msg_controllen < sizeof(struct cmsghdr)
749 #ifdef COMPAT_OLDSOCK
750                     && mp->msg_flags != MSG_COMPAT
751 #endif
752                 ) {
753                         error = EINVAL;
754                         goto bad;
755                 }
756                 error = sockargs(&control, mp->msg_control,
757                     mp->msg_controllen, MT_CONTROL);
758                 if (error != 0)
759                         goto bad;
760 #ifdef COMPAT_OLDSOCK
761                 if (mp->msg_flags == MSG_COMPAT) {
762                         struct cmsghdr *cm;
763
764                         M_PREPEND(control, sizeof(*cm), M_WAITOK);
765                         cm = mtod(control, struct cmsghdr *);
766                         cm->cmsg_len = control->m_len;
767                         cm->cmsg_level = SOL_SOCKET;
768                         cm->cmsg_type = SCM_RIGHTS;
769                 }
770 #endif
771         } else {
772                 control = NULL;
773         }
774
775         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
776
777 bad:
778         free(to, M_SONAME);
779         return (error);
780 }
781
782 int
783 kern_sendit(td, s, mp, flags, control, segflg)
784         struct thread *td;
785         int s;
786         struct msghdr *mp;
787         int flags;
788         struct mbuf *control;
789         enum uio_seg segflg;
790 {
791         struct file *fp;
792         struct uio auio;
793         struct iovec *iov;
794         struct socket *so;
795         cap_rights_t rights;
796 #ifdef KTRACE
797         struct uio *ktruio = NULL;
798 #endif
799         ssize_t len;
800         int i, error;
801
802         AUDIT_ARG_FD(s);
803         cap_rights_init(&rights, CAP_SEND);
804         if (mp->msg_name != NULL) {
805                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
806                 cap_rights_set(&rights, CAP_CONNECT);
807         }
808         error = getsock_cap(td, s, &rights, &fp, NULL);
809         if (error != 0)
810                 return (error);
811         so = (struct socket *)fp->f_data;
812
813 #ifdef KTRACE
814         if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
815                 ktrsockaddr(mp->msg_name);
816 #endif
817 #ifdef MAC
818         if (mp->msg_name != NULL) {
819                 error = mac_socket_check_connect(td->td_ucred, so,
820                     mp->msg_name);
821                 if (error != 0)
822                         goto bad;
823         }
824         error = mac_socket_check_send(td->td_ucred, so);
825         if (error != 0)
826                 goto bad;
827 #endif
828
829         auio.uio_iov = mp->msg_iov;
830         auio.uio_iovcnt = mp->msg_iovlen;
831         auio.uio_segflg = segflg;
832         auio.uio_rw = UIO_WRITE;
833         auio.uio_td = td;
834         auio.uio_offset = 0;                    /* XXX */
835         auio.uio_resid = 0;
836         iov = mp->msg_iov;
837         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
838                 if ((auio.uio_resid += iov->iov_len) < 0) {
839                         error = EINVAL;
840                         goto bad;
841                 }
842         }
843 #ifdef KTRACE
844         if (KTRPOINT(td, KTR_GENIO))
845                 ktruio = cloneuio(&auio);
846 #endif
847         len = auio.uio_resid;
848         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
849         if (error != 0) {
850                 if (auio.uio_resid != len && (error == ERESTART ||
851                     error == EINTR || error == EWOULDBLOCK))
852                         error = 0;
853                 /* Generation of SIGPIPE can be controlled per socket */
854                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
855                     !(flags & MSG_NOSIGNAL)) {
856                         PROC_LOCK(td->td_proc);
857                         tdsignal(td, SIGPIPE);
858                         PROC_UNLOCK(td->td_proc);
859                 }
860         }
861         if (error == 0)
862                 td->td_retval[0] = len - auio.uio_resid;
863 #ifdef KTRACE
864         if (ktruio != NULL) {
865                 ktruio->uio_resid = td->td_retval[0];
866                 ktrgenio(s, UIO_WRITE, ktruio, error);
867         }
868 #endif
869 bad:
870         fdrop(fp, td);
871         return (error);
872 }
873
874 int
875 sys_sendto(td, uap)
876         struct thread *td;
877         struct sendto_args /* {
878                 int     s;
879                 caddr_t buf;
880                 size_t  len;
881                 int     flags;
882                 caddr_t to;
883                 int     tolen;
884         } */ *uap;
885 {
886         struct msghdr msg;
887         struct iovec aiov;
888
889         msg.msg_name = uap->to;
890         msg.msg_namelen = uap->tolen;
891         msg.msg_iov = &aiov;
892         msg.msg_iovlen = 1;
893         msg.msg_control = 0;
894 #ifdef COMPAT_OLDSOCK
895         msg.msg_flags = 0;
896 #endif
897         aiov.iov_base = uap->buf;
898         aiov.iov_len = uap->len;
899         return (sendit(td, uap->s, &msg, uap->flags));
900 }
901
902 #ifdef COMPAT_OLDSOCK
903 int
904 osend(td, uap)
905         struct thread *td;
906         struct osend_args /* {
907                 int     s;
908                 caddr_t buf;
909                 int     len;
910                 int     flags;
911         } */ *uap;
912 {
913         struct msghdr msg;
914         struct iovec aiov;
915
916         msg.msg_name = 0;
917         msg.msg_namelen = 0;
918         msg.msg_iov = &aiov;
919         msg.msg_iovlen = 1;
920         aiov.iov_base = uap->buf;
921         aiov.iov_len = uap->len;
922         msg.msg_control = 0;
923         msg.msg_flags = 0;
924         return (sendit(td, uap->s, &msg, uap->flags));
925 }
926
927 int
928 osendmsg(td, uap)
929         struct thread *td;
930         struct osendmsg_args /* {
931                 int     s;
932                 caddr_t msg;
933                 int     flags;
934         } */ *uap;
935 {
936         struct msghdr msg;
937         struct iovec *iov;
938         int error;
939
940         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
941         if (error != 0)
942                 return (error);
943         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
944         if (error != 0)
945                 return (error);
946         msg.msg_iov = iov;
947         msg.msg_flags = MSG_COMPAT;
948         error = sendit(td, uap->s, &msg, uap->flags);
949         free(iov, M_IOV);
950         return (error);
951 }
952 #endif
953
954 int
955 sys_sendmsg(td, uap)
956         struct thread *td;
957         struct sendmsg_args /* {
958                 int     s;
959                 caddr_t msg;
960                 int     flags;
961         } */ *uap;
962 {
963         struct msghdr msg;
964         struct iovec *iov;
965         int error;
966
967         error = copyin(uap->msg, &msg, sizeof (msg));
968         if (error != 0)
969                 return (error);
970         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
971         if (error != 0)
972                 return (error);
973         msg.msg_iov = iov;
974 #ifdef COMPAT_OLDSOCK
975         msg.msg_flags = 0;
976 #endif
977         error = sendit(td, uap->s, &msg, uap->flags);
978         free(iov, M_IOV);
979         return (error);
980 }
981
982 int
983 kern_recvit(td, s, mp, fromseg, controlp)
984         struct thread *td;
985         int s;
986         struct msghdr *mp;
987         enum uio_seg fromseg;
988         struct mbuf **controlp;
989 {
990         struct uio auio;
991         struct iovec *iov;
992         struct mbuf *m, *control = NULL;
993         caddr_t ctlbuf;
994         struct file *fp;
995         struct socket *so;
996         struct sockaddr *fromsa = NULL;
997         cap_rights_t rights;
998 #ifdef KTRACE
999         struct uio *ktruio = NULL;
1000 #endif
1001         ssize_t len;
1002         int error, i;
1003
1004         if (controlp != NULL)
1005                 *controlp = NULL;
1006
1007         AUDIT_ARG_FD(s);
1008         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
1009             &fp, NULL);
1010         if (error != 0)
1011                 return (error);
1012         so = fp->f_data;
1013
1014 #ifdef MAC
1015         error = mac_socket_check_receive(td->td_ucred, so);
1016         if (error != 0) {
1017                 fdrop(fp, td);
1018                 return (error);
1019         }
1020 #endif
1021
1022         auio.uio_iov = mp->msg_iov;
1023         auio.uio_iovcnt = mp->msg_iovlen;
1024         auio.uio_segflg = UIO_USERSPACE;
1025         auio.uio_rw = UIO_READ;
1026         auio.uio_td = td;
1027         auio.uio_offset = 0;                    /* XXX */
1028         auio.uio_resid = 0;
1029         iov = mp->msg_iov;
1030         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
1031                 if ((auio.uio_resid += iov->iov_len) < 0) {
1032                         fdrop(fp, td);
1033                         return (EINVAL);
1034                 }
1035         }
1036 #ifdef KTRACE
1037         if (KTRPOINT(td, KTR_GENIO))
1038                 ktruio = cloneuio(&auio);
1039 #endif
1040         len = auio.uio_resid;
1041         error = soreceive(so, &fromsa, &auio, NULL,
1042             (mp->msg_control || controlp) ? &control : NULL,
1043             &mp->msg_flags);
1044         if (error != 0) {
1045                 if (auio.uio_resid != len && (error == ERESTART ||
1046                     error == EINTR || error == EWOULDBLOCK))
1047                         error = 0;
1048         }
1049         if (fromsa != NULL)
1050                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
1051 #ifdef KTRACE
1052         if (ktruio != NULL) {
1053                 ktruio->uio_resid = len - auio.uio_resid;
1054                 ktrgenio(s, UIO_READ, ktruio, error);
1055         }
1056 #endif
1057         if (error != 0)
1058                 goto out;
1059         td->td_retval[0] = len - auio.uio_resid;
1060         if (mp->msg_name) {
1061                 len = mp->msg_namelen;
1062                 if (len <= 0 || fromsa == NULL)
1063                         len = 0;
1064                 else {
1065                         /* save sa_len before it is destroyed by MSG_COMPAT */
1066                         len = MIN(len, fromsa->sa_len);
1067 #ifdef COMPAT_OLDSOCK
1068                         if (mp->msg_flags & MSG_COMPAT)
1069                                 ((struct osockaddr *)fromsa)->sa_family =
1070                                     fromsa->sa_family;
1071 #endif
1072                         if (fromseg == UIO_USERSPACE) {
1073                                 error = copyout(fromsa, mp->msg_name,
1074                                     (unsigned)len);
1075                                 if (error != 0)
1076                                         goto out;
1077                         } else
1078                                 bcopy(fromsa, mp->msg_name, len);
1079                 }
1080                 mp->msg_namelen = len;
1081         }
1082         if (mp->msg_control && controlp == NULL) {
1083 #ifdef COMPAT_OLDSOCK
1084                 /*
1085                  * We assume that old recvmsg calls won't receive access
1086                  * rights and other control info, esp. as control info
1087                  * is always optional and those options didn't exist in 4.3.
1088                  * If we receive rights, trim the cmsghdr; anything else
1089                  * is tossed.
1090                  */
1091                 if (control && mp->msg_flags & MSG_COMPAT) {
1092                         if (mtod(control, struct cmsghdr *)->cmsg_level !=
1093                             SOL_SOCKET ||
1094                             mtod(control, struct cmsghdr *)->cmsg_type !=
1095                             SCM_RIGHTS) {
1096                                 mp->msg_controllen = 0;
1097                                 goto out;
1098                         }
1099                         control->m_len -= sizeof (struct cmsghdr);
1100                         control->m_data += sizeof (struct cmsghdr);
1101                 }
1102 #endif
1103                 len = mp->msg_controllen;
1104                 m = control;
1105                 mp->msg_controllen = 0;
1106                 ctlbuf = mp->msg_control;
1107
1108                 while (m && len > 0) {
1109                         unsigned int tocopy;
1110
1111                         if (len >= m->m_len)
1112                                 tocopy = m->m_len;
1113                         else {
1114                                 mp->msg_flags |= MSG_CTRUNC;
1115                                 tocopy = len;
1116                         }
1117
1118                         if ((error = copyout(mtod(m, caddr_t),
1119                                         ctlbuf, tocopy)) != 0)
1120                                 goto out;
1121
1122                         ctlbuf += tocopy;
1123                         len -= tocopy;
1124                         m = m->m_next;
1125                 }
1126                 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
1127         }
1128 out:
1129         fdrop(fp, td);
1130 #ifdef KTRACE
1131         if (fromsa && KTRPOINT(td, KTR_STRUCT))
1132                 ktrsockaddr(fromsa);
1133 #endif
1134         free(fromsa, M_SONAME);
1135
1136         if (error == 0 && controlp != NULL)
1137                 *controlp = control;
1138         else  if (control)
1139                 m_freem(control);
1140
1141         return (error);
1142 }
1143
1144 static int
1145 recvit(td, s, mp, namelenp)
1146         struct thread *td;
1147         int s;
1148         struct msghdr *mp;
1149         void *namelenp;
1150 {
1151         int error;
1152
1153         error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
1154         if (error != 0)
1155                 return (error);
1156         if (namelenp != NULL) {
1157                 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
1158 #ifdef COMPAT_OLDSOCK
1159                 if (mp->msg_flags & MSG_COMPAT)
1160                         error = 0;      /* old recvfrom didn't check */
1161 #endif
1162         }
1163         return (error);
1164 }
1165
1166 int
1167 sys_recvfrom(td, uap)
1168         struct thread *td;
1169         struct recvfrom_args /* {
1170                 int     s;
1171                 caddr_t buf;
1172                 size_t  len;
1173                 int     flags;
1174                 struct sockaddr * __restrict    from;
1175                 socklen_t * __restrict fromlenaddr;
1176         } */ *uap;
1177 {
1178         struct msghdr msg;
1179         struct iovec aiov;
1180         int error;
1181
1182         if (uap->fromlenaddr) {
1183                 error = copyin(uap->fromlenaddr,
1184                     &msg.msg_namelen, sizeof (msg.msg_namelen));
1185                 if (error != 0)
1186                         goto done2;
1187         } else {
1188                 msg.msg_namelen = 0;
1189         }
1190         msg.msg_name = uap->from;
1191         msg.msg_iov = &aiov;
1192         msg.msg_iovlen = 1;
1193         aiov.iov_base = uap->buf;
1194         aiov.iov_len = uap->len;
1195         msg.msg_control = 0;
1196         msg.msg_flags = uap->flags;
1197         error = recvit(td, uap->s, &msg, uap->fromlenaddr);
1198 done2:
1199         return (error);
1200 }
1201
1202 #ifdef COMPAT_OLDSOCK
1203 int
1204 orecvfrom(td, uap)
1205         struct thread *td;
1206         struct recvfrom_args *uap;
1207 {
1208
1209         uap->flags |= MSG_COMPAT;
1210         return (sys_recvfrom(td, uap));
1211 }
1212 #endif
1213
1214 #ifdef COMPAT_OLDSOCK
1215 int
1216 orecv(td, uap)
1217         struct thread *td;
1218         struct orecv_args /* {
1219                 int     s;
1220                 caddr_t buf;
1221                 int     len;
1222                 int     flags;
1223         } */ *uap;
1224 {
1225         struct msghdr msg;
1226         struct iovec aiov;
1227
1228         msg.msg_name = 0;
1229         msg.msg_namelen = 0;
1230         msg.msg_iov = &aiov;
1231         msg.msg_iovlen = 1;
1232         aiov.iov_base = uap->buf;
1233         aiov.iov_len = uap->len;
1234         msg.msg_control = 0;
1235         msg.msg_flags = uap->flags;
1236         return (recvit(td, uap->s, &msg, NULL));
1237 }
1238
1239 /*
1240  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
1241  * overlays the new one, missing only the flags, and with the (old) access
1242  * rights where the control fields are now.
1243  */
1244 int
1245 orecvmsg(td, uap)
1246         struct thread *td;
1247         struct orecvmsg_args /* {
1248                 int     s;
1249                 struct  omsghdr *msg;
1250                 int     flags;
1251         } */ *uap;
1252 {
1253         struct msghdr msg;
1254         struct iovec *iov;
1255         int error;
1256
1257         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
1258         if (error != 0)
1259                 return (error);
1260         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1261         if (error != 0)
1262                 return (error);
1263         msg.msg_flags = uap->flags | MSG_COMPAT;
1264         msg.msg_iov = iov;
1265         error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
1266         if (msg.msg_controllen && error == 0)
1267                 error = copyout(&msg.msg_controllen,
1268                     &uap->msg->msg_accrightslen, sizeof (int));
1269         free(iov, M_IOV);
1270         return (error);
1271 }
1272 #endif
1273
1274 int
1275 sys_recvmsg(td, uap)
1276         struct thread *td;
1277         struct recvmsg_args /* {
1278                 int     s;
1279                 struct  msghdr *msg;
1280                 int     flags;
1281         } */ *uap;
1282 {
1283         struct msghdr msg;
1284         struct iovec *uiov, *iov;
1285         int error;
1286
1287         error = copyin(uap->msg, &msg, sizeof (msg));
1288         if (error != 0)
1289                 return (error);
1290         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1291         if (error != 0)
1292                 return (error);
1293         msg.msg_flags = uap->flags;
1294 #ifdef COMPAT_OLDSOCK
1295         msg.msg_flags &= ~MSG_COMPAT;
1296 #endif
1297         uiov = msg.msg_iov;
1298         msg.msg_iov = iov;
1299         error = recvit(td, uap->s, &msg, NULL);
1300         if (error == 0) {
1301                 msg.msg_iov = uiov;
1302                 error = copyout(&msg, uap->msg, sizeof(msg));
1303         }
1304         free(iov, M_IOV);
1305         return (error);
1306 }
1307
1308 /* ARGSUSED */
1309 int
1310 sys_shutdown(td, uap)
1311         struct thread *td;
1312         struct shutdown_args /* {
1313                 int     s;
1314                 int     how;
1315         } */ *uap;
1316 {
1317         struct socket *so;
1318         struct file *fp;
1319         cap_rights_t rights;
1320         int error;
1321
1322         AUDIT_ARG_FD(uap->s);
1323         error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
1324             &fp, NULL);
1325         if (error == 0) {
1326                 so = fp->f_data;
1327                 error = soshutdown(so, uap->how);
1328                 /*
1329                  * Previous versions did not return ENOTCONN, but 0 in
1330                  * case the socket was not connected. Some important
1331                  * programs like syslogd up to r279016, 2015-02-19,
1332                  * still depend on this behavior.
1333                  */
1334                 if (error == ENOTCONN &&
1335                     td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
1336                         error = 0;
1337                 fdrop(fp, td);
1338         }
1339         return (error);
1340 }
1341
1342 /* ARGSUSED */
1343 int
1344 sys_setsockopt(td, uap)
1345         struct thread *td;
1346         struct setsockopt_args /* {
1347                 int     s;
1348                 int     level;
1349                 int     name;
1350                 caddr_t val;
1351                 int     valsize;
1352         } */ *uap;
1353 {
1354
1355         return (kern_setsockopt(td, uap->s, uap->level, uap->name,
1356             uap->val, UIO_USERSPACE, uap->valsize));
1357 }
1358
1359 int
1360 kern_setsockopt(td, s, level, name, val, valseg, valsize)
1361         struct thread *td;
1362         int s;
1363         int level;
1364         int name;
1365         void *val;
1366         enum uio_seg valseg;
1367         socklen_t valsize;
1368 {
1369         struct socket *so;
1370         struct file *fp;
1371         struct sockopt sopt;
1372         cap_rights_t rights;
1373         int error;
1374
1375         if (val == NULL && valsize != 0)
1376                 return (EFAULT);
1377         if ((int)valsize < 0)
1378                 return (EINVAL);
1379
1380         sopt.sopt_dir = SOPT_SET;
1381         sopt.sopt_level = level;
1382         sopt.sopt_name = name;
1383         sopt.sopt_val = val;
1384         sopt.sopt_valsize = valsize;
1385         switch (valseg) {
1386         case UIO_USERSPACE:
1387                 sopt.sopt_td = td;
1388                 break;
1389         case UIO_SYSSPACE:
1390                 sopt.sopt_td = NULL;
1391                 break;
1392         default:
1393                 panic("kern_setsockopt called with bad valseg");
1394         }
1395
1396         AUDIT_ARG_FD(s);
1397         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
1398             &fp, NULL);
1399         if (error == 0) {
1400                 so = fp->f_data;
1401                 error = sosetopt(so, &sopt);
1402                 fdrop(fp, td);
1403         }
1404         return(error);
1405 }
1406
1407 /* ARGSUSED */
1408 int
1409 sys_getsockopt(td, uap)
1410         struct thread *td;
1411         struct getsockopt_args /* {
1412                 int     s;
1413                 int     level;
1414                 int     name;
1415                 void * __restrict       val;
1416                 socklen_t * __restrict avalsize;
1417         } */ *uap;
1418 {
1419         socklen_t valsize;
1420         int error;
1421
1422         if (uap->val) {
1423                 error = copyin(uap->avalsize, &valsize, sizeof (valsize));
1424                 if (error != 0)
1425                         return (error);
1426         }
1427
1428         error = kern_getsockopt(td, uap->s, uap->level, uap->name,
1429             uap->val, UIO_USERSPACE, &valsize);
1430
1431         if (error == 0)
1432                 error = copyout(&valsize, uap->avalsize, sizeof (valsize));
1433         return (error);
1434 }
1435
1436 /*
1437  * Kernel version of getsockopt.
1438  * optval can be a userland or userspace. optlen is always a kernel pointer.
1439  */
1440 int
1441 kern_getsockopt(td, s, level, name, val, valseg, valsize)
1442         struct thread *td;
1443         int s;
1444         int level;
1445         int name;
1446         void *val;
1447         enum uio_seg valseg;
1448         socklen_t *valsize;
1449 {
1450         struct socket *so;
1451         struct file *fp;
1452         struct sockopt sopt;
1453         cap_rights_t rights;
1454         int error;
1455
1456         if (val == NULL)
1457                 *valsize = 0;
1458         if ((int)*valsize < 0)
1459                 return (EINVAL);
1460
1461         sopt.sopt_dir = SOPT_GET;
1462         sopt.sopt_level = level;
1463         sopt.sopt_name = name;
1464         sopt.sopt_val = val;
1465         sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
1466         switch (valseg) {
1467         case UIO_USERSPACE:
1468                 sopt.sopt_td = td;
1469                 break;
1470         case UIO_SYSSPACE:
1471                 sopt.sopt_td = NULL;
1472                 break;
1473         default:
1474                 panic("kern_getsockopt called with bad valseg");
1475         }
1476
1477         AUDIT_ARG_FD(s);
1478         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
1479             &fp, NULL);
1480         if (error == 0) {
1481                 so = fp->f_data;
1482                 error = sogetopt(so, &sopt);
1483                 *valsize = sopt.sopt_valsize;
1484                 fdrop(fp, td);
1485         }
1486         return (error);
1487 }
1488
1489 /*
1490  * getsockname1() - Get socket name.
1491  */
1492 /* ARGSUSED */
1493 static int
1494 getsockname1(td, uap, compat)
1495         struct thread *td;
1496         struct getsockname_args /* {
1497                 int     fdes;
1498                 struct sockaddr * __restrict asa;
1499                 socklen_t * __restrict alen;
1500         } */ *uap;
1501         int compat;
1502 {
1503         struct sockaddr *sa;
1504         socklen_t len;
1505         int error;
1506
1507         error = copyin(uap->alen, &len, sizeof(len));
1508         if (error != 0)
1509                 return (error);
1510
1511         error = kern_getsockname(td, uap->fdes, &sa, &len);
1512         if (error != 0)
1513                 return (error);
1514
1515         if (len != 0) {
1516 #ifdef COMPAT_OLDSOCK
1517                 if (compat)
1518                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
1519 #endif
1520                 error = copyout(sa, uap->asa, (u_int)len);
1521         }
1522         free(sa, M_SONAME);
1523         if (error == 0)
1524                 error = copyout(&len, uap->alen, sizeof(len));
1525         return (error);
1526 }
1527
1528 int
1529 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
1530     socklen_t *alen)
1531 {
1532         struct socket *so;
1533         struct file *fp;
1534         cap_rights_t rights;
1535         socklen_t len;
1536         int error;
1537
1538         AUDIT_ARG_FD(fd);
1539         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
1540             &fp, NULL);
1541         if (error != 0)
1542                 return (error);
1543         so = fp->f_data;
1544         *sa = NULL;
1545         CURVNET_SET(so->so_vnet);
1546         error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
1547         CURVNET_RESTORE();
1548         if (error != 0)
1549                 goto bad;
1550         if (*sa == NULL)
1551                 len = 0;
1552         else
1553                 len = MIN(*alen, (*sa)->sa_len);
1554         *alen = len;
1555 #ifdef KTRACE
1556         if (KTRPOINT(td, KTR_STRUCT))
1557                 ktrsockaddr(*sa);
1558 #endif
1559 bad:
1560         fdrop(fp, td);
1561         if (error != 0 && *sa != NULL) {
1562                 free(*sa, M_SONAME);
1563                 *sa = NULL;
1564         }
1565         return (error);
1566 }
1567
1568 int
1569 sys_getsockname(td, uap)
1570         struct thread *td;
1571         struct getsockname_args *uap;
1572 {
1573
1574         return (getsockname1(td, uap, 0));
1575 }
1576
1577 #ifdef COMPAT_OLDSOCK
1578 int
1579 ogetsockname(td, uap)
1580         struct thread *td;
1581         struct getsockname_args *uap;
1582 {
1583
1584         return (getsockname1(td, uap, 1));
1585 }
1586 #endif /* COMPAT_OLDSOCK */
1587
1588 /*
1589  * getpeername1() - Get name of peer for connected socket.
1590  */
1591 /* ARGSUSED */
1592 static int
1593 getpeername1(td, uap, compat)
1594         struct thread *td;
1595         struct getpeername_args /* {
1596                 int     fdes;
1597                 struct sockaddr * __restrict    asa;
1598                 socklen_t * __restrict  alen;
1599         } */ *uap;
1600         int compat;
1601 {
1602         struct sockaddr *sa;
1603         socklen_t len;
1604         int error;
1605
1606         error = copyin(uap->alen, &len, sizeof (len));
1607         if (error != 0)
1608                 return (error);
1609
1610         error = kern_getpeername(td, uap->fdes, &sa, &len);
1611         if (error != 0)
1612                 return (error);
1613
1614         if (len != 0) {
1615 #ifdef COMPAT_OLDSOCK
1616                 if (compat)
1617                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
1618 #endif
1619                 error = copyout(sa, uap->asa, (u_int)len);
1620         }
1621         free(sa, M_SONAME);
1622         if (error == 0)
1623                 error = copyout(&len, uap->alen, sizeof(len));
1624         return (error);
1625 }
1626
1627 int
1628 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
1629     socklen_t *alen)
1630 {
1631         struct socket *so;
1632         struct file *fp;
1633         cap_rights_t rights;
1634         socklen_t len;
1635         int error;
1636
1637         AUDIT_ARG_FD(fd);
1638         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
1639             &fp, NULL);
1640         if (error != 0)
1641                 return (error);
1642         so = fp->f_data;
1643         if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
1644                 error = ENOTCONN;
1645                 goto done;
1646         }
1647         *sa = NULL;
1648         CURVNET_SET(so->so_vnet);
1649         error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
1650         CURVNET_RESTORE();
1651         if (error != 0)
1652                 goto bad;
1653         if (*sa == NULL)
1654                 len = 0;
1655         else
1656                 len = MIN(*alen, (*sa)->sa_len);
1657         *alen = len;
1658 #ifdef KTRACE
1659         if (KTRPOINT(td, KTR_STRUCT))
1660                 ktrsockaddr(*sa);
1661 #endif
1662 bad:
1663         if (error != 0 && *sa != NULL) {
1664                 free(*sa, M_SONAME);
1665                 *sa = NULL;
1666         }
1667 done:
1668         fdrop(fp, td);
1669         return (error);
1670 }
1671
1672 int
1673 sys_getpeername(td, uap)
1674         struct thread *td;
1675         struct getpeername_args *uap;
1676 {
1677
1678         return (getpeername1(td, uap, 0));
1679 }
1680
1681 #ifdef COMPAT_OLDSOCK
1682 int
1683 ogetpeername(td, uap)
1684         struct thread *td;
1685         struct ogetpeername_args *uap;
1686 {
1687
1688         /* XXX uap should have type `getpeername_args *' to begin with. */
1689         return (getpeername1(td, (struct getpeername_args *)uap, 1));
1690 }
1691 #endif /* COMPAT_OLDSOCK */
1692
1693 static int
1694 sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
1695 {
1696         struct sockaddr *sa;
1697         struct mbuf *m;
1698         int error;
1699
1700         if (buflen > MLEN) {
1701 #ifdef COMPAT_OLDSOCK
1702                 if (type == MT_SONAME && buflen <= 112)
1703                         buflen = MLEN;          /* unix domain compat. hack */
1704                 else
1705 #endif
1706                         if (buflen > MCLBYTES)
1707                                 return (EINVAL);
1708         }
1709         m = m_get2(buflen, M_WAITOK, type, 0);
1710         m->m_len = buflen;
1711         error = copyin(buf, mtod(m, void *), buflen);
1712         if (error != 0)
1713                 (void) m_free(m);
1714         else {
1715                 *mp = m;
1716                 if (type == MT_SONAME) {
1717                         sa = mtod(m, struct sockaddr *);
1718
1719 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1720                         if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1721                                 sa->sa_family = sa->sa_len;
1722 #endif
1723                         sa->sa_len = buflen;
1724                 }
1725         }
1726         return (error);
1727 }
1728
1729 int
1730 getsockaddr(namp, uaddr, len)
1731         struct sockaddr **namp;
1732         caddr_t uaddr;
1733         size_t len;
1734 {
1735         struct sockaddr *sa;
1736         int error;
1737
1738         if (len > SOCK_MAXADDRLEN)
1739                 return (ENAMETOOLONG);
1740         if (len < offsetof(struct sockaddr, sa_data[0]))
1741                 return (EINVAL);
1742         sa = malloc(len, M_SONAME, M_WAITOK);
1743         error = copyin(uaddr, sa, len);
1744         if (error != 0) {
1745                 free(sa, M_SONAME);
1746         } else {
1747 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1748                 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1749                         sa->sa_family = sa->sa_len;
1750 #endif
1751                 sa->sa_len = len;
1752                 *namp = sa;
1753         }
1754         return (error);
1755 }