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

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

unix.superglobalmegacorp.com

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