Annotation of Net2/kern/uipc_syscalls.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California.
                      3:  * 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:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
1.1.1.3 ! root       33:  *     from: @(#)uipc_syscalls.c       7.24 (Berkeley) 6/3/91
        !            34:  *     uipc_syscalls.c,v 1.5 1993/07/17 15:24:42 mycroft Exp
1.1       root       35:  */
                     36: 
                     37: #include "param.h"
                     38: #include "filedesc.h"
                     39: #include "proc.h"
                     40: #include "file.h"
                     41: #include "buf.h"
                     42: #include "malloc.h"
                     43: #include "mbuf.h"
                     44: #include "protosw.h"
                     45: #include "socket.h"
                     46: #include "socketvar.h"
                     47: #ifdef KTRACE
                     48: #include "ktrace.h"
                     49: #endif
                     50: 
                     51: /*
                     52:  * System call interface to the socket abstraction.
                     53:  */
                     54: 
                     55: extern struct fileops socketops;
                     56: 
1.1.1.3 ! root       57: struct socket_args {
        !            58:        int     domain;
        !            59:        int     type;
        !            60:        int     protocol;
        !            61: };
        !            62: 
1.1       root       63: socket(p, uap, retval)
                     64:        struct proc *p;
1.1.1.3 ! root       65:        register struct socket_args *uap;
1.1       root       66:        int *retval;
                     67: {
                     68:        struct filedesc *fdp = p->p_fd;
                     69:        struct socket *so;
                     70:        struct file *fp;
                     71:        int fd, error;
                     72: 
                     73:        if (error = falloc(p, &fp, &fd))
                     74:                return (error);
                     75:        fp->f_flag = FREAD|FWRITE;
                     76:        fp->f_type = DTYPE_SOCKET;
                     77:        fp->f_ops = &socketops;
                     78:        if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {
                     79:                fdp->fd_ofiles[fd] = 0;
                     80:                ffree(fp);
                     81:        } else {
                     82:                fp->f_data = (caddr_t)so;
                     83:                *retval = fd;
                     84:        }
                     85:        return (error);
                     86: }
                     87: 
1.1.1.3 ! root       88: struct bind_args {
        !            89:        int     s;
        !            90:        caddr_t name;
        !            91:        int     namelen;
        !            92: };
        !            93: 
1.1       root       94: /* ARGSUSED */
                     95: bind(p, uap, retval)
                     96:        struct proc *p;
1.1.1.3 ! root       97:        register struct bind_args *uap;
1.1       root       98:        int *retval;
                     99: {
                    100:        struct file *fp;
                    101:        struct mbuf *nam;
                    102:        int error;
                    103: 
                    104:        if (error = getsock(p->p_fd, uap->s, &fp))
                    105:                return (error);
                    106:        if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
                    107:                return (error);
                    108:        error = sobind((struct socket *)fp->f_data, nam);
                    109:        m_freem(nam);
                    110:        return (error);
                    111: }
                    112: 
1.1.1.3 ! root      113: struct listen_args {
        !           114:        int     s;
        !           115:        int     backlog;
        !           116: };
        !           117: 
1.1       root      118: /* ARGSUSED */
                    119: listen(p, uap, retval)
                    120:        struct proc *p;
1.1.1.3 ! root      121:        register struct listen_args *uap;
1.1       root      122:        int *retval;
                    123: {
                    124:        struct file *fp;
                    125:        int error;
                    126: 
                    127:        if (error = getsock(p->p_fd, uap->s, &fp))
                    128:                return (error);
                    129:        return (solisten((struct socket *)fp->f_data, uap->backlog));
                    130: }
                    131: 
                    132: #ifdef COMPAT_43
1.1.1.3 ! root      133: struct accept_args {
        !           134:        int     s;
        !           135:        caddr_t name;
        !           136:        int     *anamelen;
        !           137:        int     compat_43;
        !           138: };
        !           139: 
1.1       root      140: accept(p, uap, retval)
                    141:        struct proc *p;
1.1.1.3 ! root      142:        struct accept_args *uap;
1.1       root      143:        int *retval;
                    144: {
                    145: 
                    146:        uap->compat_43 = 0;
                    147:        return (accept1(p, uap, retval));
                    148: }
                    149: 
1.1.1.3 ! root      150: struct oaccept_args {
        !           151:        int     s;
        !           152:        caddr_t name;
        !           153:        int     *anamelen;
        !           154:        int     compat_43;
        !           155: };
        !           156: 
1.1       root      157: oaccept(p, uap, retval)
                    158:        struct proc *p;
1.1.1.3 ! root      159:        struct oaccept_args *uap;
1.1       root      160:        int *retval;
                    161: {
                    162: 
                    163:        uap->compat_43 = 1;
                    164:        return (accept1(p, uap, retval));
                    165: }
                    166: #else /* COMPAT_43 */
                    167: 
                    168: #define        accept1 accept
                    169: #endif
                    170: 
1.1.1.3 ! root      171: struct accept1_args {
        !           172:        int     s;
        !           173:        caddr_t name;
        !           174:        int     *anamelen;
1.1       root      175: #ifdef COMPAT_43
1.1.1.3 ! root      176:        int     compat_43;
1.1       root      177: #endif
1.1.1.3 ! root      178: };
        !           179: 
        !           180: accept1(p, uap, retval)
        !           181:        struct proc *p;
        !           182:        register struct accept1_args *uap;
1.1       root      183:        int *retval;
                    184: {
                    185:        struct file *fp;
                    186:        struct mbuf *nam;
                    187:        int namelen, error, s;
                    188:        register struct socket *so;
                    189: 
                    190:        if (uap->name && (error = copyin((caddr_t)uap->anamelen,
                    191:            (caddr_t)&namelen, sizeof (namelen))))
                    192:                return (error);
                    193:        if (error = getsock(p->p_fd, uap->s, &fp))
                    194:                return (error);
                    195:        s = splnet();
                    196:        so = (struct socket *)fp->f_data;
                    197:        if ((so->so_options & SO_ACCEPTCONN) == 0) {
                    198:                splx(s);
                    199:                return (EINVAL);
                    200:        }
                    201:        if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
                    202:                splx(s);
                    203:                return (EWOULDBLOCK);
                    204:        }
                    205:        while (so->so_qlen == 0 && so->so_error == 0) {
                    206:                if (so->so_state & SS_CANTRCVMORE) {
                    207:                        so->so_error = ECONNABORTED;
                    208:                        break;
                    209:                }
                    210:                if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
                    211:                    netcon, 0)) {
                    212:                        splx(s);
                    213:                        return (error);
                    214:                }
                    215:        }
                    216:        if (so->so_error) {
                    217:                error = so->so_error;
                    218:                so->so_error = 0;
                    219:                splx(s);
                    220:                return (error);
                    221:        }
                    222:        if (error = falloc(p, &fp, retval)) {
                    223:                splx(s);
                    224:                return (error);
                    225:        }
                    226:        { struct socket *aso = so->so_q;
                    227:          if (soqremque(aso, 1) == 0)
                    228:                panic("accept");
                    229:          so = aso;
                    230:        }
                    231:        fp->f_type = DTYPE_SOCKET;
                    232:        fp->f_flag = FREAD|FWRITE;
                    233:        fp->f_ops = &socketops;
                    234:        fp->f_data = (caddr_t)so;
                    235:        nam = m_get(M_WAIT, MT_SONAME);
                    236:        (void) soaccept(so, nam);
                    237:        if (uap->name) {
                    238: #ifdef COMPAT_43
                    239:                if (uap->compat_43)
                    240:                        mtod(nam, struct osockaddr *)->sa_family =
                    241:                            mtod(nam, struct sockaddr *)->sa_family;
                    242: #endif
                    243:                if (namelen > nam->m_len)
                    244:                        namelen = nam->m_len;
                    245:                /* SHOULD COPY OUT A CHAIN HERE */
                    246:                if ((error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
                    247:                    (u_int)namelen)) == 0)
                    248:                        error = copyout((caddr_t)&namelen,
                    249:                            (caddr_t)uap->anamelen, sizeof (*uap->anamelen));
                    250:        }
                    251:        m_freem(nam);
                    252:        splx(s);
                    253:        return (error);
                    254: }
                    255: 
