Annotation of Net2/netiso/cltp_usrreq.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 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:  *     @(#)cltp_usrreq.c       7.6 (Berkeley) 6/27/91
        !            34:  */
        !            35: 
        !            36: #ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
        !            37: #include "param.h"
        !            38: #include "malloc.h"
        !            39: #include "mbuf.h"
        !            40: #include "protosw.h"
        !            41: #include "socket.h"
        !            42: #include "socketvar.h"
        !            43: #include "errno.h"
        !            44: #include "stat.h"
        !            45: 
        !            46: #include "../net/if.h"
        !            47: #include "../net/route.h"
        !            48: 
        !            49: #include "argo_debug.h"
        !            50: #include "iso.h"
        !            51: #include "iso_pcb.h"
        !            52: #include "iso_var.h"
        !            53: #include "clnp.h"
        !            54: #include "cltp_var.h"
        !            55: #endif
        !            56: 
        !            57: /*
        !            58:  * CLTP protocol implementation.
        !            59:  * Per ISO 8602, December, 1987.
        !            60:  */
        !            61: cltp_init()
        !            62: {
        !            63: 
        !            64:        cltb.isop_next = cltb.isop_prev = &cltb;
        !            65: }
        !            66: 
        !            67: int cltp_cksum = 1;
        !            68: 
        !            69: 
        !            70: /* ARGUSED */
        !            71: cltp_input(m0, srcsa, dstsa, cons_channel, output)
        !            72:        struct mbuf *m0;
        !            73:        struct sockaddr *srcsa, *dstsa;
        !            74:        u_int cons_channel;
        !            75:        int (*output)();
        !            76: {
        !            77:        register struct isopcb *isop;
        !            78:        register struct mbuf *m = m0;
        !            79:        register u_char *up = mtod(m, u_char *);
        !            80:        register struct sockaddr_iso *src = (struct sockaddr_iso *)srcsa;
        !            81:        int len, hdrlen = *up + 1, dlen = 0;
        !            82:        u_char *uplim = up + hdrlen;
        !            83:        caddr_t dtsap;
        !            84: 
        !            85:        for (len = 0; m; m = m->m_next)
        !            86:                len += m->m_len;
        !            87:        up += 2; /* skip header */
        !            88:        while (up < uplim) switch (*up) { /* process options */
        !            89:        case CLTPOVAL_SRC:
        !            90:                src->siso_tlen = up[1];
        !            91:                src->siso_len = up[1] + TSEL(src) - (caddr_t)src;
        !            92:                if (src->siso_len < sizeof(*src))
        !            93:                        src->siso_len = sizeof(*src);
        !            94:                else if (src->siso_len > sizeof(*src)) {
        !            95:                        MGET(m, M_DONTWAIT, MT_SONAME);
        !            96:                        if (m == 0)
        !            97:                                goto bad;
        !            98:                        m->m_len = src->siso_len;
        !            99:                        src = mtod(m, struct sockaddr_iso *);
        !           100:                        bcopy((caddr_t)srcsa, (caddr_t)src, srcsa->sa_len);
        !           101:                }
        !           102:                bcopy((caddr_t)up + 2, TSEL(src), up[1]);
        !           103:                up += 2 + src->siso_tlen;
        !           104:                continue;
        !           105:        
        !           106:        case CLTPOVAL_DST:
        !           107:                dtsap = 2 + (caddr_t)up;
        !           108:                dlen = up[1];
        !           109:                up += 2 + dlen;
        !           110:                continue;
        !           111: 
        !           112:        case CLTPOVAL_CSM:
        !           113:                if (iso_check_csum(m0, len)) {
        !           114:                        cltpstat.cltps_badsum++;
        !           115:                        goto bad;
        !           116:                }
        !           117:                up += 4;
        !           118:                continue;
        !           119: 
        !           120:        default:
        !           121:                printf("clts: unknown option (%x)\n", up[0]);
        !           122:                cltpstat.cltps_hdrops++;
        !           123:                goto bad;
        !           124:        }
        !           125:        if (dlen == 0 || src->siso_tlen == 0)
        !           126:                goto bad;
        !           127:        for (isop = cltb.isop_next;; isop = isop->isop_next) {
        !           128:                if (isop == &cltb) {
        !           129:                        cltpstat.cltps_noport++;
        !           130:                        goto bad;
        !           131:                }
        !           132:                if (isop->isop_laddr &&
        !           133:                    bcmp(TSEL(isop->isop_laddr), dtsap, dlen) == 0)
        !           134:                        break;
        !           135:        }
        !           136:        m = m0;
        !           137:        m->m_len -= hdrlen;
        !           138:        m->m_data += hdrlen;
        !           139:        if (sbappendaddr(&isop->isop_socket->so_rcv, (struct sockaddr *)src,
        !           140:            m, (struct mbuf *)0) == 0)
        !           141:                goto bad;
        !           142:        cltpstat.cltps_ipackets++;
        !           143:        sorwakeup(isop->isop_socket);
        !           144:        m0 = 0;
        !           145: bad:
        !           146:        if (src != (struct sockaddr_iso *)srcsa)
        !           147:                m_freem(dtom(src));
        !           148:        if (m0)
        !           149:                m_freem(m0);
        !           150:        return 0;
        !           151: }
        !           152: 
        !           153: /*
        !           154:  * Notify a cltp user of an asynchronous error;
        !           155:  * just wake up so that he can collect error status.
        !           156:  */
        !           157: cltp_notify(isop)
        !           158:        register struct isopcb *isop;
        !           159: {
        !           160: 
        !           161:        sorwakeup(isop->isop_socket);
        !           162:        sowwakeup(isop->isop_socket);
        !           163: }
        !           164: 
        !           165: cltp_ctlinput(cmd, sa)
        !           166:        int cmd;
        !           167:        struct sockaddr *sa;
        !           168: {
        !           169:        extern u_char inetctlerrmap[];
        !           170:        struct sockaddr_iso *siso;
        !           171:        int iso_rtchange();
        !           172: 
        !           173:        if ((unsigned)cmd > PRC_NCMDS)
        !           174:                return;
        !           175:        if (sa->sa_family != AF_ISO && sa->sa_family != AF_CCITT)
        !           176:                return;
        !           177:        siso = (struct sockaddr_iso *)sa;
        !           178:        if (siso == 0 || siso->siso_nlen == 0)
        !           179:                return;
        !           180: 
        !           181:        switch (cmd) {
        !           182:        case PRC_ROUTEDEAD:
        !           183:        case PRC_REDIRECT_NET:
        !           184:        case PRC_REDIRECT_HOST:
        !           185:        case PRC_REDIRECT_TOSNET:
        !           186:        case PRC_REDIRECT_TOSHOST:
        !           187:                iso_pcbnotify(&cltb, siso,
        !           188:                                (int)inetctlerrmap[cmd], iso_rtchange);
        !           189:                break;
        !           190: 
        !           191:        default:
        !           192:                if (inetctlerrmap[cmd] == 0)
        !           193:                        return;         /* XXX */
        !           194:                iso_pcbnotify(&cltb, siso, (int)inetctlerrmap[cmd],
        !           195:                        cltp_notify);
        !           196:        }
        !           197: }
        !           198: 
        !           199: cltp_output(isop, m)
        !           200:        register struct isopcb *isop;
        !           201:        register struct mbuf *m;
        !           202: {
        !           203:        register int len;
        !           204:        register struct sockaddr_iso *siso;
        !           205:        int hdrlen, error = 0, docsum;
        !           206:        register u_char *up;
        !           207: 
        !           208:        if (isop->isop_laddr == 0 || isop->isop_faddr == 0) {
        !           209:                error = ENOTCONN;
        !           210:                goto bad;
        !           211:        }
        !           212:        /*
        !           213:         * Calculate data length and get a mbuf for CLTP header.
        !           214:         */
        !           215:        hdrlen = 2 + 2 + isop->isop_laddr->siso_tlen
        !           216:                   + 2 + isop->isop_faddr->siso_tlen;
        !           217:        if (docsum = /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum)
        !           218:                hdrlen += 4;
        !           219:        M_PREPEND(m, hdrlen, M_WAIT);
        !           220:        len = m->m_pkthdr.len;
        !           221:        /*
        !           222:         * Fill in mbuf with extended CLTP header
        !           223:         */
        !           224:        up = mtod(m, u_char *);
        !           225:        up[0] = hdrlen - 1;
        !           226:        up[1] = UD_TPDU_type;
        !           227:        up[2] = CLTPOVAL_SRC;
        !           228:        up[3] = (siso = isop->isop_laddr)->siso_tlen;
        !           229:        up += 4;
        !           230:        bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
        !           231:        up += siso->siso_tlen;
        !           232:        up[0] = CLTPOVAL_DST;
        !           233:        up[1] = (siso = isop->isop_faddr)->siso_tlen;
        !           234:        up += 2;
        !           235:        bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
        !           236:        /*
        !           237:         * Stuff checksum and output datagram.
        !           238:         */
        !           239:        if (docsum) {
        !           240:                up += siso->siso_tlen;
        !           241:                up[0] = CLTPOVAL_CSM;
        !           242:                up[1] = 2;
        !           243:                iso_gen_csum(m, 2 + up - mtod(m, u_char *), len);
        !           244:        }
        !           245:        cltpstat.cltps_opackets++;
        !           246:        return (tpclnp_output(isop, m, len, !docsum));
        !           247: bad:
        !           248:        m_freem(m);
        !           249:        return (error);
        !           250: }
        !           251: 
        !           252: #ifndef TP_LOCAL
        !           253: /* XXXX should go in iso.h maybe? from tp_param.h, in any case */
        !           254: #define                TP_LOCAL                                22
        !           255: #define                TP_FOREIGN                              33
        !           256: #endif
        !           257: 
        !           258: u_long cltp_sendspace = 9216;          /* really max datagram size */
        !           259: u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso));
        !           260:                                        /* 40 1K datagrams */
        !           261: 
        !           262: 
        !           263: /*ARGSUSED*/
        !           264: cltp_usrreq(so, req, m, nam, control)
        !           265:        struct socket *so;
        !           266:        int req;
        !           267:        struct mbuf *m, *nam, *control;
        !           268: {
        !           269:        struct isopcb *isop = sotoisopcb(so);
        !           270:        int s, error = 0;
        !           271: 
        !           272:        if (req == PRU_CONTROL)
        !           273:                return (iso_control(so, (int)m, (caddr_t)nam,
        !           274:                        (struct ifnet *)control));
        !           275:        if ((isop == NULL && req != PRU_ATTACH) ||
        !           276:            (control && control->m_len)) {
        !           277:                error = EINVAL;
        !           278:                goto release;
        !           279:        }
        !           280:        switch (req) {
        !           281: 
        !           282:        case PRU_ATTACH:
        !           283:                if (isop != NULL) {
        !           284:                        error = EINVAL;
        !           285:                        break;
        !           286:                }
        !           287:                error = iso_pcballoc(so, &cltb);
        !           288:                if (error)
        !           289:                        break;
        !           290:                error = soreserve(so, cltp_sendspace, cltp_recvspace);
        !           291:                if (error)
        !           292:                        break;
        !           293:                break;
        !           294: 
        !           295:        case PRU_DETACH:
        !           296:                iso_pcbdetach(isop);
        !           297:                break;
        !           298: 
        !           299:        case PRU_BIND:
        !           300:                error = iso_pcbbind(isop, nam);
        !           301:                break;
        !           302: 
        !           303:        case PRU_LISTEN:
        !           304:                error = EOPNOTSUPP;
        !           305:                break;
        !           306: 
        !           307:        case PRU_CONNECT:
        !           308:                if (isop->isop_faddr) {
        !           309:                        error = EISCONN;
        !           310:                        break;
        !           311:                }
        !           312:                error = iso_pcbconnect(isop, nam);
        !           313:                if (error == 0)
        !           314:                        soisconnected(so);
        !           315:                break;
        !           316: 
        !           317:        case PRU_CONNECT2:
        !           318:                error = EOPNOTSUPP;
        !           319:                break;
        !           320: 
        !           321:        case PRU_ACCEPT:
        !           322:                error = EOPNOTSUPP;
        !           323:                break;
        !           324: 
        !           325:        case PRU_DISCONNECT:
        !           326:                if (isop->isop_faddr == 0) {
        !           327:                        error = ENOTCONN;
        !           328:                        break;
        !           329:                }
        !           330:                iso_pcbdisconnect(isop);
        !           331:                so->so_state &= ~SS_ISCONNECTED;                /* XXX */
        !           332:                break;
        !           333: 
        !           334:        case PRU_SHUTDOWN:
        !           335:                socantsendmore(so);
        !           336:                break;
        !           337: 
        !           338:        case PRU_SEND:
        !           339:                if (nam) {
        !           340:                        if (isop->isop_faddr) {
        !           341:                                error = EISCONN;
        !           342:                                break;
        !           343:                        }
        !           344:                        /*
        !           345:                         * Must block input while temporarily connected.
        !           346:                         */
        !           347:                        s = splnet();
        !           348:                        error = iso_pcbconnect(isop, nam);
        !           349:                        if (error) {
        !           350:                                splx(s);
        !           351:                                break;
        !           352:                        }
        !           353:                } else {
        !           354:                        if (isop->isop_faddr == 0) {
        !           355:                                error = ENOTCONN;
        !           356:                                break;
        !           357:                        }
        !           358:                }
        !           359:                error = cltp_output(isop, m);
        !           360:                m = 0;
        !           361:                if (nam) {
        !           362:                        iso_pcbdisconnect(isop);
        !           363:                        splx(s);
        !           364:                }
        !           365:                break;
        !           366: 
        !           367:        case PRU_ABORT:
        !           368:                soisdisconnected(so);
        !           369:                iso_pcbdetach(isop);
        !           370:                break;
        !           371: 
        !           372:        case PRU_SOCKADDR:
        !           373:                iso_getnetaddr(isop, nam, TP_LOCAL);
        !           374:                break;
        !           375: 
        !           376:        case PRU_PEERADDR:
        !           377:                iso_getnetaddr(isop, nam, TP_FOREIGN);
        !           378:                break;
        !           379: 
        !           380:        case PRU_SENSE:
        !           381:                /*
        !           382:                 * stat: don't bother with a blocksize.
        !           383:                 */
        !           384:                return (0);
        !           385: 
        !           386:        case PRU_SENDOOB:
        !           387:        case PRU_FASTTIMO:
        !           388:        case PRU_SLOWTIMO:
        !           389:        case PRU_PROTORCV:
        !           390:        case PRU_PROTOSEND:
        !           391:                error =  EOPNOTSUPP;
        !           392:                break;
        !           393: 
        !           394:        case PRU_RCVD:
        !           395:        case PRU_RCVOOB:
        !           396:                return (EOPNOTSUPP);    /* do not free mbuf's */
        !           397: 
        !           398:        default:
        !           399:                panic("cltp_usrreq");
        !           400:        }
        !           401: release:
        !           402:        if (control != NULL)
        !           403:                m_freem(control);
        !           404:        if (m != NULL)
        !           405:                m_freem(m);
        !           406:        return (error);
        !           407: }

unix.superglobalmegacorp.com

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