Annotation of Net2/netiso/tp_subr2.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: @(#)tp_subr2.c    7.10 (Berkeley) 6/27/91
        !            34:  *     tp_subr2.c,v 1.2 1993/05/20 05:27:59 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:  * ARGO TP
                     65:  *
                     66:  * Some auxiliary routines:
                     67:  *     tp_protocol_error: required by xebec- called when a combo of state,
                     68:  *         event, predicate isn't covered for by the transition file.
                     69:  *     tp_indicate: gives indications(signals) to the user process
                     70:  *     tp_getoptions: initializes variables that are affected by the options
                     71:  *         chosen.
                     72:  */
                     73: 
                     74: /* this def'n is to cause the expansion of this macro in the
                     75:  * routine tp_local_credit :
                     76:  */
                     77: #define LOCAL_CREDIT_EXPAND
                     78: 
                     79: #include "param.h"
                     80: #include "systm.h"
                     81: #include "mbuf.h"
                     82: #include "socket.h"
                     83: #include "socketvar.h"
                     84: #include "domain.h"
                     85: #include "protosw.h"
                     86: #include "errno.h"
                     87: #include "types.h"
                     88: #include "time.h"
                     89: #include "kernel.h"
                     90: #undef MNULL
                     91: #include "argo_debug.h"
                     92: #include "tp_param.h"
                     93: #include "tp_ip.h"
                     94: #include "iso.h"
                     95: #include "iso_errno.h"
                     96: #include "iso_pcb.h"
                     97: #include "tp_timer.h"
                     98: #include "tp_stat.h"
                     99: #include "tp_tpdu.h"
                    100: #include "tp_pcb.h"
                    101: #include "tp_seq.h"
                    102: #include "tp_trace.h"
                    103: #include "tp_user.h"
                    104: #include "cons.h"
                    105: 
                    106: #include "../net/if.h"
                    107: #ifdef TRUE
                    108: #undef FALSE
                    109: #undef TRUE
                    110: #endif
                    111: #include "../netccitt/x25.h"
                    112: #include "../netccitt/pk.h"
                    113: #include "../netccitt/pk_var.h"
                    114: 
                    115: /*
                    116:  * NAME:       tp_local_credit()
                    117:  *
                    118:  * CALLED FROM:
                    119:  *  tp_emit(), tp_usrreq()
                    120:  *
                    121:  * FUNCTION and ARGUMENTS:
                    122:  *     Computes the local credit and stashes it in tpcb->tp_lcredit.
                    123:  *  It's a macro in the production system rather than a procdure.
                    124:  *
                    125:  * RETURNS:
                    126:  *
                    127:  * SIDE EFFECTS:
                    128:  *
                    129:  * NOTES:
                    130:  *  This doesn't actually get called in a production system - 
                    131:  *  the macro gets expanded instead in place of calls to this proc.
                    132:  *  But for debugging, we call this and that allows us to add
                    133:  *  debugging messages easily here.
                    134:  */
                    135: void
                    136: tp_local_credit(tpcb)
                    137:        struct tp_pcb *tpcb;
                    138: {
                    139:        LOCAL_CREDIT(tpcb);
                    140:        IFDEBUG(D_CREDIT)
                    141:                printf("ref 0x%x lcdt 0x%x l_tpdusize 0x%x decbit 0x%x\n",
                    142:                        tpcb->tp_refp - tp_ref, 
                    143:                        tpcb->tp_lcredit, 
                    144:                        tpcb->tp_l_tpdusize, 
                    145:                        tpcb->tp_decbit, 
                    146:                        tpcb->tp_cong_win
                    147:                        );
                    148:        ENDDEBUG
                    149:        IFTRACE(D_CREDIT)
                    150:                tptraceTPCB(TPPTmisc,
                    151:                        "lcdt tpdusz \n",
                    152:                         tpcb->tp_lcredit, tpcb->tp_l_tpdusize, 0, 0);
                    153:        ENDTRACE
                    154: }
                    155: 
                    156: /*
                    157:  * NAME:  tp_protocol_error()
                    158:  *
                    159:  * CALLED FROM:
                    160:  *  tp_driver(), when it doesn't know what to do with
                    161:  *     a combo of event, state, predicate
                    162:  *
                    163:  * FUNCTION and ARGUMENTS:
                    164:  *  print error mesg 
                    165:  *
                    166:  * RETURN VALUE:
                    167:  *  EIO - always
                    168:  *
                    169:  * SIDE EFFECTS:
                    170:  *
                    171:  * NOTES:
                    172:  */
                    173: int
                    174: tp_protocol_error(e,tpcb)
                    175:        struct tp_event *e;
                    176:        struct tp_pcb   *tpcb;
                    177: {
                    178:        printf("TP PROTOCOL ERROR! tpcb 0x%x event 0x%x, state 0x%x\n",
                    179:                tpcb, e->ev_number, tpcb->tp_state);
                    180:        IFTRACE(D_DRIVER)
                    181:                tptraceTPCB(TPPTmisc, "PROTOCOL ERROR tpcb event state",
                    182:                        tpcb, e->ev_number, tpcb->tp_state, 0 );
                    183:        ENDTRACE
                    184:        return EIO; /* for lack of anything better */
                    185: }
                    186: 
                    187: 
                    188: /* Not used at the moment */
                    189: ProtoHook
                    190: tp_drain()
                    191: {
                    192:        return 0;
                    193: }
                    194: 
                    195: 
                    196: /*
                    197:  * NAME: tp_indicate()
                    198:  *
                    199:  * CALLED FROM:
                    200:  *     tp.trans when XPD arrive, when a connection is being disconnected by
                    201:  *  the arrival of a DR or ER, and when a connection times out.
                    202:  *
                    203:  * FUNCTION and ARGUMENTS:
                    204:  *  (ind) is the type of indication : T_DISCONNECT, T_XPD
                    205:  *  (error) is an E* value that will be put in the socket structure
                    206:  *  to be passed along to the user later.
                    207:  *     Gives a SIGURG to the user process or group indicated by the socket
                    208:  *     attached to the tpcb.
                    209:  *
                    210:  * RETURNS:  Rien
                    211:  * 
                    212:  * SIDE EFFECTS:
                    213:  *
                    214:  * NOTES:
                    215:  */
                    216: void
                    217: tp_indicate(ind, tpcb, error)
                    218:        int                             ind; 
                    219:        u_short                 error;
                    220:        register struct tp_pcb  *tpcb;
                    221: {
                    222:        register struct socket *so = tpcb->tp_sock;
                    223:        IFTRACE(D_INDICATION)
                    224:                tptraceTPCB(TPPTindicate, ind, *(u_short *)(tpcb->tp_lsuffix), 
                    225:                        *(u_short *)(tpcb->tp_fsuffix), error,so->so_pgid);
                    226:        ENDTRACE
                    227:        IFDEBUG(D_INDICATION)
                    228:                char *ls, *fs;
                    229:                ls = tpcb->tp_lsuffix, 
                    230:                fs = tpcb->tp_fsuffix, 
                    231: 
                    232:                printf(
                    233: "indicate 0x%x lsuf 0x%02x%02x fsuf 0x%02x%02x err 0x%x  noind 0x%x ref 0x%x\n",
                    234:                ind, 
                    235:                *ls, *(ls+1), *fs, *(fs+1),
                    236:                error, /*so->so_pgrp,*/
                    237:                tpcb->tp_no_disc_indications,
                    238:                tpcb->tp_lref);
                    239:        ENDDEBUG
                    240: 
                    241:        if (ind == ER_TPDU) {
                    242:                register struct mbuf *m;
                    243:                struct tp_disc_reason x;
                    244: 
                    245:                if ((so->so_state & SS_CANTRCVMORE) == 0 &&
                    246:                                (m = m_get(M_DONTWAIT, MT_OOBDATA)) != 0) {
                    247: 
                    248:                        x.dr_hdr.cmsg_len = m->m_len = sizeof(x);
                    249:                        x.dr_hdr.cmsg_level = SOL_TRANSPORT;
                    250:                        x.dr_hdr.cmsg_type= TPOPT_DISC_REASON;
                    251:                        x.dr_reason = error;
                    252:                        *mtod(m, struct tp_disc_reason *) = x;
                    253:                        sbappendrecord(&tpcb->tp_Xrcv, m);
                    254:                        error = 0;
                    255:                } else
                    256:                        error = ECONNRESET;
                    257:        }
                    258:        so->so_error = error;
                    259: 
                    260:        if (ind == T_DISCONNECT)  {
                    261:                so->so_error = ENOTCONN;
                    262:                if ( tpcb->tp_no_disc_indications )
                    263:                        return;
                    264:        }
                    265:        IFTRACE(D_INDICATION)
                    266:                tptraceTPCB(TPPTmisc, "doing sohasoutofband(so)", so,0,0,0);
                    267:        ENDTRACE
                    268:        sohasoutofband(so);
                    269: }
                    270: 
                    271: /*
                    272:  * NAME : tp_getoptions()
                    273:  *
                    274:  * CALLED FROM:
                    275:  *     tp.trans whenever we go into OPEN state 
                    276:  *
                    277:  * FUNCTION and ARGUMENTS:
                    278:  *  sets the proper flags and values in the tpcb, to control
                    279:  *  the appropriate actions for the given class, options,
                    280:  *  sequence space, etc, etc.
                    281:  * 
                    282:  * RETURNS: Nada
                    283:  * 
                    284:  * SIDE EFFECTS:
                    285:  *
                    286:  * NOTES:
                    287:  */
                    288: void
                    289: tp_getoptions(tpcb)
                    290: struct tp_pcb *tpcb;
                    291: {
                    292:        tpcb->tp_seqmask = 
                    293:                tpcb->tp_xtd_format ?   TP_XTD_FMT_MASK :       TP_NML_FMT_MASK ;
                    294:        tpcb->tp_seqbit =
                    295:                tpcb->tp_xtd_format ?   TP_XTD_FMT_BIT :        TP_NML_FMT_BIT ;
                    296:        tpcb->tp_seqhalf = tpcb->tp_seqbit >> 1;
                    297:        tpcb->tp_dt_ticks =
                    298:                MAX(tpcb->tp_dt_ticks, (tpcb->tp_peer_acktime + 2));
                    299: 
                    300: }
                    301: 
                    302: /*
                    303:  * NAME:  tp_recycle_tsuffix()
                    304:  *
                    305:  * CALLED FROM:
                    306:  *  Called when a ref is frozen.
                    307:  *
                    308:  * FUNCTION and ARGUMENTS:
                    309:  *  allows the suffix to be reused. 
                    310:  *
                    311:  * RETURNS: zilch
                    312:  *
                    313:  * SIDE EFFECTS:
                    314:  *
                    315:  * NOTES:
                    316:  */
                    317: void
                    318: tp_recycle_tsuffix(tpcb)
                    319:        struct tp_pcb   *tpcb;
                    320: {
                    321:        bzero((caddr_t)tpcb->tp_lsuffix, sizeof( tpcb->tp_lsuffix));
                    322:        bzero((caddr_t)tpcb->tp_fsuffix, sizeof( tpcb->tp_fsuffix));
                    323:        tpcb->tp_fsuffixlen = tpcb->tp_lsuffixlen = 0;
                    324: 
                    325:        (tpcb->tp_nlproto->nlp_recycle_suffix)(tpcb->tp_npcb);
                    326: }
                    327: 
                    328: /*
                    329:  * NAME: tp_quench()
                    330:  *
                    331:  * CALLED FROM:
                    332:  *  tp{af}_quench() when ICMP source quench or similar thing arrives.
                    333:  *
                    334:  * FUNCTION and ARGUMENTS:
                    335:  *  Drop the congestion window back to 1.
                    336:  *  Congestion window scheme:
                    337:  *  Initial value is 1.  ("slow start" as Nagle, et. al. call it)
                    338:  *  For each good ack that arrives, the congestion window is increased
                    339:  *  by 1 (up to max size of logical infinity, which is to say, 
                    340:  *     it doesn't wrap around).
                    341:  *  Source quench causes it to drop back to 1.
                    342:  *  tp_send() uses the smaller of (regular window, congestion window). 
                    343:  *  One retransmission strategy option is to have any retransmission 
                    344:  *     cause reset the congestion window back  to 1.
                    345:  *
                    346:  *     (cmd) is either PRC_QUENCH: source quench, or
                    347:  *             PRC_QUENCH2: dest. quench (dec bit)
                    348:  *
                    349:  * RETURNS:
                    350:  * 
                    351:  * SIDE EFFECTS:
                    352:  * 
                    353:  * NOTES:
                    354:  */
                    355: void
                    356: tp_quench( tpcb, cmd )
                    357:        struct tp_pcb *tpcb;
                    358:        int cmd;
                    359: {
                    360:        IFDEBUG(D_QUENCH)
                    361:                printf("tp_quench tpcb 0x%x ref 0x%x sufx 0x%x\n",
                    362:                        tpcb, tpcb->tp_lref, *(u_short *)(tpcb->tp_lsuffix));
                    363:                printf("cong_win 0x%x decbit 0x%x \n",
                    364:                        tpcb->tp_cong_win, tpcb->tp_decbit);
                    365:        ENDDEBUG
                    366:        switch(cmd) {
                    367:                case PRC_QUENCH:
                    368:                        tpcb->tp_cong_win = 1;
                    369:                        IncStat(ts_quench);
                    370:                        break;
                    371:                case PRC_QUENCH2:
                    372:                        tpcb->tp_cong_win = 1; /* might as well quench source also */
                    373:                        tpcb->tp_decbit = TP_DECBIT_CLEAR_COUNT;
                    374:                        IncStat(ts_rcvdecbit);
                    375:                        break;
                    376:        }
                    377: }
                    378: 
                    379: 
                    380: /*
                    381:  * NAME:       tp_netcmd()
                    382:  *
                    383:  * CALLED FROM:                        
                    384:  *
                    385:  * FUNCTION and ARGUMENTS:                     
                    386:  *
                    387:  * RETURNS:                    
                    388:  *
                    389:  * SIDE EFFECTS:       
                    390:  *
                    391:  * NOTES:                      
                    392:  */
                    393: tp_netcmd( tpcb, cmd )
                    394:        struct tp_pcb *tpcb;
                    395:        int cmd;
                    396: {
                    397: #ifdef TPCONS
                    398:        struct isopcb *isop;
                    399:        struct pklcd *lcp;
                    400: 
                    401:        if (tpcb->tp_netservice != ISO_CONS)
                    402:                return;
                    403:        isop = (struct isopcb *)tpcb->tp_npcb;
                    404:        lcp = (struct pklcd *)isop->isop_chan;
                    405:        switch (cmd) {
                    406: 
                    407:        case CONN_CLOSE:
                    408:        case CONN_REFUSE:
                    409:                if (isop->isop_refcnt == 1)
                    410:                        pk_disconnect(lcp);
                    411:                isop->isop_chan = 0;
                    412:                isop->isop_refcnt = 0;
                    413:                break;
                    414: 
                    415:        default:
                    416:                printf("tp_netcmd(0x%x, 0x%x) NOT IMPLEMENTED\n", tpcb, cmd);
                    417:                break;
                    418:        }
                    419: #else TPCONS
                    420:        printf("tp_netcmd(): X25 NOT CONFIGURED!!\n");
                    421: #endif
                    422: }
                    423: /*
                    424:  * CALLED FROM:
                    425:  *  tp_ctloutput() and tp_emit()
                    426:  * FUNCTION and ARGUMENTS:
                    427:  *     Convert a class mask to the highest numeric value it represents.
                    428:  */
                    429: 
                    430: int
                    431: tp_mask_to_num(x)
                    432:        u_char x;
                    433: {
                    434:        register int j;
                    435: 
                    436:        for(j = 4; j>=0 ;j--) {
                    437:                if(x & (1<<j))
                    438:                        break;
                    439:        }
                    440:        ASSERT( (j == 4) || (j == 0) ); /* for now */
                    441:        if( (j != 4) && (j != 0) ) {
                    442:                printf("ASSERTION ERROR: tp_mask_to_num: x 0x%x j %d\n",
                    443:                        x, j);
                    444:        }
                    445:        IFTRACE(D_TPINPUT)
                    446:                tptrace(TPPTmisc, "tp_mask_to_num(x) returns j", x, j, 0, 0);
                    447:        ENDTRACE
                    448:        IFDEBUG(D_TPINPUT)
                    449:                printf("tp_mask_to_num(0x%x) returns 0x%x\n", x, j);
                    450:        ENDDEBUG
                    451:        return j;
                    452: }
                    453: 
                    454: static 
                    455: copyQOSparms(src, dst)
                    456:        struct tp_conn_param *src, *dst;
                    457: {
                    458:        /* copy all but the bits stuff at the end */
                    459: #define COPYSIZE (12 * sizeof(short))
                    460: 
                    461:        bcopy((caddr_t)src, (caddr_t)dst, COPYSIZE);
                    462:        dst->p_tpdusize = src->p_tpdusize;
                    463:        dst->p_ack_strat = src->p_ack_strat;
                    464:        dst->p_rx_strat = src->p_rx_strat;
                    465: #undef COPYSIZE
                    466: }
                    467: 
                    468: /*
                    469:  * CALLED FROM:
                    470:  *  tp_usrreq on PRU_CONNECT and tp_input on receipt of CR
                    471:  *     
                    472:  * FUNCTION and ARGUMENTS:
                    473:  *     route directly to x.25 if the address is type 37 - GROT.
                    474:  *  furthermore, let TP0 handle only type-37 addresses
                    475:  *
                    476:  *     Since this assumes that its address argument is in a mbuf, the
                    477:  *     parameter was changed to reflect this assumtion. This also
                    478:  *     implies that an mbuf must be allocated when this is
                    479:  *     called from tp_input
                    480:  *     
                    481:  * RETURNS:
                    482:  *     errno value      : 
                    483:  *     EAFNOSUPPORT if can't find an nl_protosw for x.25 (really could panic)
                    484:  *     ECONNREFUSED if trying to run TP0 with non-type 37 address
                    485:  *  possibly other E* returned from cons_netcmd()
                    486:  * NOTE:
                    487:  *  Would like to eliminate as much of this as possible -- 
                    488:  *  only one set of defaults (let the user set the parms according
                    489:  *  to parameters provided in the directory service).
                    490:  *  Left here for now 'cause we don't yet have a clean way to handle
                    491:  *  it on the passive end.
                    492:  */
                    493: int
                    494: tp_route_to( m, tpcb, channel)
                    495:        struct mbuf                                     *m;
                    496:        register struct tp_pcb          *tpcb;
                    497:        caddr_t                                         channel;
                    498: {
                    499:        register struct sockaddr_iso *siso;     /* NOTE: this may be a sockaddr_in */
                    500:        extern struct tp_conn_param tp_conn_param[];
                    501:        struct pklcd *lcp = (struct pklcd *)channel;
                    502:        int error = 0;
                    503: 
                    504:        siso = mtod(m, struct sockaddr_iso *);
                    505:        IFTRACE(D_CONN)
                    506:                tptraceTPCB(TPPTmisc, 
                    507:                "route_to: so  afi netservice class",
                    508:                tpcb->tp_sock, siso->siso_addr.isoa_genaddr[0], tpcb->tp_netservice,
                    509:                        tpcb->tp_class);
                    510:        ENDTRACE
                    511:        IFDEBUG(D_CONN)
                    512:                printf("tp_route_to( m x%x, channel 0x%x, tpcb 0x%x netserv 0x%x)\n", 
                    513:                        m, channel, tpcb, tpcb->tp_netservice);
                    514:                printf("m->mlen x%x, m->m_data:\n", m->m_len);
                    515:                dump_buf(mtod(m, caddr_t), m->m_len);
                    516:        ENDDEBUG
                    517:        if (siso->siso_family != tpcb->tp_domain) {
                    518:                error = EAFNOSUPPORT;
                    519:                goto done;
                    520:        }
                    521:        IFDEBUG(D_CONN)
                    522:                printf("tp_route_to  calling nlp_pcbconn, netserv %d\n",
                    523:                        tpcb->tp_netservice);
                    524:        ENDDEBUG
                    525: #ifdef TPCONS
                    526:        if (lcp) {
                    527:                struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext,
                    528:                        *isop_new = (struct isopcb *)tpcb->tp_sock->so_pcb;
                    529:                remque(isop_new);
                    530:                free(isop_new, M_PCB);
                    531:                tpcb->tp_sock->so_pcb = (caddr_t)isop;
                    532:                if (isop->isop_refcnt == 0) {
                    533:                        extern struct isopcb tp_isopcb;
                    534:                        remque(isop);
                    535:                        insque(isop, &tp_isopcb);
                    536:                        isop->isop_head = &tp_isopcb;
                    537:                        iso_putsufx(isop, tpcb->tp_lsuffix, tpcb->tp_lsuffixlen, TP_LOCAL);
                    538:                }
                    539:                /* else there are already connections sharing this */
                    540:                isop->isop_refcnt++;
                    541:        } else
                    542: #endif
                    543:                error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_sock->so_pcb, m);
                    544:        if( error )
                    545:                goto done;
                    546: 
                    547:        {
                    548:                register int save_netservice = tpcb->tp_netservice;
                    549: 
                    550:                switch(tpcb->tp_netservice) {
                    551:                case ISO_COSNS:
                    552:                case ISO_CLNS:
                    553:                        /* This is a kludge but seems necessary so the passive end
                    554:                         * can get long enough timers. sigh.
                    555:                        if( siso->siso_addr.osinet_idi[1] == (u_char)IDI_OSINET )
                    556:                         */
                    557: #define        IDI_OSINET      0x0004  /* bcd of "0004" */     
                    558:                        if( siso->siso_addr.isoa_genaddr[2] == (char)IDI_OSINET ) {
                    559:                                if( tpcb->tp_dont_change_params == 0) {
                    560:                                        copyQOSparms( &tp_conn_param[ISO_COSNS],
                    561:                                                        &tpcb->_tp_param);
                    562:                                }
                    563:                                tpcb->tp_flags |= TPF_NLQOS_PDN;
                    564:                        }
                    565:                        /* drop through to IN_CLNS*/
                    566:                case IN_CLNS:
                    567:                        if (iso_localifa(siso))
                    568:                                tpcb->tp_flags |= TPF_PEER_ON_SAMENET;
                    569:                        if( (tpcb->tp_class & TP_CLASS_4)==0 ) {
                    570:                                error = EPROTOTYPE;
                    571:                                break;
                    572:                        } 
                    573:                        tpcb->tp_class = TP_CLASS_4;  /* IGNORE dont_change_parms */
                    574:                        break;
                    575: 
                    576:                case ISO_CONS:
                    577: #ifdef TPCONS
                    578:                        tpcb->tp_flags |= TPF_NLQOS_PDN;
                    579:                        if( tpcb->tp_dont_change_params == 0 ) {
                    580:                                copyQOSparms( &tp_conn_param[ISO_CONS],
                    581:                                                        &tpcb->_tp_param);
                    582:                        }
                    583:                        /*
                    584:                         * for use over x.25 really need a small receive window,
                    585:                         * need to start slowly, need small max negotiable tpdu size,
                    586:                         * and need to use the congestion window to the max
                    587:                         * IGNORES tp_dont_change_params for these!
                    588:                         */
                    589:                        if( tpcb->tp_sock->so_snd.sb_hiwat > 512 ) {
                    590:                                (void) soreserve(tpcb->tp_sock, 512, 512 );/* GAG */
                    591:                        }
                    592:                        tpcb->tp_rx_strat =  TPRX_USE_CW;
                    593: 
                    594:                        if( (tpcb->tp_nlproto != &nl_protosw[ISO_CONS]) ) {
                    595:                                IFDEBUG(D_CONN)
                    596:                                        printf(
                    597:                                        "tp_route_to( CHANGING nlproto old 0x%x new 0x%x)\n", 
                    598:                                                        tpcb->tp_nlproto , &nl_protosw[ISO_CONS]);
                    599:                                ENDDEBUG
                    600:                                tpcb->tp_nlproto = &nl_protosw[ISO_CONS];
                    601:                        }
                    602:                        /* class 4 doesn't need to open a vc now - may use one already 
                    603:                         * opened or may open one only when it sends a pkt.
                    604:                         */
                    605: #else TPCONS
                    606:                        error = ECONNREFUSED;
                    607: #endif TPCONS
                    608:                        break;
                    609:                default:
                    610:                        error = EPROTOTYPE;
                    611:                }
                    612: 
                    613:                ASSERT( save_netservice == tpcb->tp_netservice);
                    614:        }
                    615:        if (error) {
                    616:                tp_netcmd( tpcb, CONN_CLOSE);
                    617:                goto done;
                    618:        } 
                    619:        {       /* start with the global rtt, rtv stats */
                    620:                register int i =
                    621:                   (int) tpcb->tp_flags & (TPF_PEER_ON_SAMENET | TPF_NLQOS_PDN);
                    622: 
                    623:                tpcb->tp_rtt = tp_stat.ts_rtt[i];
                    624:                tpcb->tp_rtv = tp_stat.ts_rtv[i];
                    625:        }
                    626: done:
                    627:        IFDEBUG(D_CONN)
                    628:                printf("tp_route_to  returns 0x%x\n", error);
                    629:        ENDDEBUG
                    630:        IFTRACE(D_CONN)
                    631:                tptraceTPCB(TPPTmisc, "route_to: returns: error netserv class", error, 
                    632:                        tpcb->tp_netservice, tpcb->tp_class, 0);
                    633:        ENDTRACE
                    634:        return error;
                    635: }
                    636: 
                    637: 
                    638: /* class zero version */
                    639: void
                    640: tp0_stash( tpcb, e )
                    641:        register struct tp_pcb          *tpcb;
                    642:        register struct tp_event        *e;
                    643: {
                    644: #ifndef lint
                    645: #define E e->ATTR(DT_TPDU)
                    646: #else lint
                    647: #define E e->ev_union.EV_DT_TPDU
                    648: #endif lint
                    649: 
                    650:        register struct sockbuf *sb = &tpcb->tp_sock->so_rcv;
                    651:        register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
                    652: 
                    653:        IFPERF(tpcb)
                    654:                PStat(tpcb, Nb_from_ll) += E.e_datalen;
                    655:                tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time,
                    656:                                E.e_seq, PStat(tpcb, Nb_from_ll), E.e_datalen);
                    657:        ENDPERF
                    658: 
                    659:        IFDEBUG(D_STASH)
                    660:                printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x", 
                    661:                E.e_seq, E.e_datalen, E.e_eot);
                    662:        ENDDEBUG
                    663: 
                    664:        IFTRACE(D_STASH)
                    665:                tptraceTPCB(TPPTmisc, "stash EQ: seq len eot", 
                    666:                E.e_seq, E.e_datalen, E.e_eot, 0);
                    667:        ENDTRACE
                    668: 
                    669:        if ( E.e_eot ) {
                    670:                register struct mbuf *n = E.e_data;
                    671:                n->m_flags |= M_EOR;
                    672:                n->m_act = MNULL; /* set on tp_input */
                    673:        }
                    674:        sbappend(sb, E.e_data);
                    675:        IFDEBUG(D_STASH)
                    676:                dump_mbuf(sb->sb_mb, "stash 0: so_rcv after appending");
                    677:        ENDDEBUG
                    678:        if (tpcb->tp_netservice != ISO_CONS)
                    679:                printf("tp0_stash: tp running over something wierd\n");
                    680:        else {
                    681:                register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
                    682:                pk_flowcontrol(lcp, sbspace(sb) <= 0, 1);
                    683:        }
                    684: } 
                    685: 
                    686: void
                    687: tp0_openflow(tpcb)
                    688: register struct tp_pcb *tpcb;
                    689: {
                    690:        register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
                    691:        if (tpcb->tp_netservice != ISO_CONS)
                    692:                printf("tp0_openflow: tp running over something wierd\n");
                    693:        else {
                    694:                register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
                    695:                if (lcp->lcd_rxrnr_condition)
                    696:                        pk_flowcontrol(lcp, 0, 0);
                    697:        }
                    698: }
                    699: #ifndef TPCONS
                    700: static
                    701: pk_flowcontrol() {}
                    702: #endif
                    703: 
                    704: #ifdef TP_PERF_MEAS
                    705: /*
                    706:  * CALLED FROM:
                    707:  *  tp_ctloutput() when the user sets TPOPT_PERF_MEAS on
                    708:  *  and tp_newsocket() when a new connection is made from 
                    709:  *  a listening socket with tp_perf_on == true.
                    710:  * FUNCTION and ARGUMENTS:
                    711:  *  (tpcb) is the usual; this procedure gets a clear cluster mbuf for
                    712:  *  a tp_pmeas structure, and makes tpcb->tp_p_meas point to it.
                    713:  * RETURN VALUE:
                    714:  *  ENOBUFS if it cannot get a cluster mbuf.
                    715:  */
                    716: 
                    717: int 
                    718: tp_setup_perf(tpcb)
                    719:        register struct tp_pcb *tpcb;
                    720: {
                    721:        register struct mbuf *q;
                    722: 
                    723:        if( tpcb->tp_p_meas == 0 ) {
                    724:                MGET(q, M_WAITOK, MT_PCB);
                    725:                if (q == 0)
                    726:                        return ENOBUFS;
                    727:                MCLGET(q, M_WAITOK);
                    728:                if ((q->m_flags & M_EXT) == 0) {
                    729:                        (void) m_free(q);
                    730:                        return ENOBUFS;
                    731:                }
                    732:                q->m_len = sizeof (struct tp_pmeas);
                    733:                tpcb->tp_p_mbuf = q;
                    734:                tpcb->tp_p_meas = mtod(q, struct tp_pmeas *);
                    735:                bzero( (caddr_t)tpcb->tp_p_meas, sizeof (struct tp_pmeas) );
                    736:                IFDEBUG(D_PERF_MEAS)
                    737:                        printf(
                    738:                        "tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n", 
                    739:                                tpcb, tpcb->tp_sock, tpcb->tp_lref, 
                    740:                                tpcb->tp_p_meas, tpcb->tp_perf_on);
                    741:                ENDDEBUG
                    742:                tpcb->tp_perf_on = 1;
                    743:        }
                    744:        return 0;
                    745: }
                    746: #endif TP_PERF_MEAS
                    747: 
                    748: #ifdef ARGO_DEBUG
                    749: dump_addr (addr)
                    750:        register struct sockaddr *addr;
                    751: {
                    752:        switch( addr->sa_family ) {
                    753:                case AF_INET:
                    754:                        dump_inaddr((struct sockaddr_in *)addr);
                    755:                        break;
                    756: #ifdef ISO
                    757:                case AF_ISO:
                    758:                        dump_isoaddr((struct sockaddr_iso *)addr);
                    759:                        break;
                    760: #endif ISO
                    761:                default:
                    762:                        printf("BAD AF: 0x%x\n", addr->sa_family);
                    763:                        break;
                    764:        }
                    765: }
                    766: 
                    767: #define        MAX_COLUMNS     8
                    768: /*
                    769:  *     Dump the buffer to the screen in a readable format. Format is:
                    770:  *
                    771:  *             hex/dec  where hex is the hex format, dec is the decimal format.
                    772:  *             columns of hex/dec numbers will be printed, followed by the
                    773:  *             character representations (if printable).
                    774:  */
                    775: Dump_buf(buf, len)
                    776: caddr_t        buf;
                    777: int            len;
                    778: {
                    779:        int             i,j;
                    780: #define Buf ((u_char *)buf)
                    781:        printf("Dump buf 0x%x len 0x%x\n", buf, len);
                    782:        for (i = 0; i < len; i += MAX_COLUMNS) {
                    783:                printf("+%d:\t", i);
                    784:                for (j = 0; j < MAX_COLUMNS; j++) {
                    785:                        if (i + j < len) {
                    786:                                printf("%x/%d\t", Buf[i+j], Buf[i+j]);
                    787:                        } else {
                    788:                                printf("        ");
                    789:                        }
                    790:                }
                    791: 
                    792:                for (j = 0; j < MAX_COLUMNS; j++) {
                    793:                        if (i + j < len) {
                    794:                                if (((Buf[i+j]) > 31) && ((Buf[i+j]) < 128))
                    795:                                        printf("%c", Buf[i+j]);
                    796:                                else
                    797:                                        printf(".");
                    798:                        }
                    799:                }
                    800:                printf("\n");
                    801:        }
                    802: }
                    803: 
                    804: 
                    805: #endif ARGO_DEBUG
                    806: 

unix.superglobalmegacorp.com

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