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

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

unix.superglobalmegacorp.com

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