1.1.1.3 ! root      256: struct connect_args {
        !           257:        int     s;
        !           258:        caddr_t name;
        !           259:        int     namelen;
        !           260: };
        !           261: 
1.1       root      262: /* ARGSUSED */
                    263: connect(p, uap, retval)
                    264:        struct proc *p;
1.1.1.3 ! root      265:        register struct connect_args *uap;
1.1       root      266:        int *retval;
                    267: {
                    268:        struct file *fp;
                    269:        register struct socket *so;
                    270:        struct mbuf *nam;
                    271:        int error, s;
                    272: 
                    273:        if (error = getsock(p->p_fd, uap->s, &fp))
                    274:                return (error);
                    275:        so = (struct socket *)fp->f_data;
                    276:        if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
                    277:                return (EALREADY);
                    278:        if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
                    279:                return (error);
                    280:        error = soconnect(so, nam);
                    281:        if (error)
                    282:                goto bad;
                    283:        if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
                    284:                m_freem(nam);
                    285:                return (EINPROGRESS);
                    286:        }
                    287:        s = splnet();
                    288:        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
                    289:                if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
                    290:                    netcon, 0))
                    291:                        break;
                    292:        if (error == 0) {
                    293:                error = so->so_error;
                    294:                so->so_error = 0;
                    295:        }
                    296:        splx(s);
                    297: bad:
                    298:        so->so_state &= ~SS_ISCONNECTING;
                    299:        m_freem(nam);
                    300:        if (error == ERESTART)
                    301:                error = EINTR;
                    302:        return (error);
                    303: }
                    304: 
1.1.1.3 ! root      305: struct socketpair_args {
        !           306:        int     domain;
        !           307:        int     type;
        !           308:        int     protocol;
        !           309:        int     *rsv;
        !           310: };
        !           311: 
1.1       root      312: socketpair(p, uap, retval)
                    313:        struct proc *p;
1.1.1.3 ! root      314:        register struct socketpair_args *uap;
1.1       root      315:        int retval[];
                    316: {
                    317:        register struct filedesc *fdp = p->p_fd;
                    318:        struct file *fp1, *fp2;
                    319:        struct socket *so1, *so2;
                    320:        int fd, error, sv[2];
                    321: 
                    322:        if (error = socreate(uap->domain, &so1, uap->type, uap->protocol))
                    323:                return (error);
                    324:        if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))
                    325:                goto free1;
                    326:        if (error = falloc(p, &fp1, &fd))
                    327:                goto free2;
                    328:        sv[0] = fd;
                    329:        fp1->f_flag = FREAD|FWRITE;
                    330:        fp1->f_type = DTYPE_SOCKET;
                    331:        fp1->f_ops = &socketops;
                    332:        fp1->f_data = (caddr_t)so1;
                    333:        if (error = falloc(p, &fp2, &fd))
                    334:                goto free3;
                    335:        fp2->f_flag = FREAD|FWRITE;
                    336:        fp2->f_type = DTYPE_SOCKET;
                    337:        fp2->f_ops = &socketops;
                    338:        fp2->f_data = (caddr_t)so2;
                    339:        sv[1] = fd;
                    340:        if (error = soconnect2(so1, so2))
                    341:                goto free4;
                    342:        if (uap->type == SOCK_DGRAM) {
                    343:                /*
                    344:                 * Datagram socket connection is asymmetric.
                    345:                 */
                    346:                 if (error = soconnect2(so2, so1))
                    347:                        goto free4;
                    348:        }
                    349:        error = copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
                    350:        retval[0] = sv[0];              /* XXX ??? */
                    351:        retval[1] = sv[1];              /* XXX ??? */
                    352:        return (error);
                    353: free4:
                    354:        ffree(fp2);
                    355:        fdp->fd_ofiles[sv[1]] = 0;
                    356: free3:
                    357:        ffree(fp1);
                    358:        fdp->fd_ofiles[sv[0]] = 0;
                    359: free2:
                    360:        (void)soclose(so2);
                    361: free1:
                    362:        (void)soclose(so1);
                    363:        return (error);
                    364: }
                    365: 
