Annotation of 43BSDReno/sys/netiso/if_lpb.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2:                Copyright IBM Corporation 1987
                      3: 
                      4:                       All Rights Reserved
                      5: 
                      6: Permission to use, copy, modify, and distribute this software and its 
                      7: documentation for any purpose and without fee is hereby granted, 
                      8: provided that the above copyright notice appear in all copies and that
                      9: both that copyright notice and this permission notice appear in 
                     10: supporting documentation, and that the name of IBM not be
                     11: used in advertising or publicity pertaining to distribution of the
                     12: software without specific, written prior permission.  
                     13: 
                     14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     20: SOFTWARE.
                     21: 
                     22: ******************************************************************/
                     23: 
                     24: /*
                     25:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     26:  */
                     27: /*
                     28:  * $Header: if_lpb.c,v 4.2 88/06/29 14:59:38 hagens Exp $
                     29:  * $Source: /usr/argo/sys/netiso/RCS/if_lpb.c,v $
                     30:  *
                     31:  *     LOOPBACK driver that mimics the
                     32:  *     Eicon x.25 board for use by CONS
                     33:  */
                     34: 
                     35: #ifndef lint
                     36: static char *rcsid = "$Header: if_lpb.c,v 4.2 88/06/29 14:59:38 hagens Exp $";
                     37: #endif lint
                     38: 
                     39: 
                     40: #include "param.h"
                     41: #include "systm.h"
                     42: #include "types.h"
                     43: #include "mbuf.h"
                     44: #include "buf.h"
                     45: #include "protosw.h"
                     46: #include "socket.h"
                     47: #include "ioctl.h"
                     48: #include "errno.h"
                     49: 
                     50: #include "../net/if.h"
                     51: #include "../net/netisr.h"
                     52: #include "../net/route.h"
                     53: #include "machine/io.h"
                     54: #include "../machineio/ioccvar.h"
                     55: 
                     56: #include "ecn.h"
                     57: #include "iso.h"
                     58: #include "argo_debug.h"
                     59: #include "../caif/eicon.h"
                     60: #include "iso_errno.h"
                     61: 
                     62: #define LPB_DEBUG
                     63: #ifdef LPB_DEBUG
                     64: #define MT_LPB_OPEN    0x55
                     65: #define MT_LPB_ACK     0x56
                     66: #else LPB_DEBUG
                     67: #define MT_LPB_DATA MT_DATA
                     68: #define MT_LPB_ACK MT_DATA
                     69: #endif LPB_DEBUG
                     70: 
                     71: extern struct ifqueue  consintrq;      
                     72: int                                            lpboutput();
                     73: 
                     74: /* These next 2 declarations are for Logical Unit Numbers - i.e. VC # -
                     75:  * the 2I assigns and frees them; we have to fake it
                     76:  */
                     77: 
                     78: static u_char                  free_luns[32];
                     79: static u_char                  *next_lun = free_luns;
                     80: 
                     81: /*
                     82:  * Initialize all LUNs as available for use.
                     83:  */
                     84: init_lpb()
                     85: {
                     86:        register int i;
                     87: 
                     88:        for (i = 0; i < 32; i++) {
                     89:                free_luns[i] = i+1;
                     90:        }
                     91:        next_lun = free_luns;
                     92: }
                     93: 
                     94: /*
                     95:  *     Allocate new logical unit number.
                     96:  *  Allocating number n means that both n and -n are allocated & used.
                     97:  *  NOTE: next_lun always points to an UNALLOCATED lun, hence
                     98:  *      take a lun then increment, or decrement then stash the lun.
                     99:  */
                    100: 
                    101: u_char 
                    102: getlun()
                    103: {
                    104:        if( ((next_lun) - free_luns) > 32 ) {
                    105:                printf("PANIC: if_lpb: too many channels! \n");
                    106:                return 0;
                    107:        }
                    108:        IFDEBUG(D_CCONN)
                    109:                printf("getlun: returns 0x%x\n", *next_lun);
                    110:        ENDDEBUG
                    111:        ASSERT( *next_lun != 0 );
                    112:        if( *next_lun == 0 ) {
                    113:                register int i;
                    114: 
                    115:                printf(
                    116:                "PANIC IN lpb: free_luns 0x%x next_len 0x%x *next_lun 0x%x\n",
                    117:                        free_luns, next_lun, *next_lun);
                    118:                
                    119:                for(i=0; i<32; i++) {
                    120:                        printf("free_luns[ 0x%x ] = 0x%x\n", i, free_luns[i] );
                    121:                }
                    122:        }
                    123:        return *(next_lun++);
                    124: 
                    125: }
                    126: 
                    127: /* 
                    128:  * When you free one you free its neg 
                    129:  */
                    130: 
                    131: freelun(lun)
                    132: u_char lun;
                    133: {
                    134:        IFDEBUG(D_CCONN)
                    135:                printf("freelun(0x%x)\n", lun);
                    136:        ENDDEBUG
                    137:        if( lun > 32 )
                    138:                return;
                    139: 
                    140:        ASSERT( (lun & 0xc0) == 0 );
                    141:        ASSERT( lun <= 32 );
                    142: 
                    143:        /* check for lun already in the list */
                    144:        {
                    145:                register u_char *r = next_lun;
                    146: 
                    147:                while( (int)(r - free_luns) <= 32 ) {
                    148:                        if( *r == lun ) {
                    149:                                return;
                    150:                        }
                    151:                        r++;
                    152:                }
                    153:        }
                    154: 
                    155:        next_lun --;
                    156:        *next_lun = lun;
                    157: }
                    158: 
                    159: 
                    160: /*
                    161:  * FUNCTION:           lpboutput
                    162:  *
                    163:  * PURPOSE:                    Process an eicon x.25 request from a higher layer
                    164:  *                                     protocol.
                    165:  * ARGUMENTS:          (ifp) is points to the ifnet structure for this unit/device
                    166:  *                                     (m)  is an mbuf *, *m is an eicon request structure
                    167:  *
                    168:  * RETURNS:                    unix error code
                    169:  *
                    170:  * NOTES:                      Mimics the eicon driver.
                    171:  *
                    172:  */
                    173: lpboutput(ifp,m)
                    174:        register struct ifnet   *ifp;
                    175:        register struct mbuf    *m;                     /* request */
                    176: {
                    177:        int                                                     s;
                    178:        struct eicon_request            *req;
                    179:        int                                                     error = 0;
                    180: 
                    181:        /* Do this even if (ifp->if_flags & IFF_LOOPBACK) == 0
                    182:         * because whether or not a vc is on loopback is determined
                    183:         * at the time of connection establishement.
                    184:         */
                    185:        s = splnet();
                    186:        req = mtod(m, struct eicon_request *);
                    187:        IFDEBUG(D_CDUMP_REQ)
                    188:                dump_buf(req, sizeof(struct eicon_request));
                    189:        ENDDEBUG
                    190:        switch (req->e_cmd) {
                    191:                case ECN_CALL: {
                    192:                        /*
                    193:                         *      ECN_CALL        ->      ECN_ACCEPT (for orig CONNECT)
                    194:                         *                              ->      ECN_CONNECT     (other side's connect indication)
                    195:                         */
                    196:                        struct mbuf *mdata;
                    197:                        struct mbuf *mopen;
                    198:                        struct eicon_request *open;
                    199: 
                    200:                        MGET(mopen, M_DONTWAIT, MT_LPB_OPEN);
                    201:                        if (mopen == NULL) {
                    202:                                printf("No mbufs for copy\n");
                    203:                                error = ENOBUFS;
                    204:                                break;
                    205:                        }
                    206:                        mopen->m_len = sizeof(struct eicon_request);
                    207: 
                    208:                        open = mtod(mopen, struct eicon_request *);
                    209:                        bcopy( req, open, sizeof(struct eicon_request) );
                    210: 
                    211:                        /* get mbuf for the connect data */
                    212:                        MGET(mdata, M_DONTWAIT, MT_LPB_OPEN);
                    213:                        if (mdata == NULL) {
                    214:                                printf("No mbufs for copy\n");
                    215:                                error = ENOBUFS;
                    216:                                break;
                    217:                        }
                    218:                        mdata->m_len = (e_data(req))->m_len;
                    219:                        e_data(open) = mdata; /* e_data is really mtod(open)->m_next */
                    220:                        /* make a copy of the connect data */
                    221:                        IFDEBUG(D_CCONN)
                    222:                                printf("bcopy( 0x%x, 0x%x, 0x%x)\n", mtod(e_data(req), caddr_t),
                    223:                                                mtod(mdata, caddr_t), 
                    224:                                                (e_data(req))->m_len);
                    225:                        ENDDEBUG
                    226:                        bcopy( mtod(e_data(req), caddr_t), mtod(mdata, caddr_t), 
                    227:                                                (e_data(req))->m_len);
                    228:                        /* setup call */
                    229:                        open->e_cmd = ECN_CONNECT;
                    230:                        open->e_vc = getlun();
                    231: 
                    232:                        /* setup call confirm */
                    233:                        req->e_cmd = ECN_ACCEPT;
                    234:                        req->e_vc = -(open->e_vc);
                    235: 
                    236:                        IFDEBUG(D_CDUMP_REQ)
                    237:                                printf("lpboutput CALL middle \n");
                    238:                        ENDDEBUG
                    239: 
                    240:                        if (IF_QFULL(&consintrq)) {
                    241:                                IF_DROP(&consintrq);
                    242:                                m_freem(mopen);
                    243:                                printf("lpboutput: response dropped\n");
                    244:                                error = ENOBUFS;
                    245:                                break;
                    246:                        } else {
                    247:                                /* connect */
                    248:                                IFDEBUG(D_CCONS);
                    249:                                        printf("CONNECT 0x%x --> X25INTRQ\n", mopen);
                    250:                                ENDDEBUG
                    251:                                IF_ENQUEUE(&consintrq, mopen);
                    252:                                IFDEBUG(D_CDUMP_REQ);
                    253:                                        dump_buf(open, sizeof(struct eicon_request));
                    254:                                ENDDEBUG
                    255: 
                    256:                                /* confirm */
                    257:                                IFDEBUG(D_CCONS);
                    258:                                        printf("CONFIRM 0x%x (data 0x%x =?= 0x%x) --> X25INTRQ\n", 
                    259:                                                m, m->m_next, e_data(req));
                    260:                                ENDDEBUG
                    261:                                IF_ENQUEUE(&consintrq, m);
                    262:                                IFDEBUG(D_CDUMP_REQ);
                    263:                                        dump_buf(req, sizeof(struct eicon_request));
                    264:                                ENDDEBUG
                    265:                        }
                    266:                } break;
                    267:                
                    268:                case ECN_RESET: 
                    269:                case ECN_CLEAR: {
                    270:                        /*
                    271:                         *      ECN_RESET       ->      ECN_RESET       (other side's reset indication)
                    272:                         *      ECN_CLEAR       ->      ECN_CLEAR       (other side's close indication)
                    273:                         * TODO: MAY HAVE DATA PACKET! 
                    274:                         * TODO: Have to be able to handle a 2nd CLEAR on on vc!
                    275:                         */
                    276:                        freelun(req->e_vc);
                    277:                        freelun((-req->e_vc)&0xff);
                    278:                        req->e_vc = -req->e_vc; /* other side */
                    279:                        req->e_reason = E_CO_PDNCLRESET;
                    280:                        if (IF_QFULL(&consintrq)) {
                    281:                                IF_DROP(&consintrq);
                    282:                                printf("lpboutput: respose dropped\n");
                    283:                                error = ENOBUFS;
                    284:                        } else {
                    285:                                IFDEBUG(D_CCONS);
                    286:                                        printf("CLOSE 0x%x --> X25INTRQ\n", m);
                    287:                                ENDDEBUG
                    288:                                IF_ENQUEUE(&consintrq, m);
                    289:                                IFDEBUG(D_CDUMP_REQ);
                    290:                                        dump_buf(req, sizeof(struct eicon_request));
                    291:                                ENDDEBUG
                    292:                        }
                    293:                } break;
                    294:                
                    295:                case ECN_SEND: {
                    296:                        /*
                    297:                         *      ECN_SEND        ->      ECN_RECEIVE     (data send becomes data recvd)
                    298:                         */
                    299:                        struct mbuf *m0;
                    300:                        struct eicon_request *ack;
                    301: 
                    302:                        MGET(m0, M_DONTWAIT, MT_LPB_ACK); /* sets type, next, off */
                    303:                        if (m0 == NULL) {
                    304:                                printf("PANIC No mbufs for copy\n");
                    305:                                error = ENOBUFS;
                    306:                                break;
                    307:                        }
                    308:                        m0->m_len = sizeof(struct eicon_request);
                    309: 
                    310:                        ack = mtod(m0, struct eicon_request *);
                    311:                        /* setup ack */
                    312:                        ack->e_cmd = ECN_ACK;
                    313:                        ack->e_vc = req->e_vc;
                    314:                        req->e_vc = -req->e_vc;
                    315:                        req->e_cmd = ECN_RECEIVE;
                    316: 
                    317:                        if (IF_QFULL(&consintrq)) {
                    318:                                IF_DROP(&consintrq);
                    319:                                printf("lpboutput: ADR_ACK DROPPED\n");
                    320:                                m_freem(m0);
                    321:                                error = ECONNABORTED;
                    322:                        } else {
                    323:                                IF_ENQUEUE(&consintrq, m);
                    324:                                IFDEBUG(D_CCONS);
                    325:                                        printf("DATA 0x%x --> X25INTRQ\n", m);
                    326:                                ENDDEBUG
                    327:                                IFDEBUG(D_CDUMP_REQ);
                    328:                                        dump_buf(req, sizeof(struct eicon_request));
                    329:                                ENDDEBUG
                    330:                                IFDEBUG(D_CCONS);
                    331:                                        printf("ACK 0x%x --> X25INTRQ\n", m0);
                    332:                                ENDDEBUG
                    333:                                IF_ENQUEUE(&consintrq, m0);
                    334:                                IFDEBUG(D_CDUMP_REQ);
                    335:                                        dump_buf(ack, sizeof(struct eicon_request));
                    336:                                ENDDEBUG
                    337:                        }
                    338:                } break;
                    339:                
                    340:                default:
                    341:                        printf("Bad loopback request 0x%x\n", req->e_cmd);
                    342:                        error = EINVAL;
                    343:        }
                    344: 
                    345:        if( error ) {
                    346:                m_freem(m);
                    347:        } else
                    348:                schednetisr(NETISR_X25);
                    349: 
                    350:        splx(s);
                    351:        return error;
                    352: }
                    353: 
                    354: #if NECN>0
                    355:        /* nothing */
                    356: #else
                    357: 
                    358: /* KLUDGE: when no ecn board config-ed in, we need a routing
                    359:  * ecnifp to return null.  We want to be able to configure with
                    360:  * sw loopback only.
                    361:  */
                    362: struct ifnet  *
                    363: ecnifp(unit)
                    364: int unit;
                    365: {
                    366:        return (struct ifnet *)NULL;
                    367: }
                    368: 
                    369: int
                    370: ecnoutput(ifp, m)
                    371:        struct ifnet *ifp;
                    372:        struct mbuf *m;
                    373: {
                    374:        printf("ecnoutput: ecn not configured\n");
                    375:        (void) m_freem(m);
                    376:        return ENETDOWN;
                    377:                
                    378: }
                    379: 
                    380: ecnshutdown(ifp)
                    381: {
                    382:        printf("ecnshutdown: ecn not configured\n");
                    383: }
                    384: 
                    385: ecnrestart(ifp)
                    386: {
                    387:        printf("ecnrestart: ecn not configured\n");
                    388: }
                    389: #endif NECN>0

unix.superglobalmegacorp.com

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