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

unix.superglobalmegacorp.com

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