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.

685 lines
18 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. mcap.c
  5. Abstract:
  6. ARP1394 MCAP protocol code.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 10-01-99 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. //
  15. // File-specific debugging defaults.
  16. //
  17. #define TM_CURRENT TM_MCAP
  18. //=========================================================================
  19. // L O C A L P R O T O T Y P E S
  20. //=========================================================================
  21. NDIS_STATUS
  22. arpParseMcapPkt(
  23. IN PIP1394_MCAP_PKT pMcapPkt,
  24. IN UINT cbBufferSize,
  25. OUT PIP1394_MCAP_PKT_INFO pPktInfo
  26. );
  27. VOID
  28. arpProcessMcapAdvertise(
  29. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  30. PIP1394_MCAP_PKT_INFO pPktInfo,
  31. PRM_STACK_RECORD pSR
  32. );
  33. VOID
  34. arpProcessMcapSolicit(
  35. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  36. PIP1394_MCAP_PKT_INFO pPktInfo,
  37. PRM_STACK_RECORD pSR
  38. );
  39. VOID
  40. arpUpdateMcapInfo(
  41. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  42. IN PIP1394_MCAP_PKT_INFO pPktInfo,
  43. PRM_STACK_RECORD pSR
  44. );
  45. NDIS_STATUS
  46. arpParseMcapPkt(
  47. IN PIP1394_MCAP_PKT pMcapPkt,
  48. IN UINT cbBufferSize,
  49. OUT PIP1394_MCAP_PKT_INFO pPktInfo
  50. );
  51. NDIS_STATUS
  52. arpParseMcapPkt(
  53. IN PIP1394_MCAP_PKT pMcapPkt,
  54. IN UINT cbBufferSize,
  55. OUT PIP1394_MCAP_PKT_INFO pPktInfo
  56. )
  57. /*++
  58. Routine Description:
  59. Parse the contents of IP/1394 MCAP packet data starting at
  60. pMcapPkt. Place the results into pPktInfo.
  61. Arguments:
  62. pMcapPkt - Contains the unaligned contents of an ip/1394 MCAP Pkt.
  63. pPktInfo - Unitialized structure to be filled with the parsed contents of the
  64. pkt.
  65. Return Value:
  66. NDIS_STATUS_FAILURE if the parse failed (typically because of invalid pkt
  67. contents.)
  68. NDIS_STATUS_SUCCESS on successful parsing.
  69. --*/
  70. {
  71. ENTER("arpParseMcapPkt", 0x95175d5a)
  72. NDIS_STATUS Status;
  73. DBGSTMT(CHAR *szError = "General failure";)
  74. Status = NDIS_STATUS_FAILURE;
  75. do
  76. {
  77. UINT OpCode; // MCAP op code (solicit/advertise)
  78. UINT Length; // Length of valid part of packet, including the encap header.
  79. UINT NumGds; // Number of group_descriptors;
  80. // Minimum size.
  81. //
  82. if (cbBufferSize < FIELD_OFFSET(IP1394_MCAP_PKT, group_descriptors))
  83. {
  84. DBGSTMT(szError = "Packet too small";)
  85. break;
  86. }
  87. // Ethertype
  88. //
  89. if (pMcapPkt->header.EtherType != H2N_USHORT(NIC1394_ETHERTYPE_MCAP))
  90. {
  91. DBGSTMT(szError = "header.EtherType!=MCAP";)
  92. break;
  93. }
  94. // length
  95. //
  96. {
  97. // pMcapPkt->length is the length of packet excluding the unfragmented
  98. // header.
  99. //
  100. Length = (ULONG) N2H_USHORT(pMcapPkt->length) + sizeof(pMcapPkt->header);
  101. if (Length > cbBufferSize)
  102. {
  103. DBGSTMT(szError = "Length field too large";)
  104. break;
  105. }
  106. // Note: it's valid to have zero group descriptors.
  107. //
  108. if (Length < FIELD_OFFSET(IP1394_MCAP_PKT, group_descriptors))
  109. {
  110. DBGSTMT(szError = "Length field too small";)
  111. break;
  112. }
  113. }
  114. // reserved field
  115. //
  116. if (pMcapPkt->reserved != 0)
  117. {
  118. DBGSTMT(szError = "reserved != 0";)
  119. break;
  120. }
  121. // Opcode
  122. //
  123. {
  124. OpCode = N2H_USHORT(pMcapPkt->opcode);
  125. if ( OpCode != IP1394_MCAP_OP_ADVERTISE
  126. && OpCode != IP1394_MCAP_OP_SOLICIT)
  127. {
  128. DBGSTMT(szError = "Invalid opcode";)
  129. break;
  130. }
  131. }
  132. // Now we check the descriptors
  133. //
  134. {
  135. PIP1394_MCAP_GD pGd;
  136. DBGSTMT(PIP1394_MCAP_GD pGdEnd;)
  137. UINT u;
  138. // Note: we've already verified that Length is large enough.
  139. //
  140. NumGds = (Length - FIELD_OFFSET(IP1394_MCAP_PKT, group_descriptors))
  141. / sizeof(IP1394_MCAP_GD);
  142. pGd = pMcapPkt->group_descriptors;
  143. DBGSTMT(pGdEnd = (PIP1394_MCAP_GD) (((PUCHAR) pMcapPkt) + cbBufferSize);)
  144. for (u=NumGds; u>0; u--, pGd++)
  145. {
  146. IP1394_MCAP_GD Gd;
  147. ASSERT(pGd < pGdEnd);
  148. Gd = *pGd; // Unaligned struct copy.
  149. if (Gd.length != sizeof(Gd))
  150. {
  151. // bad length
  152. //
  153. DBGSTMT(szError = "Bad GD: bad length";)
  154. break;
  155. }
  156. if (Gd.type != IP1394_MCAP_GD_TYPE_V1)
  157. {
  158. // bad type
  159. //
  160. DBGSTMT(szError = "Bad GD: bad type";)
  161. break;
  162. }
  163. if (Gd.reserved != 0)
  164. {
  165. // bad reserved
  166. //
  167. DBGSTMT(szError = "Bad GD: bad reserved";)
  168. break;
  169. }
  170. if (Gd.channel > 63)
  171. {
  172. // bad channel
  173. //
  174. DBGSTMT(szError = "Bad GD: bad channel";)
  175. break;
  176. }
  177. // We don't check speed code to interop with unknown speeds.
  178. // (we map unknown speeds to the highest speed code we know about.
  179. if (Gd.reserved2 != 0)
  180. {
  181. // bad reserved2
  182. //
  183. DBGSTMT(szError = "Bad GD: bad reserved2";)
  184. break;
  185. }
  186. if (Gd.bandwidth != 0)
  187. {
  188. // bad bandwidth
  189. //
  190. DBGSTMT(szError = "Bad GD: bad bandwidth";)
  191. break;
  192. }
  193. {
  194. UINT Addr = H2N_ULONG(Gd.group_address);
  195. if ( (Addr & 0xf0000000) != 0xe0000000)
  196. {
  197. // Address is not class D
  198. //
  199. DBGSTMT(szError = "Bad GD: address not class D";)
  200. break;
  201. }
  202. if (Addr == 0xe0000001 || Addr == 0xe0000002)
  203. {
  204. // 224.0.0.1 and 224.0.0.2 must be sent on the broadcast
  205. // channel
  206. //
  207. DBGSTMT(szError = "Bad GD: Address 224.0.0.1 or 2";)
  208. break;
  209. }
  210. }
  211. }
  212. if (u!=0)
  213. {
  214. break;
  215. }
  216. }
  217. //
  218. // Pkt appears valid, let's fill out the parsed information....
  219. //
  220. ARP_ZEROSTRUCT(pPktInfo);
  221. pPktInfo->NumGroups = NumGds;
  222. pPktInfo->SenderNodeID = N2H_USHORT(pMcapPkt->header.NodeId);
  223. pPktInfo->OpCode = OpCode;
  224. // Parse the group descriptors...
  225. // If required, dynamically allocate space for the descriptors,
  226. // otherwise we use pPktInfo->GdSpace;
  227. //
  228. {
  229. PIP1394_MCAP_GD pGd;
  230. PIP1394_MCAP_GD_INFO pGdi;
  231. UINT cb = NumGds * sizeof(*pGdi);
  232. UINT u;
  233. if (cb <= sizeof(pPktInfo->GdiSpace))
  234. {
  235. pGdi = pPktInfo->GdiSpace;
  236. }
  237. else
  238. {
  239. NdisAllocateMemoryWithTag(&pGdi, cb, MTAG_MCAP_GD);
  240. if (pGdi == NULL)
  241. {
  242. DBGSTMT(szError = "Allocation Failure";)
  243. Status = NDIS_STATUS_RESOURCES;
  244. break;
  245. }
  246. }
  247. pPktInfo->pGdis = pGdi;
  248. // Now parse...
  249. //
  250. pGd = pMcapPkt->group_descriptors;
  251. for (u=NumGds; u>0; u--, pGd++, pGdi++)
  252. {
  253. pGdi->Expiration = pGd->expiration;
  254. pGdi->Channel = pGd->channel;
  255. pGdi->SpeedCode = pGd->speed;
  256. pGdi->GroupAddress = pGd->group_address; // Leave in Network order
  257. if (pGdi->Channel >= ARP_NUM_CHANNELS)
  258. {
  259. TR_INFO(("Bad channel in GD 0x%p\n", pGdi));
  260. continue;
  261. }
  262. //
  263. // Although RFC doesn't stipulate a max expiry time, we
  264. // cap it ourselves, in case this is a rogue packet.
  265. //
  266. #define MAX_EXPIRATION 120
  267. if (pGdi->Expiration >= MAX_EXPIRATION)
  268. {
  269. TR_INFO(("Capping expiry time to %d sec\n", MAX_EXPIRATION));
  270. pGdi->Expiration = MAX_EXPIRATION;
  271. continue;
  272. }
  273. if (pGdi->SpeedCode > SCODE_3200_RATE)
  274. {
  275. //
  276. // This is either a bad value, or a rate higher than we know
  277. // about. We can't distinguish between the two, so we just set
  278. // the speed to the highest we know about.
  279. //
  280. pGdi->SpeedCode = SCODE_3200_RATE;
  281. }
  282. }
  283. }
  284. Status = NDIS_STATUS_SUCCESS;
  285. } while (FALSE);
  286. if (FAIL(Status))
  287. {
  288. TR_WARN(("Bad mcap pkt data at 0x%p (%s)\n", pMcapPkt, szError));
  289. }
  290. else
  291. {
  292. #if DBG
  293. UINT Addr = 0;
  294. UINT Channel = 0;
  295. UINT Exp = 0;
  296. PUCHAR pc = (PUCHAR) &Addr;
  297. if (pPktInfo->NumGroups!=0)
  298. {
  299. Addr = pPktInfo->pGdis[0].GroupAddress;
  300. Channel = pPktInfo->pGdis[0].Channel;
  301. Exp = pPktInfo->pGdis[0].Expiration;
  302. }
  303. #endif // DBG
  304. TR_WARN(("Received MCAP PKT. NodeId=0x%04lx NumGrps=%lu."
  305. " 1st=(Grp=%lu.%lu.%lu.%lu, Ch=%lu, TTL=%lu)\n",
  306. pPktInfo->SenderNodeID,
  307. pPktInfo->NumGroups,
  308. pc[0], pc[1], pc[2], pc[3],
  309. Channel,
  310. Exp
  311. ));
  312. }
  313. EXIT()
  314. return Status;
  315. }
  316. NDIS_STATUS
  317. arpCreateMcapPkt(
  318. IN PARP1394_INTERFACE pIF,
  319. IN PIP1394_MCAP_PKT_INFO pPktInfo,
  320. OUT PNDIS_PACKET *ppNdisPacket,
  321. PRM_STACK_RECORD pSR
  322. )
  323. /*++
  324. Routine Description:
  325. Use information in pPktInfo to allocate and initialize an mcap packet.
  326. Arguments:
  327. pPktInfo - Parsed version of the arp request/response packet.
  328. ppNdisPacket - Points to a place to store a pointer to the allocated packet.
  329. Return Value:
  330. NDIS_STATUS_RESOURCES - If we couldn't allocate the packet.
  331. NDIS_STATUS_SUCCESS - on success.
  332. --*/
  333. {
  334. UINT NumGroups;
  335. UINT Length;
  336. NDIS_STATUS Status;
  337. PIP1394_MCAP_PKT pPktData;
  338. NumGroups = pPktInfo->NumGroups;
  339. Length = FIELD_OFFSET(IP1394_MCAP_PKT, group_descriptors);
  340. Length += NumGroups * sizeof(IP1394_MCAP_GD);
  341. Status = arpAllocateControlPacket(
  342. pIF,
  343. Length,
  344. ARP1394_PACKET_FLAGS_MCAP,
  345. ppNdisPacket,
  346. &pPktData,
  347. pSR
  348. );
  349. if (FAIL(Status)) return Status; // ***** EARLY RETURN ******
  350. // Can't use ARP_ZEROSTRUCT because NumGroups may be zero.
  351. //
  352. NdisZeroMemory(pPktData, Length);
  353. pPktData->header.EtherType = H2N_USHORT(NIC1394_ETHERTYPE_MCAP);
  354. pPktData->opcode = (UCHAR)pPktInfo->OpCode;
  355. Length -= sizeof(pPktData->header); // Skip the header.
  356. pPktData->length = H2N_USHORT(Length);
  357. // Construct the group descriptors.
  358. //
  359. if (NumGroups)
  360. {
  361. PIP1394_MCAP_GD_INFO pGdi = pPktInfo->pGdis;
  362. PIP1394_MCAP_GD pGd = pPktData->group_descriptors;
  363. for(;NumGroups; pGdi++, pGd++, NumGroups--)
  364. {
  365. ARP_ZEROSTRUCT(pGd);
  366. pGd->length = (UCHAR) sizeof(*pGd);
  367. pGd->expiration = (UCHAR) pGdi->Expiration;
  368. pGd->channel = (UCHAR) pGdi->Channel;
  369. pGd->speed = (UCHAR) pGdi->SpeedCode;
  370. pGd->group_address = pGdi->GroupAddress;
  371. }
  372. }
  373. return NDIS_STATUS_SUCCESS;
  374. }
  375. #if 0
  376. // Parsed version of the IP/1394 MCAP Group Descriptor
  377. //
  378. typedef struct
  379. {
  380. UINT Expiration;
  381. UINT Channel;
  382. UINT SpeedCode;
  383. IP_ADDRESS GroupAddress;
  384. } IP1394_MCAP_GD_INFO, * PIP1394_MCAP_GD_INFO;
  385. // Parsed version of an IP/1394 MCAP packet.
  386. //
  387. typedef struct
  388. {
  389. UINT SenderNodeID;
  390. UINT OpCode;
  391. UINT NumGroups;
  392. PIP1394_MCAP_GD_INFO pGdis;
  393. // Space for storing up-to 4 GD_INFOs
  394. //
  395. IP1394_MCAP_GD_INFO GdiSpace[4];
  396. } IP1394_MCAP_PKT_INFO, *PIP1394_MCAP_PKT_INFO;
  397. #endif // 0
  398. VOID
  399. arpUpdateMcapInfo(
  400. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  401. IN PIP1394_MCAP_PKT_INFO pPktInfo,
  402. PRM_STACK_RECORD pSR
  403. )
  404. {
  405. ENTER("arpUpdateMcapInfo", 0xcac15343)
  406. PIP1394_MCAP_GD_INFO pGdi;
  407. UINT NumGroups;
  408. UINT Current;
  409. UINT NodeId;
  410. RM_DECLARE_STACK_RECORD(sr)
  411. RM_ASSERT_OBJUNLOCKED(&pIF->Hdr, pSR);
  412. // Get the current time (in seconds).
  413. //
  414. Current = arpGetSystemTime();
  415. //
  416. // Go through the group discriptors, updating our database.
  417. //
  418. NumGroups = pPktInfo->NumGroups;
  419. pGdi = pPktInfo->pGdis;
  420. NodeId = pPktInfo->SenderNodeID;
  421. for(;NumGroups; pGdi++, NumGroups--)
  422. {
  423. UINT Expiration = pGdi->Expiration;
  424. UINT Channel = pGdi->Channel;
  425. IP_ADDRESS GroupAddress = pGdi->GroupAddress;
  426. PMCAP_CHANNEL_INFO pMci;
  427. //
  428. // Process this group descriptor.
  429. //
  430. if (Channel >= ARP_NUM_CHANNELS)
  431. {
  432. ASSERT(FALSE); // we should have already screened this value.
  433. continue;
  434. }
  435. LOCKOBJ(pIF, &sr);
  436. pMci = &pIF->mcapinfo.rgChannelInfo[Channel];
  437. pMci->Channel = Channel;
  438. pMci->GroupAddress = GroupAddress;
  439. pMci->UpdateTime = Current;
  440. pMci->ExpieryTime = Current + Expiration; // Expiration is in seconds.
  441. pMci->Flags = 0; // Reset flags.
  442. pMci->NodeId = NodeId; // TODO: check if existing node id is higher?
  443. UNLOCKOBJ(pIF, &sr);
  444. }
  445. RM_ASSERT_OBJUNLOCKED(&pIF->Hdr, pSR);
  446. }
  447. VOID
  448. arpProcessMcapPkt(
  449. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  450. PIP1394_MCAP_PKT pMcapPkt,
  451. UINT cbBufferSize
  452. )
  453. {
  454. NDIS_STATUS Status;
  455. IP1394_MCAP_PKT_INFO PktInfo;
  456. ENTER("arpProcessMcapPkt", 0xc5ba8005)
  457. RM_DECLARE_STACK_RECORD(sr)
  458. DBGMARK(0x3cfaf454);
  459. Status = arpParseMcapPkt(
  460. pMcapPkt,
  461. cbBufferSize,
  462. &PktInfo
  463. );
  464. if (!FAIL(Status))
  465. {
  466. if (PktInfo.OpCode == IP1394_MCAP_OP_ADVERTISE)
  467. {
  468. arpProcessMcapAdvertise(pIF, &PktInfo, &sr);
  469. }
  470. else
  471. {
  472. ASSERT(PktInfo.OpCode == IP1394_MCAP_OP_SOLICIT);
  473. arpProcessMcapSolicit(pIF, &PktInfo, &sr);
  474. }
  475. }
  476. RM_ASSERT_CLEAR(&sr);
  477. EXIT()
  478. }
  479. VOID
  480. arpProcessMcapAdvertise(
  481. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  482. PIP1394_MCAP_PKT_INFO pPktInfo,
  483. PRM_STACK_RECORD pSR
  484. )
  485. {
  486. //
  487. // Update our database.
  488. //
  489. arpUpdateMcapInfo(
  490. pIF, // NOLOCKIN NOLOCKOUT
  491. pPktInfo,
  492. pSR
  493. );
  494. }
  495. VOID
  496. arpProcessMcapSolicit(
  497. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  498. PIP1394_MCAP_PKT_INFO pPktInfo,
  499. PRM_STACK_RECORD pSR
  500. )
  501. {
  502. //
  503. // We ignore solicit messages.
  504. //
  505. //
  506. }
  507. MYBOOL
  508. arpIsActiveMcapChannel(
  509. PMCAP_CHANNEL_INFO pMci,
  510. UINT CurrentTime
  511. )
  512. {
  513. ENTER("IsActiveMcapChannel", 0x0)
  514. MYBOOL fOk = TRUE;
  515. // Check update time.
  516. //
  517. #define ARP_MAX_MCAP_UPDATE_INTERVAL 60
  518. if ((pMci->UpdateTime+ARP_MAX_MCAP_UPDATE_INTERVAL) < CurrentTime)
  519. {
  520. TR_WARN(("McapDB: channel %lu update time crossed.\n",
  521. pMci->Channel
  522. ));
  523. fOk = FALSE;
  524. }
  525. // Check expire time.
  526. //
  527. if (pMci->ExpieryTime <= CurrentTime)
  528. {
  529. TR_WARN(("McapDB: channel %lu time expired.\n",
  530. pMci->Channel
  531. ));
  532. fOk = FALSE;
  533. }
  534. return fOk;
  535. }
  536. VOID
  537. arpLocallyUpdateMcapInfo(
  538. PARP1394_INTERFACE pIF,
  539. UINT Channel,
  540. UINT GroupAddress,
  541. UINT CurrentTime,
  542. PRM_STACK_RECORD pSR
  543. )
  544. {
  545. ENTER("arpLocallyUpdateMcapInfo", 0x0)
  546. PMCAP_CHANNEL_INFO pMci;
  547. LOCKOBJ(pIF, pSR);
  548. pMci = &pIF->mcapinfo.rgChannelInfo[Channel];
  549. pMci->Channel = Channel;
  550. pMci->GroupAddress = GroupAddress;
  551. pMci->UpdateTime = CurrentTime;
  552. pMci->ExpieryTime = CurrentTime + 60; // Expiration is in seconds.
  553. pMci->Flags = 0; // Reset flags.
  554. pMci->NodeId = 0; // NodeId; // TODO: get real node id.
  555. UNLOCKOBJ(pIF, pSR);
  556. }