Annotation of Net2/netiso/tp_subr2.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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