1.1.1.3 ! root      366: struct sendto_args {
        !           367:        int     s;
        !           368:        caddr_t buf;
        !           369:        int     len;
        !           370:        int     flags;
        !           371:        caddr_t to;
        !           372:        int     tolen;
        !           373: };
        !           374: 
1.1       root      375: sendto(p, uap, retval)
                    376:        struct proc *p;
1.1.1.3 ! root      377:        register struct sendto_args *uap;
1.1       root      378:        int *retval;
                    379: {
                    380:        struct msghdr msg;
                    381:        struct iovec aiov;
                    382:        int error;
                    383: 
                    384:        msg.msg_name = uap->to;
                    385:        msg.msg_namelen = uap->tolen;
                    386:        msg.msg_iov = &aiov;
                    387:        msg.msg_iovlen = 1;
                    388:        msg.msg_control = 0;
                    389: #ifdef COMPAT_43
                    390:        msg.msg_flags = 0;
                    391: #endif
                    392:        aiov.iov_base = uap->buf;
                    393:        aiov.iov_len = uap->len;
                    394:        return (sendit(p, uap->s, &msg, uap->flags, retval));
                    395: }
                    396: 
                    397: #ifdef COMPAT_43
1.1.1.3 ! root      398: struct osend_args {
        !           399:        int     s;
        !           400:        caddr_t buf;
        !           401:        int     len;
        !           402:        int     flags;
        !           403: };
        !           404: 
1.1       root      405: osend(p, uap, retval)
                    406:        struct proc *p;
1.1.1.3 ! root      407:        register struct osend_args *uap;
1.1       root      408:        int *retval;
                    409: {
                    410:        struct msghdr msg;
                    411:        struct iovec aiov;
                    412: 
                    413:        msg.msg_name = 0;
                    414:        msg.msg_namelen = 0;
                    415:        msg.msg_iov = &aiov;
                    416:        msg.msg_iovlen = 1;
                    417:        aiov.iov_base = uap->buf;
                    418:        aiov.iov_len = uap->len;
                    419:        msg.msg_control = 0;
                    420:        msg.msg_flags = 0;
                    421:        return (sendit(p, uap->s, &msg, uap->flags, retval));
                    422: }
                    423: 
1.1.1.3 ! root      424: struct osendmsg_args {
        !           425:        int     s;
        !           426:        caddr_t msg;
        !           427:        int     flags;
        !           428: };
        !           429: 
1.1       root      430: #define MSG_COMPAT     0x8000
                    431: osendmsg(p, uap, retval)
                    432:        struct proc *p;
1.1.1.3 ! root      433:        register struct osendmsg_args *uap;
1.1       root      434:        int *retval;
                    435: {
                    436:        struct msghdr msg;
                    437:        struct iovec aiov[UIO_SMALLIOV], *iov;
                    438:        int error;
                    439: 
                    440:        if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (struct omsghdr)))
                    441:                return (error);
                    442:        if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
                    443:                if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
                    444:                        return (EMSGSIZE);
                    445:                MALLOC(iov, struct iovec *,
                    446:                      sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV, 
                    447:                      M_WAITOK);
                    448:        } else
                    449:                iov = aiov;
                    450:        if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
                    451:            (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
                    452:                goto done;
                    453:        msg.msg_flags = MSG_COMPAT;
                    454:        msg.msg_iov = iov;
                    455:        error = sendit(p, uap->s, &msg, uap->flags, retval);
                    456: done:
                    457:        if (iov != aiov)
                    458:                FREE(iov, M_IOV);
                    459:        return (error);
                    460: }
                    461: #endif
                    462: 
1.1.1.3 ! root      463: struct sendmsg_args {
        !           464:        int     s;
        !           465:        caddr_t msg;
        !           466:        int     flags;
        !           467: };
        !           468: 
1.1       root      469: sendmsg(p, uap, retval)
                    470:        struct proc *p;
