Annotation of Net2/netiso/tp_iso.c, revision 1.1.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.