Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1035 lines
26 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. arapdbg.c
  5. Abstract:
  6. This module implements all debug utilities used by ARAP
  7. Author:
  8. Shirish Koti
  9. Revision History:
  10. 26 March 1997 Initial Version
  11. --*/
  12. #include <atalk.h>
  13. #pragma hdrstop
  14. // File module number for errorlogging
  15. #define FILENUM ARAPDBG
  16. #define ALIGN8(Ptr) ( (((ULONG_PTR)(Ptr))+7) & (~7) )
  17. //
  18. // The following are debug-only routines. These routines help us catch bad
  19. // things before they do damage, and help us sleep better at night.
  20. //
  21. #if DBG
  22. DWORD ArapDbgDumpOnDisconnect = 0;
  23. //***
  24. //
  25. // Function: ArapProcessSniff
  26. // Stores the sniff irp. Next time some connection needs to return
  27. // the sniff info, use this irp.
  28. //
  29. // Parameters: pIrp - the Sniff irp to process
  30. //
  31. // Return: result of the operation
  32. //
  33. //***$
  34. NTSTATUS
  35. ArapProcessSniff(
  36. IN PIRP pIrp
  37. )
  38. {
  39. KIRQL OldIrql;
  40. PARAP_SEND_RECV_INFO pSndRcvInfo;
  41. ARAPTRACE(("Entered ArapProcessSniff (%lx)\n",pIrp));
  42. ACQUIRE_SPIN_LOCK(&ArapSpinLock, &OldIrql);
  43. // store the irp (we can only have one Sniff irp at a time)
  44. ASSERT (ArapSniffIrp == NULL);
  45. if (ArapSniffIrp != NULL)
  46. {
  47. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  48. ("ArapProcessSniff: Sniff irp %lx already in progress!\n", ArapSniffIrp));
  49. pSndRcvInfo = (PARAP_SEND_RECV_INFO)pIrp->AssociatedIrp.SystemBuffer;
  50. pSndRcvInfo->StatusCode = ARAPERR_IRP_IN_PROGRESS;
  51. RELEASE_SPIN_LOCK(&ArapSpinLock, OldIrql);
  52. return( STATUS_SUCCESS );
  53. }
  54. ArapSniffIrp = pIrp;
  55. RELEASE_SPIN_LOCK(&ArapSpinLock, OldIrql);
  56. return(STATUS_PENDING);
  57. }
  58. //***
  59. //
  60. // Function: ArapDumpSniffInfo
  61. // If we have collected enough sniff info, complete the sniff irp
  62. //
  63. // Parameters: pArapConn - connection in question
  64. //
  65. // Return: TRUE if we returned info to dll, FALSE otherwise
  66. //
  67. //***$
  68. BOOLEAN
  69. ArapDumpSniffInfo(
  70. IN PARAPCONN pArapConn
  71. )
  72. {
  73. PIRP pIrp;
  74. DWORD dwBytesToDll;
  75. NTSTATUS ReturnStatus=STATUS_SUCCESS;
  76. // if we don't have a sniff buffer (or no bytes in it), get out
  77. if (!pArapConn->pDbgTraceBuffer || pArapConn->SniffedBytes == 0)
  78. {
  79. return(FALSE);
  80. }
  81. //
  82. // if we have less than 500 bytes in the buffer, and we aren't disconnecting
  83. // or disconnected, don't complete the irp as yet
  84. // (it's ok not have spinlock here)
  85. //
  86. if ((pArapConn->SniffedBytes < 500) &&
  87. (pArapConn->State == MNP_UP ))
  88. {
  89. return(FALSE);
  90. }
  91. ARAP_GET_SNIFF_IRP(&pIrp);
  92. // no sniff irp available? can't do much, leave
  93. if (!pIrp)
  94. {
  95. return(FALSE);
  96. }
  97. dwBytesToDll = ArapFillIrpWithSniffInfo(pArapConn,pIrp) +
  98. sizeof(ARAP_SEND_RECV_INFO);
  99. // ok, complete that irp now!
  100. ARAP_COMPLETE_IRP(pIrp, dwBytesToDll, STATUS_SUCCESS, &ReturnStatus);
  101. return(TRUE);
  102. }
  103. //***
  104. //
  105. // Function: ArapFillIrpWithSniffInfo
  106. // Copy the sniff bytes into the irp
  107. //
  108. // Parameters: pArapConn - connection in question
  109. // pIrp - the irp to fill data in
  110. // (except in one case, this irp will be the sniff irp.
  111. // The exception case is where disconnect has occured and
  112. // and at that time, a sniff irp wasn't available. In that
  113. // case, we use the select irp that's carrying the disconnect
  114. // info to send the remaining sniff bytes).
  115. //
  116. // Return: Number of sniff bytes that were copied in
  117. //
  118. //***$
  119. DWORD
  120. ArapFillIrpWithSniffInfo(
  121. IN PARAPCONN pArapConn,
  122. IN PIRP pIrp
  123. )
  124. {
  125. PARAP_SEND_RECV_INFO pSndRcvInfo=NULL;
  126. KIRQL OldIrql;
  127. DWORD SniffedBytes;
  128. PBYTE pStartData;
  129. DWORD dwBytesToDll;
  130. ACQUIRE_SPIN_LOCK(&pArapConn->SpinLock, &OldIrql);
  131. pSndRcvInfo = (PARAP_SEND_RECV_INFO)pIrp->AssociatedIrp.SystemBuffer;
  132. //
  133. // if buffer is smaller than how much data we have, adjust by ignoring
  134. // bytes in the beginning of the buffer
  135. //
  136. if (pSndRcvInfo->DataLen < pArapConn->SniffedBytes)
  137. {
  138. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  139. ("ArapFill...Info: chopping %d bytes in the beginning\n",
  140. (pArapConn->SniffedBytes - pSndRcvInfo->DataLen)));
  141. pStartData = pArapConn->pDbgTraceBuffer +
  142. (pArapConn->SniffedBytes - pSndRcvInfo->DataLen);
  143. pArapConn->SniffedBytes = pSndRcvInfo->DataLen;
  144. }
  145. else
  146. {
  147. pStartData = pArapConn->pDbgTraceBuffer;
  148. }
  149. SniffedBytes = pArapConn->SniffedBytes;
  150. // ok, copy the data in
  151. RtlCopyMemory( &pSndRcvInfo->Data[0],
  152. pStartData,
  153. SniffedBytes );
  154. pArapConn->pDbgCurrPtr = pArapConn->pDbgTraceBuffer;
  155. pArapConn->SniffedBytes = 0;
  156. RELEASE_SPIN_LOCK(&pArapConn->SpinLock, OldIrql);
  157. // set the info (contexts need to be set each time in case of select)
  158. pSndRcvInfo->AtalkContext = pArapConn;
  159. pSndRcvInfo->pDllContext = pArapConn->pDllContext;
  160. pSndRcvInfo->DataLen = SniffedBytes;
  161. pSndRcvInfo->StatusCode = ARAPERR_NO_ERROR;
  162. return(SniffedBytes);
  163. }
  164. //***
  165. //
  166. // Function: DbgChkRcvQIntegrity
  167. // This routine looks at the first buffer on the receive queue and
  168. // verifies that things look reasonable
  169. //
  170. // Parameters: pArapConn - the connection in question
  171. //
  172. // Return: TRUE if things look reasonable, FALSE otherwise
  173. //
  174. // NOTES: IMPORTANT: spinlock must be held before calling this routine
  175. //
  176. //***$
  177. BOOLEAN
  178. DbgChkRcvQIntegrity(
  179. IN PARAPCONN pArapConn
  180. )
  181. {
  182. PLIST_ENTRY pList;
  183. PARAPBUF pArapBuf;
  184. PBYTE packet;
  185. USHORT SrpLen;
  186. pList = pArapConn->ReceiveQ.Flink;
  187. if (pList == &pArapConn->ReceiveQ)
  188. {
  189. return( TRUE );
  190. }
  191. if (!(pArapConn->Flags & ARAP_CONNECTION_UP))
  192. {
  193. return( TRUE );
  194. }
  195. pArapBuf = CONTAINING_RECORD(pList, ARAPBUF, Linkage);
  196. // wait until more bytes show up
  197. if (pArapBuf->DataSize < 6)
  198. {
  199. return( TRUE );
  200. }
  201. packet = pArapBuf->CurrentBuffer;
  202. GETSHORT2SHORT(&SrpLen, pArapBuf->CurrentBuffer);
  203. if (SrpLen > ARAP_MAXPKT_SIZE_INCOMING)
  204. {
  205. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  206. ("ARAP: packet too big (%d bytes) in %lx)\n",SrpLen,pArapBuf));
  207. return(FALSE);
  208. }
  209. if ((packet[2] != 0x50) && (packet[2] != 0x10))
  210. {
  211. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  212. ("ARAP: wrong DGroup byte (%x) in %lx)\n",packet[2],pArapBuf));
  213. return(FALSE);
  214. }
  215. if (packet[2] == 0x50)
  216. {
  217. if ((packet[3] != 0) || (packet[4] != 0) || (packet[5] != 2))
  218. {
  219. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  220. ("ARAP (%lx): wrong LAP hdr in %lx)\n",pArapBuf));
  221. return(FALSE);
  222. }
  223. }
  224. return( TRUE );
  225. }
  226. //***
  227. //
  228. // Function: DbgDumpBytes
  229. // This routine dumps first 64 bytes from a buffer to the debugger
  230. //
  231. // Parameters: pDbgMsg - string to print before the bytes (optional)
  232. // pBuffer - buffer from which to dump the bytes
  233. // BufLen - how big is the buffer
  234. // DumpLevel - if this matches ArapDumpLevel, we dump the bytes
  235. //
  236. // Return: Nothing
  237. //
  238. //***$
  239. VOID
  240. DbgDumpBytes(
  241. IN PBYTE pDbgMsg,
  242. IN PBYTE pBuffer,
  243. IN DWORD BufLen,
  244. IN DWORD DumpLevel
  245. )
  246. {
  247. BYTE OutBuf[400];
  248. DWORD NextIndex;
  249. DWORD dwBytesToDump;
  250. if (ArapDumpLevel != DumpLevel)
  251. {
  252. return;
  253. }
  254. if (pDbgMsg)
  255. {
  256. DbgPrint("%s (pkt len = %d)\n",pDbgMsg,BufLen);
  257. }
  258. else
  259. {
  260. DbgPrint("Dumping packet (pkt len = %d)\n",BufLen);
  261. }
  262. // dump the first 64 bytes
  263. dwBytesToDump = (BufLen <= 64)? BufLen : 64;
  264. dwBytesToDump = (dwBytesToDump < ArapDumpLen)?dwBytesToDump:ArapDumpLen;
  265. DbgDumpBytesPart2( pBuffer, OutBuf, dwBytesToDump, &NextIndex );
  266. OutBuf[NextIndex] = '\n';
  267. OutBuf[NextIndex+1] = 0;
  268. DbgPrint("%s",OutBuf);
  269. }
  270. //***
  271. //
  272. // Function: DbgDumpBytesPart2
  273. // This is a helper routine for the DbgDumpBytes routine
  274. //***$
  275. VOID
  276. DbgDumpBytesPart2(
  277. IN PBYTE pBuffer,
  278. OUT PBYTE OutBuf,
  279. IN DWORD BufLen,
  280. OUT DWORD *NextIndex
  281. )
  282. {
  283. BYTE Byte;
  284. BYTE nibble;
  285. DWORD i, j;
  286. j = 0;
  287. OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' ';
  288. for (i=0; i<BufLen; i++ )
  289. {
  290. Byte = pBuffer[i];
  291. nibble = (Byte >> 4);
  292. OutBuf[j++] = (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
  293. nibble = (Byte & 0x0f);
  294. OutBuf[j++] = (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
  295. OutBuf[j++] = ' ';
  296. if (((i+1) % 16) == 0)
  297. {
  298. OutBuf[j++] = '\n'; OutBuf[j++] = ' ';
  299. OutBuf[j++] = ' '; OutBuf[j++] = ' '; OutBuf[j++] = ' ';
  300. }
  301. else if (((i+1) % 8) == 0)
  302. {
  303. OutBuf[j++] = ' ';
  304. }
  305. }
  306. *NextIndex = j;
  307. return;
  308. }
  309. //***
  310. //
  311. // Function: DbgDumpNetworkNumbers
  312. // This routine dumps out all the network ranges that exist on the
  313. // network.
  314. //
  315. // Parameters: None
  316. //
  317. // Return: Nothing
  318. //
  319. //***$
  320. VOID
  321. DbgDumpNetworkNumbers(
  322. IN VOID
  323. )
  324. {
  325. KIRQL OldIrql;
  326. PRTE pRte, pNext;
  327. int i;
  328. ACQUIRE_SPIN_LOCK(&AtalkRteLock, &OldIrql);
  329. for (i = 0; i < NUM_RTMP_HASH_BUCKETS; i++)
  330. {
  331. for (pRte = AtalkRoutingTable[i]; pRte != NULL; pRte = pNext)
  332. {
  333. pNext = pRte->rte_Next;
  334. ACQUIRE_SPIN_LOCK_DPC(&pRte->rte_Lock);
  335. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  336. (" pRte: %lx LowEnd %lx HighEnd %lx\n",
  337. pRte,pRte->rte_NwRange.anr_FirstNetwork,pRte->rte_NwRange.anr_LastNetwork));
  338. RELEASE_SPIN_LOCK_DPC(&pRte->rte_Lock);
  339. }
  340. }
  341. RELEASE_SPIN_LOCK(&AtalkRteLock, OldIrql);
  342. }
  343. //***
  344. //
  345. // Function: DbgTrackInfo
  346. // This routine tracks various information, useful in arriving at
  347. // optimum buffer sizes, etc.
  348. //
  349. // Parameters: pArapConn - the connection in question
  350. // Size - size of the buffer (incoming, outgoing, as appropriate)
  351. // TrackingWhat - what are we tracking (sends, recvs etc.)
  352. //
  353. // Return: Nothing
  354. //
  355. //***$
  356. VOID
  357. DbgTrackInfo(
  358. IN PARAPCONN pArapConn,
  359. IN DWORD Size,
  360. IN DWORD TrackingWhat
  361. )
  362. {
  363. //
  364. // track the MNP send sizes (how many are 0-10 bytes, 11-20 bytes, etc.)
  365. //
  366. if (TrackingWhat == 1)
  367. {
  368. ArapDbgMnpSendSizes[Size/10]++;
  369. return;
  370. }
  371. }
  372. //***
  373. //
  374. // Function: ArapDbgTrace
  375. // This routine traces (keeps a log) of all the events (data going
  376. // in/out, acks going in/out, error conditions etc.
  377. //
  378. // Parameters: pArapConn - the connection in question
  379. // Location - who is logging this event (the location decides what
  380. // the other parms are going to be)
  381. // Context - depends on Location (e.g.could be data buffer)
  382. // dwInfo1 - depends on Location
  383. // dwInfo2 - depends on Location
  384. // dwInfo3 - depends on Location
  385. //
  386. // Return: Nothing
  387. //
  388. // NOTE: Spinlock is assumed to be held
  389. //
  390. //***$
  391. VOID
  392. ArapDbgTrace(
  393. IN PARAPCONN pArapConn,
  394. IN DWORD Location,
  395. IN PVOID Context,
  396. IN DWORD dwInfo1,
  397. IN DWORD dwInfo2,
  398. IN DWORD dwInfo3
  399. )
  400. {
  401. LARGE_INTEGER CurrTime;
  402. LARGE_INTEGER DiffTime;
  403. PBYTE pStartTrace;
  404. PBYTE pTrace;
  405. PBUFFER_DESC pBuffDesc;
  406. PARAPBUF pArapBuf;
  407. PMNPSENDBUF pMnpSendBuf;
  408. PBYTE pCurrBuff;
  409. DWORD BufLenSoFar=0;
  410. USHORT Delta;
  411. BYTE Priority;
  412. DWORD BytesCopied=0;
  413. DWORD BytesAvailable;
  414. USHORT DbgInfoLen;
  415. PSNIFF_INFO pSniff;
  416. DWORD i;
  417. if (!pArapConn->pDbgTraceBuffer)
  418. {
  419. return;
  420. }
  421. KeQuerySystemTime(&CurrTime);
  422. DiffTime = RtlLargeIntegerSubtract(CurrTime, ArapDbgLastTraceTime);
  423. ArapDbgLastTraceTime = CurrTime;
  424. // do the conversion to get ms
  425. Delta = (USHORT)(DiffTime.LowPart);
  426. pSniff = (PSNIFF_INFO)(pArapConn->pDbgCurrPtr);
  427. pTrace = pStartTrace = &pSniff->Frame[0];
  428. // put signature (starting of a "frame")
  429. pSniff->Signature = ARAP_SNIFF_SIGNATURE;
  430. // time since last event
  431. pSniff->TimeStamp = (DWORD)AtalkGetCurrentTick();
  432. // who is logging this info
  433. pSniff->Location = (USHORT)Location;
  434. //
  435. // ok, now see who has called us and log the relevant info
  436. // If we can't find the Location, it's ok: we have the Location number
  437. // logged and and that's adequate (that's why we can't find Location)
  438. //
  439. switch (Location)
  440. {
  441. // data to client is about to be compressed: copy some info
  442. case 11205:
  443. pBuffDesc = (PBUFFER_DESC)Context;
  444. Priority = (BYTE)dwInfo1;
  445. while (pBuffDesc)
  446. {
  447. if (pBuffDesc->bd_Flags & BD_CHAR_BUFFER)
  448. {
  449. pCurrBuff = pBuffDesc->bd_CharBuffer;
  450. BytesAvailable = pBuffDesc->bd_Length;
  451. }
  452. else
  453. {
  454. pCurrBuff = MmGetSystemAddressForMdlSafe(
  455. pBuffDesc->bd_OpaqueBuffer,
  456. NormalPagePriority);
  457. if (pCurrBuff == NULL) {
  458. goto error_end;
  459. }
  460. BytesAvailable = MmGetMdlByteCount(pBuffDesc->bd_OpaqueBuffer);
  461. }
  462. //
  463. // if this buffer descriptor contains (usually exclusively) the
  464. // ARAP header, then get some info out of it and skip those bytes
  465. //
  466. if ((pCurrBuff[2] == 0x10 || pCurrBuff[2] == 0x50) &&
  467. (pCurrBuff[3] == 0) && (pCurrBuff[4] == 0) && (pCurrBuff[5] == 2))
  468. {
  469. *pTrace++ = pCurrBuff[0]; // srplen byte 1
  470. *pTrace++ = pCurrBuff[1]; // srplen byte 2
  471. *pTrace++ = pCurrBuff[2]; // ARAP or Atalk packet
  472. *pTrace++ = Priority;
  473. BytesAvailable -= 6;
  474. pCurrBuff += 6;
  475. }
  476. // copy first 48 bytes of the data packet
  477. while (BytesAvailable && BytesCopied < 48)
  478. {
  479. *pTrace++ = *pCurrBuff++;
  480. BytesCopied++;
  481. BytesAvailable--;
  482. }
  483. pBuffDesc = pBuffDesc->bd_Next;
  484. }
  485. break;
  486. // we are sending out an ack
  487. case 11605:
  488. *pTrace++ = (BYTE)dwInfo1; // sequence num in our ack
  489. *pTrace++ = (BYTE)dwInfo2; // rcv credit in our ack
  490. break;
  491. // we are queuing compressed send bytes
  492. case 21205:
  493. *pTrace++ = (BYTE)dwInfo2; // priority of the send
  494. *pTrace++ = (BYTE)dwInfo3; // Start sequence for this send
  495. *pTrace++ = (BYTE)(pArapConn->MnpState.NextToSend-1); // end sequence
  496. BytesAvailable = dwInfo1; // len of compressed data
  497. pCurrBuff = (PBYTE)Context; // buffer with compressed data
  498. // copy first 24 bytes of the compressed data
  499. while (BytesAvailable && BytesCopied < 24)
  500. {
  501. *pTrace++ = *pCurrBuff++;
  502. BytesCopied++;
  503. BytesAvailable--;
  504. }
  505. break;
  506. // ArapExtractSRP: we're handing over 1 srp for routing or to dll
  507. case 21105:
  508. pArapBuf = (PARAPBUF)Context;
  509. pCurrBuff = pArapBuf->CurrentBuffer;
  510. BytesAvailable = pArapBuf->DataSize;
  511. // copy first 48 bytes of the decompressed data
  512. while (BytesAvailable && BytesCopied < 48)
  513. {
  514. *pTrace++ = *pCurrBuff++;
  515. BytesCopied++;
  516. BytesAvailable--;
  517. }
  518. break;
  519. // we just recvd a packet in ArapRcvIndication
  520. case 30105:
  521. BytesAvailable = dwInfo1-7; // lookahead size, minus start,stop,crc
  522. pCurrBuff = ((PBYTE)Context)+3; // lookahead buffer plus 3 start
  523. PUTSHORT2SHORT(pTrace,(USHORT)BytesAvailable);
  524. pTrace += sizeof(USHORT);
  525. // copy first 24 bytes of the compressed data
  526. while (BytesAvailable && BytesCopied < 24)
  527. {
  528. *pTrace++ = *pCurrBuff++;
  529. BytesCopied++;
  530. BytesAvailable--;
  531. }
  532. break;
  533. // we recvd a 0-len packet!
  534. case 30106:
  535. break;
  536. // we decompressed the incoming data
  537. case 30110:
  538. // how much was the decompressed length
  539. PUTSHORT2SHORT(pTrace,(USHORT)dwInfo1);
  540. pTrace += sizeof(USHORT);
  541. if (dwInfo1 == 0)
  542. {
  543. break;
  544. }
  545. pArapBuf = (PARAPBUF)Context;
  546. BytesAvailable = pArapBuf->DataSize; // len of decompressed data
  547. pCurrBuff = pArapBuf->CurrentBuffer;
  548. // copy first 48 bytes of the decompressed data
  549. while (BytesAvailable && BytesCopied < 48)
  550. {
  551. *pTrace++ = *pCurrBuff++;
  552. BytesCopied++;
  553. BytesAvailable--;
  554. }
  555. break;
  556. // attempting send when state was >= MNP_LDISCONNECTING
  557. case 30305:
  558. *pTrace = (BYTE)dwInfo1; // store pArapConn->State
  559. break;
  560. // we just sent out a packet in ArapNdisSend()
  561. case 30320:
  562. pMnpSendBuf = (PMNPSENDBUF)Context;
  563. *pTrace++ = pMnpSendBuf->SeqNum;
  564. // how big is the MNP packet
  565. PUTSHORT2SHORT(pTrace,pMnpSendBuf->DataSize);
  566. pTrace += sizeof(USHORT);
  567. *pTrace++ = (BYTE)dwInfo1; // is this a retransmission
  568. BytesAvailable = pMnpSendBuf->DataSize;
  569. pCurrBuff = (&pMnpSendBuf->Buffer[0]) + 3; // skip start bytes
  570. // copy first 24 bytes of the compressed data
  571. while (BytesAvailable && BytesCopied < 24)
  572. {
  573. *pTrace++ = *pCurrBuff++;
  574. BytesCopied++;
  575. BytesAvailable--;
  576. }
  577. default:
  578. break;
  579. }
  580. DbgInfoLen = (USHORT)(pTrace - pStartTrace);
  581. pSniff->FrameLen = DbgInfoLen;
  582. pArapConn->pDbgCurrPtr = (PBYTE)ALIGN8(pTrace);
  583. // fill up the round-up space with 0s
  584. for (NOTHING; pTrace < pArapConn->pDbgCurrPtr; pTrace++)
  585. {
  586. *pTrace = 0;
  587. }
  588. // make sure we haven't overrun this buffer
  589. ASSERT(*((DWORD *)&(pArapConn->pDbgTraceBuffer[ARAP_SNIFF_BUFF_SIZE-4])) == 0xcafebeef);
  590. // how many more bytes did we add to the sniff buff?
  591. pArapConn->SniffedBytes += (DWORD)(pArapConn->pDbgCurrPtr - (PBYTE)pSniff);
  592. //
  593. // if we are about to overflow, just reset the pointer to beginning
  594. // (do it while we have still 200 bytes left)
  595. //
  596. BufLenSoFar = (DWORD)(pArapConn->pDbgCurrPtr - pArapConn->pDbgTraceBuffer);
  597. error_end:
  598. if (BufLenSoFar > ARAP_SNIFF_BUFF_SIZE-200)
  599. {
  600. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_INFO,
  601. ("ArapDbgTrace: resetting debug buffer, Sniff data LOST!\n"));
  602. pArapConn->pDbgCurrPtr = pArapConn->pDbgTraceBuffer;
  603. pArapConn->SniffedBytes = 0;
  604. }
  605. }
  606. //***
  607. //
  608. // Function: ArapDbgTrace
  609. // This routine records history of MNP level packet exchange
  610. //
  611. // Parameters: pArapConn - the connection in question
  612. // Seq - sequence number (if applicable)
  613. // FrameType - LT, LA etc.
  614. //
  615. // Return: Nothing
  616. //
  617. // NOTE: Spinlock is assumed to be held
  618. //
  619. //***$
  620. VOID
  621. ArapDbgMnpHist(
  622. IN PARAPCONN pArapConn,
  623. IN BYTE Seq,
  624. IN BYTE FrameType
  625. )
  626. {
  627. LARGE_INTEGER TimeNow;
  628. DWORD ThisDelta;
  629. DWORD DbgMnpIndex;
  630. KeQuerySystemTime(&TimeNow);
  631. if (TimeNow.HighPart == pArapConn->LastTimeStamp.HighPart)
  632. {
  633. ThisDelta = (TimeNow.LowPart - pArapConn->LastTimeStamp.LowPart);
  634. }
  635. else
  636. {
  637. ThisDelta = (0xffffffff - pArapConn->LastTimeStamp.LowPart + TimeNow.LowPart);
  638. }
  639. // convert 100's ns to ms
  640. ThisDelta = (ThisDelta/10000);
  641. pArapConn->LastTimeStamp = TimeNow;
  642. pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].TimeStamp = ThisDelta;
  643. pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].FrameInfo = (FrameType << 16);
  644. pArapConn->DbgMnpHist[pArapConn->DbgMnpIndex].FrameInfo |= Seq;
  645. // wrap-around if necessary
  646. if ((++pArapConn->DbgMnpIndex) >= DBG_MNP_HISTORY_SIZE)
  647. {
  648. pArapConn->DbgMnpIndex = 0;
  649. }
  650. }
  651. //***
  652. //
  653. // Function: ArapDbgDumpMnpHistory
  654. // This routine dumps history of MNP level packet exchange
  655. //
  656. // Parameters: pArapConn - the connection in question
  657. //
  658. // Return: Nothing
  659. //
  660. //***$
  661. VOID
  662. ArapDbgDumpMnpHist(
  663. IN PARAPCONN pArapConn
  664. )
  665. {
  666. DWORD i;
  667. DWORD dwTmp;
  668. DWORD dwDelta;
  669. BYTE TmpSeq;
  670. if (!ArapDbgDumpOnDisconnect)
  671. {
  672. return;
  673. }
  674. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  675. ("DerefArapConn: Past history on %lx .....\n", pArapConn));
  676. // dump all info: old info first
  677. for (i=pArapConn->DbgMnpIndex; i<DBG_MNP_HISTORY_SIZE; i++)
  678. {
  679. dwDelta = pArapConn->DbgMnpHist[i].TimeStamp;
  680. dwTmp = (pArapConn->DbgMnpHist[i].FrameInfo & 0xffff0000);
  681. TmpSeq = (BYTE)(pArapConn->DbgMnpHist[i].FrameInfo & 0x000000ff);
  682. switch (dwTmp)
  683. {
  684. case 0x40000 : DbgPrint(" %6ld NT sends %x\n",dwDelta,TmpSeq);break;
  685. case 0x50000 : DbgPrint(" %6ld NT acks %x\n",dwDelta,TmpSeq);break;
  686. case 0x140000: DbgPrint(" %6ld Mac sends %x\n",dwDelta,TmpSeq);break;
  687. case 0x150000: DbgPrint(" %6ld Mac acks %x\n",dwDelta,TmpSeq);break;
  688. default : DbgPrint(" %6ld Unknown: %lx\n",dwDelta,pArapConn->DbgMnpHist[i].FrameInfo);
  689. }
  690. }
  691. // dump the current info
  692. for (i=0; i<pArapConn->DbgMnpIndex; i++)
  693. {
  694. dwDelta = pArapConn->DbgMnpHist[i].TimeStamp;
  695. dwTmp = (pArapConn->DbgMnpHist[i].FrameInfo & 0xffff0000);
  696. TmpSeq = (BYTE)(pArapConn->DbgMnpHist[i].FrameInfo & 0x000000ff);
  697. switch (dwTmp)
  698. {
  699. case 0x40000 : DbgPrint(" %6ld NT sends %x\n",dwDelta,TmpSeq);break;
  700. case 0x50000 : DbgPrint(" %6ld NT acks %x\n",dwDelta,TmpSeq);break;
  701. case 0x140000: DbgPrint(" %6ld Mac sends %x\n",dwDelta,TmpSeq);break;
  702. case 0x150000: DbgPrint(" %6ld Mac acks %x\n",dwDelta,TmpSeq);break;
  703. default : DbgPrint(" %6ld Unknown: %lx\n",dwDelta,pArapConn->DbgMnpHist[i].FrameInfo);
  704. }
  705. }
  706. }
  707. //***
  708. //
  709. // Function: ArapDumpNdisPktInfo
  710. // walk the ARAP connections list and find out how many Ndis packets
  711. // are in use right now
  712. //
  713. // Parameters: nothing
  714. //
  715. // Return: nothing
  716. //
  717. //***$
  718. VOID
  719. ArapDumpNdisPktInfo(
  720. IN VOID
  721. )
  722. {
  723. PARAPCONN pArapConn;
  724. PLIST_ENTRY pConnList;
  725. PLIST_ENTRY pList;
  726. PMNPSENDBUF pMnpSendBuf;
  727. KIRQL OldIrql;
  728. DWORD GrandTotal;
  729. DWORD ReXmit;
  730. DWORD ReXmitInNdis;
  731. DWORD Fresh;
  732. DWORD FreshInNdis;
  733. DWORD ThisConn;
  734. DWORD NumConns;
  735. if (!RasPortDesc)
  736. {
  737. return;
  738. }
  739. ACQUIRE_SPIN_LOCK(&RasPortDesc->pd_Lock, &OldIrql);
  740. pConnList = RasPortDesc->pd_ArapConnHead.Flink;
  741. GrandTotal = 0;
  742. NumConns = 0;
  743. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  744. ("NdisPacketInfo: counting total number of ndis packets used by ARAP....\n"));
  745. //
  746. // first, let's find the right connection to work on
  747. //
  748. while (pConnList != &RasPortDesc->pd_ArapConnHead)
  749. {
  750. ReXmit = 0;
  751. ReXmitInNdis = 0;
  752. Fresh = 0;
  753. FreshInNdis = 0;
  754. ThisConn = 0;
  755. pConnList = pConnList->Flink;
  756. pArapConn = CONTAINING_RECORD(pConnList, ARAPCONN, Linkage);
  757. ACQUIRE_SPIN_LOCK_DPC(&pArapConn->SpinLock);
  758. pList = pArapConn->RetransmitQ.Flink;
  759. // collect all buffers on the retransmit queue first
  760. while (pList != &pArapConn->RetransmitQ)
  761. {
  762. pList = pList->Flink;
  763. pMnpSendBuf = CONTAINING_RECORD(pList, MNPSENDBUF, Linkage);
  764. ReXmit++;
  765. if (pMnpSendBuf->Flags == 1)
  766. {
  767. ReXmitInNdis++;
  768. }
  769. }
  770. pList = pArapConn->HighPriSendQ.Flink;
  771. // collect all buffers on the fresh send
  772. while (pList != &pArapConn->HighPriSendQ)
  773. {
  774. pList = pList->Flink;
  775. pMnpSendBuf = CONTAINING_RECORD(pList, MNPSENDBUF, Linkage);
  776. Fresh++;
  777. if (pMnpSendBuf->Flags == 1)
  778. {
  779. FreshInNdis++;
  780. }
  781. }
  782. ThisConn = ReXmit+ReXmitInNdis+Fresh+FreshInNdis;
  783. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  784. (" %ld packets on %lx, %d in Ndis (%d+%d+%d+%d)\n",
  785. ThisConn,pArapConn,ReXmitInNdis,ReXmit,ReXmitInNdis,Fresh,FreshInNdis));
  786. GrandTotal += ThisConn;
  787. NumConns++;
  788. RELEASE_SPIN_LOCK_DPC(&pArapConn->SpinLock);
  789. }
  790. RELEASE_SPIN_LOCK(&RasPortDesc->pd_Lock, OldIrql);
  791. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  792. ("NdisPacketInfo: total of %ld Ndis Packets on %d connections\n",
  793. GrandTotal, NumConns));
  794. }
  795. #endif // DBG