1.1.1.3 ! root      471:        register struct sendmsg_args *uap;
1.1       root      472:        int *retval;
                    473: {
                    474:        struct msghdr msg;
                    475:        struct iovec aiov[UIO_SMALLIOV], *iov;
                    476:        int error;
                    477: 
                    478:        if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)))
                    479:                return (error);
                    480:        if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
                    481:                if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
                    482:                        return (EMSGSIZE);
                    483:                MALLOC(iov, struct iovec *,
                    484:                       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
                    485:                       M_WAITOK);
                    486:        } else
                    487:                iov = aiov;
                    488:        if (msg.msg_iovlen &&
                    489:            (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
                    490:            (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
                    491:                goto done;
                    492:        msg.msg_iov = iov;
                    493: #ifdef COMPAT_43
                    494:        msg.msg_flags = 0;
                    495: #endif
                    496:        error = sendit(p, uap->s, &msg, uap->flags, retval);
                    497: done:
                    498:        if (iov != aiov)
                    499:                FREE(iov, M_IOV);
                    500:        return (error);
                    501: }
                    502: 
                    503: sendit(p, s, mp, flags, retsize)
                    504:        register struct proc *p;
                    505:        int s;
                    506:        register struct msghdr *mp;
                    507:        int flags, *retsize;
                    508: {
                    509:        struct file *fp;
                    510:        struct uio auio;
                    511:        register struct iovec *iov;
                    512:        register int i;
                    513:        struct mbuf *to, *control;
                    514:        int len, error;
                    515: #ifdef KTRACE
                    516:        struct iovec *ktriov = NULL;
                    517: #endif
                    518:        
                    519:        if (error = getsock(p->p_fd, s, &fp))
                    520:                return (error);
                    521:        auio.uio_iov = mp->msg_iov;
                    522:        auio.uio_iovcnt = mp->msg_iovlen;
                    523:        auio.uio_segflg = UIO_USERSPACE;
                    524:        auio.uio_rw = UIO_WRITE;
                    525:        auio.uio_procp = p;
                    526:        auio.uio_offset = 0;                    /* XXX */
                    527:        auio.uio_resid = 0;
                    528:        iov = mp->msg_iov;
                    529:        for (i = 0; i < mp->msg_iovlen; i++, iov++) {
                    530:                if (iov->iov_len < 0)
                    531:                        return (EINVAL);
                    532:                if ((auio.uio_resid += iov->iov_len) < 0)
                    533:                        return (EINVAL);
                    534:        }
                    535:        if (mp->msg_name) {
                    536:                if (error = sockargs(&to, mp->msg_name, mp->msg_namelen,
                    537:                    MT_SONAME))
                    538:                        return (error);
                    539:        } else
                    540:                to = 0;
                    541:        if (mp->msg_control) {
                    542:                if (mp->msg_controllen < sizeof(struct cmsghdr)
                    543: #ifdef COMPAT_43
                    544:                    && mp->msg_flags != MSG_COMPAT
                    545: #endif
                    546:                ) {
                    547:                        error = EINVAL;
                    548:                        goto bad;
                    549:                }
                    550:                if (error = sockargs(&control, mp->msg_control,
                    551:                    mp->msg_controllen, MT_CONTROL))
                    552:                        goto bad;
                    553: #ifdef COMPAT_43
                    554:                if (mp->msg_flags == MSG_COMPAT) {
                    555:                        register struct cmsghdr *cm;
                    556: 
                    557:                        M_PREPEND(control, sizeof(*cm), M_WAIT);
                    558:                        if (control == 0) {
                    559:                                error = ENOBUFS;
                    560:                                goto bad;
                    561:                        } else {
                    562:                                cm = mtod(control, struct cmsghdr *);
                    563:                                cm->cmsg_len = control->m_len;
                    564:                                cm->cmsg_level = SOL_SOCKET;
                    565:                                cm->cmsg_type = SCM_RIGHTS;
                    566:                        }
                    567:                }
                    568: #endif
                    569:        } else
                    570:                control = 0;
                    571: #ifdef KTRACE
                    572:        if (KTRPOINT(p, KTR_GENIO)) {
                    573:                int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
                    574: 
                    575:                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                    576:                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                    577:        }
                    578: #endif
                    579:        len = auio.uio_resid;
                    580:        if (error = sosend((struct socket *)fp->f_data, to, &auio,
                    581:            (struct mbuf *)0, control, flags)) {
                    582:                if (auio.uio_resid != len && (error == ERESTART ||
                    583:                    error == EINTR || error == EWOULDBLOCK))
                    584:                        error = 0;
                    585:                if (error == EPIPE)
                    586:                        psignal(p, SIGPIPE);
                    587:        }
                    588:        if (error == 0)
                    589:                *retsize = len - auio.uio_resid;
                    590: #ifdef KTRACE
                    591:        if (ktriov != NULL) {
                    592:                if (error == 0)
                    593:                        ktrgenio(p->p_tracep, s, UIO_WRITE,
                    594:                                ktriov, *retsize, error);
                    595:                FREE(ktriov, M_TEMP);
                    596:        }
                    597: #endif
                    598: bad:
                    599:        if (to)
                    600:                m_freem(to);
                    601:        return (error);
                    602: }
                    603: 
                    604: #ifdef COMPAT_43
1.1.1.3 ! root      605: struct orecvfrom_args {
        !           606:        int     s;
        !           607:        caddr_t buf;
        !           608:        int     len;
        !           609:        int     flags;
        !           610:        caddr_t from;
        !           611:        int     *fromlenaddr;
        !           612: };
        !           613: 
1.1       root      614: orecvfrom(p, uap, retval)
                    615:        struct proc *p;
1.1.1.3 ! root      616:        struct orecvfrom_args *uap;
1.1       root      617:        int *retval;
                    618: {
                    619: 
                    620:        uap->flags |= MSG_COMPAT;
                    621:        return (recvfrom(p, uap, retval));
                    622: }
                    623: #endif
                    624: 
1.1.1.3 ! root      625: struct recvfrom_args {
        !           626:        int     s;
        !           627:        caddr_t buf;
        !           628:        int     len;
        !           629:        int     flags;
        !           630:        caddr_t from;
        !           631:        int     *fromlenaddr;
        !           632: };
        !           633: 
1.1       root      634: recvfrom(p, uap, retval)
                    635:        struct proc *p;
1.1.1.3 ! root      636:        register struct recvfrom_args *uap;
1.1       root      637:        int *retval;
                    638: {
                    639:        struct msghdr msg;
                    640:        struct iovec aiov;
                    641:        int error;
                    642: 
                    643:        if (uap->fromlenaddr) {
                    644:                if (error = copyin((caddr_t)uap->fromlenaddr,
                    645:                    (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen)))
                    646:                        return (error);
                    647:        } else
                    648:                msg.msg_namelen = 0;
                    649:        msg.msg_name = uap->from;
                    650:        msg.msg_iov = &aiov;
                    651:        msg.msg_iovlen = 1;
                    652:        aiov.iov_base = uap->buf;
                    653:        aiov.iov_len = uap->len;
                    654:        msg.msg_control = 0;
                    655:        msg.msg_flags = uap->flags;
                    656:        return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
                    657: }
                    658: 
                    659: #ifdef COMPAT_43
1.1.1.3 ! root      660: struct orecv_args {
        !           661:        int     s;
        !           662:        caddr_t buf;
        !           663:        int     len;
        !           664:        int     flags;
        !           665: };
        !           666: 
1.1       root      667: orecv(p, uap, retval)
                    668:        struct proc *p;
1.1.1.3 ! root      669:        register struct orecv_args *uap;
1.1       root      670:        int *retval;
                    671: {
                    672:        struct msghdr msg;
                    673:        struct iovec aiov;
                    674: 
                    675:        msg.msg_name = 0;
                    676:        msg.msg_namelen = 0;
                    677:        msg.msg_iov = &aiov;
                    678:        msg.msg_iovlen = 1;
                    679:        aiov.iov_base = uap->buf;
                    680:        aiov.iov_len = uap->len;
                    681:        msg.msg_control = 0;
                    682:        msg.msg_flags = uap->flags;
                    683:        return (recvit(p, uap->s, &msg, (caddr_t)0, retval));
                    684: }
                    685: 
1.1.1.3 ! root      686: struct orecvmsg_args {
        !           687:        int     s;
        !           688:        struct  omsghdr *msg;
        !           689:        int     flags;
        !           690: };
        !           691: 
1.1       root      692: /*
                    693:  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
                    694:  * overlays the new one, missing only the flags, and with the (old) access
                    695:  * rights where the control fields are now.
                    696:  */
                    697: orecvmsg(p, uap, retval)
                    698:        struct proc *p;
1.1.1.3 ! root      699:        register struct orecvmsg_args *uap;
1.1       root      700:        int *retval;
                    701: {
                    702:        struct msghdr msg;
                    703:        struct iovec aiov[UIO_SMALLIOV], *iov;
                    704:        int error;
                    705: 
                    706:        if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg,
                    707:            sizeof (struct omsghdr)))
                    708:                return (error);
                    709:        if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
                    710:                if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
                    711:                        return (EMSGSIZE);
                    712:                MALLOC(iov, struct iovec *,
                    713:                      sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
                    714:                      M_WAITOK);
                    715:        } else
                    716:                iov = aiov;
                    717:        msg.msg_flags = uap->flags | MSG_COMPAT;
                    718:        if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
                    719:            (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
                    720:                goto done;
                    721:        msg.msg_iov = iov;
                    722:        error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
                    723: 
                    724:        if (msg.msg_controllen && error == 0)
                    725:                error = copyout((caddr_t)&msg.msg_controllen,
                    726:                    (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));
                    727: done:
                    728:        if (iov != aiov)
                    729:                FREE(iov, M_IOV);
                    730:        return (error);
                    731: }
                    732: #endif
                    733: 
