windows-nt/Source/XPSP1/NT/net/sfm/atalk/sys/arapdbg.c
2020-09-26 16:20:57 +08:00

1036 lines
26 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
arapdbg.c
Abstract:
This module implements all debug utilities used by ARAP
Author:
Shirish Koti
Revision History:
26 March 1997 Initial Version
--*/
#include <atalk.h>
#pragma hdrstop
// File module number for errorlogging
#define FILENUM ARAPDBG
#define ALIGN8(Ptr) ( (((ULONG_PTR)(Ptr))+7) & (~7) )
//
// The following are debug-only routines. These routines help us catch bad
// things before they do damage, and help us sleep better at night.
//
#if DBG
DWORD ArapDbgDumpOnDisconnect = 0;
//***
//
// Function: ArapProcessSniff
// Stores the sniff irp. Next time some connection needs to return
// the sniff info, use this irp.
//
// Parameters: pIrp - the Sniff irp to process
//
// Return: result of the operation
//
//***$
NTSTATUS
ArapProcessSniff(
IN PIRP pIrp
)
{
KIRQL OldIrql;
PARAP_SEND_RECV_INFO pSndRcvInfo;
ARAPTRACE(("Entered ArapProcessSniff (%lx)\n",pIrp));
ACQUIRE_SPIN_LOCK(&ArapSpinLock, &OldIrql);
// store the irp (we can only have one Sniff irp at a time)
ASSERT (ArapSniffIrp == NULL);
if (ArapSniffIrp != NULL)
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("ArapProcessSniff: Sniff irp %lx already in progress!\n", ArapSniffIrp));
pSndRcvInfo = (PARAP_SEND_RECV_INFO)pIrp->AssociatedIrp.SystemBuffer;
pSndRcvInfo->StatusCode = ARAPERR_IRP_IN_PROGRESS;
RELEASE_SPIN_LOCK(&ArapSpinLock, OldIrql);
return( STATUS_SUCCESS );
}
ArapSniffIrp = pIrp;
RELEASE_SPIN_LOCK(&ArapSpinLock, OldIrql);
return(STATUS_PENDING);
}
//***
//
// Function: ArapDumpSniffInfo
// If we have collected enough sniff info, complete the sniff irp
//
// Parameters: pArapConn - connection in question
//
// Return: TRUE if we returned info to dll, FALSE otherwise
//
//***$
BOOLEAN
ArapDumpSniffInfo(
IN PARAPCONN pArapConn
)
{
PIRP pIrp;
DWORD dwBytesToDll;
NTSTATUS ReturnStatus=STATUS_SUCCESS;
// if we don't have a sniff buffer (or no bytes in it), get out
if (!pArapConn->pDbgTraceBuffer || pArapConn->SniffedBytes == 0)
{
return(FALSE);
}
//
// if we have less than 500 bytes in the buffer, and we aren't disconnecting
// or disconnected, don't complete the irp as yet
// (it's ok not have spinlock here)
//
if ((pArapConn->SniffedBytes < 500) &&
(pArapConn->State == MNP_UP ))
{
return(FALSE);
}
ARAP_GET_SNIFF_IRP(&pIrp);
// no sniff irp available? can't do much, leave
if (!pIrp)
{
return(FALSE);
}
dwBytesToDll = ArapFillIrpWithSniffInfo(pArapConn,pIrp) +
sizeof(ARAP_SEND_RECV_INFO);
// ok, complete that irp now!
ARAP_COMPLETE_IRP(pIrp, dwBytesToDll, STATUS_SUCCESS, &ReturnStatus);
return(TRUE);
}
//***
//
// Function: ArapFillIrpWithSniffInfo
// Copy the sniff bytes into the irp
//
// Parameters: pArapConn - connection in question
// pIrp - the irp to fill data in
// (except in one case, this irp will be the sniff irp.
// The exception case is where disconnect has occured and
// and at that time, a sniff irp wasn't available. In that
// case, we use the select irp that's carrying the disconnect
// info to send the remaining sniff bytes).
//
// Return: Number of sniff bytes that were copied in
//
//***$
DWORD
ArapFillIrpWithSniffInfo(
IN PARAPCONN pArapConn,
IN PIRP pIrp
)
{
PARAP_SEND_RECV_INFO pSndRcvInfo=NULL;
KIRQL OldIrql;
DWORD SniffedBytes;
PBYTE pStartData;
DWORD dwBytesToDll;
ACQUIRE_SPIN_LOCK(&pArapConn->SpinLock, &OldIrql);
pSndRcvInfo = (PARAP_SEND_RECV_INFO)pIrp->AssociatedIrp.SystemBuffer;
//
// if buffer is smaller than how much data we have, adjust by ignoring
// bytes in the beginning of the buffer
//
if (pSndRcvInfo->DataLen < pArapConn->SniffedBytes)
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("ArapFill...Info: chopping %d bytes in the beginning\n",
(pArapConn->SniffedBytes - pSndRcvInfo->DataLen)));
pStartData = pArapConn->pDbgTraceBuffer +
(pArapConn->SniffedBytes - pSndRcvInfo->DataLen);
pArapConn->SniffedBytes = pSndRcvInfo->DataLen;
}
else
{
pStartData = pArapConn->pDbgTraceBuffer;
}
SniffedBytes = pArapConn->SniffedBytes;
// ok, copy the data in
RtlCopyMemory( &pSndRcvInfo->Data[0],
pStartData,
SniffedBytes );
pArapConn->pDbgCurrPtr = pArapConn->pDbgTraceBuffer;
pArapConn->SniffedBytes = 0;
RELEASE_SPIN_LOCK(&pArapConn->SpinLock, OldIrql);
// set the info (contexts need to be set each time in case of select)
pSndRcvInfo->AtalkContext = pArapConn;
pSndRcvInfo->pDllContext = pArapConn->pDllContext;
pSndRcvInfo->DataLen = SniffedBytes;
pSndRcvInfo->StatusCode = ARAPERR_NO_ERROR;
return(SniffedBytes);
}
//***
//
// Function: DbgChkRcvQIntegrity
// This routine looks at the first buffer on the receive queue and
// verifies that things look reasonable
//
// Parameters: pArapConn - the connection in question
//
// Return: TRUE if things look reasonable, FALSE otherwise
//
// NOTES: IMPORTANT: spinlock must be held before calling this routine
//
//***$
BOOLEAN
DbgChkRcvQIntegrity(
IN PARAPCONN pArapConn
)
{
PLIST_ENTRY pList;
PARAPBUF pArapBuf;
PBYTE packet;
USHORT SrpLen;
pList = pArapConn->ReceiveQ.Flink;
if (pList == &pArapConn->ReceiveQ)
{
return( TRUE );
}
if (!(pArapConn->Flags & ARAP_CONNECTION_UP))
{
return( TRUE );
}
pArapBuf = CONTAINING_RECORD(pList, ARAPBUF, Linkage);
// wait until more bytes show up
if (pArapBuf->DataSize < 6)
{
return( TRUE );
}
packet = pArapBuf->CurrentBuffer;
GETSHORT2SHORT(&SrpLen, pArapBuf->CurrentBuffer);
if (SrpLen > ARAP_MAXPKT_SIZE_INCOMING)
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("ARAP: packet too big (%d bytes) in %lx)\n",SrpLen,pArapBuf));
return(FALSE);
}
if ((packet[2] != 0x50) && (packet[2] != 0x10))
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("ARAP: wrong DGroup byte (%x) in %lx)\n",packet[2],pArapBuf));
return(FALSE);
}
if (packet[2] == 0x50)
{
if ((packet[3] != 0) || (packet[4] != 0) || (packet[5] != 2))
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("ARAP (%lx): wrong LAP hdr in %lx)\n",pArapBuf));
return(FALSE);
}
}
return( TRUE );
}
//***
//
// Function: DbgDumpBytes
// This routine dumps first 64 bytes from a buffer to the debugger
//
// Parameters: pDbgMsg - string to print before the bytes (optional)
// pBuffer - buffer from which to dump the bytes
// BufLen - how big is the buffer
// DumpLevel - if this matches ArapDumpLevel, we dump the bytes
//
// Return: Nothing
//
//***$
VOID
DbgDumpBytes(
IN PBYTE pDbgMsg,
IN PBYTE pBuffer,
IN DWORD BufLen,
IN DWORD DumpLevel
)
{
BYTE OutBuf[400];
DWORD NextIndex;
DWORD dwBytesToDump;
if (ArapDumpLevel != DumpLevel)
{
return;
}
if (pDbgMsg)
{
DbgPrint("%s (pkt len = %d)\n",pDbgMsg,BufLen);
}
else
{
DbgPrint("Dumping packet (pkt len = %d)\n",BufLen);
}
// dump the first 64 bytes
dwBytesToDump = (BufLen <= 64)? BufLen : 64;
dwBytesToDump = (dwBytesToDump < ArapDumpLen)?dwBytesToDump:ArapDumpLen;
DbgDumpBytesPart2( pBuffer, OutBuf, dwBytesToDump, &NextIndex );
OutBuf[NextIndex] = '\n';
OutBuf[NextIndex+1] = 0;
DbgPrint("%s",OutBuf);
}
//***
//
// Function: DbgDumpBytesPart2
// This is a helper routine for the DbgDumpBytes routine
//***$
VOID
DbgDumpBytesPart2(
IN PBYTE pBuffer,
OUT PBYTE OutBuf,
IN DWORD BufLen,
OUT DWORD *NextIndex
)
{
BYTE Byte;
BYTE nibble;
DWORD i, j;
j = 0;
OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' ';
for (i=0; i<BufLen; i++ )
{
Byte = pBuffer[i];
nibble = (Byte >> 4);
OutBuf[j++] = (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
nibble = (Byte & 0x0f);
OutBuf[j++] = (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
OutBuf[j++] = ' ';
if (((i+1) % 16) == 0)
{
OutBuf[j++] = '\n'; OutBuf[j++] = ' ';
OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' ';
}
else if (((i+1) % 8) == 0)
{
OutBuf[j++] = ' ';
}
}
*NextIndex = j;
return;
}
//***
//
// Function: DbgDumpNetworkNumbers
// This routine dumps out all the network ranges that exist on the
// network.
//
// Parameters: None
//
// Return: Nothing
//
//***$
VOID
DbgDumpNetworkNumbers(
IN VOID
)
{
KIRQL OldIrql;
PRTE pRte, pNext;
int i;
ACQUIRE_SPIN_LOCK(&AtalkRteLock, &OldIrql);
for (i = 0; i < NUM_RTMP_HASH_BUCKETS; i++)
{
for (pRte = AtalkRoutingTable[i]; pRte != NULL; pRte = pNext)
{
pNext = pRte->rte_Next;
ACQUIRE_SPIN_LOCK_DPC(&pRte->rte_Lock);
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
(" pRte: %lx LowEnd %lx HighEnd %lx\n",
pRte,pRte->rte_NwRange.anr_FirstNetwork,pRte->rte_NwRange.anr_LastNetwork));
RELEASE_SPIN_LOCK_DPC(&pRte->rte_Lock);
}
}
RELEASE_SPIN_LOCK(&AtalkRteLock, OldIrql);
}
//***
//
// Function: DbgTrackInfo
// This routine tracks various information, useful in arriving at
// optimum buffer sizes, etc.
//
// Parameters: pArapConn - the connection in question
// Size - size of the buffer (incoming, outgoing, as appropriate)
// TrackingWhat - what are we tracking (sends, recvs etc.)
//
// Return: Nothing
//
//***$
VOID
DbgTrackInfo(
IN PARAPCONN pArapConn,
IN DWORD Size,
IN DWORD TrackingWhat
)
{
//
// track the MNP send sizes (how many are 0-10 bytes, 11-20 bytes, etc.)
//
if (TrackingWhat == 1)
{
ArapDbgMnpSendSizes[Size/10]++;
return;
}
}
//***
//
// Function: ArapDbgTrace
// This routine traces (keeps a log) of all the events (data going
// in/out, acks going in/out, error conditions etc.
//
// Parameters: pArapConn - the connection in question
// Location - who is logging this event (the location decides what
// the other parms are going to be)
// Context - depends on Location (e.g.could be data buffer)
// dwInfo1 - depends on Location
// dwInfo2 - depends on Location
// dwInfo3 - depends on Location
//
// Return: Nothing
//
// NOTE: Spinlock is assumed to be held
//
//***$
VOID
ArapDbgTrace(
IN PARAPCONN pArapConn,
IN DWORD Location,
IN PVOID Context,
IN DWORD dwInfo1,
IN DWORD dwInfo2,
IN DWORD dwInfo3
)
{
LARGE_INTEGER CurrTime;
LARGE_INTEGER DiffTime;
PBYTE pStartTrace;
PBYTE pTrace;
PBUFFER_DESC pBuffDesc;
PARAPBUF pArapBuf;
PMNPSENDBUF pMnpSendBuf;
PBYTE pCurrBuff;
DWORD BufLenSoFar=0;
USHORT Delta;
BYTE Priority;
DWORD BytesCopied=0;
DWORD BytesAvailable;
USHORT DbgInfoLen;
PSNIFF_INFO pSniff;
DWORD i;
if (!pArapConn->pDbgTraceBuffer)
{
return;
}
KeQuerySystemTime(&CurrTime);
DiffTime = RtlLargeIntegerSubtract(CurrTime, ArapDbgLastTraceTime);
ArapDbgLastTraceTime = CurrTime;
// do the conversion to get ms
Delta = (USHORT)(DiffTime.LowPart);
pSniff = (PSNIFF_INFO)(pArapConn->pDbgCurrPtr);
pTrace = pStartTrace = &pSniff->Frame[0];
// put signature (starting of a "frame")
pSniff->Signature = ARAP_SNIFF_SIGNATURE;
// time since last event
pSniff->TimeStamp = (DWORD)AtalkGetCurrentTick();
// who is logging this info
pSniff->Location = (USHORT)Location;
//
// ok, now see who has called us and log the relevant info
// If we can't find the Location, it's ok: we have the Location number
// logged and and that's adequate (that's why we can't find Location)
//
switch (Location)
{
// data to client is about to be compressed: copy some info
case 11205:
pBuffDesc = (PBUFFER_DESC)Context;
Priority = (BYTE)dwInfo1;
while (pBuffDesc)
{
if (pBuffDesc->bd_Flags & BD_CHAR_BUFFER)
{
pCurrBuff = pBuffDesc->bd_CharBuffer;
BytesAvailable = pBuffDesc->bd_Length;
}
else
{
pCurrBuff = MmGetSystemAddressForMdlSafe(
pBuffDesc->bd_OpaqueBuffer,
NormalPagePriority);
if (pCurrBuff == NULL) {
goto error_end;
}
BytesAvailable = MmGetMdlByteCount(pBuffDesc->bd_OpaqueBuffer);
}
//
// if this buffer descriptor contains (usually exclusively) the
// ARAP header, then get some info out of it and skip those bytes
//
if ((pCurrBuff[2] == 0x10 || pCurrBuff[2] == 0x50) &&
(pCurrBuff[3] == 0) && (pCurrBuff[4] == 0) && (pCurrBuff[5] == 2))
{
*pTrace++ = pCurrBuff[0]; // srplen byte 1
*pTrace++ = pCurrBuff[1]; // srplen byte 2
*pTrace++ = pCurrBuff[2]; // ARAP or Atalk packet
*pTrace++ = Priority;
BytesAvailable -= 6;
pCurrBuff += 6;
}
// copy first 48 bytes of the data packet
while (BytesAvailable && BytesCopied < 48)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
pBuffDesc = pBuffDesc->bd_Next;
}
break;
// we are sending out an ack
case 11605:
*pTrace++ = (BYTE)dwInfo1; // sequence num in our ack
*pTrace++ = (BYTE)dwInfo2; // rcv credit in our ack
break;
// we are queuing compressed send bytes
case 21205:
*pTrace++ = (BYTE)dwInfo2; // priority of the send
*pTrace++ = (BYTE)dwInfo3; // Start sequence for this send
*pTrace++ = (BYTE)(pArapConn->MnpState.NextToSend-1); // end sequence
BytesAvailable = dwInfo1; // len of compressed data
pCurrBuff = (PBYTE)Context; // buffer with compressed data
// copy first 24 bytes of the compressed data
while (BytesAvailable && BytesCopied < 24)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
break;
// ArapExtractSRP: we're handing over 1 srp for routing or to dll
case 21105:
pArapBuf = (PARAPBUF)Context;
pCurrBuff = pArapBuf->CurrentBuffer;
BytesAvailable = pArapBuf->DataSize;
// copy first 48 bytes of the decompressed data
while (BytesAvailable && BytesCopied < 48)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
break;
// we just recvd a packet in ArapRcvIndication
case 30105:
BytesAvailable = dwInfo1-7; // lookahead size, minus start,stop,crc
pCurrBuff = ((PBYTE)Context)+3; // lookahead buffer plus 3 start
PUTSHORT2SHORT(pTrace,(USHORT)BytesAvailable);
pTrace += sizeof(USHORT);
// copy first 24 bytes of the compressed data
while (BytesAvailable && BytesCopied < 24)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
break;
// we recvd a 0-len packet!
case 30106:
break;
// we decompressed the incoming data
case 30110:
// how much was the decompressed length
PUTSHORT2SHORT(pTrace,(USHORT)dwInfo1);
pTrace += sizeof(USHORT);
if (dwInfo1 == 0)
{
break;
}
pArapBuf = (PARAPBUF)Context;
BytesAvailable = pArapBuf->DataSize; // len of decompressed data
pCurrBuff = pArapBuf->CurrentBuffer;
// copy first 48 bytes of the decompressed data
while (BytesAvailable && BytesCopied < 48)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
break;
// attempting send when state was >= MNP_LDISCONNECTING
case 30305:
*pTrace = (BYTE)dwInfo1; // store pArapConn->State
break;
// we just sent out a packet in ArapNdisSend()
case 30320:
pMnpSendBuf = (PMNPSENDBUF)Context;
*pTrace++ = pMnpSendBuf->SeqNum;
// how big is the MNP packet
PUTSHORT2SHORT(pTrace,pMnpSendBuf->DataSize);
pTrace += sizeof(USHORT);
*pTrace++ = (BYTE)dwInfo1; // is this a retransmission
BytesAvailable = pMnpSendBuf->DataSize;
pCurrBuff = (&pMnpSendBuf->Buffer[0]) + 3; // skip start bytes
// copy first 24 bytes of the compressed data
while (BytesAvailable && BytesCopied < 24)
{
*pTrace++ = *pCurrBuff++;
BytesCopied++;
BytesAvailable--;
}
default:
break;
}
DbgInfoLen = (USHORT)(pTrace - pStartTrace);
pSniff->FrameLen = DbgInfoLen;
pArapConn->pDbgCurrPtr = (PBYTE)ALIGN8(pTrace);
// fill up the round-up space with 0s
for (NOTHING; pTrace < pArapConn->pDbgCurrPtr; pTrace++)
{
*pTrace = 0;
}
// make sure we haven't overrun this buffer
ASSERT(*((DWORD *)&(pArapConn->pDbgTraceBuffer[ARAP_SNIFF_BUFF_SIZE-4])) == 0xcafebeef);
// how many more bytes did we add to the sniff buff?
pArapConn->SniffedBytes += (DWORD)(pArapConn->pDbgCurrPtr - (PBYTE)pSniff);
//
// if we are about to overflow, just reset the pointer to beginning
// (do it while we have still 200 bytes left)
//
BufLenSoFar = (DWORD)(pArapConn->pDbgCurrPtr - pArapConn->pDbgTraceBuffer);
error_end:
if (BufLenSoFar > ARAP_SNIFF_BUFF_SIZE-200)
{
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_INFO,
("ArapDbgTrace: resetting debug buffer, Sniff data LOST!\n"));
pArapConn->pDbgCurrPtr = pArapConn->pDbgTraceBuffer;
pArapConn->SniffedBytes = 0;
}
}
//***
//
// Function: ArapDbgTrace
// This routine records history of MNP level packet exchange
//
// Parameters: pArapConn - the connection in question
// Seq - sequence number (if applicable)
// FrameType - LT, LA etc.
//
// Return: Nothing
//
// NOTE: Spinlock is assumed to be held
//
//***$
VOID
ArapDbgMnpHist(
IN PARAPCONN pArapConn,
IN BYTE Seq,
IN BYTE FrameType
)
{
LARGE_INTEGER TimeNow;
DWORD ThisDelta;
DWORD DbgMnpIndex;
KeQuerySystemTime(&TimeNow);
if (TimeNow.HighPart == pArapConn->LastTimeStamp.HighPart)
{
ThisDelta = (TimeNow.LowPart - pArapConn->LastTimeStamp.LowPart);
}
else
{
ThisDelta = (0xffffffff - pArapConn->LastTimeStamp.LowPart + TimeNow.LowPart);
}
// convert 100's ns to ms
ThisDelta = (ThisDelta/10000);
pArapConn->LastTimeStamp = TimeNow;
pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].TimeStamp = ThisDelta;
pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].FrameInfo = (FrameType << 16);
pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].FrameInfo |= Seq;
// wrap-around if necessary
if ((++pArapConn->DbgMnpIndex) >= DBG_MNP_HISTORY_SIZE)
{
pArapConn->DbgMnpIndex = 0;
}
}
//***
//
// Function: ArapDbgDumpMnpHistory
// This routine dumps history of MNP level packet exchange
//
// Parameters: pArapConn - the connection in question
//
// Return: Nothing
//
//***$
VOID
ArapDbgDumpMnpHist(
IN PARAPCONN pArapConn
)
{
DWORD i;
DWORD dwTmp;
DWORD dwDelta;
BYTE TmpSeq;
if (!ArapDbgDumpOnDisconnect)
{
return;
}
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("DerefArapConn: Past history on %lx .....\n", pArapConn));
// dump all info: old info first
for (i=pArapConn->DbgMnpIndex; i<DBG_MNP_HISTORY_SIZE; i++)
{
dwDelta = pArapConn->DbgMnpHist[i].TimeStamp;
dwTmp = (pArapConn->DbgMnpHist[i].FrameInfo & 0xffff0000);
TmpSeq = (BYTE)(pArapConn->DbgMnpHist[i].FrameInfo & 0x000000ff);
switch (dwTmp)
{
case 0x40000 : DbgPrint(" %6ld NT sends %x\n",dwDelta,TmpSeq);break;
case 0x50000 : DbgPrint(" %6ld NT acks %x\n",dwDelta,TmpSeq);break;
case 0x140000: DbgPrint(" %6ld Mac sends %x\n",dwDelta,TmpSeq);break;
case 0x150000: DbgPrint(" %6ld Mac acks %x\n",dwDelta,TmpSeq);break;
default : DbgPrint(" %6ld Unknown: %lx\n",dwDelta,pArapConn->DbgMnpHist[i].FrameInfo);
}
}
// dump the current info
for (i=0; i<pArapConn->DbgMnpIndex; i++)
{
dwDelta = pArapConn->DbgMnpHist[i].TimeStamp;
dwTmp = (pArapConn->DbgMnpHist[i].FrameInfo & 0xffff0000);
TmpSeq = (BYTE)(pArapConn->DbgMnpHist[i].FrameInfo & 0x000000ff);
switch (dwTmp)
{
case 0x40000 : DbgPrint(" %6ld NT sends %x\n",dwDelta,TmpSeq);break;
case 0x50000 : DbgPrint(" %6ld NT acks %x\n",dwDelta,TmpSeq);break;
case 0x140000: DbgPrint(" %6ld Mac sends %x\n",dwDelta,TmpSeq);break;
case 0x150000: DbgPrint(" %6ld Mac acks %x\n",dwDelta,TmpSeq);break;
default : DbgPrint(" %6ld Unknown: %lx\n",dwDelta,pArapConn->DbgMnpHist[i].FrameInfo);
}
}
}
//***
//
// Function: ArapDumpNdisPktInfo
// walk the ARAP connections list and find out how many Ndis packets
// are in use right now
//
// Parameters: nothing
//
// Return: nothing
//
//***$
VOID
ArapDumpNdisPktInfo(
IN VOID
)
{
PARAPCONN pArapConn;
PLIST_ENTRY pConnList;
PLIST_ENTRY pList;
PMNPSENDBUF pMnpSendBuf;
KIRQL OldIrql;
DWORD GrandTotal;
DWORD ReXmit;
DWORD ReXmitInNdis;
DWORD Fresh;
DWORD FreshInNdis;
DWORD ThisConn;
DWORD NumConns;
if (!RasPortDesc)
{
return;
}
ACQUIRE_SPIN_LOCK(&RasPortDesc->pd_Lock, &OldIrql);
pConnList = RasPortDesc->pd_ArapConnHead.Flink;
GrandTotal = 0;
NumConns = 0;
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("NdisPacketInfo: counting total number of ndis packets used by ARAP....\n"));
//
// first, let's find the right connection to work on
//
while (pConnList != &RasPortDesc->pd_ArapConnHead)
{
ReXmit = 0;
ReXmitInNdis = 0;
Fresh = 0;
FreshInNdis = 0;
ThisConn = 0;
pConnList = pConnList->Flink;
pArapConn = CONTAINING_RECORD(pConnList, ARAPCONN, Linkage);
ACQUIRE_SPIN_LOCK_DPC(&pArapConn->SpinLock);
pList = pArapConn->RetransmitQ.Flink;
// collect all buffers on the retransmit queue first
while (pList != &pArapConn->RetransmitQ)
{
pList = pList->Flink;
pMnpSendBuf = CONTAINING_RECORD(pList, MNPSENDBUF, Linkage);
ReXmit++;
if (pMnpSendBuf->Flags == 1)
{
ReXmitInNdis++;
}
}
pList = pArapConn->HighPriSendQ.Flink;
// collect all buffers on the fresh send
while (pList != &pArapConn->HighPriSendQ)
{
pList = pList->Flink;
pMnpSendBuf = CONTAINING_RECORD(pList, MNPSENDBUF, Linkage);
Fresh++;
if (pMnpSendBuf->Flags == 1)
{
FreshInNdis++;
}
}
ThisConn = ReXmit+ReXmitInNdis+Fresh+FreshInNdis;
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
(" %ld packets on %lx, %d in Ndis (%d+%d+%d+%d)\n",
ThisConn,pArapConn,ReXmitInNdis,ReXmit,ReXmitInNdis,Fresh,FreshInNdis));
GrandTotal += ThisConn;
NumConns++;
RELEASE_SPIN_LOCK_DPC(&pArapConn->SpinLock);
}
RELEASE_SPIN_LOCK(&RasPortDesc->pd_Lock, OldIrql);
DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
("NdisPacketInfo: total of %ld Ndis Packets on %d connections\n",
GrandTotal, NumConns));
}
#endif // DBG