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

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

unix.superglobalmegacorp.com

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