1.1.1.3 ! root      734: struct recvmsg_args {
        !           735:        int     s;
        !           736:        struct  msghdr *msg;
        !           737:        int     flags;
        !           738: };
        !           739: 
1.1       root      740: recvmsg(p, uap, retval)
                    741:        struct proc *p;
1.1.1.3 ! root      742:        register struct recvmsg_args *uap;
1.1       root      743:        int *retval;
                    744: {
                    745:        struct msghdr msg;
                    746:        struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
                    747:        register int error;
                    748: 
                    749:        if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg)))
                    750:                return (error);
                    751:        if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
                    752:                if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
                    753:                        return (EMSGSIZE);
                    754:                MALLOC(iov, struct iovec *,
                    755:                       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
                    756:                       M_WAITOK);
                    757:        } else
                    758:                iov = aiov;
                    759: #ifdef COMPAT_43
                    760:        msg.msg_flags = uap->flags &~ MSG_COMPAT;
                    761: #else
                    762:        msg.msg_flags = uap->flags;
                    763: #endif
                    764:        uiov = msg.msg_iov;
                    765:        msg.msg_iov = iov;
                    766:        if (error = copyin((caddr_t)uiov, (caddr_t)iov,
                    767:            (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
                    768:                goto done;
                    769:        if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {
                    770:                msg.msg_iov = uiov;
                    771:                error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));
                    772:        }
                    773: done:
                    774:        if (iov != aiov)
                    775:                FREE(iov, M_IOV);
                    776:        return (error);
                    777: }
                    778: 
                    779: recvit(p, s, mp, namelenp, retsize)
                    780:        register struct proc *p;
                    781:        int s;
                    782:        register struct msghdr *mp;
                    783:        caddr_t namelenp;
                    784:        int *retsize;
                    785: {
                    786:        struct file *fp;
                    787:        struct uio auio;
                    788:        register struct iovec *iov;
                    789:        register int i;
                    790:        int len, error;
                    791:        struct mbuf *from = 0, *control = 0;
                    792: #ifdef KTRACE
                    793:        struct iovec *ktriov = NULL;
                    794: #endif
                    795:        
                    796:        if (error = getsock(p->p_fd, s, &fp))
                    797:                return (error);
                    798:        auio.uio_iov = mp->msg_iov;
                    799:        auio.uio_iovcnt = mp->msg_iovlen;
                    800:        auio.uio_segflg = UIO_USERSPACE;
                    801:        auio.uio_rw = UIO_READ;
                    802:        auio.uio_procp = p;
                    803:        auio.uio_offset = 0;                    /* XXX */
                    804:        auio.uio_resid = 0;
                    805:        iov = mp->msg_iov;
                    806:        for (i = 0; i < mp->msg_iovlen; i++, iov++) {
                    807:                if (iov->iov_len < 0)
                    808:                        return (EINVAL);
                    809:                if ((auio.uio_resid += iov->iov_len) < 0)
                    810:                        return (EINVAL);
                    811:        }
                    812: #ifdef KTRACE
                    813:        if (KTRPOINT(p, KTR_GENIO)) {
                    814:                int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
                    815: 
                    816:                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                    817:                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                    818:        }
                    819: #endif
                    820:        len = auio.uio_resid;
                    821:        if (error = soreceive((struct socket *)fp->f_data, &from, &auio,
1.1.1.3 ! root      822:            (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0,
        !           823:            &mp->msg_flags)) {
1.1       root      824:                if (auio.uio_resid != len && (error == ERESTART ||
                    825:                    error == EINTR || error == EWOULDBLOCK))
                    826:                        error = 0;
                    827:        }
                    828: #ifdef KTRACE
                    829:        if (ktriov != NULL) {
                    830:                if (error == 0)
                    831:                        ktrgenio(p->p_tracep, s, UIO_READ,
                    832:                                ktriov, len - auio.uio_resid, error);
                    833:                FREE(ktriov, M_TEMP);
                    834:        }
                    835: #endif
                    836:        if (error)
                    837:                goto out;
                    838:        *retsize = len - auio.uio_resid;
                    839:        if (mp->msg_name) {
                    840:                len = mp->msg_namelen;
                    841:                if (len <= 0 || from == 0)
                    842:                        len = 0;
                    843:                else {
                    844: #ifdef COMPAT_43
                    845:                        if (mp->msg_flags & MSG_COMPAT)
                    846:                                mtod(from, struct osockaddr *)->sa_family =
                    847:                                    mtod(from, struct sockaddr *)->sa_family;
                    848: #endif
                    849:                        if (len > from->m_len)
                    850:                                len = from->m_len;
                    851:                        /* else if len < from->m_len ??? */
                    852:                        if (error = copyout(mtod(from, caddr_t),
                    853:                            (caddr_t)mp->msg_name, (unsigned)len))
                    854:                                goto out;
                    855:                }
                    856:                mp->msg_namelen = len;
                    857:                if (namelenp &&
                    858:                    (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
                    859: #ifdef COMPAT_43
                    860:                        if (mp->msg_flags & MSG_COMPAT)
                    861:                                error = 0;      /* old recvfrom didn't check */
                    862:                        else
                    863: #endif
                    864:                        goto out;
                    865:                }
                    866:        }
                    867:        if (mp->msg_control) {
                    868: #ifdef COMPAT_43
                    869:                /*
                    870:                 * We assume that old recvmsg calls won't receive access
                    871:                 * rights and other control info, esp. as control info
                    872:                 * is always optional and those options didn't exist in 4.3.
                    873:                 * If we receive rights, trim the cmsghdr; anything else
                    874:                 * is tossed.
                    875:                 */
                    876:                if (control && mp->msg_flags & MSG_COMPAT) {
                    877:                        if (mtod(control, struct cmsghdr *)->cmsg_level !=
                    878:                            SOL_SOCKET ||
                    879:                            mtod(control, struct cmsghdr *)->cmsg_type !=
                    880:                            SCM_RIGHTS) {
                    881:                                mp->msg_controllen = 0;
                    882:                                goto out;
                    883:                        }
                    884:                        control->m_len -= sizeof (struct cmsghdr);
                    885:                        control->m_data += sizeof (struct cmsghdr);
                    886:                }
                    887: #endif
                    888:                len = mp->msg_controllen;
                    889:                if (len <= 0 || control == 0)
                    890:                        len = 0;
                    891:                else {
                    892:                        if (len >= control->m_len)
                    893:                                len = control->m_len;
                    894:                        else
                    895:                                mp->msg_flags |= MSG_CTRUNC;
                    896:                        error = copyout((caddr_t)mtod(control, caddr_t),
                    897:                            (caddr_t)mp->msg_control, (unsigned)len);
                    898:                }
                    899:                mp->msg_controllen = len;
                    900:        }
                    901: out:
                    902:        if (from)
                    903:                m_freem(from);
                    904:        if (control)
                    905:                m_freem(control);
                    906:        return (error);
                    907: }
                    908: 
1.1.1.3 ! root      909: struct shutdown_args {
        !           910:        int     s;
        !           911:        int     how;
        !           912: };
        !           913: 
1.1       root      914: /* ARGSUSED */
                    915: shutdown(p, uap, retval)
                    916:        struct proc *p;
1.1.1.3 ! root      917:        register struct shutdown_args *uap;
1.1       root      918:        int *retval;
                    919: {
                    920:        struct file *fp;
                    921:        int error;
                    922: 
                    923:        if (error = getsock(p->p_fd, uap->s, &fp))
                    924:                return (error);
                    925:        return (soshutdown((struct socket *)fp->f_data, uap->how));
                    926: }
                    927: 
1.1.1.3 ! root      928: struct setsockopt_args {
        !           929:        int     s;
        !           930:        int     level;
        !           931:        int     name;
        !           932:        caddr_t val;
        !           933:        int     valsize;
        !           934: };
        !           935: 
1.1       root      936: /* ARGSUSED */
                    937: setsockopt(p, uap, retval)
                    938:        struct proc *p;
1.1.1.3 ! root      939:        register struct setsockopt_args *uap;
1.1       root      940:        int *retval;
                    941: {
                    942:        struct file *fp;
                    943:        struct mbuf *m = NULL;
                    944:        int error;
                    945: 
                    946:        if (error = getsock(p->p_fd, uap->s, &fp))
                    947:                return (error);
                    948:        if (uap->valsize > MLEN)
                    949:                return (EINVAL);
                    950:        if (uap->val) {
                    951:                m = m_get(M_WAIT, MT_SOOPTS);
                    952:                if (m == NULL)
                    953:                        return (ENOBUFS);
                    954:                if (error = copyin(uap->val, mtod(m, caddr_t),
                    955:                    (u_int)uap->valsize)) {
                    956:                        (void) m_free(m);
                    957:                        return (error);
                    958:                }
                    959:                m->m_len = uap->valsize;
                    960:        }
                    961:        return (sosetopt((struct socket *)fp->f_data, uap->level,
                    962:            uap->name, m));
                    963: }
                    964: 
1.1.1.3 ! root      965: struct getsockopt_args {
        !           966:        int     s;
        !           967:        int     level;
        !           968:        int     name;
        !           969:        caddr_t val;
        !           970:        int     *avalsize;
        !           971: };
        !           972: 
1.1       root      973: /* ARGSUSED */
                    974: getsockopt(p, uap, retval)
                    975:        struct proc *p;
1.1.1.3 ! root      976:        register struct getsockopt_args *uap;
1.1       root      977:        int *retval;
                    978: {
                    979:        struct file *fp;
                    980:        struct mbuf *m = NULL;
                    981:        int valsize, error;
                    982: 
                    983:        if (error = getsock(p->p_fd, uap->s, &fp))
                    984:                return (error);
                    985:        if (uap->val) {
                    986:                if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
                    987:                    sizeof (valsize)))
                    988:                        return (error);
                    989:        } else
                    990:                valsize = 0;
                    991:        if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
                    992:            uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
                    993:                if (valsize > m->m_len)
                    994:                        valsize = m->m_len;
                    995:                error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
                    996:                if (error == 0)
                    997:                        error = copyout((caddr_t)&valsize,
                    998:                            (caddr_t)uap->avalsize, sizeof (valsize));
                    999:        }
                   1000:        if (m != NULL)
                   1001:                (void) m_free(m);
                   1002:        return (error);
                   1003: }
                   1004: 
                   1005: /* ARGSUSED */
                   1006: pipe(p, uap, retval)
                   1007:        struct proc *p;
                   1008:        struct args *uap;
                   1009:        int retval[];
                   1010: {
                   1011:        register struct filedesc *fdp = p->p_fd;
                   1012:        struct file *rf, *wf;
                   1013:        struct socket *rso, *wso;
                   1014:        int fd, error;
                   1015: 
                   1016:        if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0))
                   1017:                return (error);
                   1018:        if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0))
                   1019:                goto free1;
                   1020:        if (error = falloc(p, &rf, &fd))
                   1021:                goto free2;
                   1022:        retval[0] = fd;
                   1023:        rf->f_flag = FREAD;
                   1024:        rf->f_type = DTYPE_SOCKET;
                   1025:        rf->f_ops = &socketops;
                   1026:        rf->f_data = (caddr_t)rso;
                   1027:        if (error = falloc(p, &wf, &fd))
                   1028:                goto free3;
                   1029:        wf->f_flag = FWRITE;
                   1030:        wf->f_type = DTYPE_SOCKET;
                   1031:        wf->f_ops = &socketops;
                   1032:        wf->f_data = (caddr_t)wso;
                   1033:        retval[1] = fd;
                   1034:        if (error = unp_connect2(wso, rso))
                   1035:                goto free4;
                   1036:        return (0);
                   1037: free4:
                   1038:        ffree(wf);
                   1039:        fdp->fd_ofiles[retval[1]] = 0;
                   1040: free3:
                   1041:        ffree(rf);
                   1042:        fdp->fd_ofiles[retval[0]] = 0;
                   1043: free2:
                   1044:        (void)soclose(wso);
                   1045: free1:
                   1046:        (void)soclose(rso);
                   1047:        return (error);
                   1048: }
                   1049: 
                   1050: /*
                   1051:  * Get socket name.
                   1052:  */
                   1053: #ifdef COMPAT_43
