Annotation of kernel/bsd/netiso/tp_iso.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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