Annotation of 43BSDReno/sys/netiso/tp_iso.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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