1.1.1.3 ! root     1054: struct getsockname_args {
        !          1055:        int     fdes;
        !          1056:        caddr_t asa;
        !          1057:        int     *alen;
        !          1058:        int     compat_43;
        !          1059: };
        !          1060: 
1.1       root     1061: getsockname(p, uap, retval)
                   1062:        struct proc *p;
1.1.1.3 ! root     1063:        struct getsockname_args *uap;
1.1       root     1064:        int *retval;
                   1065: {
                   1066: 
                   1067:        uap->compat_43 = 0;
                   1068:        return (getsockname1(p, uap, retval));
                   1069: }
                   1070: 
1.1.1.3 ! root     1071: struct ogetsockname_args {
        !          1072:        int     fdes;
        !          1073:        caddr_t asa;
        !          1074:        int     *alen;
        !          1075:        int     compat_43;
        !          1076: };
        !          1077: 
1.1       root     1078: ogetsockname(p, uap, retval)
                   1079:        struct proc *p;
1.1.1.3 ! root     1080:        struct ogetsockname_args *uap;
1.1       root     1081:        int *retval;
                   1082: {
                   1083: 
                   1084:        uap->compat_43 = 1;
                   1085:        return (getsockname1(p, uap, retval));
                   1086: }
                   1087: #else /* COMPAT_43 */
                   1088: 
                   1089: #define        getsockname1    getsockname
                   1090: #endif
                   1091: 
