Annotation of Net2/netiso/if_cons.c, revision 1.1

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

unix.superglobalmegacorp.com

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