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

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1991 The 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:  *     @(#)tp_iso.c    7.11 (Berkeley) 5/6/91
        !            34:  */
        !            35: 
        !            36: /***********************************************************
        !            37:                Copyright IBM Corporation 1987
        !            38: 
        !            39:                       All Rights Reserved
        !            40: 
        !            41: Permission to use, copy, modify, and distribute this software and its 
        !            42: documentation for any purpose and without fee is hereby granted, 
        !            43: provided that the above copyright notice appear in all copies and that
        !            44: both that copyright notice and this permission notice appear in 
        !            45: supporting documentation, and that the name of IBM not be
        !            46: used in advertising or publicity pertaining to distribution of the
        !            47: software without specific, written prior permission.  
        !            48: 
        !            49: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            50: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            51: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            52: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            53: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            54: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            55: SOFTWARE.
        !            56: 
        !            57: ******************************************************************/
        !            58: 
        !            59: /*
        !            60:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
        !            61:  */
        !            62: /* 
        !            63:  * ARGO TP
        !            64:  * $Header: /var/src/sys/netiso/RCS/tp_iso.c,v 5.1 89/02/09 16:20:51 hagens Exp $
        !            65:  * $Source: /var/src/sys/netiso/RCS/tp_iso.c,v $
        !            66:  *
        !            67:  * Here is where you find the iso-dependent code.  We've tried
        !            68:  * keep all net-level and (primarily) address-family-dependent stuff
        !            69:  * out of the tp source, and everthing here is reached indirectly
        !            70:  * through a switch table (struct nl_protosw *) tpcb->tp_nlproto 
        !            71:  * (see tp_pcb.c). 
        !            72:  * The routines here are:
        !            73:  *             iso_getsufx: gets transport suffix out of an isopcb structure.
        !            74:  *             iso_putsufx: put transport suffix into an isopcb structure.
        !            75:  *             iso_putnetaddr: put a whole net addr into an isopcb.
        !            76:  *             iso_getnetaddr: get a whole net addr from an isopcb.
        !            77:  *             iso_cmpnetaddr: compare a whole net addr from an isopcb.
        !            78:  *             iso_recycle_suffix: clear suffix for reuse in isopcb
        !            79:  *             tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff
        !            80:  *             tpclnp_mtu: figure out what size tpdu to use
        !            81:  *             tpclnp_input: take a pkt from clnp, strip off its clnp header, 
        !            82:  *                             give to tp
        !            83:  *             tpclnp_output_dg: package a pkt for clnp given 2 addresses & some data
        !            84:  *             tpclnp_output: package a pkt for clnp given an isopcb & some data
        !            85:  */
        !            86: 
        !            87: #ifdef ISO
        !            88: 
        !            89: #include "param.h"
        !            90: #include "socket.h"
        !            91: #include "socketvar.h"
        !            92: #include "domain.h"
        !            93: #include "malloc.h"
        !            94: #include "mbuf.h"
        !            95: #include "errno.h"
        !            96: #include "time.h"
        !            97: #include "protosw.h"
        !            98: 
        !            99: #include "../net/if.h"
        !           100: #include "../net/route.h"
        !           101: 
        !           102: #include "argo_debug.h"
        !           103: #include "tp_param.h"
        !           104: #include "tp_stat.h"
        !           105: #include "tp_pcb.h"
        !           106: #include "tp_trace.h"
        !           107: #include "tp_stat.h"
        !           108: #include "tp_tpdu.h"
        !           109: #include "tp_clnp.h"
        !           110: #include "cltp_var.h"
        !           111: 
        !           112: /*
        !           113:  * CALLED FROM:
        !           114:  *     pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
        !           115:  * FUNCTION, ARGUMENTS:
        !           116:  *     The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
        !           117:  */
        !           118: 
        !           119: iso_getsufx(isop, lenp, data_out, which)
        !           120:        struct isopcb *isop;
        !           121:        u_short *lenp;
        !           122:        caddr_t data_out;
        !           123:        int which;
        !           124: {
        !           125:        register struct sockaddr_iso *addr = 0;
        !           126: 
        !           127:        switch (which) {
        !           128:        case TP_LOCAL:
        !           129:                addr = isop->isop_laddr;
        !           130:                break;
        !           131: 
        !           132:        case TP_FOREIGN:
        !           133:                addr = isop->isop_faddr;
        !           134:        }
        !           135:        if (addr)
        !           136:                bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
        !           137: }
        !           138: 
        !           139: /* CALLED FROM:
        !           140:  *     tp_newsocket(); i.e., when a connection is being established by an
        !           141:  *     incoming CR_TPDU.
        !           142:  *
        !           143:  * FUNCTION, ARGUMENTS:
        !           144:  *     Put a transport suffix (found in name) into an isopcb structure (isop).
        !           145:  *     The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
        !           146:  */
        !           147: void
        !           148: iso_putsufx(isop, sufxloc, sufxlen, which)
        !           149:        struct isopcb *isop;
        !           150:        caddr_t sufxloc;
        !           151:        int sufxlen, which;
        !           152: {
        !           153:        struct sockaddr_iso **dst, *backup;
        !           154:        register struct sockaddr_iso *addr;
        !           155:        struct mbuf *m;
        !           156:        int len;
        !           157: 
        !           158:        switch (which) {
        !           159:        default:
        !           160:                return;
        !           161: 
        !           162:        case TP_LOCAL:
        !           163:                dst = &isop->isop_laddr;
        !           164:                backup = &isop->isop_sladdr;
        !           165:                break;
        !           166: 
        !           167:        case TP_FOREIGN:
        !           168:                dst = &isop->isop_faddr;
        !           169:                backup = &isop->isop_sfaddr;
        !           170:        }
        !           171:        if ((addr = *dst) == 0) {
        !           172:                addr = *dst = backup;
        !           173:                addr->siso_nlen = 0;
        !           174:                addr->siso_slen = 0;
        !           175:                addr->siso_plen = 0;
        !           176:                printf("iso_putsufx on un-initialized isopcb\n");
        !           177:        }
        !           178:        len = sufxlen + addr->siso_nlen +
        !           179:                        (sizeof(*addr) - sizeof(addr->siso_data));
        !           180:        if (addr == backup) {
        !           181:                if (len > sizeof(*addr)) {
        !           182:                                m = m_getclr(M_DONTWAIT, MT_SONAME);
        !           183:                                if (m == 0)
        !           184:                                        return;
        !           185:                                addr = *dst = mtod(m, struct sockaddr_iso *);
        !           186:                                *addr = *backup;
        !           187:                                m->m_len = len;
        !           188:                }
        !           189:        }
        !           190:        bcopy(sufxloc, TSEL(addr), sufxlen);
        !           191:        addr->siso_tlen = sufxlen;
        !           192:        addr->siso_len = len;
        !           193: }
        !           194: 
        !           195: /*
        !           196:  * CALLED FROM:
        !           197:  *     tp.trans whenever we go into REFWAIT state.
        !           198:  * FUNCTION and ARGUMENT:
        !           199:  *      Called when a ref is frozen, to allow the suffix to be reused. 
        !           200:  *     (isop) is the net level pcb.  This really shouldn't have to be
        !           201:  *     done in a NET level pcb but... for the internet world that just
        !           202:  *     the way it is done in BSD...
        !           203:  *     The alternative is to have the port unusable until the reference
        !           204:  *     timer goes off.
        !           205:  */
        !           206: void
        !           207: iso_recycle_tsuffix(isop)
        !           208:        struct isopcb   *isop;
        !           209: {
        !           210:        isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * CALLED FROM:
        !           215:  *     tp_newsocket(); i.e., when a connection is being established by an
        !           216:  *     incoming CR_TPDU.
        !           217:  *
        !           218:  * FUNCTION and ARGUMENTS:
        !           219:  *     Copy a whole net addr from a struct sockaddr (name).
        !           220:  *     into an isopcb (isop).
        !           221:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN
        !           222:  */ 
        !           223: void
        !           224: iso_putnetaddr(isop, name, which)
        !           225:        register struct isopcb  *isop;
        !           226:        struct sockaddr_iso     *name;
        !           227:        int which;
        !           228: {
        !           229:        struct sockaddr_iso **sisop, *backup;
        !           230:        register struct sockaddr_iso *siso;
        !           231: 
        !           232:        switch (which) {
        !           233:        default:
        !           234:                printf("iso_putnetaddr: should panic\n");
        !           235:                return;
        !           236:        case TP_LOCAL:
        !           237:                sisop = &isop->isop_laddr;
        !           238:                backup = &isop->isop_sladdr;
        !           239:                break;
        !           240:        case TP_FOREIGN:
        !           241:                sisop = &isop->isop_faddr;
        !           242:                backup = &isop->isop_sfaddr;
        !           243:        }
        !           244:        siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
        !           245:        IFDEBUG(D_TPISO)
        !           246:                printf("ISO_PUTNETADDR\n");
        !           247:                dump_isoaddr(isop->isop_faddr);
        !           248:        ENDDEBUG
        !           249:        siso->siso_addr = name->siso_addr;
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * CALLED FROM:
        !           254:  *     tp_input() when a connection is being established by an
        !           255:  *     incoming CR_TPDU, and considered for interception.
        !           256:  *
        !           257:  * FUNCTION and ARGUMENTS:
        !           258:  *     compare a whole net addr from a struct sockaddr (name),
        !           259:  *     with that implicitly stored in an isopcb (isop).
        !           260:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN.
        !           261:  */ 
        !           262: iso_cmpnetaddr(isop, name, which)
        !           263:        register struct isopcb  *isop;
        !           264:        register struct sockaddr_iso    *name;
        !           265:        int which;
        !           266: {
        !           267:        struct sockaddr_iso **sisop, *backup;
        !           268:        register struct sockaddr_iso *siso;
        !           269: 
        !           270:        switch (which) {
        !           271:        default:
        !           272:                printf("iso_cmpnetaddr: should panic\n");
        !           273:                return 0;
        !           274:        case TP_LOCAL:
        !           275:                sisop = &isop->isop_laddr;
        !           276:                backup = &isop->isop_sladdr;
        !           277:                break;
        !           278:        case TP_FOREIGN:
        !           279:                sisop = &isop->isop_faddr;
        !           280:                backup = &isop->isop_sfaddr;
        !           281:        }
        !           282:        siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
        !           283:        IFDEBUG(D_TPISO)
        !           284:                printf("ISO_CMPNETADDR\n");
        !           285:                dump_isoaddr(siso);
        !           286:        ENDDEBUG
        !           287:        if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen))
        !           288:                return (0);
        !           289:        return (bcmp((caddr_t)name->siso_data,
        !           290:                         (caddr_t)siso->siso_data, name->siso_nlen) == 0);
        !           291: }
        !           292: 
        !           293: /*
        !           294:  * CALLED FROM:
        !           295:  *  pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
        !           296:  * FUNCTION and ARGUMENTS:
        !           297:  *     Copy a whole net addr from an isopcb (isop) into
        !           298:  *     a struct sockaddr (name).
        !           299:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN.
        !           300:  */ 
        !           301: 
        !           302: void
        !           303: iso_getnetaddr( isop, name, which)
        !           304:        struct isopcb *isop;
        !           305:        struct mbuf *name;
        !           306:        int which;
        !           307: {
        !           308:        struct sockaddr_iso *siso =
        !           309:                (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
        !           310:        if (siso)
        !           311:                bcopy((caddr_t)siso, mtod(name, caddr_t),
        !           312:                                (unsigned)(name->m_len = siso->siso_len));
        !           313:        else
        !           314:                name->m_len = 0;
        !           315: }
        !           316: 
        !           317: /*
        !           318:  * CALLED FROM:
        !           319:  *  tp_input() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
        !           320:  * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
        !           321:  * Determine the proper maximum transmission unit, i.e., MTU, to use, given
        !           322:  * a) the header size for the network protocol and the max transmission
        !           323:  *       unit on the subnet interface, determined from the information in (isop),
        !           324:  * b) the max size negotiated so far (negot)
        !           325:  * c) the window size used by the tp connection (found in so),
        !           326:  *
        !           327:  * The result is put in the integer *size in its integer form and in
        !           328:  * *negot in its logarithmic form.  
        !           329:  * 
        !           330:  * The rules are:
        !           331:  * a) can only negotiate down from the value found in *negot.
        !           332:  * b) the MTU must be < the windowsize,
        !           333:  * c) If src and dest are on the same net,
        !           334:  *       we will negotiate the closest size larger than  MTU but really USE 
        !           335:  *    the actual device mtu - ll hdr sizes.
        !           336:  *   otherwise we negotiate the closest size smaller than MTU - ll hdr sizes.
        !           337:  */
        !           338: 
        !           339: void
        !           340: tpclnp_mtu(so, isop, size, negot )
        !           341:        struct socket *so;
        !           342:        struct isopcb *isop;
        !           343:        int *size;
        !           344:        u_char *negot;
        !           345: {
        !           346:        struct ifnet *ifp = 0;
        !           347:        struct iso_ifaddr *ia = 0;
        !           348:        register int i;
        !           349:        int windowsize = so->so_rcv.sb_hiwat;
        !           350:        int clnp_size, mtu;
        !           351:        int sizeismtu = 0;
        !           352:        register struct rtentry *rt = isop->isop_route.ro_rt;
        !           353: 
        !           354:        IFDEBUG(D_CONN)
        !           355:                printf("tpclnp_mtu(0x%x,0x%x,0x%x,0x%x)\n", so, isop, size, negot);
        !           356:        ENDDEBUG
        !           357:        IFTRACE(D_CONN)
        !           358:                tptrace(TPPTmisc, "ENTER GET MTU: size negot \n",*size, *negot, 0, 0);
        !           359:        ENDTRACE
        !           360: 
        !           361:        *size = 1 << *negot;
        !           362: 
        !           363:        if( *size > windowsize ) {
        !           364:                *size = windowsize;
        !           365:        }
        !           366: 
        !           367:        if (rt == 0 || (rt->rt_flags & RTF_UP == 0) ||
        !           368:                (ia = (struct iso_ifaddr *)rt->rt_ifa) == 0 ||
        !           369:            (ifp = ia->ia_ifp) == 0) {
        !           370:                IFDEBUG(D_CONN)
        !           371:                        printf("tpclnp_mtu routing abort rt=0x%x ia=0x%x ifp=0x%x\n",
        !           372:                                        rt, ia, ifp)
        !           373:                ENDDEBUG
        !           374:                return;
        !           375:        }
        !           376: 
        !           377: 
        !           378: 
        !           379:        /* TODO - make this indirect off the socket structure to the
        !           380:         * network layer to get headersize
        !           381:         */
        !           382:        clnp_size = sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
        !           383:                        2 * sizeof(struct iso_addr);
        !           384:        mtu = SN_MTU(ifp, rt) - clnp_size;
        !           385:        if(*size > mtu) {
        !           386:                *size = mtu;
        !           387:                sizeismtu = 1;
        !           388:        }
        !           389:        /* have to transform size to the log2 of size */
        !           390:        for(i=TP_MIN_TPDUSIZE; (i<=TP_MAX_TPDUSIZE && ((1<<i) <= *size)) ; i++)
        !           391:                ;
        !           392:        i--;
        !           393: 
        !           394:        IFTRACE(D_CONN)
        !           395:                tptrace(TPPTmisc, "GET MTU MID: tpcb size negot i \n",
        !           396:                *size, *negot, i, 0);
        !           397:        ENDTRACE
        !           398: 
        !           399:        *size = 1<<i;
        !           400:        *negot = i;
        !           401: 
        !           402:        IFDEBUG(D_CONN)
        !           403:                printf("GET MTU RETURNS: ifp %s size 0x%x negot 0x%x\n",
        !           404:                ifp->if_name,   *size, *negot);
        !           405:        ENDDEBUG
        !           406:        IFTRACE(D_CONN)
        !           407:                tptrace(TPPTmisc, "EXIT GET MTU: tpcb size negot \n",
        !           408:                *size, *negot, 0, 0);
        !           409:        ENDTRACE
        !           410: }
        !           411: 
        !           412: 
        !           413: /*
        !           414:  * CALLED FROM:
        !           415:  *  tp_emit()
        !           416:  * FUNCTION and ARGUMENTS:
        !           417:  *  Take a packet(m0) from tp and package it so that clnp will accept it.
        !           418:  *  This means prepending space for the clnp header and filling in a few
        !           419:  *  of the fields.
        !           420:  *  inp is the isopcb structure; datalen is the length of the data in the
        !           421:  *  mbuf string m0.
        !           422:  * RETURN VALUE:
        !           423:  *  whatever (E*) is returned form the net layer output routine.
        !           424:  */
        !           425: 
        !           426: int
        !           427: tpclnp_output(isop, m0, datalen, nochksum)
        !           428:        struct isopcb           *isop;
        !           429:        struct mbuf             *m0;
        !           430:        int                             datalen;
        !           431:        int                                     nochksum;
        !           432: {
        !           433:        register struct mbuf *m = m0;
        !           434:        IncStat(ts_tpdu_sent);
        !           435: 
        !           436:        IFDEBUG(D_TPISO)
        !           437:                struct tpdu *hdr = mtod(m0, struct tpdu *);
        !           438: 
        !           439:                printf(
        !           440: "abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
        !           441:                        datalen,
        !           442:                        (int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum);
        !           443:                dump_isoaddr(isop->isop_faddr);
        !           444:                printf("\nsrc addr:\n");
        !           445:                dump_isoaddr(isop->isop_laddr);
        !           446:                dump_mbuf(m0, "at tpclnp_output");
        !           447:        ENDDEBUG
        !           448: 
        !           449:        return 
        !           450:                clnp_output(m0, isop, datalen,  /* flags */nochksum ? CLNP_NO_CKSUM : 0);
        !           451: }
        !           452: 
        !           453: /*
        !           454:  * CALLED FROM:
        !           455:  *  tp_error_emit()
        !           456:  * FUNCTION and ARGUMENTS:
        !           457:  *  This is a copy of tpclnp_output that takes the addresses
        !           458:  *  instead of a pcb.  It's used by the tp_error_emit, when we
        !           459:  *  don't have an iso_pcb with which to call the normal output rtn.
        !           460:  * RETURN VALUE:
        !           461:  *  ENOBUFS or
        !           462:  *  whatever (E*) is returned form the net layer output routine.
        !           463:  */
        !           464: 
        !           465: int
        !           466: tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
        !           467:        struct iso_addr         *laddr, *faddr;
        !           468:        struct mbuf             *m0;
        !           469:        int                             datalen;
        !           470:        struct route            *ro;
        !           471:        int                                     nochksum;
        !           472: {
        !           473:        struct isopcb           tmppcb;
        !           474:        int                                     err;
        !           475:        int                                     flags;
        !           476:        register struct mbuf *m = m0;
        !           477: 
        !           478:        IFDEBUG(D_TPISO)
        !           479:                printf("tpclnp_output_dg  datalen 0x%x m0 0x%x\n", datalen, m0);
        !           480:        ENDDEBUG
        !           481: 
        !           482:        /*
        !           483:         *      Fill in minimal portion of isopcb so that clnp can send the
        !           484:         *      packet.
        !           485:         */
        !           486:        bzero((caddr_t)&tmppcb, sizeof(tmppcb));
        !           487:        tmppcb.isop_laddr = &tmppcb.isop_sladdr;
        !           488:        tmppcb.isop_laddr->siso_addr = *laddr;
        !           489:        tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
        !           490:        tmppcb.isop_faddr->siso_addr = *faddr;
        !           491: 
        !           492:        IFDEBUG(D_TPISO)
        !           493:                printf("tpclnp_output_dg  faddr: \n");
        !           494:                dump_isoaddr(&tmppcb.isop_sfaddr);
        !           495:                printf("\ntpclnp_output_dg  laddr: \n");
        !           496:                dump_isoaddr(&tmppcb.isop_sladdr);
        !           497:                printf("\n");
        !           498:        ENDDEBUG
        !           499: 
        !           500:        /*
        !           501:         *      Do not use packet cache since this is a one shot error packet
        !           502:         */
        !           503:        flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0));
        !           504: 
        !           505:        IncStat(ts_tpdu_sent);
        !           506: 
        !           507:        err = clnp_output(m0, &tmppcb, datalen,  flags);
        !           508:        
        !           509:        /*
        !           510:         *      Free route allocated by clnp (if the route was indeed allocated)
        !           511:         */
        !           512:        if (tmppcb.isop_route.ro_rt)
        !           513:                RTFREE(tmppcb.isop_route.ro_rt);
        !           514:        
        !           515:        return(err);
        !           516: }
        !           517: /*
        !           518:  * CALLED FROM:
        !           519:  *     clnp's input routine, indirectly through the protosw.
        !           520:  * FUNCTION and ARGUMENTS:
        !           521:  * Take a packet (m) from clnp, strip off the clnp header and give it to tp
        !           522:  * No return value.  
        !           523:  */
        !           524: ProtoHook
        !           525: tpclnp_input(m, src, dst, clnp_len, ce_bit)
        !           526:        register struct mbuf *m;
        !           527:        struct sockaddr_iso *src, *dst;
        !           528:        int clnp_len, ce_bit;
        !           529: {
        !           530:        int s = splnet();
        !           531:        struct mbuf *tp_inputprep();
        !           532:        int tp_input(), cltp_input(), (*input)() = tp_input;
        !           533: 
        !           534:        IncStat(ts_pkt_rcvd);
        !           535: 
        !           536:        IFDEBUG(D_TPINPUT)
        !           537:                printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len);
        !           538:                dump_mbuf(m, "at tpclnp_input");
        !           539:        ENDDEBUG
        !           540:        /*
        !           541:         * CLNP gives us an mbuf chain WITH the clnp header pulled up,
        !           542:         * and the length of the clnp header.
        !           543:         * First, strip off the Clnp header. leave the mbuf there for the
        !           544:         * pullup that follows.
        !           545:         */
        !           546: 
        !           547:        m->m_len -= clnp_len;
        !           548:        m->m_data += clnp_len;
        !           549: 
        !           550:        m = tp_inputprep(m);
        !           551:        if (m == 0)
        !           552:                return 0;
        !           553:        if (mtod(m, u_char *)[1] == UD_TPDU_type)
        !           554:                input = cltp_input;
        !           555: 
        !           556:        IFDEBUG(D_TPINPUT)
        !           557:                dump_mbuf(m, "after tpclnp_input both pullups");
        !           558:        ENDDEBUG
        !           559: 
        !           560:        IFDEBUG(D_TPISO)
        !           561:                printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n", 
        !           562:                        (input == tp_input ? "tp_" : "clts_"), src, dst);
        !           563:                dump_isoaddr(src);
        !           564:                printf(" dst addr:\n");
        !           565:                dump_isoaddr(dst);
        !           566:        ENDDEBUG
        !           567: 
        !           568:        (void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst,
        !           569:                                0, tpclnp_output_dg, ce_bit);
        !           570: 
        !           571:        IFDEBUG(D_QUENCH)
        !           572:                { 
        !           573:                        if(time.tv_usec & 0x4 && time.tv_usec & 0x40) {
        !           574:                                printf("tpclnp_input: FAKING %s\n", 
        !           575:                                        tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2");
        !           576:                                if(tp_stat.ts_pkt_rcvd & 0x1) {
        !           577:                                        tpclnp_ctlinput(PRC_QUENCH, &src);
        !           578:                                } else {
        !           579:                                        tpclnp_ctlinput(PRC_QUENCH2, &src);
        !           580:                                }
        !           581:                        }
        !           582:                }
        !           583:        ENDDEBUG
        !           584: 
        !           585:        splx(s);
        !           586:        return 0;
        !           587: }
        !           588: 
        !           589: ProtoHook
        !           590: iso_rtchange()
        !           591: {
        !           592:        return 0;
        !           593: }
        !           594: 
        !           595: /*
        !           596:  * CALLED FROM:
        !           597:  *  tpclnp_ctlinput()
        !           598:  * FUNCTION and ARGUMENTS:
        !           599:  *  find the tpcb pointer and pass it to tp_quench
        !           600:  */
        !           601: void
        !           602: tpiso_decbit(isop)
        !           603:        struct isopcb *isop;
        !           604: {
        !           605:        tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH2);
        !           606: }
        !           607: /*
        !           608:  * CALLED FROM:
        !           609:  *  tpclnp_ctlinput()
        !           610:  * FUNCTION and ARGUMENTS:
        !           611:  *  find the tpcb pointer and pass it to tp_quench
        !           612:  */
        !           613: void
        !           614: tpiso_quench(isop)
        !           615:        struct isopcb *isop;
        !           616: {
        !           617:        tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH);
        !           618: }
        !           619: 
        !           620: /*
        !           621:  * CALLED FROM:
        !           622:  *  The network layer through the protosw table.
        !           623:  * FUNCTION and ARGUMENTS:
        !           624:  *     When clnp an ICMP-like msg this gets called.
        !           625:  *     It either returns an error status to the user or
        !           626:  *     it causes all connections on this address to be aborted
        !           627:  *     by calling the appropriate xx_notify() routine.
        !           628:  *     (cmd) is the type of ICMP error.   
        !           629:  *     (siso) is the address of the guy who sent the ER CLNPDU
        !           630:  */
        !           631: ProtoHook
        !           632: tpclnp_ctlinput(cmd, siso)
        !           633:        int cmd;
        !           634:        struct sockaddr_iso *siso;
        !           635: {
        !           636:        extern u_char inetctlerrmap[];
        !           637:        extern ProtoHook tpiso_abort();
        !           638:        extern ProtoHook iso_rtchange();
        !           639:        extern ProtoHook tpiso_reset();
        !           640:        void iso_pcbnotify();
        !           641: 
        !           642:        IFDEBUG(D_TPINPUT)
        !           643:                printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
        !           644:                dump_isoaddr(siso);
        !           645:        ENDDEBUG
        !           646: 
        !           647:        if (cmd < 0 || cmd > PRC_NCMDS)
        !           648:                return 0;
        !           649:        if (siso->siso_family != AF_ISO)
        !           650:                return 0;
        !           651:        switch (cmd) {
        !           652: 
        !           653:                case    PRC_QUENCH2:
        !           654:                        iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit);
        !           655:                        break;
        !           656: 
        !           657:                case    PRC_QUENCH:
        !           658:                        iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench);
        !           659:                        break;
        !           660: 
        !           661:                case    PRC_TIMXCEED_REASS:
        !           662:                case    PRC_ROUTEDEAD:
        !           663:                        iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
        !           664:                        break;
        !           665: 
        !           666:                case    PRC_HOSTUNREACH:
        !           667:                case    PRC_UNREACH_NET:
        !           668:                case    PRC_IFDOWN:
        !           669:                case    PRC_HOSTDEAD:
        !           670:                        iso_pcbnotify(&tp_isopcb, siso,
        !           671:                                        (int)inetctlerrmap[cmd], iso_rtchange);
        !           672:                        break;
        !           673: 
        !           674:                default:
        !           675:                /*
        !           676:                case    PRC_MSGSIZE:
        !           677:                case    PRC_UNREACH_HOST:
        !           678:                case    PRC_UNREACH_PROTOCOL:
        !           679:                case    PRC_UNREACH_PORT:
        !           680:                case    PRC_UNREACH_NEEDFRAG:
        !           681:                case    PRC_UNREACH_SRCFAIL:
        !           682:                case    PRC_REDIRECT_NET:
        !           683:                case    PRC_REDIRECT_HOST:
        !           684:                case    PRC_REDIRECT_TOSNET:
        !           685:                case    PRC_REDIRECT_TOSHOST:
        !           686:                case    PRC_TIMXCEED_INTRANS:
        !           687:                case    PRC_PARAMPROB:
        !           688:                */
        !           689:                iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort);
        !           690:                break;
        !           691:        }
        !           692:        return 0;
        !           693: }
        !           694: /*
        !           695:  * XXX - Variant which is called by clnp_er.c with an isoaddr rather
        !           696:  * than a sockaddr_iso.
        !           697:  */
        !           698: 
        !           699: static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};
        !           700: tpclnp_ctlinput1(cmd, isoa)
        !           701:        int cmd;
        !           702:        struct iso_addr *isoa;
        !           703: {
        !           704:        bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr));
        !           705:        bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len);
        !           706:        tpclnp_ctlinput(cmd, &siso);
        !           707: }
        !           708: 
        !           709: /*
        !           710:  * These next 2 routines are
        !           711:  * CALLED FROM:
        !           712:  *     xxx_notify() from tp_ctlinput() when
        !           713:  *  net level gets some ICMP-equiv. type event.
        !           714:  * FUNCTION and ARGUMENTS:
        !           715:  *  Cause the connection to be aborted with some sort of error
        !           716:  *  reason indicating that the network layer caused the abort.
        !           717:  *  Fakes an ER TPDU so we can go through the driver.
        !           718:  *  abort always aborts the TP connection.
        !           719:  *  reset may or may not, depending on the TP class that's in use.
        !           720:  */
        !           721: ProtoHook
        !           722: tpiso_abort(isop)
        !           723:        struct isopcb *isop;
        !           724: {
        !           725:        struct tp_event e;
        !           726: 
        !           727:        IFDEBUG(D_CONN)
        !           728:                printf("tpiso_abort 0x%x\n", isop);
        !           729:        ENDDEBUG
        !           730:        e.ev_number = ER_TPDU;
        !           731:        e.ATTR(ER_TPDU).e_reason = ECONNABORTED;
        !           732:        return  tp_driver((struct tp_pcb *)isop->isop_socket->so_tpcb, &e);
        !           733: }
        !           734: 
        !           735: ProtoHook
        !           736: tpiso_reset(isop)
        !           737:        struct isopcb *isop;
        !           738: {
        !           739:        struct tp_event e;
        !           740: 
        !           741:        e.ev_number = T_NETRESET;
        !           742:        return tp_driver((struct tp_pcb *)isop->isop_socket->so_tpcb, &e);
        !           743: 
        !           744: }
        !           745: 
        !           746: #endif ISO

unix.superglobalmegacorp.com

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