1.1.1.3 ! root     1092: struct getsockname1_args {
        !          1093:        int     fdes;
        !          1094:        caddr_t asa;
        !          1095:        int     *alen;
        !          1096: #ifdef COMPAT_43
        !          1097:        int     compat_43;
        !          1098: #endif
        !          1099: };
        !          1100: 
1.1       root     1101: /* ARGSUSED */
                   1102: getsockname1(p, uap, retval)
                   1103:        struct proc *p;
1.1.1.3 ! root     1104:        register struct getsockname1_args *uap;
1.1       root     1105:        int *retval;
                   1106: {
                   1107:        struct file *fp;
                   1108:        register struct socket *so;
                   1109:        struct mbuf *m;
                   1110:        int len, error;
                   1111: 
                   1112:        if (error = getsock(p->p_fd, uap->fdes, &fp))
                   1113:                return (error);
                   1114:        if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
                   1115:                return (error);
                   1116:        so = (struct socket *)fp->f_data;
                   1117:        m = m_getclr(M_WAIT, MT_SONAME);
                   1118:        if (m == NULL)
                   1119:                return (ENOBUFS);
                   1120:        if (error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0))
                   1121:                goto bad;
                   1122:        if (len > m->m_len)
                   1123:                len = m->m_len;
                   1124: #ifdef COMPAT_43
                   1125:        if (uap->compat_43)
                   1126:                mtod(m, struct osockaddr *)->sa_family =
                   1127:                    mtod(m, struct sockaddr *)->sa_family;
                   1128: #endif
                   1129:        error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
                   1130:        if (error == 0)
                   1131:                error = copyout((caddr_t)&len, (caddr_t)uap->alen,
                   1132:                    sizeof (len));
                   1133: bad:
                   1134:        m_freem(m);
                   1135:        return (error);
                   1136: }
                   1137: 
                   1138: /*
                   1139:  * Get name of peer for connected socket.
                   1140:  */
                   1141: #ifdef COMPAT_43
