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

1.1       root        1: /*-
                      2:  * Copyright (c) 1991 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)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.