Annotation of kernel/bsd/netiso/if_cons.c, revision 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:  *     @(#)if_cons.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:  * cons.c - Connection Oriented Network Service:
        !            88:  * including support for a) user transport-level service, 
        !            89:  *     b) COSNS below CLNP, and c) CONS below TP.
        !            90:  */
        !            91: 
        !            92: #if TPCONS
        !            93: #ifdef _KERNEL
        !            94: #ifdef ARGO_DEBUG
        !            95: #define Static  
        !            96: unsigned LAST_CALL_PCB;
        !            97: #else /* ARGO_DEBUG */
        !            98: #define Static static
        !            99: #endif /* ARGO_DEBUG */
        !           100: 
        !           101: #ifndef SOCK_STREAM
        !           102: #include <sys/param.h>
        !           103: #include <sys/systm.h>
        !           104: #include <sys/mbuf.h>
        !           105: #include <sys/protosw.h>
        !           106: #include <sys/socket.h>
        !           107: #include <sys/socketvar.h>
        !           108: #include <sys/errno.h>
        !           109: #include <sys/ioctl.h>
        !           110: #include <sys/tsleep.h>
        !           111: 
        !           112: #include <net/if.h>
        !           113: #include <net/netisr.h>
        !           114: #include <net/route.h>
        !           115: 
        !           116: #include <netiso/iso_errno.h>
        !           117: #include <netiso/argo_debug.h>
        !           118: #include <netiso/tp_trace.h>
        !           119: #include <netiso/iso.h>
        !           120: #include <netiso/cons.h>
        !           121: #include <netiso/iso_pcb.h>
        !           122: 
        !           123: #include <netccitt/x25.h>
        !           124: #include <netccitt/pk.h>
        !           125: #include <netccitt/pk_var.h>
        !           126: #endif
        !           127: 
        !           128: #ifdef ARGO_DEBUG
        !           129: #define MT_XCONN       0x50
        !           130: #define MT_XCLOSE      0x51
        !           131: #define MT_XCONFIRM    0x52
        !           132: #define MT_XDATA       0x53
        !           133: #define MT_XHEADER     0x54
        !           134: #else
        !           135: #define MT_XCONN       MT_DATA
        !           136: #define MT_XCLOSE      MT_DATA
        !           137: #define MT_XCONFIRM    MT_DATA
        !           138: #define MT_XDATA       MT_DATA
        !           139: #define MT_XHEADER     MT_HEADER
        !           140: #endif /* ARGO_DEBUG */
        !           141: 
        !           142: #define DONTCLEAR       -1
        !           143: 
        !           144: /********************************************************************* 
        !           145:  * cons.c - CONS interface to the x.25 layer
        !           146:  *
        !           147:  * TODO: figure out what resources we might run out of besides mbufs.
        !           148:  *  If we run out of any of them (including mbufs) close and recycle
        !           149:  *  lru x% of the connections, for some parameter x.
        !           150:  *
        !           151:  * There are 2 interfaces from above:
        !           152:  * 1) from TP0: 
        !           153:  *    cons CO network service
        !           154:  *    TP associates a transport connection with a network connection.
        !           155:  *       cons_output( isop, m, len, isdgm==0 ) 
        !           156:  *        co_flags == 0
        !           157:  * 2) from TP4:
        !           158:  *       It's a datagram service, like clnp is. - even though it calls
        !           159:  *                     cons_output( isop, m, len, isdgm==1 ) 
        !           160:  *       it eventually goes through
        !           161:  *                     cosns_output(ifp, m, dst).
        !           162:  *    TP4 permits multiplexing (reuse, possibly simultaneously) of the 
        !           163:  *       network connections.
        !           164:  *    This means that many sockets (many tpcbs) may be associated with
        !           165:  *    this pklcd, hence cannot have a back ptr from pklcd to a tpcb.
        !           166:  *        co_flags & CONSF_DGM 
        !           167:  *    co_socket is null since there may be many sockets that use this pklcd.
        !           168:  *
        !           169: NOTE:
        !           170:        streams would really be nice. sigh.
        !           171: NOTE:
        !           172:        PVCs could be handled by config-ing a cons with an address and with the
        !           173:        IFF_POINTTOPOINT flag on.  This code would then have to skip the
        !           174:        connection setup stuff for pt-to-pt links.  
        !           175: 
        !           176: 
        !           177:  *********************************************************************/
        !           178: 
        !           179: 
        !           180: #define CONS_IFQMAXLEN 5
        !           181: 
        !           182: 
        !           183: /* protosw pointers for getting to higher layer */
        !           184: Static         struct protosw  *CLNP_proto;
        !           185: Static         struct protosw  *TP_proto;
        !           186: Static         struct protosw  *X25_proto;
        !           187: Static         int                             issue_clear_req();
        !           188: 
        !           189: #ifndef        PHASEONE
        !           190: extern struct ifaddr   *ifa_ifwithnet();
        !           191: #endif /* PHASEONE */
        !           192: 
        !           193: extern struct ifaddr   *ifa_ifwithaddr();
        !           194: 
        !           195: extern struct  isopcb  tp_isopcb; /* chain of all TP pcbs */
        !           196: 
        !           197: 
        !           198: Static         int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
        !           199: Static int FACILtoNSAP(), DTEtoNSAP();
        !           200: Static struct pklcd *cons_chan_to_pcb();
        !           201: 
        !           202: #define HIGH_NIBBLE 1
        !           203: #define LOW_NIBBLE 0
        !           204: 
        !           205: /*
        !           206:  * NAME:       nibble_copy()
        !           207:  * FUNCTION and ARGUMENTS:
        !           208:  *     copies (len) nibbles from (src_octet), high or low nibble
        !           209:  *  to (dst_octet), high or low nibble,
        !           210:  * src_nibble & dst_nibble should be:
        !           211:  *     HIGH_NIBBLE (1) if leftmost 4 bits/ most significant nibble
        !           212:  *     LOW_NIBBLE (0) if rightmost 4 bits/ least significant nibble
        !           213:  * RETURNS: VOID
        !           214:  */
        !           215: void
        !           216: nibble_copy(src_octet, src_nibble, dst_octet, dst_nibble, len)
        !           217:        register char   *src_octet;
        !           218:        register char   *dst_octet;
        !           219:        register unsigned               src_nibble;
        !           220:        register unsigned               dst_nibble;
        !           221:        int             len;
        !           222: {
        !           223: 
        !           224:        register        i;
        !           225:        register        unsigned dshift, sshift;
        !           226: 
        !           227:        IFDEBUG(D_CADDR)
        !           228:                printf("nibble_copy ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n", 
        !           229:                 src_octet, src_nibble, dst_octet, dst_nibble, len);
        !           230:        ENDDEBUG
        !           231: #define SHIFT 0x4
        !           232: 
        !           233:        dshift = dst_nibble << 2;
        !           234:        sshift = src_nibble << 2;
        !           235: 
        !           236:        for (i=0; i<len; i++) {
        !           237:                /* clear dst_nibble  */
        !           238:                *dst_octet      &= ~(0xf<< dshift);
        !           239: 
        !           240:                /* set dst nibble */
        !           241:                *dst_octet      |= ( 0xf & (*src_octet >> sshift))<< dshift;
        !           242: 
        !           243:                dshift          ^= SHIFT;
        !           244:                sshift          ^= SHIFT;
        !           245:                src_nibble      = 1-src_nibble;
        !           246:                dst_nibble      = 1-dst_nibble;
        !           247:                src_octet       += src_nibble;
        !           248:                dst_octet       += dst_nibble;
        !           249:        }
        !           250:        IFDEBUG(D_CADDR)
        !           251:                printf("nibble_copy DONE\n");
        !           252:        ENDDEBUG
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * NAME:       nibble_match()
        !           257:  * FUNCTION and ARGUMENTS:
        !           258:  *     compares src_octet/src_nibble and dst_octet/dst_nibble  for len nibbles.
        !           259:  * RETURNS: 0 if they differ, 1 if they are the same.
        !           260:  */
        !           261: int
        !           262: nibble_match( src_octet, src_nibble, dst_octet, dst_nibble, len)
        !           263:        register char   *src_octet;
        !           264:        register char   *dst_octet;
        !           265:        register unsigned               src_nibble;
        !           266:        register unsigned               dst_nibble;
        !           267:        int             len;
        !           268: {
        !           269: 
        !           270:        register        i;
        !           271:        register        unsigned dshift, sshift;
        !           272:        u_char          nibble_a, nibble_b;
        !           273: 
        !           274:        IFDEBUG(D_CADDR)
        !           275:                printf("nibble_match ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n", 
        !           276:                 src_octet, src_nibble, dst_octet, dst_nibble, len);
        !           277:        ENDDEBUG
        !           278: #define SHIFT 0x4
        !           279: 
        !           280:        dshift = dst_nibble << 2;
        !           281:        sshift = src_nibble << 2;
        !           282: 
        !           283:        for (i=0; i<len; i++) {
        !           284:                nibble_b = ((*dst_octet)>>dshift) & 0xf;
        !           285:                nibble_a = ( 0xf & (*src_octet >> sshift));
        !           286:                if (nibble_b != nibble_a)
        !           287:                        return 0;
        !           288: 
        !           289:                dshift          ^= SHIFT;
        !           290:                sshift          ^= SHIFT;
        !           291:                src_nibble      = 1-src_nibble;
        !           292:                dst_nibble      = 1-dst_nibble;
        !           293:                src_octet       += src_nibble;
        !           294:                dst_octet       += dst_nibble;
        !           295:        }
        !           296:        IFDEBUG(D_CADDR)
        !           297:                printf("nibble_match DONE\n");
        !           298:        ENDDEBUG
        !           299:        return 1;
        !           300: }
        !           301: 
        !           302: /*
        !           303:  **************************** NET PROTOCOL cons ***************************
        !           304:  */
        !           305: /*
        !           306:  * NAME:       cons_init()
        !           307:  * CALLED FROM:
        !           308:  *     autoconf
        !           309:  * FUNCTION:
        !           310:  *     initialize the protocol
        !           311:  */
        !           312: cons_init()
        !           313: {
        !           314:        int tp_incoming(), clnp_incoming();
        !           315: 
        !           316: 
        !           317:        CLNP_proto = pffindproto(AF_ISO, ISOPROTO_CLNP, SOCK_DGRAM); 
        !           318:        X25_proto = pffindproto(AF_ISO, ISOPROTO_X25, SOCK_STREAM);
        !           319:        TP_proto = pffindproto(AF_ISO, ISOPROTO_TP0, SOCK_SEQPACKET);
        !           320:        IFDEBUG(D_CCONS)
        !           321:                printf("cons_init end : cnlp_proto 0x%x cons proto 0x%x tp proto 0x%x\n",
        !           322:                        CLNP_proto, X25_proto, TP_proto);
        !           323:        ENDDEBUG
        !           324: #ifdef notdef
        !           325:        pk_protolisten(0x81, 0, clnp_incoming);
        !           326:        pk_protolisten(0x82, 0, esis_incoming);
        !           327:        pk_protolisten(0x84, 0, tp8878_A_incoming);
        !           328:        pk_protolisten(0, 0, tp_incoming);
        !           329: #endif
        !           330: }
        !           331: 
        !           332: tp_incoming(lcp, m)
        !           333: struct pklcd *lcp;
        !           334: register struct mbuf *m;
        !           335: {
        !           336:        register struct isopcb *isop;
        !           337:        int cons_tpinput();
        !           338: 
        !           339:        if (iso_pcballoc((struct socket *)0, &tp_isopcb)) {
        !           340:                pk_close(lcp);
        !           341:                return;
        !           342:        }
        !           343:        isop = tp_isopcb.isop_next;
        !           344:        lcp->lcd_upper = cons_tpinput;
        !           345:        lcp->lcd_upnext = (caddr_t)isop;
        !           346:        lcp->lcd_send(lcp); /* Confirms call */
        !           347:        isop->isop_chan = (caddr_t)lcp;
        !           348:        isop->isop_laddr = &isop->isop_sladdr;
        !           349:        isop->isop_faddr = &isop->isop_sfaddr;
        !           350:        DTEtoNSAP(isop->isop_laddr, &lcp->lcd_laddr);
        !           351:        DTEtoNSAP(isop->isop_faddr, &lcp->lcd_faddr);
        !           352:        parse_facil(lcp, isop, &(mtod(m, struct x25_packet *)->packet_data),
        !           353:                m->m_pkthdr.len - PKHEADERLN);
        !           354: }
        !           355: 
        !           356: cons_tpinput(lcp, m0)
        !           357: struct mbuf *m0;
        !           358: struct pklcd *lcp;
        !           359: {
        !           360:        register struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
        !           361:        register struct x25_packet *xp;
        !           362:        int cmd, ptype = CLEAR;
        !           363: 
        !           364:        if (isop == 0)
        !           365:                return;
        !           366:        if (m0 == 0)
        !           367:                goto dead;
        !           368:        switch(m0->m_type) {
        !           369:        case MT_DATA:
        !           370:        case MT_OOBDATA:
        !           371:                tpcons_input(m0, isop->isop_faddr, isop->isop_laddr, (caddr_t)lcp);
        !           372:                return;
        !           373: 
        !           374:        case MT_CONTROL:
        !           375:                switch (ptype = pk_decode(mtod(m0, struct x25_packet *))) {
        !           376: 
        !           377:                case RR:
        !           378:                        cmd = PRC_CONS_SEND_DONE;
        !           379:                        break;
        !           380: 
        !           381:                case CALL_ACCEPTED:
        !           382:                        if (lcp->lcd_sb.sb_mb)
        !           383:                                lcp->lcd_send(lcp); /* XXX - fix this */
        !           384:                        /*FALLTHROUGH*/
        !           385:                default:
        !           386:                        return;
        !           387: 
        !           388:                dead:
        !           389:                case CLEAR:
        !           390:                case CLEAR_CONF:
        !           391:                        lcp->lcd_upper = 0;
        !           392:                        lcp->lcd_upnext = 0;
        !           393:                        isop->isop_chan = 0;
        !           394:                case RESET:
        !           395:                        cmd = PRC_ROUTEDEAD;
        !           396:                }
        !           397:                tpcons_ctlinput(cmd, isop->isop_faddr, isop);
        !           398:                if (cmd = PRC_ROUTEDEAD && isop->isop_refcnt == 0) 
        !           399:                        iso_pcbdetach(isop);
        !           400:        }
        !           401: }
        !           402: 
        !           403: /*
        !           404:  * NAME:       cons_connect()
        !           405:  * CALLED FROM:
        !           406:  *     tpcons_pcbconnect() when opening a new connection.  
        !           407:  * FUNCTION anD ARGUMENTS:
        !           408:  *  Figures out which device to use, finding a route if one doesn't
        !           409:  *  already exist.
        !           410:  * RETURN VALUE:
        !           411:  *  returns E*
        !           412:  */
        !           413: cons_connect(isop)
        !           414:        register struct isopcb *isop;
        !           415: {
        !           416:        register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
        !           417:        register struct mbuf    *m;
        !           418:        struct ifaddr                   *ifa;
        !           419:        int error;
        !           420: 
        !           421:        IFDEBUG(D_CCONN)
        !           422:                printf("cons_connect(0x%x): ", isop);
        !           423:                dump_isoaddr(isop->isop_faddr);
        !           424:                printf("myaddr: ");
        !           425:                dump_isoaddr(isop->isop_laddr);
        !           426:                printf("\n" );
        !           427:        ENDDEBUG
        !           428:        NSAPtoDTE(isop->isop_faddr, &lcp->lcd_faddr);
        !           429:        lcp->lcd_upper = cons_tpinput;
        !           430:        lcp->lcd_upnext = (caddr_t)isop;
        !           431:        IFDEBUG(D_CCONN)
        !           432:                printf(
        !           433:                "calling make_partial_x25_packet( 0x%x, 0x%x, 0x%x)\n",
        !           434:                        &lcp->lcd_faddr, &lcp->lcd_laddr, 
        !           435:                        isop->isop_socket->so_proto->pr_protocol); 
        !           436:        ENDDEBUG
        !           437:        if ((error = make_partial_x25_packet(isop, lcp, m)) == 0)
        !           438:                error = pk_connect(lcp, &lcp->lcd_faddr);
        !           439:        return error;
        !           440: }
        !           441: 
        !           442: /*
        !           443:  **************************** DEVICE cons ***************************
        !           444:  */
        !           445: 
        !           446: 
        !           447: /* 
        !           448:  * NAME:       cons_ctlinput()
        !           449:  * CALLED FROM:
        !           450:  *  lower layer when ECN_CLEAR occurs : this routine is here
        !           451:  *  for consistency - cons subnet service calls its higher layer
        !           452:  *  through the protosw entry.
        !           453:  * FUNCTION & ARGUMENTS:
        !           454:  *  cmd is a PRC_* command, list found in ../sys/protosw.h
        !           455:  *  copcb is the obvious.
        !           456:  *  This serves the higher-layer cons service.
        !           457:  * NOTE: this takes 3rd arg. because cons uses it to inform itself
        !           458:  *  of things (timeouts, etc) but has a pcb instead of an address.
        !           459:  */
        !           460: cons_ctlinput(cmd, sa, copcb)
        !           461:        int cmd;
        !           462:        struct sockaddr *sa;
        !           463:        register struct pklcd *copcb;
        !           464: {
        !           465: }
        !           466: 
        !           467: 
        !           468: find_error_reason( xp )
        !           469:        register struct x25_packet *xp;
        !           470: {
        !           471:        extern u_char x25_error_stats[];
        !           472:        int error, cause;
        !           473: 
        !           474:        if (xp) {
        !           475:                cause = 4[(char *)xp];
        !           476:                switch (cause) {
        !           477:                        case 0x00:
        !           478:                        case 0x80:
        !           479:                                /* DTE originated; look at the diagnostic */
        !           480:                                error = (CONL_ERROR_MASK | cause);
        !           481:                                goto done;
        !           482: 
        !           483:                        case 0x01: /* number busy */
        !           484:                        case 0x81:
        !           485:                        case 0x09: /* Out of order */
        !           486:                        case 0x89:
        !           487:                        case 0x11: /* Remot Procedure Error */
        !           488:                        case 0x91:
        !           489:                        case 0x19: /* reverse charging accept not subscribed */
        !           490:                        case 0x99:
        !           491:                        case 0x21: /* Incampat destination */
        !           492:                        case 0xa1:
        !           493:                        case 0x29: /* fast select accept not subscribed */
        !           494:                        case 0xa9:
        !           495:                        case 0x39: /* ship absent */
        !           496:                        case 0xb9:
        !           497:                        case 0x03: /* invalid facil request */
        !           498:                        case 0x83:
        !           499:                        case 0x0b: /* access barred */
        !           500:                        case 0x8b:
        !           501:                        case 0x13: /* local procedure error */
        !           502:                        case 0x93:
        !           503:                        case 0x05: /* network congestion */
        !           504:                        case 0x85:
        !           505:                        case 0x8d: /* not obtainable */
        !           506:                        case 0x0d:
        !           507:                        case 0x95: /* RPOA out of order */
        !           508:                        case 0x15:
        !           509:                                /* take out bit 8 
        !           510:                                 * so we don't have to have so many perror entries 
        !           511:                                 */
        !           512:                                error = (CONL_ERROR_MASK | 0x100 | (cause & ~0x80));
        !           513:                                goto done;
        !           514: 
        !           515:                        case 0xc1: /* gateway-detected proc error */
        !           516:                        case 0xc3: /* gateway congestion */
        !           517: 
        !           518:                                error = (CONL_ERROR_MASK | 0x100 | cause);
        !           519:                                goto done;
        !           520:                } 
        !           521:        } 
        !           522:        /* otherwise, a *hopefully* valid perror exists in the e_reason field */
        !           523:        error = xp->packet_data;
        !           524:        if (error = 0) {
        !           525:                printf("Incoming PKT TYPE 0x%x with reason 0x%x\n",
        !           526:                        pk_decode(xp),
        !           527:                        cause);
        !           528:                error = E_CO_HLI_DISCA;
        !           529:        } 
        !           530: 
        !           531: done:
        !           532:        return error;
        !           533: }
        !           534: 
        !           535: 
        !           536: 
        !           537: #endif /* KERNEL */
        !           538: 
        !           539: /*
        !           540:  * NAME:       make_partial_x25_packet()
        !           541:  *
        !           542:  * FUNCTION and ARGUMENTS:
        !           543:  *     Makes part of an X.25 call packet, for use by x25.
        !           544:  *  (src) and (dst) are the NSAP-addresses of source and destination.
        !           545:  *     (buf) is a ptr to a buffer into which to write this partial header.
        !           546:  *
        !           547:  *      0                      Facility length (in octets)
        !           548:  *      1                      Facility field, which is a set of:
        !           549:  *       m                     facil code
        !           550:  *       m+1           facil param len (for >2-byte facilities) in octets
        !           551:  *       m+2..p        facil param field
        !           552:  *  q                  user data (protocol identification octet)
        !           553:  * 
        !           554:  *
        !           555:  * RETURNS: 
        !           556:  *  0 if OK
        !           557:  *  E* if failed.
        !           558:  *
        !           559:  * SIDE EFFECTS:
        !           560:  * Stores facilites mbuf in X.25 control block, where the connect
        !           561:  * routine knows where to look for it.
        !           562:  */
        !           563: 
        !           564: #ifdef X25_1984 
        !           565: int cons_use_facils = 1;
        !           566: #else /* X25_1984  */
        !           567: int cons_use_facils = 0;
        !           568: #endif /* X25_1984  */
        !           569: 
        !           570: int cons_use_udata = 1; /* KLUDGE FOR DEBUGGING */
        !           571: 
        !           572: Static int
        !           573: make_partial_x25_packet(isop, lcp)
        !           574:        struct isopcb *isop;
        !           575:        struct pklcd *lcp;
        !           576: {
        !           577:        u_int                           proto;
        !           578:        int                                     flag;
        !           579:        caddr_t                         buf;
        !           580:        register caddr_t        ptr;
        !           581:        register int            len     = 0;
        !           582:        int                             buflen  =0;
        !           583:        caddr_t                         facil_len;
        !           584:        int                             oddness = 0;
        !           585:        struct mbuf *m;
        !           586: 
        !           587: 
        !           588:        IFDEBUG(D_CCONN)
        !           589:                printf("make_partial_x25_packet(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
        !           590:                        isop->isop_laddr, isop->isop_faddr, proto, m, flag);
        !           591:        ENDDEBUG
        !           592:        if (cons_use_udata) {
        !           593:                if (isop->isop_x25crud_len > 0) {
        !           594:                        /*
        !           595:                         *      The user specified something. Stick it in
        !           596:                         */
        !           597:                        bcopy(isop->isop_x25crud, lcp->lcd_faddr.x25_udata,
        !           598:                                        isop->isop_x25crud_len);
        !           599:                        lcp->lcd_faddr.x25_udlen = isop->isop_x25crud_len;
        !           600:                }
        !           601:        }
        !           602: 
        !           603:        if (cons_use_facils == 0) {
        !           604:                lcp->lcd_facilities = 0;
        !           605:                return 0;
        !           606:        }
        !           607:        MGETHDR(m, MT_DATA, M_WAITOK);
        !           608:        if (m == 0)
        !           609:                return ENOBUFS;
        !           610:        buf = mtod(m, caddr_t);
        !           611:        ptr = buf;
        !           612:        
        !           613:        /* ptr now points to facil length (len of whole facil field in OCTETS */
        !           614:        facil_len = ptr ++;
        !           615:        m->m_len = 0;
        !           616:        pk_build_facilities(m, &lcp->lcd_faddr, 0);
        !           617: 
        !           618:        IFDEBUG(D_CADDR)
        !           619:                printf("make_partial  calling: ptr 0x%x, len 0x%x\n", ptr, 
        !           620:                                isop->isop_laddr->siso_addr.isoa_len);
        !           621:        ENDDEBUG
        !           622:        if (cons_use_facils) {
        !           623:                *ptr++ = 0;      /* Marker to separate X.25 facitilies from CCITT ones */
        !           624:                *ptr++ = 0x0f;
        !           625:                *ptr = 0xcb; /* calling facility code */
        !           626:                ptr ++;
        !           627:                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
        !           628:                ptr ++; /* leave room for the facil param len (in nibbles),
        !           629:                                 * high two bits of which indicate full/partial NSAP
        !           630:                                 */
        !           631:                len = isop->isop_laddr->siso_addr.isoa_len;
        !           632:                bcopy( isop->isop_laddr->siso_data, ptr, len);
        !           633:                *(ptr-2) = len+1; /* facil param len in octets */
        !           634:                *(ptr-1) = len<<1; /* facil param len in nibbles */
        !           635:                ptr += len;
        !           636: 
        !           637:                IFDEBUG(D_CADDR)
        !           638:                        printf("make_partial  called: ptr 0x%x, len 0x%x\n", ptr, 
        !           639:                                        isop->isop_faddr->siso_addr.isoa_len);
        !           640:                ENDDEBUG
        !           641:                *ptr = 0xc9; /* called facility code */
        !           642:                ptr ++;
        !           643:                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
        !           644:                ptr ++; /* leave room for the facil param len (in nibbles),
        !           645:                                 * high two bits of which indicate full/partial NSAP
        !           646:                                 */
        !           647:                len = isop->isop_faddr->siso_nlen;
        !           648:                bcopy(isop->isop_faddr->siso_data, ptr, len);
        !           649:                *(ptr-2) = len+1; /* facil param len = addr len + 1 for each of these
        !           650:                                                  * two length fields, in octets */
        !           651:                *(ptr-1) = len<<1; /* facil param len in nibbles */
        !           652:                ptr += len;
        !           653: 
        !           654:        }
        !           655:        *facil_len = ptr - facil_len - 1;
        !           656:        if (*facil_len > MAX_FACILITIES)
        !           657:                return E_CO_PNA_LONG;
        !           658: 
        !           659:        buflen = (int)(ptr - buf);
        !           660: 
        !           661:        IFDEBUG(D_CDUMP_REQ)
        !           662:                register int i;
        !           663: 
        !           664:                printf("ECN_CONNECT DATA buf 0x%x len %d (0x%x)\n", 
        !           665:                        buf, buflen, buflen);
        !           666:                for( i=0; i < buflen; ) {
        !           667:                        printf("+%d: %x %x %x %x    %x %x %x %x\n",
        !           668:                                i,
        !           669:                                *(buf+i), *(buf+i+1), *(buf+i+2), *(buf+i+3),
        !           670:                                *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7));
        !           671:                        i+=8;
        !           672:                }
        !           673:        ENDDEBUG
        !           674:        IFDEBUG(D_CADDR)
        !           675:                printf("make_partial returns buf 0x%x size 0x%x bytes\n", 
        !           676:                        mtod(m, caddr_t), buflen);
        !           677:        ENDDEBUG
        !           678: 
        !           679:        if (buflen > MHLEN)
        !           680:                return E_CO_PNA_LONG;
        !           681: 
        !           682:        m->m_pkthdr.len = m->m_len = buflen;
        !           683:        lcp->lcd_facilities = m;
        !           684:        return  0;
        !           685: }
        !           686: 
        !           687: /*
        !           688:  * NAME:       NSAPtoDTE()
        !           689:  * CALLED FROM:
        !           690:  *  make_partial_x25_packet()
        !           691:  * FUNCTION and ARGUMENTS: 
        !           692:  *  get a DTE address from an NSAP-address (struct sockaddr_iso)
        !           693:  *  (dst_octet) is the octet into which to begin stashing the DTE addr
        !           694:  *  (dst_nibble) takes 0 or 1.  1 means begin filling in the DTE addr
        !           695:  *             in the high-order nibble of dst_octet.  0 means low-order nibble.
        !           696:  *  (addr) is the NSAP-address
        !           697:  *  (flag) is true if the transport suffix is to become the
        !           698:  *             last two digits of the DTE address
        !           699:  *  A DTE address is a series of ASCII digits
        !           700:  *
        !           701:  *     A DTE address may have leading zeros. The are significant.
        !           702:  *             1 digit per nibble, may be an odd number of nibbles.
        !           703:  *
        !           704:  *  An NSAP-address has the DTE address in the IDI. Leading zeros are
        !           705:  *             significant. Trailing hex f indicates the end of the DTE address.
        !           706:  *     The IDI is a series of BCD digits, one per nibble.
        !           707:  *
        !           708:  * RETURNS
        !           709:  *  # significant digits in the DTE address, -1 if error.
        !           710:  */
        !           711: 
        !           712: Static int
        !           713: NSAPtoDTE(siso, sx25)
        !           714:        register struct sockaddr_iso *siso;
        !           715:        register struct sockaddr_x25 *sx25;
        !           716: {
        !           717:        int             dtelen = -1;
        !           718: 
        !           719:        IFDEBUG(D_CADDR)
        !           720:                printf("NSAPtoDTE: nsap: %s\n", clnp_iso_addrp(&siso->siso_addr));
        !           721:        ENDDEBUG
        !           722: 
        !           723:        if (siso->siso_data[0] == AFI_37) {
        !           724:                register char *out = sx25->x25_addr;
        !           725:                register char *in = siso->siso_data + 1;
        !           726:                register int nibble;
        !           727:                char *lim = siso->siso_data + siso->siso_nlen;
        !           728:                char *olim = out+15;
        !           729:                int lowNibble = 0;
        !           730: 
        !           731:                while (in < lim) {
        !           732:                        nibble = ((lowNibble ? *in++ : (*in >> 4)) & 0xf) | 0x30;
        !           733:                        lowNibble ^= 1;
        !           734:                        if (nibble != 0x3f && out < olim)
        !           735:                                *out++ = nibble;
        !           736:                }
        !           737:                dtelen = out - sx25->x25_addr;
        !           738:                *out++ = 0;
        !           739:        } else {
        !           740:                /* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
        !           741:                register struct rtentry *rt;
        !           742:                extern struct sockaddr_iso blank_siso;
        !           743:                struct sockaddr_iso nsiso;
        !           744: 
        !           745:                nsiso = blank_siso;
        !           746:                bcopy(nsiso.siso_data, siso->siso_data,
        !           747:                                nsiso.siso_nlen = siso->siso_nlen);
        !           748:                if (rt = rtalloc1(&nsiso, 1)) {
        !           749:                        register struct sockaddr_x25 *sxx =
        !           750:                                                        (struct sockaddr_x25 *)rt->rt_gateway;
        !           751:                        register char *in = sxx->x25_addr;
        !           752: 
        !           753:                        rt->rt_use--;
        !           754:                        if (sxx && sxx->x25_family == AF_CCITT) {
        !           755:                                bcopy(sx25->x25_addr, sxx->x25_addr, sizeof(sx25->x25_addr));
        !           756:                                while (*in++) {}
        !           757:                                dtelen = in - sxx->x25_addr;
        !           758:                        }
        !           759:                }
        !           760:        }
        !           761:        return dtelen;
        !           762: }
        !           763: 
        !           764: /*
        !           765:  * NAME:       FACILtoNSAP()
        !           766:  * CALLED FROM:
        !           767:  *  parse_facil()
        !           768:  * FUNCTION and ARGUMENTS:
        !           769:  *     Creates and NSAP in the sockaddr_iso (addr) from the
        !           770:  *  x.25 facility found at buf - 1.
        !           771:  * RETURNS:
        !           772:  *  0 if ok, -1 if error.
        !           773:  */
        !           774: 
        !           775: Static int
        !           776: FACILtoNSAP(addr, buf)
        !           777:        register u_char                 *buf;
        !           778:        register struct sockaddr_iso *addr;
        !           779: {
        !           780:        int                     len_in_nibbles = *++buf & 0x3f;
        !           781:        u_char          buf_len = (len_in_nibbles + 1) >> 1;; /* in bytes */
        !           782: 
        !           783:        IFDEBUG(D_CADDR)
        !           784:                printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n", 
        !           785:                        buf, buf_len, addr );
        !           786:        ENDDEBUG
        !           787: 
        !           788:        len_in_nibbles = *buf & 0x3f;
        !           789:        /* despite the fact that X.25 makes us put a length in nibbles
        !           790:         * here, the NSAP-addrs are always in full octets
        !           791:         */
        !           792:        switch (*buf++ & 0xc0) {
        !           793:        case 0:
        !           794:                /* Entire OSI NSAP address */
        !           795:                bcopy((caddr_t)buf, addr->siso_data, addr->siso_nlen = buf_len);
        !           796:                break;
        !           797: 
        !           798:        case 40:
        !           799:                /* Partial OSI NSAP address, assume trailing */
        !           800:                if (buf_len + addr->siso_nlen > sizeof(addr->siso_addr))
        !           801:                        return -1;
        !           802:                bcopy((caddr_t)buf, TSEL(addr), buf_len);
        !           803:                addr->siso_nlen += buf_len;
        !           804:                break;
        !           805: 
        !           806:        default:
        !           807:                /* Rather than blow away the connection, just ignore and use
        !           808:                   NSAP from DTE */;
        !           809:        }
        !           810:        return 0;
        !           811: }
        !           812: 
        !           813: Static
        !           814: init_siso(siso)
        !           815: register struct sockaddr_iso *siso;
        !           816: {
        !           817:        siso->siso_len = sizeof (*siso);
        !           818:        siso->siso_family = AF_ISO;
        !           819:        siso->siso_data[0] = AFI_37;
        !           820:        siso->siso_nlen = 8;
        !           821: }
        !           822: 
        !           823: /*
        !           824:  * NAME:       DTEtoNSAP()
        !           825:  * CALLED FROM:
        !           826:  *  parse_facil()
        !           827:  * FUNCTION and ARGUMENTS:
        !           828:  *  Creates a type 37 NSAP in the sockaddr_iso (addr)
        !           829:  *     from a DTE address found in a sockaddr_x25.
        !           830:  *  
        !           831:  * RETURNS:
        !           832:  *  0 if ok; E* otherwise.
        !           833:  */
        !           834: 
        !           835: Static  int
        !           836: DTEtoNSAP(addr, sx)
        !           837:        struct sockaddr_iso *addr;
        !           838:        struct sockaddr_x25 *sx;
        !           839: {
        !           840:        register char           *in, *out;
        !           841:        register int            first;
        !           842:        int                                     pad_tail = 0;
        !           843:        int                             src_len;
        !           844: 
        !           845: 
        !           846:        init_siso(addr);
        !           847:        in = sx->x25_addr;
        !           848:        src_len = strlen(in);
        !           849:        addr->siso_nlen = (src_len + 3) / 2;
        !           850:        out = addr->siso_data;
        !           851:        *out++ = 0x37;
        !           852:        if (src_len & 1) {
        !           853:                pad_tail = 0xf;
        !           854:                src_len++;
        !           855:        }
        !           856:        for (first = 0; src_len > 0; src_len--) {
        !           857:                first |= 0xf & *in++;
        !           858:                if (src_len & 1) {
        !           859:                        *out++ = first;
        !           860:                        first = 0;
        !           861:                }
        !           862:                else first <<= 4;
        !           863:        }
        !           864:        if (pad_tail)
        !           865:                out[-1] |= 0xf;
        !           866:        return 0; /* ok */
        !           867: }
        !           868: 
        !           869: /*
        !           870:  * FUNCTION and ARGUMENTS:
        !           871:  *     parses (buf_len) bytes beginning at (buf) and finds
        !           872:  *  a called nsap, a calling nsap, and protocol identifier.
        !           873:  * RETURNS:
        !           874:  *  0 if ok, E* otherwise.
        !           875:  */
        !           876: 
        !           877: Static int
        !           878: parse_facil(lcp, isop, buf, buf_len)
        !           879:        caddr_t                 buf;
        !           880:        u_char                  buf_len; /* in bytes */
        !           881:        struct                  isopcb *isop;
        !           882:        struct                  pklcd *lcp;
        !           883: {
        !           884:        register int    i;
        !           885:        register u_char         *ptr = (u_char *)buf;
        !           886:        u_char                  *ptr_lim, *facil_lim;
        !           887:        int                     facil_param_len, facil_len;
        !           888: 
        !           889:        IFDEBUG(D_CADDR)
        !           890:                printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n", 
        !           891:                        lcp, isop, buf, buf_len);
        !           892:                dump_buf(buf, buf_len);
        !           893:        ENDDEBUG
        !           894: 
        !           895:        /* find the beginnings of the facility fields in buf 
        !           896:         * by skipping over the called & calling DTE addresses
        !           897:         * i <- # nibbles in called + # nibbles in calling
        !           898:         * i += 1 so that an odd nibble gets rounded up to even  
        !           899:         * before dividing by 2, then divide by two to get # octets
        !           900:         */
        !           901:        i = (int)(*ptr >> 4) + (int)(*ptr&0xf);
        !           902:        i++;
        !           903:        ptr += i >> 1;
        !           904:        ptr ++; /* plus one for the DTE lengths byte */
        !           905: 
        !           906:        /* ptr now is at facil_length field */
        !           907:        facil_len = *ptr++;
        !           908:        facil_lim = ptr + facil_len;
        !           909:        IFDEBUG(D_CADDR)
        !           910:                printf("parse_facils: facil length is  0x%x\n", (int) facil_len);
        !           911:        ENDDEBUG
        !           912: 
        !           913:        while (ptr < facil_lim) {
        !           914:                /* get NSAP addresses from facilities */
        !           915:                switch (*ptr++) {
        !           916:                        case 0xcb:
        !           917:                                /* calling NSAP */
        !           918:                                facil_param_len = FACILtoNSAP(isop->isop_faddr, ptr);
        !           919:                                break;
        !           920:                        case 0xc9:
        !           921:                                /* called NSAP */
        !           922:                                facil_param_len = FACILtoNSAP(isop->isop_laddr, ptr);
        !           923:                                break;
        !           924: 
        !           925:                                /* from here to default are legit cases that I ignore */
        !           926:                                /* variable length */
        !           927:                        case 0xca:  /* end-to-end transit delay negot */
        !           928:                        case 0xc6:  /* network user id */
        !           929:                        case 0xc5:      /* charging info : indicating monetary unit */
        !           930:                        case 0xc2:      /* charging info : indicating segment count */
        !           931:                        case 0xc1:      /* charging info : indicating call duration */
        !           932:                        case 0xc4:      /* RPOA extended format */
        !           933:                        case 0xc3:      /* call redirection notification */
        !           934:                                facil_param_len = 0;
        !           935:                                break;
        !           936: 
        !           937:                                /* 1 octet */
        !           938:                        case 0x0a:  /* min. throughput class negot */
        !           939:                        case 0x02:  /* throughput class */
        !           940:                        case 0x03:  case 0x47:  /* CUG xxxx */
        !           941:                        case 0x0b:  /* expedited data negot */
        !           942:                        case 0x01:  /* Fast select or reverse charging 
        !           943:                                                (example of intelligent protocol design) */
        !           944:                        case 0x04:      /* charging info : requesting service */
        !           945:                        case 0x08:      /* called line addr modified notification */
        !           946:                        case 0x00:  /* marker to indicate beginning of CCITT facils */
        !           947:                                facil_param_len = 1;
        !           948:                                break;
        !           949: 
        !           950:                                /* any 2 octets */
        !           951:                        case 0x42:  /* pkt size */
        !           952:                        case 0x43:  /* win size */
        !           953:                        case 0x44:  /* RPOA basic format */
        !           954:                        case 0x41:  /* bilateral CUG xxxx */
        !           955:                        case 0x49:      /* transit delay selection and indication */
        !           956:                                facil_param_len = 2;
        !           957:                                break;
        !           958: 
        !           959:                        default:
        !           960:                                printf(
        !           961: "BOGUS FACILITY CODE facil_lim 0x%x facil_len %d, ptr 0x%x *ptr 0x%x\n",
        !           962:                                        facil_lim, facil_len, ptr - 1, ptr[-1]);
        !           963:                                /* facil that we don't handle
        !           964:                                return E_CO_HLI_REJI; */
        !           965:                                switch (ptr[-1] & 0xc0) {
        !           966:                                case 0x00:      facil_param_len = 1; break;
        !           967:                                case 0x40:      facil_param_len = 2; break;
        !           968:                                case 0x80:      facil_param_len = 3; break;
        !           969:                                case 0xc0:      facil_param_len = 0; break;
        !           970:                                }
        !           971:                }
        !           972:                if (facil_param_len == -1)
        !           973:                        return E_CO_REG_ICDA;
        !           974:                if (facil_param_len == 0) /* variable length */ 
        !           975:                        facil_param_len = (int)*ptr++; /* 1 + the real facil param */
        !           976:                ptr += facil_param_len;
        !           977:        }
        !           978:        return 0;
        !           979: }
        !           980: 
        !           981: #endif /* TPCONS */

unix.superglobalmegacorp.com

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