1.1.1.3 ! root     1142: struct getpeername_args {
        !          1143:        int     fdes;
        !          1144:        caddr_t asa;
        !          1145:        int     *alen;
        !          1146:        int     compat_43;
        !          1147: };
        !          1148: 
1.1       root     1149: getpeername(p, uap, retval)
                   1150:        struct proc *p;
1.1.1.3 ! root     1151:        struct getpeername_args *uap;
1.1       root     1152:        int *retval;
                   1153: {
                   1154: 
                   1155:        uap->compat_43 = 0;
                   1156:        return (getpeername1(p, uap, retval));
                   1157: }
                   1158: 
1.1.1.3 ! root     1159: struct ogetpeername_args {
        !          1160:        int     fdes;
        !          1161:        caddr_t asa;
        !          1162:        int     *alen;
        !          1163:        int     compat_43;
        !          1164: };
        !          1165: 
1.1       root     1166: ogetpeername(p, uap, retval)
                   1167:        struct proc *p;
1.1.1.3 ! root     1168:        struct ogetpeername_args *uap;
1.1       root     1169:        int *retval;
                   1170: {
                   1171: 
                   1172:        uap->compat_43 = 1;
                   1173:        return (getpeername1(p, uap, retval));
                   1174: }
                   1175: #else /* COMPAT_43 */
                   1176: 
                   1177: #define        getpeername1    getpeername
                   1178: #endif
                   1179: 
1.1.1.3 ! root     1180: struct getpeername1_args {
        !          1181:        int     fdes;
        !          1182:        caddr_t asa;
        !          1183:        int     *alen;
        !          1184: #ifdef COMPAT_43
        !          1185:        int     compat_43;
        !          1186: #endif
        !          1187: };
        !          1188: 
1.1       root     1189: /* ARGSUSED */
                   1190: getpeername1(p, uap, retval)
                   1191:        struct proc *p;
1.1.1.3 ! root     1192:        register struct getpeername1_args *uap;
1.1       root     1193:        int *retval;
                   1194: {
                   1195:        struct file *fp;
                   1196:        register struct socket *so;
                   1197:        struct mbuf *m;
                   1198:        int len, error;
                   1199: 
                   1200:        if (error = getsock(p->p_fd, uap->fdes, &fp))
                   1201:                return (error);
                   1202:        so = (struct socket *)fp->f_data;
                   1203:        if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
                   1204:                return (ENOTCONN);
                   1205:        m = m_getclr(M_WAIT, MT_SONAME);
                   1206:        if (m == NULL)
                   1207:                return (ENOBUFS);
                   1208:        if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
                   1209:                return (error);
                   1210:        if (error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0))
                   1211:                goto bad;
                   1212:        if (len > m->m_len)
                   1213:                len = m->m_len;
                   1214: #ifdef COMPAT_43
                   1215:        if (uap->compat_43)
                   1216:                mtod(m, struct osockaddr *)->sa_family =
                   1217:                    mtod(m, struct sockaddr *)->sa_family;
                   1218: #endif
                   1219:        if (error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len))
                   1220:                goto bad;
                   1221:        error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
                   1222: bad:
                   1223:        m_freem(m);
                   1224:        return (error);
                   1225: }
                   1226: 
                   1227: sockargs(mp, buf, buflen, type)
                   1228:        struct mbuf **mp;
                   1229:        caddr_t buf;
                   1230:        int buflen, type;
                   1231: {
                   1232:        register struct mbuf *m;
                   1233:        int error;
                   1234: 
                   1235:        if ((u_int)buflen > MLEN) {
                   1236: #ifdef COMPAT_43
                   1237:                if (type == MT_SONAME && (u_int)buflen <= 112)
                   1238:                        buflen = MLEN;          /* unix domain compat. hack */
                   1239:                else
                   1240: #endif
                   1241:                return (EINVAL);
                   1242:        }
                   1243:        m = m_get(M_WAIT, type);
                   1244:        if (m == NULL)
                   1245:                return (ENOBUFS);
                   1246:        m->m_len = buflen;
                   1247:        error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
1.1.1.2   root     1248:        if (error) {
1.1       root     1249:                (void) m_free(m);
1.1.1.2   root     1250:                return(error);
                   1251:        }
                   1252:        *mp = m;
1.1       root     1253:        if (type == MT_SONAME) {
                   1254:                register struct sockaddr *sa = mtod(m, struct sockaddr *);
                   1255: 
                   1256: #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN
                   1257:                if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
                   1258:                        sa->sa_family = sa->sa_len;
                   1259: #endif
                   1260:                sa->sa_len = buflen;
                   1261:        }
1.1.1.2   root     1262:        return (0);
1.1       root     1263: }
                   1264: 
                   1265: getsock(fdp, fdes, fpp)
                   1266:        struct filedesc *fdp;
                   1267:        int fdes;
                   1268:        struct file **fpp;
                   1269: {
                   1270:        register struct file *fp;
                   1271: 
                   1272:        if ((unsigned)fdes >= fdp->fd_nfiles ||
                   1273:            (fp = fdp->fd_ofiles[fdes]) == NULL)
                   1274:                return (EBADF);
                   1275:        if (fp->f_type != DTYPE_SOCKET)
                   1276:                return (ENOTSOCK);
                   1277:        *fpp = fp;
                   1278:        return (0);
                   1279: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.