Annotation of XNU/bsd/netat/adsp_Packet.c, revision 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.