Annotation of XNU/bsd/netat/adsp_Packet.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* 
                     23:  * Packet.c 
                     24:  *
                     25:  * v01.23  All incoming packets come here first    06/21/90 mbs
                     26:  *    Modified for MP, 1996 by Tuyen Nguyen
                     27:  *   Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
                     28:  */
                     29: 
                     30: #include <sys/errno.h>
                     31: #include <sys/types.h>
                     32: #include <sys/param.h>
                     33: #include <machine/spl.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/kernel.h>
                     36: #include <sys/proc.h>
                     37: #include <sys/filedesc.h>
                     38: #include <sys/fcntl.h>
                     39: #include <sys/mbuf.h>
                     40: #include <sys/ioctl.h>
                     41: #include <sys/malloc.h>
                     42: #include <sys/socket.h>
                     43: #include <sys/socketvar.h>
                     44: #include <sys/time.h>
                     45: 
                     46: #include <net/if.h>
                     47: 
                     48: #include <netat/sysglue.h>
                     49: #include <netat/appletalk.h>
                     50: #include <netat/at_pcb.h>
                     51: #include <netat/ddp.h>
                     52: #include <netat/at_var.h>
                     53: 
                     54: #include <netat/adsp.h>
                     55: #include <netat/adsp_internal.h>
                     56: 
                     57: extern at_ifaddr_t *ifID_home;
                     58: 
                     59: /*
                     60:  * GleanSession
                     61:  *
                     62:  * We just got a packet for this session, glean its address &
                     63:  * reset probe timer
                     64:  *
                     65:  * INPUTS:
                     66:  *    Session
                     67:  * OUTPUTS:
                     68:  *    none
                     69:  */
                     70: static void GleanSession(sp)           /* (CCBPtr sp) */
                     71:     CCBPtr sp;
                     72: {
                     73:     if (sp->openState == O_STATE_OPEN) {
                     74:        /* This is true for both state = sOpen & sClosing */
                     75:         RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
                     76:        InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 
                     77:                        sp->probeInterval);
                     78:        sp->probeCntr   = 4;
                     79:     }
                     80: 
                     81: }
                     82: 
                     83: 
                     84: /*
                     85:  * The same code handles incoming Open Connection Request,
                     86:  * Open Request + Ack, Open Connection Ack, Open Connection Denial
                     87:  *
                     88:  * We could be in four different states, LISTEN, OPENWAIT, ESTABLISHED,
                     89:  * OPEN.
                     90:  */
                     91: 
                     92: /*
                     93:  *
                     94:  * Ok, there are 16 combinations.  8 are do-nothings, 2 have to be
                     95:  * special cased (Open Deny and Req+Ack on Open session)
                     96:  *
                     97:  * Build a table of actions:
                     98:  *    Ignore?
                     99:  *    What to match on (local socket, whole address, DestCID, SrcCID)
                    100:  *    What to send (Ack or Req+Ack)
                    101:  *    Next State (both the ccb state and the open state)
                    102:  */
                    103: 
                    104: /*
                    105:  *
                    106:  */
                    107: typedef struct {
                    108:     u_char match;              /* Characteristics that have to match 
                    109:                                 * (Bit-Mapped, see below) */
                    110:     char action;               /* What to do if CCB matches */
                    111:     char send;                 /* What to send in response 
                    112:                                 * (Bit mapped, same as sendCtl field of 
                    113:                                 * CCB) */
                    114:     char openState;            /* Next Open state */
                    115:     char state;                        /* Next ccb state. */
                    116:     char pad;                  /* Too bad we need this to make structure 
                    117:                                 * even size */
                    118: } TBL, *TBLPtr;
                    119: 
                    120: #define M_LSOC         0x01    /* bit  0 - Match on local socket */
                    121: #define M_ADDR         0x02    /* bit  1 - Match on whole address */
                    122: #define M_DCID         0x04    /* bit  2 - Match on DestCID */
                    123: #define M_SCID         0x08    /* bit  3 - Match SrcCID */
                    124: #define M_DCIDZERO     0x10    /* bit  4 - Dest CID must be 0 */
                    125: #define M_SCIDZERO     0x20    /* bit  5 - Src CID must be 0 */
                    126: #define M_FILTER       0x40    /* bit  6 - Match address filter */
                    127: #define M_IGNORE       0x80    /* bit  7 - Ignore */
                    128: 
                    129: #define A_COMPLETE     0x01    /* Complete open parameter block */
                    130: #define A_SAVEPARMS    0x02    /* Save connection parameters */
                    131: #define A_OREQACKOPEN  0x04    /* special case for open Req+Ack on 
                    132:                                 * OPEN session */
                    133: #define A_GLEAN                0x08    /* We'll be talking back to this guy */
                    134: #define A_DENY         0x10    /* We've been denied! */
                    135: 
                    136: 
                    137: /*
                    138:  * So here's our table
                    139:  */
                    140: 
                    141: static TBL tbl[16] = {
                    142: 
                    143: /*
                    144:  * For Open Request ($81)
                    145:  *
                    146:  *     LISTENING
                    147:  *             Match on destination socket
                    148:  *             Match on address filter
                    149:  *             Dest CID must be 0
                    150:  *             Glean connection
                    151:  *             Save Open Connection parameters
                    152:  *             Send OREQACK
                    153:  *             Change state to ESTABLISHED
                    154:  */
                    155:        {       M_LSOC + M_DCIDZERO + M_FILTER,
                    156:                A_SAVEPARMS + A_GLEAN,
                    157:                B_CTL_OREQACK,
                    158:                O_STATE_ESTABLISHED,
                    159:                sOpening,
                    160:                0
                    161:        },
                    162: 
                    163: /*
                    164:  *
                    165:  *     OPENWAIT
                    166:  *             Match on Remote Address & destination socket
                    167:  *             Dest CID must be 0
                    168:  *             Save Open Connection parameters
                    169:  *             Send Ack
                    170:  *             Change state to ESTABLISHED
                    171:  */
                    172:        {       M_LSOC + M_ADDR + M_DCIDZERO,
                    173:                A_SAVEPARMS + A_GLEAN,
                    174:                B_CTL_OACK,
                    175:                O_STATE_ESTABLISHED,
                    176:                sOpening,
                    177:                0
                    178:        },
                    179: /*
                    180:  *
                    181:  *     ESTABLISHED
                    182:  *             Match on Remote Address & SrcCID
                    183:  *             Dest CID must be 0
                    184:  *             Send Req + Ack
                    185:  */
                    186:        {       M_ADDR + M_SCID + M_DCIDZERO, 
                    187:                A_GLEAN, 
                    188:                B_CTL_OACK, 
                    189:                O_STATE_ESTABLISHED,
                    190:                sOpening,
                    191:                0
                    192:        },
                    193: /*
                    194:  *     OPEN
                    195:  *             Ignore
                    196:  */
                    197:        {       M_IGNORE, 
                    198:                0, 
                    199:                0, 
                    200:                0,
                    201:                0,
                    202:                0
                    203:        },
                    204: 
                    205: /*
                    206:  *
                    207:  * For Open Ack ($82)
                    208:  *
                    209:  *     LISTENING
                    210:  *             Ignore
                    211:  */
                    212:        {       M_IGNORE, 
                    213:                0, 
                    214:                0, 
                    215:                0,
                    216:                0,
                    217:                0
                    218:        },
                    219: /*
                    220:  *
                    221:  *     OPENWAIT
                    222:  *             Ignore
                    223:  */
                    224:        {       M_IGNORE, 
                    225:                0, 
                    226:                0, 
                    227:                0, 
                    228:                0, 
                    229:                0
                    230:        },
                    231: /*
                    232:  *
                    233:  *     ESTABLISHED
                    234:  *             Match on SrcCID & DestCID & Address & Local Socket
                    235:  *             Complete Listen or Connect PB
                    236:  *             OPEN
                    237:  */
                    238:        {       M_ADDR + M_DCID + M_SCID + M_LSOC, 
                    239:                A_COMPLETE + A_GLEAN, 
                    240:                0, 
                    241:                O_STATE_OPEN,
                    242:                sOpen,
                    243:                0
                    244:        },
                    245: /*
                    246:  *
                    247:  *     OPEN
                    248:  *             Ignore
                    249: */
                    250:        {       M_IGNORE, 
                    251:                0, 
                    252:                0, 
                    253:                0, 
                    254:                0, 
                    255:                0
                    256:        },
                    257: 
                    258: /*
                    259:  *
                    260:  * For Open Request + Ack ($83)
                    261:  *
                    262:  *     LISTENING
                    263:  *             Ignore
                    264: */
                    265:        {       M_IGNORE, 
                    266:                0, 
                    267:                0, 
                    268:                0, 
                    269:                0, 
                    270:                0
                    271:        },
                    272: /*
                    273:  *
                    274:  *     OPENWAIT
                    275:  *             Match on DestCID & socket
                    276:  *                     Do not test remote address -- our open req could have
                    277:  *                     been passed to another address by a connection server
                    278:  *             Save Open Connection parameters
                    279:  *             Complete Connect parameter block
                    280:  *             Send Ack
                    281:  *             OPEN
                    282:  */
                    283:        {       M_DCID + M_LSOC,
                    284:                A_COMPLETE + A_SAVEPARMS + A_GLEAN,
                    285:                B_CTL_OACK,
                    286:                O_STATE_OPEN,
                    287:                sOpen,
                    288:                0
                    289:        },
                    290: /*
                    291:  *
                    292:  *     ESTABLISHED
                    293:  *             Ignore
                    294:  */
                    295:        {       M_IGNORE, 
                    296:                0, 
                    297:                0, 
                    298:                0, 
                    299:                0, 
                    300:                0
                    301:        },
                    302: /*
                    303:  *
                    304:  *     OPEN
                    305:  *             Match on Remote Address & SrcCID & DestCID & Local Socket
                    306:  *             If we've never gotten any data
                    307:  *             Send Ack & Retransmit
                    308:  */
                    309:        {       M_ADDR + M_DCID + M_SCID + M_LSOC,
                    310:                A_OREQACKOPEN + A_GLEAN,
                    311:                B_CTL_OACK,
                    312:                O_STATE_OPEN,
                    313:                sOpen,
                    314:                0
                    315:        },
                    316: 
                    317: /*
                    318:  *
                    319:  *
                    320:  * For Open Deny ($84)
                    321:  *
                    322:  *     LISTENING
                    323:  *             Ignore
                    324:  */
                    325:        {       M_IGNORE, 
                    326:                0, 
                    327:                0, 
                    328:                0, 
                    329:                0, 
                    330:                0
                    331:        },
                    332: /*
                    333:  *
                    334:  *     OPENWAIT
                    335:  *             Match on DestCID & Address
                    336:  *             Source CID must be 0
                    337:  *             Complete with error
                    338:  */
                    339:        {       M_SCIDZERO + M_DCID + M_ADDR, 
                    340:                A_DENY,
                    341:                0, 
                    342:                O_STATE_NOTHING,
                    343:                sClosed,
                    344:                0
                    345:        },
                    346: /*
                    347:  *
                    348:  *     ESTABLISHED
                    349:  *             Ignore
                    350:  */
                    351:        {       M_IGNORE, 
                    352:                0, 
                    353:                0, 
                    354:                0, 
                    355:                0, 
                    356:                0
                    357:        },      /* %%% No we probably don't want to ignore in this case */
                    358: /*
                    359:  *
                    360:  *    OPEN
                    361:  *       Ignore
                    362:  */
                    363:        {       M_IGNORE, 
                    364:                0, 
                    365:                0, 
                    366:                0, 
                    367:                0, 
                    368:                0
                    369:        }
                    370: };
                    371: 
                    372: extern at_ifaddr_t *ifID_table[];
                    373: 
                    374: /*
                    375:  * Used to search down queue of sessions for a session waiting for an
                    376:  * open request.
                    377:  */
                    378: typedef struct {
                    379:    AddrUnion   addr;
                    380:    word                dstCID;
                    381:    word                srcCID;
                    382:    byte                socket;
                    383:    byte                descriptor;
                    384:    byte                idx;            /* Index into state tables */
                    385:    TBLPtr      t;              /* Ptr to entry in table above */
                    386: } MATCH, *MATCHPtr;
                    387: 
                    388: /*
                    389:  * MatchStream
                    390:  *
                    391:  * Called by Rx connection to find which stream (if any) should get this open
                    392:  * request/ack/req+ack/deny packet.
                    393:  *
                    394:  */
                    395: 
                    396: static boolean
                    397: MatchStream(sp, m)             /* (CCBPtr sp, MATCHPtr m) */
                    398:     CCBPtr sp;
                    399:     MATCHPtr m;
                    400: {
                    401:        unsigned char match;
                    402:        struct adspcmd  *opb;
                    403:     
                    404:        if (sp->openState < O_STATE_LISTEN ||
                    405:            sp->openState > O_STATE_OPEN)
                    406:            return 0;
                    407: 
                    408: 
                    409:        m->t = &tbl[sp->openState - O_STATE_LISTEN + m->idx];
                    410: 
                    411:        match = m->t->match;    /* Get match criteria */
                    412: 
                    413:        if (match & M_IGNORE)   /* Ignore this combination */
                    414:            return 0;
                    415: 
                    416:        if (match & M_LSOC) {   /* Match on Local socket */
                    417:            if (sp->localSocket != m->socket)
                    418:                return 0;
                    419:        }
                    420: 
                    421:        if (match & M_ADDR) {   /* Match on Address */
                    422:            AddrUnion   addr;
                    423:            addr = m->addr;     /* Make local copy for efficiency */
                    424:            if (sp->remoteAddress.a.node != addr.a.node)
                    425:                return 0;
                    426:            if (sp->remoteAddress.a.socket != addr.a.socket)
                    427:                return 0;
                    428:            if (sp->remoteAddress.a.net && addr.a.net &&
                    429:                (sp->remoteAddress.a.net != addr.a.net))
                    430:                return 0;
                    431:                        
                    432:            /*
                    433:             * Handle special case to reject self-sent open request
                    434:             */
                    435:            if ((m->srcCID == sp->locCID) && 
                    436:                (addr.a.node == ifID_home->ifThisNode.s_node) &&
                    437:                /* *** was (addr.a.node == ddpcfg.node_addr.node) && *** */
                    438:                ((addr.a.net == 0) || 
                    439:                 (ifID_home->ifThisNode.s_net == 0) || 
                    440:                 (ifID_home->ifThisNode.s_net == addr.a.net)) )
                    441:              /* *** was 
                    442:                (NET_VALUE(ddpcfg.node_addr.net) == 0) || 
                    443:                (NET_VALUE(ddpcfg.node_addr.net) == NET_VALUE(addr.a.net))) )
                    444:                 *** */
                    445:                                /* CID's match, and */
                    446:                                /* If nodeID matches, and */
                    447:                                /* network matches, */
                    448:                return 0;       /* then came from us! */
                    449:        }
                    450:        
                    451:        if (match & M_DCID) {   /* Match on DestCID */
                    452:            if (sp->locCID != m->dstCID)
                    453:                return 0;
                    454:        }
                    455:        
                    456:        if (match & M_SCID) {   /* Match on SourceCID */
                    457:            if (sp->remCID != m->srcCID)
                    458:                return 0;
                    459:        }
                    460:        
                    461:        if (match & M_DCIDZERO) { /* Destination CID must be 0 */
                    462:            if (m->dstCID != 0)
                    463:                return 0;
                    464:        }
                    465:        
                    466:        if (match & M_SCIDZERO) /* Source CID must be 0 */
                    467:        {
                    468:            if (m->srcCID != 0)
                    469:                return 0;
                    470:        }
                    471:        
                    472:        if (match & M_FILTER) { /* Check address filter? */
                    473:            if ((opb = sp->opb)) /* There should be a param block... */
                    474:            {
                    475:                AddrUnion       addr;
                    476:                addr = m->addr; /* Make local copy for efficiency */
                    477:                if ((opb->u.openParams.filterAddress.net && 
                    478:                     addr.a.net &&
                    479:                     opb->u.openParams.filterAddress.net != addr.a.net) ||
                    480:                    (opb->u.openParams.filterAddress.node != 0 &&
                    481:                     opb->u.openParams.filterAddress.node != addr.a.node)||
                    482:                    (opb->u.openParams.filterAddress.socket != 0 &&
                    483:                     opb->u.openParams.filterAddress.socket != addr.a.socket))
                    484:                    return 0;
                    485:            }
                    486:        }
                    487:        
                    488:        return 1;
                    489: }
                    490: 
                    491: /*
                    492:  * MatchListener
                    493:  *
                    494:  * Called by rx connection to see which connection listener (if any) should
                    495:  * get this incoming open connection request.
                    496:  *
                    497:  */
                    498: 
                    499: static boolean MatchListener(sp, m) /* (CCBPtr sp, MATCHPtr m) */
                    500:     CCBPtr sp;
                    501:     MATCHPtr m;
                    502: {
                    503: 
                    504:     if ((sp->state == (word)sListening) && /* This CCB is a listener */
                    505:        (sp->localSocket == m->socket)) /* on the right socket */
                    506:        return 1;
                    507:     
                    508:     return 0;
                    509: }
                    510: 
                    511: /*
                    512:  * RXConnection
                    513:  *
                    514:  * We just received one of the 4 Open Connection packets
                    515:  * Interrupts are masked OFF at this point
                    516:  *
                    517:  * INPUTS:
                    518:  *     spPtr   Place to put ptr to stream (if we found one -- not 
                    519:  *                                             for listeners)
                    520:  *     f       Pointer to ADSP header for packet, data follows behind it
                    521:  *     len     # of byte in ADSP header + data
                    522:  *     addr    Who sent the packet
                    523:  *     dsoc    Where they sent it to
                    524:  *
                    525:  * OUTPUTS:
                    526:  *    Returns 1 if packet was ignored
                    527:  */
                    528: static int RXConnection(gref, spPtr, f, len, addr, dsoc) 
                    529:     /* (CCBPtr *spPtr, ADSP_FRAMEPtr f, word len, AddrUnion addr, byte dsoc) */
                    530:     gref_t *gref;                      /* READ queue */
                    531:     CCBPtr *spPtr;
                    532:     ADSP_FRAMEPtr f;
                    533:     int len;
                    534:     AddrUnion addr;
                    535:     unsigned char dsoc;
                    536: {
                    537:     CCBPtr sp;
                    538:     ADSP_OPEN_DATAPtr op;
                    539:     struct adspcmd *pb;
                    540:     MATCH m;
                    541:     gbuf_t *mp;
                    542:     ADSP_FRAMEPtr adspp;
                    543:     ADSP_OPEN_DATAPtr adspop;
                    544:     int s;
                    545: 
                    546:     op = (ADSP_OPEN_DATAPtr)&f->data[0]; /* Point to Open-Connection parms */
                    547:     len -= ADSP_FRAME_LEN;
                    548:     
                    549:     if (len < (sizeof(ADSP_OPEN_DATA))) /* Packet too small */
                    550:        return 1;
                    551: 
                    552: 
                    553:     if (UAS_VALUE(op->version) != netw(0x0100)) { /* Check version num (on even-byte) */
                    554:        /*
                    555:         * The open request has been denied.  Try to send him a denial.  
                    556:         */
                    557: 
                    558:        mp = gbuf_alloc(AT_WR_OFFSET + DDPL_FRAME_LEN + ADSP_FRAME_LEN + ADSP_OPEN_FRAME_LEN,
                    559:                    PRI_LO);
                    560:        gbuf_rinc(mp,AT_WR_OFFSET);
                    561:        gbuf_wset(mp,DDPL_FRAME_LEN);
                    562:        adspp = (ADSP_FRAMEPtr)gbuf_wptr(mp);
                    563:        gbuf_winc(mp,ADSP_FRAME_LEN);
                    564:        bzero((caddr_t) gbuf_rptr(mp),DDPL_FRAME_LEN + ADSP_FRAME_LEN + 
                    565:              ADSP_OPEN_FRAME_LEN);
                    566:        adspp->descriptor = ADSP_CONTROL_BIT | ADSP_CTL_ODENY;
                    567:        adspop = (ADSP_OPEN_DATAPtr)gbuf_wptr(mp);
                    568:        gbuf_winc(mp,ADSP_OPEN_FRAME_LEN);
                    569:        UAS_UAS(adspop->dstCID, f->CID);
                    570:        UAS_ASSIGN(adspop->version, 0x100);
                    571:        adsp_sendddp(0, mp, DDPL_FRAME_LEN + ADSP_FRAME_LEN + 
                    572:                   ADSP_OPEN_FRAME_LEN, &addr, DDP_ADSP);
                    573: 
                    574:        return 0;
                    575:     }
                    576:     m.addr = addr;
                    577:     m.socket = dsoc;
                    578:     m.descriptor = f->descriptor;
                    579:     m.srcCID = UAS_VALUE(f->CID);
                    580:     m.dstCID = UAS_VALUE(op->dstCID);  /* On even-byte boundry */
                    581:     m.idx = ((f->descriptor & ADSP_CONTROL_MASK) - 1) * 4;
                    582:                                           
                    583:     /*
                    584:      * See if we can find a stream that knows what to do with this packet
                    585:      */
                    586:     if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchStream)) == 0)
                    587:     {
                    588:        struct adspcmd *p;
                    589:        struct adspcmd *n;
                    590:        /*
                    591:         * No match, so look for connection listeners if this is an 
                    592:         * open request
                    593:         */
                    594:        if ((f->descriptor & ADSP_CONTROL_MASK) != (byte)ADSP_CTL_OREQ)
                    595:            return 1;
                    596: 
                    597:        if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, 
                    598:                                  (ProcPtr)MatchListener)) == 0)
                    599:            return 1;
                    600: 
                    601:        ATDISABLE(s, sp->lock);
                    602:        p = (struct adspcmd *)&sp->opb;
                    603:        while (n = (struct adspcmd *)p->qLink) /* Hunt down list of listens */
                    604:        {
                    605:            /* Check address filter */
                    606:            if (((n->u.openParams.filterAddress.net == 0) ||
                    607:                 (addr.a.net == 0) ||
                    608:                 (n->u.openParams.filterAddress.net == addr.a.net)) &&
                    609:                
                    610:                ((n->u.openParams.filterAddress.node == 0) || 
                    611:                 (n->u.openParams.filterAddress.node == addr.a.node)) &&
                    612:                
                    613:                ((n->u.openParams.filterAddress.socket == 0) || 
                    614:                 (n->u.openParams.filterAddress.socket == addr.a.socket))) {
                    615:                p->qLink = n->qLink; /* Unlink this param block */
                    616:                n->u.openParams.remoteCID = m.srcCID;
                    617:                *((AddrUnionPtr)&n->u.openParams.remoteAddress) = addr;
                    618:                n->u.openParams.sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
                    619:                n->u.openParams.sendWindow = netw(UAS_VALUE(f->pktRecvWdw));
                    620:                n->u.openParams.attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq));
                    621:                n->ioResult = 0;
                    622:                ATENABLE(s, sp->lock);
                    623:                completepb(sp, n); /* complete copy of request */
                    624:                                /* complete(n, 0); */
                    625:                return 0;
                    626:            }                   /* found CLListen */
                    627:                        
                    628:            p = n;              /* down the list we go... */
                    629:                        
                    630:        }                       /* while */
                    631:                
                    632:        ATENABLE(s, sp->lock);
                    633:        return 1;
                    634:     }
                    635:        
                    636:     *spPtr = sp;               /* Save ptr to stream we just found */
                    637:        
                    638:        ATDISABLE(s, sp->lock);
                    639:     sp->openState = m.t->openState; /* Move to next state (may be same) */
                    640:     sp->state = m.t->state;    /* Move to next state (may be same) */
                    641: 
                    642:     if (m.t->action & A_SAVEPARMS) { /* Need to Save open-conn parms */
                    643:        sp->firstRtmtSeq = sp->sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
                    644:        sp->sendWdwSeq = netdw(UAL_VALUE(f->pktNextRecvSeq)) + netw(UAS_VALUE(f->pktRecvWdw)) - 1;
                    645:        sp->attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq)); /* on even boundry */
                    646: 
                    647:                
                    648:        sp->remCID = UAS_VALUE(f->CID); /* Save Source CID as RemCID */
                    649:        UAS_UAS(sp->of.dstCID, f->CID); /* Save CID in open ctl packet */
                    650:                
                    651:        sp->remoteAddress = addr; /* Save his address */
                    652: 
                    653:     }
                    654:        ATENABLE(s, sp->lock);
                    655: 
                    656:     if (m.t->action & A_DENY) {        /* We've been denied ! */
                    657:        DoClose(sp, errOpenDenied, -1);
                    658:     }
                    659: 
                    660:     if (m.t->action & A_OREQACKOPEN) { 
                    661:                                /* Special case for OREQACK */
                    662:                                /* on an open session */
                    663:         RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
                    664:        sp->sendSeq = sp->firstRtmtSeq;
                    665:        sp->pktSendCnt  = 0;
                    666:        sp->waitingAck  = 0;
                    667:        sp->callSend = 1;
                    668:     }
                    669: 
                    670:     if (m.t->send) {           /* Need to send a response */
                    671:        sp->sendCtl |= m.t->send;
                    672:        sp->callSend = 1;
                    673:     }
                    674: 
                    675:     if (m.t->action & A_COMPLETE) { /* Need to complete open param blk */
                    676:         RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
                    677:                        
                    678:        if (pb = sp->opb) {
                    679:            sp->opb = 0;
                    680:            pb->u.openParams.localCID = sp->locCID;
                    681:            pb->u.openParams.remoteCID = sp->remCID;
                    682:            pb->u.openParams.remoteAddress = 
                    683:                *((at_inet_t *)&sp->remoteAddress);
                    684:            pb->u.openParams.sendSeq = sp->sendSeq;
                    685:            pb->u.openParams.sendWindow = sp->sendWdwSeq - sp->sendSeq;
                    686:            pb->u.openParams.attnSendSeq = sp->attnSendSeq;
                    687:            pb->ioResult = 0;
                    688:            completepb(sp, pb); /* complete(pb, 0); */
                    689:            return 0;
                    690:        }
                    691:                                /* Start probe timer */
                    692:        InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 
                    693:                        sp->probeInterval);
                    694:     }
                    695:     return 0;
                    696: }
                    697: 
                    698: /*
                    699:  * ADSPPacket
                    700:  *
                    701:  * When a packet is received by the protocol stack with DDP type equal
                    702:  * to ADSP, then execution comes here
                    703:  *
                    704:  * DS is set to ATALK's DGROUP
                    705:  *
                    706:  * This routine, or one of its children MUST call glean packet
                    707:  *
                    708:  * INPUTS:
                    709:  *    Pointer to DDP header 
                    710:  * OUTPUTS:
                    711:  *    none
                    712:  *
                    713:  * Note that the incoming message block (mp) is usually discarded, either
                    714:  * by the "ignored" path, or via the "checksend" path.  The only case
                    715:  * where the message is NOT freed is via the RxData case in the
                    716:  * non control packet switch.  I zero mp after the RxData case succeeds
                    717:  * so that mp will not be freed.
                    718:  */
                    719: int adspPacket(gref, mp) 
                    720:     /* (bytePtr data, word len, AddrUnion a, byte dsoc) */
                    721:     gref_t *gref;
                    722:     gbuf_t *mp;
                    723: {
                    724:     unsigned char *bp;
                    725:     int len;
                    726:     AddrUnion a;
                    727:     int dsoc;
                    728:     int s;
                    729:     register DDPX_FRAME *ddp;  /* DDP frame pointer */
                    730:     register ADSP_FRAMEPtr f;  /* Frame */
                    731:     CCBPtr sp;
                    732: 
                    733:     sp = 0;                    /* No stream */
                    734:     bp = (unsigned char *)gbuf_rptr(mp);
                    735:     ddp = (DDPX_FRAME *)bp;
                    736:     if (ddp->ddpx_type != DDP_ADSP)
                    737:        return -1;
                    738:     f = (ADSP_FRAMEPtr)(bp + DDPL_FRAME_LEN);
                    739: 
                    740:     len = UAS_VALUE(ddp->ddpx_length) & 0x3ff; /* (ten bits of length) */
                    741:     len -= DDPL_FRAME_LEN;
                    742:     if (len < (sizeof(ADSP_FRAME) - 1))        /* Packet too small */
                    743:        return -1;              /* mark the failure */
                    744: 
                    745:     a.a.net = NET_VALUE(ddp->ddpx_snet);
                    746:     a.a.node = ddp->ddpx_snode;
                    747:     a.a.socket = ddp->ddpx_source;
                    748: 
                    749:     dsoc = ddp->ddpx_dest;
                    750: 
                    751:     if (sp = (CCBPtr)FindSender(f, a))
                    752:        GleanSession(sp);
                    753: 
                    754:     if (f->descriptor & ADSP_ATTENTION_BIT) { /* ATTN packet */
                    755:        if (sp && RXAttention(sp, mp, f, len)) 
                    756:            goto ignore;
                    757:        else
                    758:            mp = 0;             /* attention data is being held */
                    759:     }                          /* ATTENTION BIT */
                    760: 
                    761:     else if (f->descriptor & ADSP_CONTROL_BIT) { /* Control packet */
                    762:        switch (f->descriptor & ADSP_CONTROL_MASK) {
                    763:        case ADSP_CTL_PROBE:    /* Probe or acknowledgement */
                    764:            if (sp)
                    765:                CheckRecvSeq(sp, f);
                    766:            break;
                    767: 
                    768:        case ADSP_CTL_OREQ:     /* Open Connection Request */
                    769:        case ADSP_CTL_OREQACK:  /* Open Request and acknowledgement */
                    770:        case ADSP_CTL_OACK:     /* Open Request acknowledgment */
                    771:        case ADSP_CTL_ODENY:    /* Open Request denial */
                    772:            if (RXConnection(gref, &sp, f, len, a, dsoc))
                    773:                goto ignore;
                    774:            break;
                    775:                        
                    776:        case ADSP_CTL_CLOSE:    /* Close connection advice */
                    777:            if (sp) {
                    778:                /* This pkt may also ack some data we sent */
                    779:                CheckRecvSeq(sp, f); 
                    780:                RxClose(sp);
                    781:                sp = 0;
                    782:            } else
                    783:                goto ignore;
                    784:            break;
                    785: 
                    786:        case ADSP_CTL_FRESET:   /* Forward Reset */
                    787:                                /* May I rot in hell for the code below... */
                    788:            if (sp && (CheckRecvSeq(sp, f), RXFReset(sp, f)))
                    789:                goto ignore;
                    790:            break;
                    791:                        
                    792:        case ADSP_CTL_FRESET_ACK: /* Forward Reset Acknowledgement */
                    793:            if (sp && (CheckRecvSeq(sp, f), RXFResetAck(sp, f)))
                    794:                goto ignore;
                    795:            break;
                    796: 
                    797:        case ADSP_CTL_RETRANSMIT: /* Retransmit advice */
                    798:            if (sp) {
                    799:                /* This pkt may also ack some data we sent */
                    800:                CheckRecvSeq(sp, f); 
                    801:                RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
                    802:                ATDISABLE(s, sp->lock);
                    803:                sp->sendSeq = sp->firstRtmtSeq;
                    804:                sp->pktSendCnt = 0;
                    805:                sp->waitingAck = 0;
                    806:                sp->callSend = 1;
                    807:                ATENABLE(s, sp->lock);
                    808:            } else
                    809:                goto ignore;
                    810:            break;
                    811:                        
                    812:        default:
                    813:            goto ignore;
                    814:        }                       /* switch */
                    815:     }                          /* Control packet */
                    816: 
                    817:     else {                     /* Data Packet */
                    818:        if ((sp == 0) || RXData(sp, mp, f, len))
                    819:            goto ignore;
                    820:        else
                    821:            mp = 0;             /* RXData used up the data, DONT free it! */
                    822:     }                          /* Data Packet */
                    823: 
                    824:     if (mp)
                    825:        gbuf_freem(mp);
                    826: 
                    827: checksend:                     /* incoming data was not ignored */
                    828:     if (sp && sp->callSend)    /* If we have a stream & we need to send */
                    829:        CheckSend(sp);
                    830:     
                    831:     return 0;
                    832:        
                    833: ignore:
                    834:     gbuf_freem(mp);
                    835:     return 0;
                    836: }

unix.superglobalmegacorp.com

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