X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/bd504ef0e0b883cdd7917b73b3574eb9ce669905..39236c6e673c41db228275375ab7fdb0f837b292:/bsd/netat/adsp_Packet.c diff --git a/bsd/netat/adsp_Packet.c b/bsd/netat/adsp_Packet.c deleted file mode 100644 index c73d82e58..000000000 --- a/bsd/netat/adsp_Packet.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * Packet.c - * - * v01.23 All incoming packets come here first 06/21/90 mbs - * Modified for MP, 1996 by Tuyen Nguyen - * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -extern at_ifaddr_t *ifID_home; - -/* - * GleanSession - * - * We just got a packet for this session, glean its address & - * reset probe timer - * - * INPUTS: - * Session - * OUTPUTS: - * none - */ -static void GleanSession(CCBPtr); - -static void GleanSession(sp) /* (CCBPtr sp) */ - CCBPtr sp; -{ - if (sp->openState == O_STATE_OPEN) { - /* This is true for both state = sOpen & sClosing */ - RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer); - InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, - sp->probeInterval); - sp->probeCntr = 4; - } - -} - - -/* - * The same code handles incoming Open Connection Request, - * Open Request + Ack, Open Connection Ack, Open Connection Denial - * - * We could be in four different states, LISTEN, OPENWAIT, ESTABLISHED, - * OPEN. - */ - -/* - * - * Ok, there are 16 combinations. 8 are do-nothings, 2 have to be - * special cased (Open Deny and Req+Ack on Open session) - * - * Build a table of actions: - * Ignore? - * What to match on (local socket, whole address, DestCID, SrcCID) - * What to send (Ack or Req+Ack) - * Next State (both the ccb state and the open state) - */ - -/* - * - */ -typedef struct { - u_char match; /* Characteristics that have to match - * (Bit-Mapped, see below) */ - char action; /* What to do if CCB matches */ - char send; /* What to send in response - * (Bit mapped, same as sendCtl field of - * CCB) */ - char openState; /* Next Open state */ - char state; /* Next ccb state. */ - char pad; /* Too bad we need this to make structure - * even size */ -} TBL, *TBLPtr; - -#define M_LSOC 0x01 /* bit 0 - Match on local socket */ -#define M_ADDR 0x02 /* bit 1 - Match on whole address */ -#define M_DCID 0x04 /* bit 2 - Match on DestCID */ -#define M_SCID 0x08 /* bit 3 - Match SrcCID */ -#define M_DCIDZERO 0x10 /* bit 4 - Dest CID must be 0 */ -#define M_SCIDZERO 0x20 /* bit 5 - Src CID must be 0 */ -#define M_FILTER 0x40 /* bit 6 - Match address filter */ -#define M_IGNORE 0x80 /* bit 7 - Ignore */ - -#define A_COMPLETE 0x01 /* Complete open parameter block */ -#define A_SAVEPARMS 0x02 /* Save connection parameters */ -#define A_OREQACKOPEN 0x04 /* special case for open Req+Ack on - * OPEN session */ -#define A_GLEAN 0x08 /* We'll be talking back to this guy */ -#define A_DENY 0x10 /* We've been denied! */ - - -/* - * So here's our table - */ - -static TBL tbl[16] = { - -/* - * For Open Request ($81) - * - * LISTENING - * Match on destination socket - * Match on address filter - * Dest CID must be 0 - * Glean connection - * Save Open Connection parameters - * Send OREQACK - * Change state to ESTABLISHED - */ - { M_LSOC + M_DCIDZERO + M_FILTER, - A_SAVEPARMS + A_GLEAN, - B_CTL_OREQACK, - O_STATE_ESTABLISHED, - sOpening, - 0 - }, - -/* - * - * OPENWAIT - * Match on Remote Address & destination socket - * Dest CID must be 0 - * Save Open Connection parameters - * Send Ack - * Change state to ESTABLISHED - */ - { M_LSOC + M_ADDR + M_DCIDZERO, - A_SAVEPARMS + A_GLEAN, - B_CTL_OACK, - O_STATE_ESTABLISHED, - sOpening, - 0 - }, -/* - * - * ESTABLISHED - * Match on Remote Address & SrcCID - * Dest CID must be 0 - * Send Req + Ack - */ - { M_ADDR + M_SCID + M_DCIDZERO, - A_GLEAN, - B_CTL_OACK, - O_STATE_ESTABLISHED, - sOpening, - 0 - }, -/* - * OPEN - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, - -/* - * - * For Open Ack ($82) - * - * LISTENING - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, -/* - * - * OPENWAIT - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, -/* - * - * ESTABLISHED - * Match on SrcCID & DestCID & Address & Local Socket - * Complete Listen or Connect PB - * OPEN - */ - { M_ADDR + M_DCID + M_SCID + M_LSOC, - A_COMPLETE + A_GLEAN, - 0, - O_STATE_OPEN, - sOpen, - 0 - }, -/* - * - * OPEN - * Ignore -*/ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, - -/* - * - * For Open Request + Ack ($83) - * - * LISTENING - * Ignore -*/ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, -/* - * - * OPENWAIT - * Match on DestCID & socket - * Do not test remote address -- our open req could have - * been passed to another address by a connection server - * Save Open Connection parameters - * Complete Connect parameter block - * Send Ack - * OPEN - */ - { M_DCID + M_LSOC, - A_COMPLETE + A_SAVEPARMS + A_GLEAN, - B_CTL_OACK, - O_STATE_OPEN, - sOpen, - 0 - }, -/* - * - * ESTABLISHED - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, -/* - * - * OPEN - * Match on Remote Address & SrcCID & DestCID & Local Socket - * If we've never gotten any data - * Send Ack & Retransmit - */ - { M_ADDR + M_DCID + M_SCID + M_LSOC, - A_OREQACKOPEN + A_GLEAN, - B_CTL_OACK, - O_STATE_OPEN, - sOpen, - 0 - }, - -/* - * - * - * For Open Deny ($84) - * - * LISTENING - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, -/* - * - * OPENWAIT - * Match on DestCID & Address - * Source CID must be 0 - * Complete with error - */ - { M_SCIDZERO + M_DCID + M_ADDR, - A_DENY, - 0, - O_STATE_NOTHING, - sClosed, - 0 - }, -/* - * - * ESTABLISHED - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - }, /* %%% No we probably don't want to ignore in this case */ -/* - * - * OPEN - * Ignore - */ - { M_IGNORE, - 0, - 0, - 0, - 0, - 0 - } -}; - -extern at_ifaddr_t *ifID_table[]; - -/* - * Used to search down queue of sessions for a session waiting for an - * open request. - */ -typedef struct { - AddrUnion addr; - word dstCID; - word srcCID; - byte socket; - byte descriptor; - byte idx; /* Index into state tables */ - TBLPtr t; /* Ptr to entry in table above */ -} MATCH, *MATCHPtr; - -/* - * MatchStream - * - * Called by Rx connection to find which stream (if any) should get this open - * request/ack/req+ack/deny packet. - * - */ -static boolean MatchStream(CCBPtr, MATCHPtr); - -static boolean -MatchStream(sp, m) /* (CCBPtr sp, MATCHPtr m) */ - CCBPtr sp; - MATCHPtr m; -{ - unsigned char match; - struct adspcmd *opb; - - if (sp->openState < O_STATE_LISTEN || - sp->openState > O_STATE_OPEN) - return 0; - - - m->t = &tbl[sp->openState - O_STATE_LISTEN + m->idx]; - - match = m->t->match; /* Get match criteria */ - - if (match & M_IGNORE) /* Ignore this combination */ - return 0; - - if (match & M_LSOC) { /* Match on Local socket */ - if (sp->localSocket != m->socket) - return 0; - } - - if (match & M_ADDR) { /* Match on Address */ - AddrUnion addr; - addr = m->addr; /* Make local copy for efficiency */ - if (sp->remoteAddress.a.node != addr.a.node) - return 0; - if (sp->remoteAddress.a.socket != addr.a.socket) - return 0; - if (sp->remoteAddress.a.net && addr.a.net && - (sp->remoteAddress.a.net != addr.a.net)) - return 0; - - /* - * Handle special case to reject self-sent open request - */ - if ((m->srcCID == sp->locCID) && - (addr.a.node == ifID_home->ifThisNode.s_node) && - /* *** was (addr.a.node == ddpcfg.node_addr.node) && *** */ - ((addr.a.net == 0) || - (ifID_home->ifThisNode.s_net == 0) || - (ifID_home->ifThisNode.s_net == addr.a.net)) ) - /* *** was - (NET_VALUE(ddpcfg.node_addr.net) == 0) || - (NET_VALUE(ddpcfg.node_addr.net) == NET_VALUE(addr.a.net))) ) - *** */ - /* CID's match, and */ - /* If nodeID matches, and */ - /* network matches, */ - return 0; /* then came from us! */ - } - - if (match & M_DCID) { /* Match on DestCID */ - if (sp->locCID != m->dstCID) - return 0; - } - - if (match & M_SCID) { /* Match on SourceCID */ - if (sp->remCID != m->srcCID) - return 0; - } - - if (match & M_DCIDZERO) { /* Destination CID must be 0 */ - if (m->dstCID != 0) - return 0; - } - - if (match & M_SCIDZERO) /* Source CID must be 0 */ - { - if (m->srcCID != 0) - return 0; - } - - if (match & M_FILTER) { /* Check address filter? */ - if ((opb = sp->opb)) /* There should be a param block... */ - { - AddrUnion addr; - addr = m->addr; /* Make local copy for efficiency */ - if ((opb->u.openParams.filterAddress.net && - addr.a.net && - opb->u.openParams.filterAddress.net != addr.a.net) || - (opb->u.openParams.filterAddress.node != 0 && - opb->u.openParams.filterAddress.node != addr.a.node)|| - (opb->u.openParams.filterAddress.socket != 0 && - opb->u.openParams.filterAddress.socket != addr.a.socket)) - return 0; - } - } - - return 1; -} - -/* - * MatchListener - * - * Called by rx connection to see which connection listener (if any) should - * get this incoming open connection request. - * - */ - -static boolean MatchListener(CCBPtr, MATCHPtr); - -static boolean MatchListener(sp, m) /* (CCBPtr sp, MATCHPtr m) */ - CCBPtr sp; - MATCHPtr m; -{ - - if ((sp->state == (word)sListening) && /* This CCB is a listener */ - (sp->localSocket == m->socket)) /* on the right socket */ - return 1; - - return 0; -} - -/* - * RXConnection - * - * We just received one of the 4 Open Connection packets - * Interrupts are masked OFF at this point - * - * INPUTS: - * spPtr Place to put ptr to stream (if we found one -- not - * for listeners) - * f Pointer to ADSP header for packet, data follows behind it - * len # of byte in ADSP header + data - * addr Who sent the packet - * dsoc Where they sent it to - * - * OUTPUTS: - * Returns 1 if packet was ignored - */ -static int RXConnection( - __unused gref_t *gref, /* READ queue */ - CCBPtr *spPtr, - ADSP_FRAMEPtr f, - int len, - AddrUnion addr, - unsigned char dsoc) -{ - CCBPtr sp; - ADSP_OPEN_DATAPtr op; - struct adspcmd *pb; - MATCH m; - gbuf_t *mp; - ADSP_FRAMEPtr adspp; - ADSP_OPEN_DATAPtr adspop; - - op = (ADSP_OPEN_DATAPtr)&f->data[0]; /* Point to Open-Connection parms */ - len -= ADSP_FRAME_LEN; - - if (len < (sizeof(ADSP_OPEN_DATA))) /* Packet too small */ - return 1; - - - if (UAS_VALUE(op->version) != netw(0x0100)) { /* Check version num (on even-byte) */ - /* - * The open request has been denied. Try to send him a denial. - */ - - mp = gbuf_alloc(AT_WR_OFFSET + DDPL_FRAME_LEN + ADSP_FRAME_LEN + ADSP_OPEN_FRAME_LEN, - PRI_LO); - gbuf_rinc(mp,AT_WR_OFFSET); - gbuf_wset(mp,DDPL_FRAME_LEN); - adspp = (ADSP_FRAMEPtr)gbuf_wptr(mp); - gbuf_winc(mp,ADSP_FRAME_LEN); - bzero((caddr_t) gbuf_rptr(mp),DDPL_FRAME_LEN + ADSP_FRAME_LEN + - ADSP_OPEN_FRAME_LEN); - adspp->descriptor = ADSP_CONTROL_BIT | ADSP_CTL_ODENY; - adspop = (ADSP_OPEN_DATAPtr)gbuf_wptr(mp); - gbuf_winc(mp,ADSP_OPEN_FRAME_LEN); - UAS_UAS(adspop->dstCID, f->CID); - UAS_ASSIGN_HTON(adspop->version, 0x100); - adsp_sendddp(0, mp, DDPL_FRAME_LEN + ADSP_FRAME_LEN + - ADSP_OPEN_FRAME_LEN, &addr, DDP_ADSP); - - return 0; - } - m.addr = addr; - m.socket = dsoc; - m.descriptor = f->descriptor; - m.srcCID = UAS_VALUE_NTOH(f->CID); - m.dstCID = UAS_VALUE_NTOH(op->dstCID); /* On even-byte boundry */ - m.idx = ((f->descriptor & ADSP_CONTROL_MASK) - 1) * 4; - - /* - * See if we can find a stream that knows what to do with this packet - */ - if ((sp = (CCBPtr)qfind_m((CCB *)AT_ADSP_STREAMS, &m, (ProcPtr)MatchStream)) == 0) - { - struct adspcmd *p; - struct adspcmd *n; - /* - * No match, so look for connection listeners if this is an - * open request - */ - if ((f->descriptor & ADSP_CONTROL_MASK) != (byte)ADSP_CTL_OREQ) - return 1; - - if ((sp = (CCBPtr)qfind_m((CCB *)AT_ADSP_STREAMS, &m, - (ProcPtr)MatchListener)) == 0) - return 1; - - p = (struct adspcmd *)&sp->opb; - while ((n = (struct adspcmd *)p->qLink)) /* Hunt down list of listens */ - { - /* Check address filter */ - if (((n->u.openParams.filterAddress.net == 0) || - (addr.a.net == 0) || - (n->u.openParams.filterAddress.net == addr.a.net)) && - - ((n->u.openParams.filterAddress.node == 0) || - (n->u.openParams.filterAddress.node == addr.a.node)) && - - ((n->u.openParams.filterAddress.socket == 0) || - (n->u.openParams.filterAddress.socket == addr.a.socket))) { - p->qLink = n->qLink; /* Unlink this param block */ - n->u.openParams.remoteCID = m.srcCID; - *((AddrUnionPtr)&n->u.openParams.remoteAddress) = addr; - n->u.openParams.sendSeq = UAL_VALUE_NTOH(f->pktNextRecvSeq); - n->u.openParams.sendWindow = UAS_VALUE_NTOH(f->pktRecvWdw); - n->u.openParams.attnSendSeq = UAL_VALUE_NTOH(op->pktAttnRecvSeq); - n->ioResult = 0; - completepb(sp, n); /* complete copy of request */ - /* complete(n, 0); */ - return 0; - } /* found CLListen */ - - p = n; /* down the list we go... */ - - } /* while */ - - return 1; - } - - *spPtr = sp; /* Save ptr to stream we just found */ - - sp->openState = m.t->openState; /* Move to next state (may be same) */ - sp->state = m.t->state; /* Move to next state (may be same) */ - - if (m.t->action & A_SAVEPARMS) { /* Need to Save open-conn parms */ - sp->firstRtmtSeq = sp->sendSeq = UAL_VALUE_NTOH(f->pktNextRecvSeq); - sp->sendWdwSeq = UAL_VALUE_NTOH(f->pktNextRecvSeq) + UAS_VALUE_NTOH(f->pktRecvWdw) - 1; - sp->attnSendSeq = UAL_VALUE_NTOH(op->pktAttnRecvSeq); /* on even boundry */ - - - sp->remCID = UAS_VALUE_NTOH(f->CID); /* Save Source CID as RemCID */ - UAS_UAS(sp->of.dstCID, f->CID); /* Save CID in open ctl packet */ - - sp->remoteAddress = addr; /* Save his address */ - - } - - if (m.t->action & A_DENY) { /* We've been denied ! */ - DoClose(sp, errOpenDenied, -1); - } - - if (m.t->action & A_OREQACKOPEN) { - /* Special case for OREQACK */ - /* on an open session */ - RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer); - sp->sendSeq = sp->firstRtmtSeq; - sp->pktSendCnt = 0; - sp->waitingAck = 0; - sp->callSend = 1; - } - - if (m.t->send) { /* Need to send a response */ - sp->sendCtl |= m.t->send; - sp->callSend = 1; - } - - if (m.t->action & A_COMPLETE) { /* Need to complete open param blk */ - RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer); - - if ((pb = sp->opb)) { - sp->opb = 0; - pb->u.openParams.localCID = sp->locCID; - pb->u.openParams.remoteCID = sp->remCID; - pb->u.openParams.remoteAddress = - *((at_inet_t *)&sp->remoteAddress); - pb->u.openParams.sendSeq = sp->sendSeq; - pb->u.openParams.sendWindow = sp->sendWdwSeq - sp->sendSeq; - pb->u.openParams.attnSendSeq = sp->attnSendSeq; - pb->ioResult = 0; - completepb(sp, pb); /* complete(pb, 0); */ - return 0; - } - /* Start probe timer */ - InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, - sp->probeInterval); - } - return 0; -} - -/* - * ADSPPacket - * - * When a packet is received by the protocol stack with DDP type equal - * to ADSP, then execution comes here - * - * DS is set to ATALK's DGROUP - * - * This routine, or one of its children MUST call glean packet - * - * INPUTS: - * Pointer to DDP header - * OUTPUTS: - * none - * - * Note that the incoming message block (mp) is usually discarded, either - * by the "ignored" path, or via the "checksend" path. The only case - * where the message is NOT freed is via the RxData case in the - * non control packet switch. I zero mp after the RxData case succeeds - * so that mp will not be freed. - */ -int adspPacket(gref, mp) - /* (bytePtr data, word len, AddrUnion a, byte dsoc) */ - gref_t *gref; - gbuf_t *mp; -{ - unsigned char *bp; - int len; - AddrUnion a; - int dsoc; - register DDPX_FRAME *ddp; /* DDP frame pointer */ - register ADSP_FRAMEPtr f; /* Frame */ - CCBPtr sp; - - sp = 0; /* No stream */ - bp = (unsigned char *)gbuf_rptr(mp); - ddp = (DDPX_FRAME *)bp; - if (ddp->ddpx_type != DDP_ADSP) - return -1; - f = (ADSP_FRAMEPtr)(bp + DDPL_FRAME_LEN); - - len = UAS_VALUE_NTOH(ddp->ddpx_length) & 0x3ff; /* (ten bits of length) */ - len -= DDPL_FRAME_LEN; - if (len < (sizeof(ADSP_FRAME) - 1)) /* Packet too small */ - return -1; /* mark the failure */ - - a.a.net = NET_VALUE(ddp->ddpx_snet); - a.a.node = ddp->ddpx_snode; - a.a.socket = ddp->ddpx_source; - - dsoc = ddp->ddpx_dest; - - if ((sp = (CCBPtr)FindSender(f, a))) - GleanSession(sp); - - if (f->descriptor & ADSP_ATTENTION_BIT) { /* ATTN packet */ - if (sp && RXAttention(sp, mp, f, len)) - goto ignore; - else - mp = 0; /* attention data is being held */ - } /* ATTENTION BIT */ - - else if (f->descriptor & ADSP_CONTROL_BIT) { /* Control packet */ - switch (f->descriptor & ADSP_CONTROL_MASK) { - case ADSP_CTL_PROBE: /* Probe or acknowledgement */ - if (sp) - CheckRecvSeq(sp, f); - break; - - case ADSP_CTL_OREQ: /* Open Connection Request */ - case ADSP_CTL_OREQACK: /* Open Request and acknowledgement */ - case ADSP_CTL_OACK: /* Open Request acknowledgment */ - case ADSP_CTL_ODENY: /* Open Request denial */ - if (RXConnection(gref, &sp, f, len, a, dsoc)) - goto ignore; - break; - - case ADSP_CTL_CLOSE: /* Close connection advice */ - if (sp) { - /* This pkt may also ack some data we sent */ - CheckRecvSeq(sp, f); - RxClose(sp); - sp = 0; - } else - goto ignore; - break; - - case ADSP_CTL_FRESET: /* Forward Reset */ - /* May I rot in hell for the code below... */ - if (sp && (CheckRecvSeq(sp, f), RXFReset(sp, f))) - goto ignore; - break; - - case ADSP_CTL_FRESET_ACK: /* Forward Reset Acknowledgement */ - if (sp && (CheckRecvSeq(sp, f), RXFResetAck(sp, f))) - goto ignore; - break; - - case ADSP_CTL_RETRANSMIT: /* Retransmit advice */ - if (sp) { - /* This pkt may also ack some data we sent */ - CheckRecvSeq(sp, f); - RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer); - sp->sendSeq = sp->firstRtmtSeq; - sp->pktSendCnt = 0; - sp->waitingAck = 0; - sp->callSend = 1; - } else - goto ignore; - break; - - default: - goto ignore; - } /* switch */ - } /* Control packet */ - - else { /* Data Packet */ - if ((sp == 0) || RXData(sp, mp, f, len)) - goto ignore; - else - mp = 0; /* RXData used up the data, DONT free it! */ - } /* Data Packet */ - - if (mp) - gbuf_freem(mp); - - /* incoming data was not ignored */ - if (sp && sp->callSend) /* If we have a stream & we need to send */ - CheckSend(sp); - - return 0; - -ignore: - gbuf_freem(mp); - return 0; -}