Source code of Windows XP (NT5)
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.

3795 lines
103 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. eth.c
  5. Abstract:
  6. ARP1394 Ethernet emulation-related handlers.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 11-22-99 Created
  11. Adube 10-2000 Added Bridging
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. //
  16. // File-specific debugging defaults.
  17. //
  18. #define TM_CURRENT TM_ETH
  19. UINT Arp1394ToIcs = 0;
  20. //=========================================================================
  21. // L O C A L P R O T O T Y P E S
  22. //=========================================================================
  23. // These are ethernet arp specific constants
  24. //
  25. #define ARP_ETH_ETYPE_IP 0x800
  26. #define ARP_ETH_ETYPE_ARP 0x806
  27. #define ARP_ETH_REQUEST 1
  28. #define ARP_ETH_RESPONSE 2
  29. #define ARP_ETH_HW_ENET 1
  30. #define ARP_ETH_HW_802 6
  31. //
  32. // Check whether an address is multicast
  33. //
  34. #define ETH_IS_MULTICAST(Address) \
  35. (BOOLEAN)(((PUCHAR)(Address))[0] & ((UCHAR)0x01))
  36. //
  37. // Check whether an address is broadcast.
  38. //
  39. #define ETH_IS_BROADCAST(Address) \
  40. ((((PUCHAR)(Address))[0] == ((UCHAR)0xff)) && (((PUCHAR)(Address))[1] == ((UCHAR)0xff)))
  41. #pragma pack (push, 1)
  42. //* Structure of an Ethernet header (taken from ip\arpdef.h).
  43. typedef struct ENetHeader {
  44. ENetAddr eh_daddr;
  45. ENetAddr eh_saddr;
  46. USHORT eh_type;
  47. } ENetHeader;
  48. const ENetAddr BroadcastENetAddr =
  49. {
  50. {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
  51. };
  52. // Following is a template for creating Ethernet Multicast addresses
  53. // from ip multicast addresses.
  54. // The last 3 bytes are the last 3 bytes (network byte order) of the mcast
  55. // address.
  56. //
  57. const ENetAddr MulticastENetAddr =
  58. {
  59. {0x01,0x00,0x5E,0x00, 0x00, 0x00}
  60. };
  61. //
  62. // This is the Ethernet address to which the bridge sends STA packets.
  63. // STA packets are used by the bridge to detect loops
  64. //
  65. // Size of a basic UDP header
  66. #define SIZE_OF_UDP_HEADER 8 // bytes
  67. // Minimum size of the payload of a BOOTP packet
  68. #define SIZE_OF_BASIC_BOOTP_PACKET 236 // bytes
  69. // The UDP IP protocol type
  70. #define UDP_PROTOCOL 0x11
  71. // Size of Ethernet header
  72. #define ETHERNET_HEADER_SIZE (ETH_LENGTH_OF_ADDRESS * 2 ) + 2
  73. UCHAR gSTAMacAddr[ETH_LENGTH_OF_ADDRESS] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 };
  74. #define NIC1394_ETHERTYPE_STA 0x777
  75. const
  76. NIC1394_ENCAPSULATION_HEADER
  77. Arp1394_StaEncapHeader =
  78. {
  79. 0x0000, // Reserved
  80. H2N_USHORT(NIC1394_ETHERTYPE_STA)
  81. };
  82. // Structure of an Ethernet ARP packet.
  83. //
  84. typedef struct {
  85. ENetHeader header;
  86. USHORT hardware_type;
  87. USHORT protocol_type;
  88. UCHAR hw_addr_len;
  89. UCHAR IP_addr_len;
  90. USHORT opcode; // Opcode.
  91. ENetAddr sender_hw_address;
  92. IP_ADDRESS sender_IP_address;
  93. ENetAddr target_hw_address;
  94. IP_ADDRESS target_IP_address;
  95. } ETH_ARP_PKT, *PETH_ARP_PKT;
  96. #pragma pack (pop)
  97. // Parsed version of an ethernet ARP packet.
  98. //
  99. typedef struct {
  100. ENetAddr SourceEthAddress; // Ethernet source h/w address.
  101. ENetAddr DestEthAddress; // Ethernet source h/w address.
  102. UINT OpCode; // ARP_ETH_REQUEST/RESPONSE
  103. ENetAddr SenderEthAddress; // Ethernet source h/w address.
  104. IP_ADDRESS SenderIpAddress; // IP source address
  105. ENetAddr TargetEthAddress; // Ethernet destination h/w address.
  106. IP_ADDRESS TargetIpAddress; // IP target address
  107. } ETH_ARP_PKT_INFO, *PETH_ARP_PKT_INFO;
  108. #define ARP_FAKE_ETH_ADDRESS(_AdapterNum) \
  109. { \
  110. 0x02 | (((UCHAR)(_AdapterNum) & 0x3f) << 2), \
  111. ((UCHAR)(_AdapterNum) & 0x3f), \
  112. 0,0,0,0 \
  113. }
  114. #define ARP_DEF_REMOTE_ETH_ADDRESS \
  115. ARP_FAKE_ETH_ADDRESS(0xf)
  116. #define ARP_IS_BOOTP_REQUEST(_pData) (_pData[0] == 0x1) // Byte 0 is the operation; 1 for a request, 2 for a reply
  117. #define ARP_IS_BOOTP_RESPONSE(_pData) (_pData[0] == 0x2) // Byte 0 is the operation; 1 for a request, 2 for a reply
  118. typedef struct _ARP_BOOTP_INFO
  119. {
  120. ULONG Xid;
  121. BOOLEAN bIsRequest;
  122. ENetAddr requestorMAC;
  123. } ARP_BOOTP_INFO , *PARP_BOOTP_INFO;
  124. NDIS_STATUS
  125. arpIcsTranslateIpPkt(
  126. IN PARP1394_INTERFACE pIF,
  127. IN PNDIS_PACKET pOrigPkt,
  128. IN ARP_ICS_FORWARD_DIRECTION Direction,
  129. IN MYBOOL fUnicast,
  130. OUT PNDIS_PACKET *ppNewPkt,
  131. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  132. PRM_STACK_RECORD pSR
  133. );
  134. NDIS_STATUS
  135. arpGetEthHeaderFrom1394IpPkt(
  136. IN PARP1394_INTERFACE pIF,
  137. IN PVOID pvData,
  138. IN UINT cbData,
  139. IN MYBOOL fUnicast,
  140. OUT ENetHeader *pEthHdr,
  141. OUT PIP_ADDRESS pDestIpAddress, // OPTIONAL
  142. PRM_STACK_RECORD pSR
  143. );
  144. NDIS_STATUS
  145. arpGet1394HeaderFromEthIpPkt(
  146. IN PARP1394_INTERFACE pIF,
  147. IN PNDIS_BUFFER pFirstBuffer,
  148. IN PVOID pvData,
  149. IN UINT cbData,
  150. IN MYBOOL fUnicast,
  151. OUT NIC1394_ENCAPSULATION_HEADER
  152. *p1394Hdr,
  153. OUT PREMOTE_DEST_KEY pDestIpAddress, // OPTIONAL
  154. PRM_STACK_RECORD pSR
  155. );
  156. NDIS_STATUS
  157. arpGetEthAddrFromIpAddr(
  158. IN PARP1394_INTERFACE pIF,
  159. IN MYBOOL fUnicast,
  160. IN IP_ADDRESS DestIpAddress,
  161. OUT ENetAddr *pEthAddr,
  162. PRM_STACK_RECORD pSR
  163. );
  164. NDIS_STATUS
  165. arpParseEthArpPkt(
  166. IN PETH_ARP_PKT pArpPkt,
  167. IN UINT cbBufferSize,
  168. OUT PETH_ARP_PKT_INFO pPktInfo
  169. );
  170. VOID
  171. arpPrepareEthArpPkt(
  172. IN PETH_ARP_PKT_INFO pPktInfo,
  173. OUT PETH_ARP_PKT pArpPkt
  174. );
  175. MYBOOL
  176. arpIsUnicastEthDest(
  177. IN UNALIGNED ENetHeader *pEthHdr
  178. );
  179. VOID
  180. arpEthProcess1394ArpPkt(
  181. IN PARP1394_INTERFACE pIF,
  182. IN PIP1394_ARP_PKT pArpPkt,
  183. IN UINT HeaderSize
  184. );
  185. VOID
  186. arpEthProcessEthArpPkt(
  187. IN PARP1394_INTERFACE pIF,
  188. IN PETH_ARP_PKT pArpPkt,
  189. IN UINT HeaderSize
  190. );
  191. NDIS_STATUS
  192. arpConstructEthArpInfoFrom1394ArpInfo(
  193. IN PARP1394_INTERFACE pIF,
  194. IN PIP1394_ARP_PKT_INFO p1394PktInfo,
  195. OUT PETH_ARP_PKT_INFO pEthPktInfo,
  196. PRM_STACK_RECORD pSR
  197. );
  198. NDIS_STATUS
  199. arpConstruct1394ArpInfoFromEthArpInfo(
  200. IN PARP1394_INTERFACE pIF,
  201. IN PETH_ARP_PKT_INFO pEthPktInfo,
  202. OUT PIP1394_ARP_PKT_INFO p1394PktInfo,
  203. PRM_STACK_RECORD pSR
  204. );
  205. VOID
  206. arpIcsForwardIpPacket(
  207. IN PARP1394_INTERFACE pIF,
  208. IN PNDIS_PACKET pPacket,
  209. IN ARP_ICS_FORWARD_DIRECTION Direction,
  210. IN MYBOOL fUnicast,
  211. IN PRM_STACK_RECORD pSR
  212. );
  213. VOID
  214. arpUpdateEthArpCache(
  215. IN PARP1394_INTERFACE pIF,
  216. IN IP_ADDRESS DestIpAddr,
  217. IN PARP_REMOTE_ETH_PARAMS pCreateParams, // Creation params
  218. IN MYBOOL fCreateIfRequired,
  219. IN PRM_STACK_RECORD pSR
  220. );
  221. NDIS_STATUS
  222. arpGetSourceMacAddressFor1394Pkt (
  223. IN PARP1394_ADAPTER pAdapter,
  224. IN UCHAR SourceNodeAddress,
  225. IN BOOLEAN fIsValidSourceNodeAddress,
  226. OUT ENetAddr* pSourceMacAddress,
  227. PRM_STACK_RECORD pSR
  228. );
  229. NDIS_STATUS
  230. arpEthConstructSTAEthHeader(
  231. IN PUCHAR pvData,
  232. IN UINT cbData,
  233. OUT ENetHeader *pEthHdr
  234. );
  235. NDIS_STATUS
  236. arpEthModifyBootPPacket(
  237. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  238. IN ARP_ICS_FORWARD_DIRECTION Direction,
  239. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  240. IN PUCHAR pucNewData,
  241. IN ULONG PacketLength,
  242. IN PRM_STACK_RECORD pSR
  243. );
  244. BOOLEAN
  245. arpEthPreprocessBootPPacket(
  246. IN PARP1394_INTERFACE pIF,
  247. IN PUCHAR pPacketData,
  248. IN PUCHAR pBootPData, // Actual BOOTP packet
  249. OUT PBOOLEAN pbIsRequest,
  250. PARP_BOOTP_INFO pInfoBootP,
  251. PRM_STACK_RECORD pSR
  252. );
  253. VOID
  254. arpIcsForwardIpPacket(
  255. IN PARP1394_INTERFACE pIF,
  256. IN PNDIS_PACKET pPacket,
  257. IN ARP_ICS_FORWARD_DIRECTION Direction,
  258. IN MYBOOL fUnicast,
  259. IN PRM_STACK_RECORD pSR
  260. )
  261. /*++
  262. Routine Description:
  263. Forward a packet from the ip/1394 side to the ethernet side, or vice-versa.
  264. Arguments:
  265. --*/
  266. {
  267. NDIS_STATUS Status;
  268. PNDIS_PACKET pNewPkt = NULL;
  269. ENTER("arpIcsForwardIpPacket", 0x98630e8f)
  270. do
  271. {
  272. PARPCB_DEST pDest = NULL;
  273. //
  274. // Create the translated packet.
  275. //
  276. Status = arpIcsTranslateIpPkt(
  277. pIF,
  278. pPacket,
  279. Direction,
  280. fUnicast,
  281. &pNewPkt,
  282. NULL, // Optional pIpDestAddr
  283. pSR
  284. );
  285. if (FAIL(Status))
  286. {
  287. if (Status == NDIS_STATUS_ALREADY_MAPPED)
  288. {
  289. //
  290. // This is a loop-backed packet.
  291. //
  292. arpEthReceivePacket(
  293. pIF,
  294. pPacket
  295. );
  296. }
  297. pNewPkt = NULL;
  298. break;
  299. }
  300. // We special case unicast sends to 1394, because that requires
  301. // special treatment: we need to lookup the destination and if
  302. // required create a VC to that destination. This
  303. // is done elsewhere (in arpEthernetReceivePacket), so we assert
  304. // we never get this this case.
  305. //
  306. ASSERT(!(Direction == ARP_ICS_FORWARD_TO_1394 && fUnicast))
  307. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  308. //
  309. // Determine destination
  310. //
  311. if (Direction == ARP_ICS_FORWARD_TO_1394)
  312. {
  313. pDest = pIF->pBroadcastDest;
  314. }
  315. else
  316. {
  317. ASSERT(Direction == ARP_ICS_FORWARD_TO_ETHERNET);
  318. pDest = pIF->pEthernetDest;
  319. };
  320. arpSendControlPkt(
  321. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  322. pNewPkt,
  323. pDest,
  324. pSR
  325. );
  326. } while (FALSE);
  327. EXIT()
  328. }
  329. NDIS_STATUS
  330. arpIcsTranslateIpPkt(
  331. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  332. IN PNDIS_PACKET pOrigPkt,
  333. IN ARP_ICS_FORWARD_DIRECTION Direction,
  334. IN MYBOOL fUnicast,
  335. OUT PNDIS_PACKET *ppNewPkt,
  336. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  337. PRM_STACK_RECORD pSR
  338. )
  339. {
  340. NDIS_STATUS Status;
  341. PNDIS_PACKET pNewPkt = NULL;
  342. PVOID pvNewData = NULL;
  343. do
  344. {
  345. PNDIS_BUFFER pOrigBuf = NULL;
  346. PVOID pvOrigData = NULL;
  347. UINT OrigBufSize;
  348. PVOID pvNewHdr = NULL;
  349. UINT OrigHdrSize;
  350. UINT NewHdrSize;
  351. UINT OrigPktSize;
  352. UINT NewPktSize;
  353. UINT BytesCopied;
  354. NIC1394_ENCAPSULATION_HEADER
  355. Nic1394Hdr;
  356. ENetHeader EthHdr;
  357. // Get size of 1st buffer and pointer to it's data.
  358. // (We only bother about the 1st buffer)
  359. //
  360. NdisQueryPacket(
  361. pOrigPkt,
  362. NULL,
  363. NULL,
  364. &pOrigBuf,
  365. &OrigPktSize
  366. );
  367. if (OrigPktSize > 0)
  368. {
  369. NdisQueryBuffer(
  370. pOrigBuf,
  371. &pvOrigData,
  372. &OrigBufSize
  373. );
  374. }
  375. else
  376. {
  377. OrigBufSize = 0;
  378. }
  379. if (pvOrigData == NULL)
  380. {
  381. Status = NDIS_STATUS_FAILURE;
  382. break;
  383. }
  384. // Compute direction-specific information
  385. //
  386. if(Direction == ARP_ICS_FORWARD_TO_1394)
  387. {
  388. OrigHdrSize = sizeof(EthHdr);
  389. NewHdrSize = sizeof(Nic1394Hdr);
  390. Status = arpGet1394HeaderFromEthIpPkt(
  391. pIF,
  392. pOrigBuf,
  393. pvOrigData,
  394. OrigBufSize,
  395. fUnicast,
  396. &Nic1394Hdr,
  397. pDestAddress,
  398. pSR
  399. );
  400. pvNewHdr = (PVOID) &Nic1394Hdr;
  401. }
  402. else
  403. {
  404. ASSERT(Direction==ARP_ICS_FORWARD_TO_ETHERNET);
  405. OrigHdrSize = sizeof(Nic1394Hdr);
  406. NewHdrSize = sizeof(EthHdr);
  407. Status = arpGetEthHeaderFrom1394IpPkt(
  408. pIF,
  409. pvOrigData,
  410. OrigBufSize,
  411. fUnicast,
  412. &EthHdr,
  413. &pDestAddress->IpAddress,
  414. pSR
  415. );
  416. pvNewHdr = (PVOID) &EthHdr;
  417. };
  418. if (FAIL(Status)) break;
  419. // Make sure the 1st buffer contains enough data for the header.
  420. //
  421. if (OrigBufSize < OrigHdrSize)
  422. {
  423. ASSERT(FALSE); // We should check why we're getting
  424. // this kind of tiny 1st buffer.
  425. Status = NDIS_STATUS_FAILURE;
  426. break;
  427. }
  428. // Compute the new packet size.
  429. //
  430. NewPktSize = OrigPktSize - OrigHdrSize + NewHdrSize;
  431. // Allocate an appropriately sized control packet.
  432. //
  433. Status = arpAllocateControlPacket(
  434. pIF,
  435. NewPktSize,
  436. ARP1394_PACKET_FLAGS_ICS,
  437. &pNewPkt,
  438. &pvNewData,
  439. pSR
  440. );
  441. if (FAIL(Status))
  442. {
  443. ASSERT(FALSE); // we want to know if we hit this in regular use.
  444. pNewPkt = NULL;
  445. break;
  446. }
  447. // Copy over the new header.
  448. //
  449. NdisMoveMemory(pvNewData, pvNewHdr, NewHdrSize);
  450. // Copy the rest of the packet contents.
  451. //
  452. NdisCopyFromPacketToPacket(
  453. pNewPkt, // Dest pkt
  454. NewHdrSize, // Dest offset
  455. OrigPktSize - OrigHdrSize, // BytesToCopy
  456. pOrigPkt, // Source,
  457. OrigHdrSize, // SourceOffset
  458. &BytesCopied
  459. );
  460. if (BytesCopied != (OrigPktSize - OrigHdrSize))
  461. {
  462. ASSERT(FALSE); // Should never get here.
  463. Status = NDIS_STATUS_FAILURE;
  464. break;
  465. }
  466. // Add the Bootp code here.
  467. Status = arpEthModifyBootPPacket(pIF,
  468. Direction,
  469. pDestAddress,
  470. (PUCHAR)pvNewData,
  471. NewPktSize ,
  472. pSR);
  473. if (Status != NDIS_STATUS_SUCCESS)
  474. {
  475. ASSERT (!"TempAssert -arpEthModifyBootPPacket FAILED");
  476. break;
  477. }
  478. } while (FALSE);
  479. if (FAIL(Status) && pNewPkt != NULL)
  480. {
  481. arpFreeControlPacket(
  482. pIF,
  483. pNewPkt,
  484. pSR
  485. );
  486. *ppNewPkt = NULL;
  487. }
  488. else
  489. {
  490. *ppNewPkt = pNewPkt;
  491. }
  492. return Status;
  493. }
  494. NDIS_STATUS
  495. arpGetEthHeaderFrom1394IpPkt(
  496. IN PARP1394_INTERFACE pIF,
  497. IN PVOID pvData,
  498. IN UINT cbData,
  499. IN MYBOOL fUnicast,
  500. OUT ENetHeader *pEthHdr,
  501. OUT PIP_ADDRESS pDestIpAddress, // OPTIONAL
  502. PRM_STACK_RECORD pSR
  503. )
  504. /*++
  505. Return a fully filled ethernet header, with source and estination
  506. MAC addresses and ethertype set to IP.
  507. The source address is always the local adapter's MAC address.
  508. The destination address is set by calling arpGetEthAddrFromIpAddr
  509. --*/
  510. {
  511. ENTER("arpGetEthHeaderFrom1394IpPkt", 0x0)
  512. static
  513. ENetHeader
  514. StaticEthernetHeader =
  515. {
  516. {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // eh_daddr == BCAST
  517. ARP_DEF_REMOTE_ETH_ADDRESS,
  518. H2N_USHORT(NIC1394_ETHERTYPE_IP) // eh_type
  519. };
  520. ARP1394_ADAPTER * pAdapter;
  521. BOOLEAN fBridgeMode;
  522. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  523. PNDIS1394_UNFRAGMENTED_HEADER pHeader = (PNDIS1394_UNFRAGMENTED_HEADER)pvData;
  524. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  525. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  526. do
  527. {
  528. UNALIGNED IPHeader *pIpHdr;
  529. IP_ADDRESS IpDest;
  530. if (cbData < (sizeof(NIC1394_ENCAPSULATION_HEADER) + sizeof(IPHeader)))
  531. {
  532. //
  533. // Packet is too small.
  534. //
  535. TR_INFO(("Discarding packet because pkt too small\n"));
  536. break;
  537. }
  538. pIpHdr = (UNALIGNED IPHeader*)
  539. (((PUCHAR) pvData)+sizeof(NIC1394_ENCAPSULATION_HEADER));
  540. IpDest = pIpHdr->iph_dest;
  541. if (pDestIpAddress != NULL)
  542. {
  543. *pDestIpAddress = IpDest;
  544. }
  545. if (!fBridgeMode)
  546. {
  547. //
  548. // TODO: we currently return a hardcoded ethernet address.
  549. // Need to constuct one by looking into the actual IP packet data.
  550. //
  551. *pEthHdr = StaticEthernetHeader;
  552. Status = NDIS_STATUS_SUCCESS;
  553. break;
  554. }
  555. //
  556. // Following is specific to BRIDGE mode
  557. //
  558. // Always set the source address according to the sender.
  559. //
  560. {
  561. ENetAddr SourceMacAddress;
  562. Status = \
  563. arpGetSourceMacAddressFor1394Pkt (pAdapter,
  564. pHeader->u1.SourceAddress,
  565. pHeader->u1.fHeaderHasSourceAddress,
  566. &SourceMacAddress,
  567. pSR);
  568. if (FAIL(Status))
  569. {
  570. break;
  571. }
  572. pEthHdr->eh_saddr = SourceMacAddress ;
  573. }
  574. //
  575. // If we have a STA packet then construct the STA Header
  576. // or else construct the sender/destination specific Ethernet
  577. // Header
  578. //
  579. {
  580. if (pHeader->u1.EtherType == N2H_USHORT(NIC1394_ETHERTYPE_STA) )
  581. {
  582. arpEthConstructSTAEthHeader(pvData,cbData, pEthHdr);
  583. }
  584. else
  585. {
  586. pEthHdr->eh_type = H2N_USHORT(ARP_ETH_ETYPE_IP);
  587. Status = arpGetEthAddrFromIpAddr(
  588. pIF,
  589. fUnicast,
  590. IpDest,
  591. &pEthHdr->eh_daddr,
  592. pSR
  593. );
  594. }
  595. }
  596. } while (FALSE);
  597. return Status;
  598. }
  599. NDIS_STATUS
  600. arpGet1394HeaderFromEthIpPkt(
  601. IN PARP1394_INTERFACE pIF,
  602. IN PNDIS_BUFFER pFirstBuffer,
  603. IN PVOID pvData,
  604. IN UINT cbData,
  605. IN MYBOOL fUnicast,
  606. OUT NIC1394_ENCAPSULATION_HEADER
  607. *p1394Hdr,
  608. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  609. PRM_STACK_RECORD pSR
  610. )
  611. {
  612. MYBOOL fLoopBack = FALSE;
  613. ENetHeader *pEthHdr = (ENetHeader *) pvData;
  614. ARP1394_ADAPTER * pAdapter;
  615. BOOLEAN fBridgeMode;
  616. if (cbData < (sizeof(ENetHeader) ) )
  617. {
  618. //
  619. // Packet is too small.
  620. //
  621. return NDIS_STATUS_FAILURE; // ***** EARLY RETURN ****
  622. }
  623. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  624. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  625. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  626. &pAdapter->info.EthernetMacAddress,
  627. sizeof(ENetAddr)))
  628. {
  629. if (!fBridgeMode)
  630. {
  631. // We're not in bridge mode -- so this must be only on MILL
  632. // This is addressed to our local mac address.
  633. // We fail with special failure status
  634. // NDIS_STATUS_ALREADY_MAPPED, indicating "loopback".
  635. //
  636. fLoopBack = TRUE;
  637. }
  638. }
  639. else
  640. {
  641. //
  642. // Do nothing ... because we can get unicasts to our fictitious gateway
  643. //
  644. }
  645. if (fLoopBack)
  646. {
  647. return NDIS_STATUS_ALREADY_MAPPED;
  648. }
  649. else
  650. {
  651. BOOLEAN fIsSTAPacket ;
  652. //
  653. // We have an STA packet, if the destination is our special
  654. // Multicast Destination
  655. //
  656. fIsSTAPacket = (TRUE == NdisEqualMemory (&pEthHdr->eh_daddr,
  657. &gSTAMacAddr,
  658. ETH_LENGTH_OF_ADDRESS) );
  659. if (fIsSTAPacket == TRUE)
  660. {
  661. *p1394Hdr = Arp1394_StaEncapHeader;
  662. }
  663. else
  664. {
  665. *p1394Hdr = Arp1394_IpEncapHeader;
  666. }
  667. if (pDestAddress != NULL)
  668. {
  669. //
  670. // Extract the Enet Address to use it as part of the lookup
  671. //
  672. UNALIGNED ENetAddr *pENetDest;
  673. pENetDest = (UNALIGNED ENetAddr *)(pvData);
  674. pDestAddress->ENetAddress = *pENetDest;
  675. }
  676. return NDIS_STATUS_SUCCESS;
  677. }
  678. }
  679. #if TEST_ICS_HACK
  680. VOID
  681. arpDbgStartIcsTest(
  682. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  683. PRM_STACK_RECORD pSR
  684. )
  685. {
  686. PRM_TASK pTask;
  687. NDIS_STATUS Status;
  688. ENTER("arpDbgStartIcsTest", 0xb987276b)
  689. RM_ASSERT_NOLOCKS(pSR);
  690. //
  691. // Allocate and start an instance of the arpTaskDoIcsTest task.
  692. //
  693. Status = arpAllocateTask(
  694. &pIF->Hdr, // pParentObject
  695. arpTaskDoIcsTest, // pfnHandler
  696. 0, // Timeout
  697. "Task: Ics Test", // szDescription
  698. &pTask,
  699. pSR
  700. );
  701. if (FAIL(Status))
  702. {
  703. TR_WARN(("couldn't alloc test ics intf task!\n"));
  704. }
  705. else
  706. {
  707. (VOID)RmStartTask(
  708. pTask,
  709. 0, // UserParam (unused)
  710. pSR
  711. );
  712. }
  713. EXIT()
  714. }
  715. VOID
  716. arpDbgTryStopIcsTest(
  717. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  718. PRM_STACK_RECORD pSR
  719. )
  720. {
  721. PTASK_ICS_TEST pIcsTask;
  722. ENTER("arpDbgStartIcsTest", 0xb987276b)
  723. LOCKOBJ(pIF, pSR);
  724. pIcsTask = (PTASK_ICS_TEST) pIF->ethernet.pTestIcsTask;
  725. if (pIcsTask != NULL)
  726. {
  727. pIcsTask->Quit = TRUE;
  728. RmTmpReferenceObject(&pIcsTask->TskHdr.Hdr, pSR);
  729. }
  730. UNLOCKOBJ(pIF, pSR);
  731. //
  732. // Resume the ICS task if it's waiting -- it will then quit because we set
  733. // the Quit field above.
  734. //
  735. if (pIcsTask != NULL)
  736. {
  737. UINT TaskResumed;
  738. RmResumeDelayedTaskNow(
  739. &pIcsTask->TskHdr,
  740. &pIcsTask->Timer,
  741. &TaskResumed,
  742. pSR
  743. );
  744. RmTmpDereferenceObject(&pIcsTask->TskHdr.Hdr, pSR);
  745. }
  746. RM_ASSERT_NOLOCKS(pSR)
  747. EXIT()
  748. }
  749. typedef struct
  750. {
  751. NIC1394_ENCAPSULATION_HEADER Hdr;
  752. UCHAR Payload[8];
  753. } SAMPLE_1394_PKT;
  754. typedef struct
  755. {
  756. ENetHeader Hdr;
  757. UCHAR Payload[8];
  758. } SAMPLE_ETH_PKT;
  759. SAMPLE_1394_PKT Sample1394Pkt =
  760. {
  761. {
  762. 0x0000, // Reserved
  763. H2N_USHORT(NIC1394_ETHERTYPE_IP)
  764. },
  765. {0x0, 0x1, 0x2, 0x3,
  766. 0x4, 0x5, 0x6, 0x7}
  767. };
  768. SAMPLE_ETH_PKT SampleEthPkt =
  769. {
  770. {
  771. ARP_FAKE_ETH_ADDRESS(1), // dest
  772. ARP_FAKE_ETH_ADDRESS(2), // src
  773. H2N_USHORT(NIC1394_ETHERTYPE_IP) // eh_type
  774. },
  775. {0x10, 0x11, 0x12, 0x13,
  776. 0x14, 0x15, 0x16, 0x17}
  777. };
  778. // This is to save the location of the test task's op type so we can recover it
  779. // in the debugger.
  780. //
  781. PUINT g_pArpEthTestTaskOpType;
  782. NDIS_STATUS
  783. arpTaskDoIcsTest(
  784. IN struct _RM_TASK * pTask,
  785. IN RM_TASK_OPERATION Code,
  786. IN UINT_PTR UserParam,
  787. IN PRM_STACK_RECORD pSR
  788. )
  789. /*++
  790. Routine Description:
  791. Task handler responsible for loading a newly-created IP interface.
  792. This is a primary task for the interface object.
  793. Arguments:
  794. UserParam for (Code == RM_TASKOP_START) : unused
  795. --*/
  796. {
  797. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  798. ARP1394_INTERFACE * pIF = (ARP1394_INTERFACE*) RM_PARENT_OBJECT(pTask);
  799. PTASK_ICS_TEST pTestTask;
  800. enum
  801. {
  802. STAGE_Start,
  803. STAGE_ResumeDelayed,
  804. STAGE_End
  805. } Stage;
  806. ENTER("TaskDoIcsTest", 0x57e523ed)
  807. pTestTask = (PTASK_ICS_TEST) pTask;
  808. ASSERT(sizeof(TASK_ICS_TEST) <= sizeof(ARP1394_TASK));
  809. //
  810. // Message normalizing code
  811. //
  812. switch(Code)
  813. {
  814. case RM_TASKOP_START:
  815. Stage = STAGE_Start;
  816. break;
  817. case RM_TASKOP_PENDCOMPLETE:
  818. Status = (NDIS_STATUS) UserParam;
  819. ASSERT(!PEND(Status));
  820. Stage = RM_PEND_CODE(pTask);
  821. break;
  822. case RM_TASKOP_END:
  823. Status = (NDIS_STATUS) UserParam;
  824. Stage= STAGE_End;
  825. break;
  826. default:
  827. ASSERT(FALSE);
  828. return NDIS_STATUS_FAILURE; // ** EARLY RETURN **
  829. }
  830. ASSERTEX(!PEND(Status), pTask);
  831. switch(Stage)
  832. {
  833. case STAGE_Start:
  834. {
  835. // If there is an ICS test task, we exit immediately.
  836. //
  837. LOCKOBJ(pIF, pSR);
  838. if (pIF->ethernet.pTestIcsTask == NULL)
  839. {
  840. pIF->ethernet.pTestIcsTask = pTask;
  841. }
  842. else
  843. {
  844. // There already is a test task. We're done.
  845. //
  846. UNLOCKOBJ(pIF, pSR);
  847. Status = NDIS_STATUS_SUCCESS;
  848. break;
  849. }
  850. UNLOCKOBJ(pIF, pSR);
  851. //
  852. // We're now the official ICS test task for this interface.
  853. //
  854. //
  855. // Let's allocate the 1394 and ethernet dummy packets.
  856. //
  857. {
  858. PNDIS_PACKET pPkt;
  859. PVOID pvNewData;
  860. Status = arpAllocateControlPacket(
  861. pIF,
  862. sizeof(Sample1394Pkt),
  863. ARP1394_PACKET_FLAGS_ICS,
  864. &pPkt,
  865. &pvNewData,
  866. pSR
  867. );
  868. if (FAIL(Status))
  869. {
  870. ASSERT(FALSE);
  871. break;
  872. }
  873. NdisMoveMemory(pvNewData, &Sample1394Pkt, sizeof(Sample1394Pkt));
  874. pTestTask->p1394Pkt = pPkt;
  875. Status = arpAllocateControlPacket(
  876. pIF,
  877. sizeof(SampleEthPkt),
  878. ARP1394_PACKET_FLAGS_ICS,
  879. &pPkt,
  880. &pvNewData,
  881. pSR
  882. );
  883. if (FAIL(Status))
  884. {
  885. ASSERT(FALSE);
  886. break;
  887. }
  888. NdisMoveMemory(pvNewData, &SampleEthPkt, sizeof(SampleEthPkt));
  889. pTestTask->pEthPkt = pPkt;
  890. // Set default delay.
  891. //
  892. pTestTask->Delay = 5000; // 5 sec.
  893. TR_WARN(("TEST ICS: pTask=0x%8lx; &OpType=0x%08lx(%lu) &Delay=0x%08lx(%lu)\n",
  894. pTestTask,
  895. &pTestTask->PktType,
  896. pTestTask->PktType,
  897. &pTestTask->Delay,
  898. pTestTask->Delay
  899. ));
  900. g_pArpEthTestTaskOpType = &pTestTask->PktType;
  901. }
  902. // We move on to the next stage, after a delay.
  903. //
  904. RmSuspendTask(pTask, STAGE_ResumeDelayed, pSR);
  905. RmResumeTaskDelayed(
  906. pTask,
  907. 0,
  908. 1000,
  909. &pTestTask->Timer,
  910. pSR
  911. );
  912. Status = NDIS_STATUS_PENDING;
  913. }
  914. break;
  915. case STAGE_ResumeDelayed:
  916. {
  917. //
  918. // If qe're quitting, we get out of here.
  919. // Otherwise we'll send a packet either on the ethernet VC
  920. // or via the miniport's connectionless ethernet interface.
  921. //
  922. if (pTestTask->Quit)
  923. {
  924. Status = NDIS_STATUS_SUCCESS;
  925. break;
  926. }
  927. switch (pTestTask->PktType)
  928. {
  929. default:
  930. case 0:
  931. // Do nothing.
  932. break;
  933. case 1:
  934. pTestTask->PktType = 0; // One shot
  935. // Fall through...
  936. case 11:
  937. // Forward to ethernet (the packet is not held on to).
  938. //
  939. arpIcsForwardIpPacket(
  940. pIF,
  941. pTestTask->p1394Pkt,
  942. ARP_ICS_FORWARD_TO_ETHERNET,
  943. FALSE, // FALSE == non unicast
  944. pSR
  945. );
  946. break;
  947. case 2:
  948. pTestTask->PktType = 0; // One shot
  949. // Fall through...
  950. case 12:
  951. // Send on connectionless ethernet.
  952. #if RM_EXTRA_CHECKING
  953. RmLinkToExternalEx(
  954. &pIF->Hdr, // pHdr
  955. 0xf4aa69c7, // LUID
  956. (UINT_PTR) pTestTask->pEthPkt, // External entity.
  957. ARPASSOC_ETH_SEND_PACKET, // AssociationID
  958. " Outstanding connectionless ethernet pkt 0x%p\n", // szFormat
  959. pSR
  960. );
  961. #else // !RM_EXTRA_CHECKING
  962. RmLinkToExternalFast(&pIF->Hdr);
  963. #endif // !RM_EXTRA_CHECKING
  964. NdisSendPackets(
  965. pIF->ndis.AdapterHandle,
  966. &(pTestTask->pEthPkt),
  967. 1
  968. );
  969. break;
  970. }
  971. // Now we wait again...
  972. //
  973. RmSuspendTask(pTask, STAGE_ResumeDelayed, pSR);
  974. RmResumeTaskDelayed(
  975. pTask,
  976. 0,
  977. pTestTask->Delay,
  978. &pTestTask->Timer,
  979. pSR
  980. );
  981. Status = NDIS_STATUS_PENDING;
  982. }
  983. break;
  984. case STAGE_End:
  985. {
  986. NDIS_HANDLE BindContext;
  987. // Free the test packets, if we've allocated them.
  988. //
  989. if (pTestTask->p1394Pkt != NULL)
  990. {
  991. arpFreeControlPacket(pIF, pTestTask->p1394Pkt, pSR);
  992. pTestTask->p1394Pkt = NULL;
  993. }
  994. if (pTestTask->pEthPkt != NULL)
  995. {
  996. arpFreeControlPacket(pIF, pTestTask->pEthPkt, pSR);
  997. pTestTask->pEthPkt = NULL;
  998. }
  999. LOCKOBJ(pIF, pSR);
  1000. if (pIF->ethernet.pTestIcsTask == pTask)
  1001. {
  1002. // We're the official ics test task, we clear ourselves from
  1003. // the interface object and do any initialization required.
  1004. //
  1005. pIF->ethernet.pTestIcsTask = NULL;
  1006. UNLOCKOBJ(pIF, pSR);
  1007. }
  1008. else
  1009. {
  1010. // We're note the official ics test task. Nothing else to do.
  1011. //
  1012. UNLOCKOBJ(pIF, pSR);
  1013. break;
  1014. }
  1015. }
  1016. break;
  1017. default:
  1018. {
  1019. ASSERTEX(!"Unknown task op", pTask);
  1020. }
  1021. break;
  1022. } // switch (Code)
  1023. RM_ASSERT_NOLOCKS(pSR);
  1024. EXIT()
  1025. return Status;
  1026. }
  1027. VOID
  1028. arpEthSendComplete(
  1029. IN ARP1394_ADAPTER * pAdapter,
  1030. IN PNDIS_PACKET pNdisPacket,
  1031. IN NDIS_STATUS Status
  1032. )
  1033. /*++
  1034. Routine Description:
  1035. This is the Connection-less Send Complete handler, which signals
  1036. completion of such a Send.
  1037. Arguments:
  1038. <Ignored>
  1039. Return Value:
  1040. None
  1041. --*/
  1042. {
  1043. ENTER("arpEthSendComplete", 0x49eafb6d)
  1044. ARP1394_INTERFACE * pIF = pAdapter->pIF;
  1045. RM_DECLARE_STACK_RECORD(sr)
  1046. #if RM_EXTRA_CHECKING
  1047. RmUnlinkFromExternalEx(
  1048. &pIF->Hdr, // pHdr
  1049. 0xde8c8fb4, // LUID
  1050. (UINT_PTR) pNdisPacket, // External entity
  1051. ARPASSOC_ETH_SEND_PACKET, // AssociationID
  1052. &sr
  1053. );
  1054. #else // !RM_EXTRA_CHECKING
  1055. RmUnlinkFromExternalFast(&pIF->Hdr);
  1056. #endif // !RM_EXTRA_CHECKING
  1057. //
  1058. // We do not free the packet, as it's re-used by the ICS test task..
  1059. //
  1060. RM_ASSERT_CLEAR(&sr);
  1061. EXIT()
  1062. }
  1063. #endif // TEST_ICS_HACK
  1064. VOID
  1065. arpEthReceivePacket(
  1066. IN ARP1394_INTERFACE * pIF,
  1067. PNDIS_PACKET pNdisPacket
  1068. )
  1069. /*
  1070. This is the connectionLESS ethernet receive packet handler.
  1071. Following code adapted from the co receive packet handler.
  1072. */
  1073. {
  1074. ENTER("arpEthReceivePacket", 0xc8afbabb)
  1075. UINT TotalLength; // Total bytes in packet
  1076. PNDIS_BUFFER pNdisBuffer; // Pointer to first buffer
  1077. UINT BufferLength;
  1078. UINT ReturnCount;
  1079. PVOID pvPktHeader;
  1080. ENetHeader * pEthHeader;
  1081. const UINT MacHeaderLength = sizeof(ENetHeader);
  1082. ARP1394_ADAPTER * pAdapter;
  1083. BOOLEAN fBridgeMode;
  1084. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1085. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  1086. DBGMARK(0x2425d318);
  1087. ReturnCount = 0;
  1088. //
  1089. // Discard the packet if the IP interface is not activated
  1090. //
  1091. do
  1092. {
  1093. //
  1094. // Discard packet if adapter is in bridge mode.
  1095. //
  1096. if (fBridgeMode)
  1097. {
  1098. break;
  1099. }
  1100. //
  1101. // Discard the packet if the adapter is not active
  1102. //
  1103. if (!CHECK_IF_ACTIVE_STATE(pIF, ARPAD_AS_ACTIVATED))
  1104. {
  1105. TR_INFO(("Eth:Discardning received Eth pkt because pIF 0x%p is not activated.\n", pIF));
  1106. break;
  1107. }
  1108. NdisQueryPacket(
  1109. pNdisPacket,
  1110. NULL,
  1111. NULL,
  1112. &pNdisBuffer,
  1113. &TotalLength
  1114. );
  1115. if (TotalLength > 0)
  1116. {
  1117. NdisQueryBuffer(
  1118. pNdisBuffer,
  1119. (PVOID *)&pvPktHeader,
  1120. &BufferLength
  1121. );
  1122. }
  1123. else
  1124. {
  1125. break;
  1126. }
  1127. pEthHeader = (ENetHeader*) pvPktHeader;
  1128. TR_INFO(
  1129. ("EthRcv: NDISpkt 0x%x, NDISbuf 0x%x, Buflen %d, Totlen %d, Pkthdr 0x%x\n",
  1130. pNdisPacket,
  1131. pNdisBuffer,
  1132. BufferLength,
  1133. TotalLength,
  1134. pvPktHeader));
  1135. if (BufferLength < MacHeaderLength || pEthHeader == NULL)
  1136. {
  1137. // Packet is too small, discard.
  1138. //
  1139. break;
  1140. }
  1141. //
  1142. // At this point, pEthHeader contains the Ethernet header.
  1143. // We look at the ethertype to decide what to do with it.
  1144. //
  1145. if (pEthHeader->eh_type == N2H_USHORT(ARP_ETH_ETYPE_IP))
  1146. {
  1147. //
  1148. // The EtherType is IP, so we pass up this packet to the IP layer.
  1149. // (Also we indicate all packets we receive on the broadcast channel
  1150. // to the ethernet VC).
  1151. //
  1152. TR_INFO(
  1153. ("Rcv: pPkt 0x%x: EtherType is IP, passing up.\n", pNdisPacket));
  1154. ARP_IF_STAT_INCR(pIF, InNonUnicastPkts);
  1155. LOGSTATS_CopyRecvs(pIF, pNdisPacket);
  1156. #if MILLEN
  1157. ASSERT_PASSIVE();
  1158. #endif // MILLEN
  1159. pIF->ip.RcvHandler(
  1160. pIF->ip.Context,
  1161. (PVOID)((PUCHAR)pEthHeader+sizeof(*pEthHeader)),
  1162. BufferLength - MacHeaderLength,
  1163. TotalLength - MacHeaderLength,
  1164. (NDIS_HANDLE)pNdisPacket,
  1165. MacHeaderLength,
  1166. FALSE, // FALSE == NOT received via broadcast.
  1167. // Important, because we are reflecting directed
  1168. // packets up to IP. If we report TRUE here,
  1169. // IP assumes it's not a directed packet, and
  1170. // handles it differently.
  1171. NULL
  1172. );
  1173. }
  1174. else
  1175. {
  1176. //
  1177. // Discard packet -- unknown/bad EtherType
  1178. //
  1179. TR_INFO(("Encap hdr 0x%x, bad EtherType 0x%x\n",
  1180. pEthHeader, pEthHeader->eh_type));
  1181. ARP_IF_STAT_INCR(pIF, UnknownProtos);
  1182. }
  1183. } while (FALSE);
  1184. EXIT()
  1185. return;
  1186. }
  1187. VOID
  1188. arpEthProcess1394ArpPkt(
  1189. IN PARP1394_INTERFACE pIF,
  1190. IN PIP1394_ARP_PKT pArpPkt,
  1191. IN UINT HeaderSize
  1192. )
  1193. /*++
  1194. Process an ip/1394 ARP packet. We do the following:
  1195. 0. Parse the paket
  1196. 1. Update our local RemoteIP cache.
  1197. 2. Create and send an equivalent ethernet arp pkt on the ethernet VC.
  1198. (We look up the destination ethernet address in our ethernet cache)
  1199. This function must only be called when the adapter is in "Bridged mode."
  1200. --*/
  1201. {
  1202. IP1394_ARP_PKT_INFO Ip1394PktInfo;
  1203. ETH_ARP_PKT_INFO EthArpInfo;
  1204. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1205. ARP_DEST_PARAMS DestParams;
  1206. PARP1394_ADAPTER pAdapter =(PARP1394_ADAPTER ) RM_PARENT_OBJECT(pIF);
  1207. ENetAddr SenderEnetAddress;
  1208. IPAddr SenderIpAddress = 0;
  1209. REMOTE_DEST_KEY RemoteDestKey;
  1210. ENTER("arpEthProcess1394ArpPkt", 0x0)
  1211. RM_DECLARE_STACK_RECORD(Sr)
  1212. ARP_ZEROSTRUCT(&DestParams);
  1213. do {
  1214. PNDIS_PACKET pPkt = NULL;
  1215. PVOID pvData = NULL;
  1216. Status = arpParseArpPkt(
  1217. pArpPkt,
  1218. HeaderSize,
  1219. &Ip1394PktInfo
  1220. );
  1221. if (FAIL(Status))
  1222. {
  1223. TR_WARN(("Failed parse of received 1394 ARP PKT.\n"));
  1224. break;
  1225. }
  1226. DestParams.HwAddr.AddressType = NIC1394AddressType_FIFO;
  1227. DestParams.HwAddr.FifoAddress = Ip1394PktInfo.SenderHwAddr; // Struct copy
  1228. REMOTE_DEST_KEY_INIT(&RemoteDestKey);
  1229. if ((ARP_BRIDGE_ENABLED(pAdapter) == TRUE) &&
  1230. (Ip1394PktInfo.fPktHasNodeAddress == FALSE))
  1231. {
  1232. // We do not have the sender's Node ID -- fail.
  1233. TR_WARN (("Did not Receive Sender's Node ID in Pkt"))
  1234. Status = NDIS_STATUS_FAILURE;
  1235. break;
  1236. }
  1237. if (ARP_BRIDGE_ENABLED(pAdapter) == TRUE)
  1238. {
  1239. // Extract the Source Mac address using the Sender Node Address
  1240. Status = arpGetSourceMacAddressFor1394Pkt(pAdapter,
  1241. Ip1394PktInfo.SourceNodeAdddress,
  1242. TRUE,
  1243. &Ip1394PktInfo.SourceMacAddress,
  1244. &Sr);
  1245. RemoteDestKey.ENetAddress = Ip1394PktInfo.SourceMacAddress;
  1246. }
  1247. else
  1248. {
  1249. RemoteDestKey.IpAddress = Ip1394PktInfo.SenderIpAddress;
  1250. Status = NDIS_STATUS_SUCCESS;
  1251. }
  1252. if (Status != NDIS_STATUS_SUCCESS)
  1253. {
  1254. TR_WARN (("Unable to get valid Source MAC Address from Pkt"))
  1255. Status = NDIS_STATUS_SUCCESS;
  1256. break;
  1257. }
  1258. // Update our 1394 ARP cache.
  1259. //
  1260. arpUpdateArpCache(
  1261. pIF,
  1262. RemoteDestKey.IpAddress , // Remote IP Address
  1263. &RemoteDestKey.ENetAddress,
  1264. &DestParams, // Remote Destination HW Address
  1265. TRUE, // Update even if we don't already have an entry
  1266. &Sr
  1267. );
  1268. Status = arpConstructEthArpInfoFrom1394ArpInfo(
  1269. pIF,
  1270. &Ip1394PktInfo,
  1271. &EthArpInfo,
  1272. &Sr
  1273. );
  1274. if (FAIL(Status)) break;
  1275. // Allocate an appropriately sized control packet.
  1276. //
  1277. Status = arpAllocateControlPacket(
  1278. pIF,
  1279. sizeof(ETH_ARP_PKT),
  1280. ARP1394_PACKET_FLAGS_ICS,
  1281. &pPkt,
  1282. &pvData,
  1283. &Sr
  1284. );
  1285. if (FAIL(Status))
  1286. {
  1287. ASSERT(FALSE); // we want to know if we hit this in regular use.
  1288. pPkt = NULL;
  1289. break;
  1290. }
  1291. NdisInterlockedIncrement (&Arp1394ToIcs);
  1292. // Fill it out..
  1293. //
  1294. arpPrepareEthArpPkt(
  1295. &EthArpInfo,
  1296. (PETH_ARP_PKT) pvData
  1297. );
  1298. // Send the packet over the ethernet VC...
  1299. //
  1300. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  1301. arpSendControlPkt(
  1302. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  1303. pPkt,
  1304. pIF->pEthernetDest,
  1305. &Sr
  1306. );
  1307. } while (FALSE);
  1308. RM_ASSERT_CLEAR(&Sr);
  1309. }
  1310. VOID
  1311. arpEthProcessEthArpPkt(
  1312. IN PARP1394_INTERFACE pIF,
  1313. IN PETH_ARP_PKT pArpPkt,
  1314. IN UINT HeaderSize
  1315. )
  1316. /*++
  1317. Process an Ethernet ARP packet. We do the following:
  1318. 0. Parse the packet
  1319. 1. Update our local ethernet arp cache.
  1320. 2. Create and send an equivalent 1394 arp pkt on the broadcast VC.
  1321. (We look up the destination ethernet address in our ethernet cache)
  1322. This function must only be called when the adapter is in "Bridged mode."
  1323. --*/
  1324. {
  1325. ETH_ARP_PKT_INFO EthPktInfo;
  1326. IP1394_ARP_PKT_INFO Ip1394ArpInfo;
  1327. NDIS_STATUS Status;
  1328. ARP_REMOTE_ETH_PARAMS CreateParams;
  1329. ENTER("arpEthProcessEthArpPkt", 0x0)
  1330. RM_DECLARE_STACK_RECORD(Sr)
  1331. ARP_ZEROSTRUCT(&CreateParams);
  1332. do {
  1333. PNDIS_PACKET pPkt = NULL;
  1334. PVOID pvData = NULL;
  1335. Status = arpParseEthArpPkt(
  1336. pArpPkt,
  1337. HeaderSize,
  1338. &EthPktInfo
  1339. );
  1340. if (FAIL(Status))
  1341. {
  1342. TR_WARN(("Failed parse of received Ethernet ARP PKT.\n"));
  1343. break;
  1344. }
  1345. Status = arpConstruct1394ArpInfoFromEthArpInfo(
  1346. pIF,
  1347. &EthPktInfo,
  1348. &Ip1394ArpInfo,
  1349. &Sr
  1350. );
  1351. if (FAIL(Status)) break;
  1352. // Allocate an appropriately sized control packet.
  1353. //
  1354. Status = arpAllocateControlPacket(
  1355. pIF,
  1356. sizeof(IP1394_ARP_PKT),
  1357. ARP1394_PACKET_FLAGS_ICS,
  1358. &pPkt,
  1359. &pvData,
  1360. &Sr
  1361. );
  1362. if (FAIL(Status))
  1363. {
  1364. ASSERT(FALSE); // we want to know if we hit this in regular use.
  1365. pPkt = NULL;
  1366. break;
  1367. }
  1368. // Fill it out..
  1369. //
  1370. arpPrepareArpPkt(
  1371. &Ip1394ArpInfo,
  1372. (PIP1394_ARP_PKT) pvData
  1373. );
  1374. // Send the packet over the ethernet VC...
  1375. //
  1376. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  1377. arpSendControlPkt(
  1378. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  1379. pPkt,
  1380. pIF->pBroadcastDest,
  1381. &Sr
  1382. );
  1383. } while (FALSE);
  1384. RM_ASSERT_CLEAR(&Sr);
  1385. }
  1386. NDIS_STATUS
  1387. arpParseEthArpPkt(
  1388. IN PETH_ARP_PKT pArpPkt,
  1389. IN UINT cbBufferSize,
  1390. OUT PETH_ARP_PKT_INFO pPktInfo
  1391. )
  1392. /*++
  1393. Routine Description:
  1394. Parse the contents of IP/Ethernet ARP packet data starting at
  1395. pArpPkt. Place the results into pPktInfo.
  1396. Arguments:
  1397. pArpPkt - Contains the unaligned contents of an ip/eth ARP Pkt.
  1398. pPktInfo - Unitialized structure to be filled with the parsed contents of the
  1399. pkt.
  1400. Return Value:
  1401. NDIS_STATUS_FAILURE if the parse failed (typically because of invalid pkt
  1402. contents.)
  1403. NDIS_STATUS_SUCCESS on successful parsing.
  1404. --*/
  1405. {
  1406. ENTER("arpParseEthArpPkt", 0x359e9bf2)
  1407. NDIS_STATUS Status;
  1408. DBGSTMT(CHAR *szError = "General failure";)
  1409. Status = NDIS_STATUS_FAILURE;
  1410. do
  1411. {
  1412. UINT OpCode;
  1413. // Verify length.
  1414. //
  1415. if (cbBufferSize < sizeof(*pArpPkt))
  1416. {
  1417. DBGSTMT(szError = "pkt size too small";)
  1418. break;
  1419. }
  1420. // Verify constant fields.
  1421. //
  1422. if (N2H_USHORT(pArpPkt->header.eh_type) != ARP_ETH_ETYPE_ARP)
  1423. {
  1424. DBGSTMT(szError = "header.eh_type!=ARP";)
  1425. break;
  1426. }
  1427. #if 0
  1428. ARP_ETH_HW_ENET OR ARP_ETH_HW_802
  1429. if (N2H_USHORT(pArpPkt->hardware_type) != IP1394_HARDWARE_TYPE)
  1430. {
  1431. DBGSTMT(szError = "Invalid hardware_type";)
  1432. break;
  1433. }
  1434. #endif // 0
  1435. // ARP_ETH_ETYPE_IP ARP_ETH_ETYPE_ARP
  1436. if (N2H_USHORT(pArpPkt->protocol_type) != ARP_ETH_ETYPE_IP)
  1437. {
  1438. DBGSTMT(szError = "Invalid protocol_type";)
  1439. break;
  1440. }
  1441. if (pArpPkt->hw_addr_len != ARP_802_ADDR_LENGTH)
  1442. {
  1443. DBGSTMT(szError = "Invalid hw_addr_len";)
  1444. break;
  1445. }
  1446. if (pArpPkt->IP_addr_len != sizeof(ULONG))
  1447. {
  1448. DBGSTMT(szError = "Invalid IP_addr_len";)
  1449. break;
  1450. }
  1451. // Opcode
  1452. //
  1453. {
  1454. OpCode = N2H_USHORT(pArpPkt->opcode);
  1455. if ( OpCode != ARP_ETH_REQUEST
  1456. && OpCode != ARP_ETH_RESPONSE)
  1457. {
  1458. DBGSTMT(szError = "Invalid opcode";)
  1459. break;
  1460. }
  1461. }
  1462. //
  1463. // Pkt appears valid, let's fill out the parsed information....
  1464. //
  1465. ARP_ZEROSTRUCT(pPktInfo);
  1466. pPktInfo->SourceEthAddress = pArpPkt->header.eh_saddr; // struct copy.
  1467. pPktInfo->DestEthAddress = pArpPkt->header.eh_daddr; // struct copy.
  1468. pPktInfo->OpCode = (USHORT) OpCode;
  1469. // These remain network byte order...
  1470. //
  1471. pPktInfo->SenderIpAddress = (IP_ADDRESS) pArpPkt->sender_IP_address;
  1472. pPktInfo->TargetIpAddress = (IP_ADDRESS) pArpPkt->target_IP_address;
  1473. pPktInfo->SenderEthAddress = pArpPkt->sender_hw_address; // struct copy
  1474. pPktInfo->TargetEthAddress = pArpPkt->target_hw_address; // struct copy
  1475. Status = NDIS_STATUS_SUCCESS;
  1476. } while (FALSE);
  1477. if (FAIL(Status))
  1478. {
  1479. TR_INFO(("Bad arp pkt data at 0x%p (%s)\n", pArpPkt, szError));
  1480. }
  1481. else
  1482. {
  1483. PUCHAR pSip = (PUCHAR)&pPktInfo->SenderIpAddress;
  1484. PUCHAR pTip = (PUCHAR)&pPktInfo->TargetIpAddress;
  1485. TR_VERB(("Received ETH ARP PKT. OP=%lu SIP=%d.%d.%d.%d TIP=%d.%d.%d.%d.\n",
  1486. pPktInfo->OpCode,
  1487. pSip[0],pSip[1],pSip[2],pSip[3],
  1488. pTip[0],pTip[1],pTip[2],pTip[3]
  1489. ));
  1490. }
  1491. EXIT()
  1492. return Status;
  1493. }
  1494. VOID
  1495. arpPrepareEthArpPkt(
  1496. IN PETH_ARP_PKT_INFO pPktInfo,
  1497. OUT PETH_ARP_PKT pArpPkt
  1498. )
  1499. /*++
  1500. Routine Description:
  1501. Use information in pArpPktInfo to prepare an ethernet arp packet starting at
  1502. pvArpPkt.
  1503. Arguments:
  1504. pPktInfo - Parsed version of the eth arp request/response packet.
  1505. pArpPkt - unitialized memory in which to store the packet contents.
  1506. This memory must have a min size of sizeof(*pArpPkt).
  1507. --*/
  1508. {
  1509. // UINT SenderMaxRec;
  1510. UINT OpCode;
  1511. ARP_ZEROSTRUCT(pArpPkt);
  1512. pArpPkt->header.eh_type = H2N_USHORT(ARP_ETH_ETYPE_ARP);
  1513. pArpPkt->header.eh_daddr = pPktInfo->DestEthAddress;
  1514. pArpPkt->header.eh_saddr = pPktInfo->SourceEthAddress;
  1515. pArpPkt->hardware_type = H2N_USHORT(ARP_ETH_HW_ENET); // TODO
  1516. // we always set the type
  1517. // to ARP_ETH_HW_ENET -- not sure
  1518. // if this a valid assumption or
  1519. // if we need to query the NIC.
  1520. pArpPkt->protocol_type = H2N_USHORT(ARP_ETH_ETYPE_IP);
  1521. pArpPkt->hw_addr_len = (UCHAR) ARP_802_ADDR_LENGTH;
  1522. pArpPkt->IP_addr_len = (UCHAR) sizeof(ULONG);
  1523. pArpPkt->opcode = H2N_USHORT(pPktInfo->OpCode);
  1524. // These are already in network byte order...
  1525. //
  1526. pArpPkt->sender_IP_address = (ULONG) pPktInfo->SenderIpAddress;
  1527. pArpPkt->target_IP_address = (ULONG) pPktInfo->TargetIpAddress;
  1528. pArpPkt->sender_hw_address = pPktInfo->SenderEthAddress; // struct copy
  1529. pArpPkt->target_hw_address = pPktInfo->TargetEthAddress; // struct copy
  1530. }
  1531. UINT
  1532. arpEthernetReceivePacket(
  1533. IN NDIS_HANDLE ProtocolBindingContext,
  1534. IN NDIS_HANDLE ProtocolVcContext,
  1535. IN PNDIS_PACKET pNdisPacket
  1536. )
  1537. /*++
  1538. NDIS Co receive packet for the ethernet VC.
  1539. We do the following:
  1540. If it's an ARP packet, we translate it and send it on the bcast channel.
  1541. Else if it was a ethernet unicast packet, we change the header
  1542. and treat it like an IP unicast packet -- SlowIpTransmit
  1543. Else we change the header and then send it on the bcast desination.
  1544. --*/
  1545. {
  1546. PARP_VC_HEADER pVcHdr;
  1547. PARPCB_DEST pDest;
  1548. PARP1394_INTERFACE pIF;
  1549. ARP1394_ADAPTER * pAdapter;
  1550. ENetHeader *pEthHdr;
  1551. UINT TotalLength; // Total bytes in packet
  1552. PNDIS_BUFFER pNdisBuffer; // Pointer to first buffer
  1553. UINT BufferLength;
  1554. PVOID pvPktHeader;
  1555. const UINT MacHeaderLength = sizeof(ENetHeader);
  1556. MYBOOL fBridgeMode;
  1557. MYBOOL fUnicast;
  1558. MYBOOL fIsSTAPacket;
  1559. ENTER("arpEthernetReceivePacket", 0x0)
  1560. RM_DECLARE_STACK_RECORD(sr)
  1561. DBGMARK(0x72435b28);
  1562. #if TESTPROGRAM
  1563. {
  1564. extern ARP1394_INTERFACE * g_pIF;
  1565. pIF = g_pIF;
  1566. }
  1567. #else // !TESTPROGRAM
  1568. pVcHdr = (PARP_VC_HEADER) ProtocolVcContext;
  1569. pDest = CONTAINING_RECORD( pVcHdr, ARPCB_DEST, VcHdr);
  1570. ASSERT_VALID_DEST(pDest);
  1571. pIF = (ARP1394_INTERFACE*) RM_PARENT_OBJECT(pDest);
  1572. #endif // TESTPROGRAM
  1573. ASSERT_VALID_INTERFACE(pIF);
  1574. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1575. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  1576. do
  1577. {
  1578. if (!fBridgeMode) // This is really only for MILL
  1579. {
  1580. #if MILLEN
  1581. arpIcsForwardIpPacket(
  1582. pIF,
  1583. pNdisPacket,
  1584. ARP_ICS_FORWARD_TO_1394,
  1585. FALSE, // FALSE == NonUnicast
  1586. &sr
  1587. );
  1588. #endif // MILLEN
  1589. break;
  1590. }
  1591. NdisQueryPacket(
  1592. pNdisPacket,
  1593. NULL,
  1594. NULL,
  1595. &pNdisBuffer,
  1596. &TotalLength
  1597. );
  1598. if (TotalLength > 0)
  1599. {
  1600. NdisQueryBuffer(
  1601. pNdisBuffer,
  1602. (PVOID *)&pvPktHeader,
  1603. &BufferLength
  1604. );
  1605. }
  1606. else
  1607. {
  1608. break;
  1609. }
  1610. TR_VERB(
  1611. ("Eth Rcv: NDISpkt 0x%x, NDISbuf 0x%x, Buflen %d, Totlen %d, Pkthdr 0x%x\n",
  1612. pNdisPacket,
  1613. pNdisBuffer,
  1614. BufferLength,
  1615. TotalLength,
  1616. pvPktHeader));
  1617. if (BufferLength < MacHeaderLength)
  1618. {
  1619. // Packet is too small, discard.
  1620. //
  1621. break;
  1622. }
  1623. if (pvPktHeader == NULL)
  1624. {
  1625. break;
  1626. }
  1627. pEthHdr = (ENetHeader*) pvPktHeader;
  1628. fUnicast = arpIsUnicastEthDest(pEthHdr);
  1629. switch(N2H_USHORT(pEthHdr->eh_type))
  1630. {
  1631. case ARP_ETH_ETYPE_ARP:
  1632. {
  1633. PETH_ARP_PKT pArpPkt = (PETH_ARP_PKT) pEthHdr;
  1634. if (BufferLength < sizeof(*pArpPkt))
  1635. {
  1636. // discard packet.
  1637. break;
  1638. }
  1639. arpEthProcessEthArpPkt(pIF, pArpPkt, BufferLength);
  1640. }
  1641. break;
  1642. case ARP_ETH_ETYPE_IP:
  1643. {
  1644. //
  1645. // The EtherType is IP, so we translate the header and
  1646. // send if of on the appropriate 1394 FIFO vc.
  1647. //
  1648. if (fUnicast)
  1649. {
  1650. PNDIS_PACKET pNewPkt = NULL;
  1651. IP_ADDRESS IpDest;
  1652. NDIS_STATUS Status;
  1653. REMOTE_DEST_KEY Dest;
  1654. // is this meant for the 1394 net.
  1655. REMOTE_DEST_KEY_INIT(&Dest);
  1656. //
  1657. // Create the translated packet.
  1658. //
  1659. Status = arpIcsTranslateIpPkt(
  1660. pIF,
  1661. pNdisPacket,
  1662. ARP_ICS_FORWARD_TO_1394,
  1663. TRUE, // TRUE == fUnicast.
  1664. &pNewPkt,
  1665. &Dest,
  1666. &sr
  1667. );
  1668. if (FAIL(Status))
  1669. {
  1670. break;
  1671. }
  1672. Status = arpSlowIpTransmit(
  1673. pIF,
  1674. pNewPkt,
  1675. Dest,
  1676. NULL // RCE
  1677. );
  1678. if (!PEND(Status))
  1679. {
  1680. // We need to deallocate the packet ourselves
  1681. //
  1682. arpFreeControlPacket(
  1683. pIF,
  1684. pNewPkt,
  1685. &sr
  1686. );
  1687. }
  1688. }
  1689. else
  1690. {
  1691. // This is a broadcast or multicast IP packet -- swith
  1692. // the link-layer header and send it over the 1394
  1693. // broadcast channel.
  1694. //
  1695. arpIcsForwardIpPacket(
  1696. pIF,
  1697. pNdisPacket,
  1698. ARP_ICS_FORWARD_TO_1394,
  1699. FALSE, // FALSE == NonUnicast
  1700. &sr
  1701. );
  1702. }
  1703. }
  1704. break;
  1705. default:
  1706. //
  1707. // Last option is that it could be a Bridge STA packet.
  1708. // However the bridge does not use an Ethertype, so we
  1709. // have to check the destination mac address
  1710. //
  1711. fIsSTAPacket = (TRUE == NdisEqualMemory (&pEthHdr->eh_daddr,
  1712. &gSTAMacAddr,
  1713. ETH_LENGTH_OF_ADDRESS) );
  1714. if (fIsSTAPacket == TRUE)
  1715. {
  1716. //
  1717. // switch the link-layer header and send it over the 1394
  1718. // broadcast channel.
  1719. //
  1720. arpIcsForwardIpPacket(
  1721. pIF,
  1722. pNdisPacket,
  1723. ARP_ICS_FORWARD_TO_1394,
  1724. FALSE, // FALSE == NonUnicast
  1725. &sr );
  1726. }
  1727. break;
  1728. }
  1729. } while (FALSE);
  1730. RM_ASSERT_CLEAR(&sr);
  1731. return 0;
  1732. }
  1733. VOID
  1734. arpEthReceive1394Packet(
  1735. IN PARP1394_INTERFACE pIF,
  1736. IN PNDIS_PACKET pNdisPacket,
  1737. IN PVOID pvHeader,
  1738. IN UINT HeaderSize,
  1739. IN MYBOOL IsChannel
  1740. )
  1741. /*++
  1742. Handle an incoming packet from the 1394 side when in bridged mode.
  1743. pEncapHeader -- the 1st buffer in the packet.
  1744. --*/
  1745. {
  1746. PNIC1394_ENCAPSULATION_HEADER pEncapHeader;
  1747. ENTER("arpEthReceived1394Packet", 0xe317990b)
  1748. RM_DECLARE_STACK_RECORD(sr)
  1749. pEncapHeader = (PNIC1394_ENCAPSULATION_HEADER) pvHeader;
  1750. do
  1751. {
  1752. //
  1753. // Discard the packet if the adapter is not active
  1754. //
  1755. if (!CHECK_IF_ACTIVE_STATE(pIF, ARPAD_AS_ACTIVATED))
  1756. {
  1757. TR_INFO(("Eth:Discardning received 1394 pkt because pIF 0x%p is not activated.\n", pIF));
  1758. break;
  1759. }
  1760. if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_IP))
  1761. {
  1762. LOGSTATS_CopyRecvs(pIF, pNdisPacket);
  1763. //
  1764. // The EtherType is IP, so we translate the header and
  1765. // send it off on the ethernet vc.
  1766. //
  1767. arpIcsForwardIpPacket(
  1768. pIF,
  1769. pNdisPacket,
  1770. ARP_ICS_FORWARD_TO_ETHERNET,
  1771. !IsChannel,
  1772. &sr
  1773. );
  1774. }
  1775. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_ARP))
  1776. {
  1777. PIP1394_ARP_PKT pArpPkt = (PIP1394_ARP_PKT) pEncapHeader;
  1778. if (HeaderSize < sizeof(*pArpPkt))
  1779. {
  1780. // discard packet.
  1781. break;
  1782. }
  1783. arpEthProcess1394ArpPkt(pIF, pArpPkt, HeaderSize);
  1784. }
  1785. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_MCAP))
  1786. {
  1787. PIP1394_MCAP_PKT pMcapPkt = (PIP1394_MCAP_PKT) pEncapHeader;
  1788. arpProcessMcapPkt(
  1789. pIF,
  1790. pMcapPkt,
  1791. HeaderSize
  1792. );
  1793. }
  1794. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_STA))
  1795. {
  1796. //
  1797. // The EtherType is STA, so we translate the header and
  1798. // send it off on the ethernet vc.
  1799. //
  1800. arpIcsForwardIpPacket(
  1801. pIF,
  1802. pNdisPacket,
  1803. ARP_ICS_FORWARD_TO_ETHERNET,
  1804. IsChannel,
  1805. &sr
  1806. );
  1807. }
  1808. else
  1809. {
  1810. //
  1811. // Discard packet -- unknown/bad EtherType
  1812. //
  1813. TR_INFO(("Encap hdr 0x%x, bad EtherType 0x%x\n",
  1814. pEncapHeader, pEncapHeader->EtherType));
  1815. }
  1816. } while (FALSE);
  1817. EXIT()
  1818. RM_ASSERT_CLEAR(&sr);
  1819. return;
  1820. }
  1821. MYBOOL
  1822. arpIsUnicastEthDest(
  1823. IN UNALIGNED ENetHeader *pEthHdr
  1824. )
  1825. /*++
  1826. Returns TRUE IFF the packet is either ethernet broadcast or
  1827. multicast.
  1828. //
  1829. // TODO: there's probably a quicker check (single bit?).
  1830. //
  1831. --*/
  1832. {
  1833. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  1834. &BroadcastENetAddr,
  1835. sizeof(ENetAddr)))
  1836. {
  1837. // Broadcast address
  1838. //
  1839. return FALSE;
  1840. }
  1841. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  1842. &MulticastENetAddr,
  1843. 3))
  1844. {
  1845. // 1st 3 bytes match our Ethernet multicast address template, so we
  1846. // conclude that this is a multicast address.
  1847. // TODO: verify this check.
  1848. //
  1849. return FALSE;
  1850. }
  1851. return TRUE;
  1852. }
  1853. NDIS_STATUS
  1854. arpGetEthAddrFromIpAddr(
  1855. IN PARP1394_INTERFACE pIF,
  1856. IN MYBOOL fUnicast,
  1857. IN IP_ADDRESS DestIpAddress,
  1858. OUT ENetAddr *pEthAddr,
  1859. PRM_STACK_RECORD pSR
  1860. )
  1861. /*++
  1862. The destination address is set as follows:
  1863. if (fUnicast)
  1864. {
  1865. We look up our ethernet arp cache (pIF->RemoteEthGroup) and
  1866. if we find an entry there, we use the MAC address in that entry.
  1867. If we don't find, we fail this function.
  1868. }
  1869. else
  1870. {
  1871. if (destination IP address is class D)
  1872. {
  1873. we create the corresponding MAC address (based on the standard
  1874. formula for mapping IPv4 multicast addresses to MAC addresses).
  1875. }
  1876. else
  1877. {
  1878. we set the destination address to broadcast (all 0xff's).
  1879. (NOTE: we easily determine if the IP address is a broadast
  1880. address because we don't have the subnet mask, so instead we
  1881. assume that it's a broadcast destination if it's not class D
  1882. and it came over the broadcast channel (i.e. fUnicast == FALSE))
  1883. }
  1884. }
  1885. --*/
  1886. {
  1887. ENTER("arpGetEthAddrFromIpAddr", 0x0)
  1888. ARP1394_ADAPTER * pAdapter;
  1889. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1890. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1891. do
  1892. {
  1893. if (fUnicast)
  1894. {
  1895. // Lookup the ethernet MAC address in the MAC arp cache.
  1896. //
  1897. *pEthAddr = pAdapter->info.EthernetMacAddress;
  1898. Status = NDIS_STATUS_SUCCESS;
  1899. }
  1900. else
  1901. {
  1902. //
  1903. // Set the destination address to Multicast if dest IP is
  1904. // class D, else multicast
  1905. //
  1906. if (CLASSD_ADDR(DestIpAddress))
  1907. {
  1908. //
  1909. // Construct the corresponding multicast ethernet address.
  1910. // This code is adapted from tcpip\arp.c
  1911. //
  1912. // Basically we copy over a "template" of the multicast
  1913. // address, and then or-in the LSB 23 bits (in network byte
  1914. // order) of the ip address.
  1915. //
  1916. #define ARP_MCAST_MASK 0xffff7f00
  1917. UINT UNALIGNED *pTmp;
  1918. *pEthAddr = MulticastENetAddr; // struct copy.
  1919. pTmp = (UINT UNALIGNED *) & pEthAddr->addr[2];
  1920. *pTmp |= (DestIpAddress & ARP_MCAST_MASK);
  1921. }
  1922. else
  1923. {
  1924. //
  1925. // We assume DestIpAddress is a broadcast address -- see
  1926. // comments at the head of this function
  1927. //
  1928. *pEthAddr = BroadcastENetAddr; // struct copy
  1929. }
  1930. }
  1931. Status = NDIS_STATUS_SUCCESS;
  1932. } while (FALSE);
  1933. return Status;
  1934. }
  1935. NDIS_STATUS
  1936. arpConstructEthArpInfoFrom1394ArpInfo(
  1937. IN PARP1394_INTERFACE pIF,
  1938. IN PIP1394_ARP_PKT_INFO p1394PktInfo,
  1939. OUT PETH_ARP_PKT_INFO pEthPktInfo,
  1940. PRM_STACK_RECORD pSR
  1941. )
  1942. /*++
  1943. Translate a parsed version of an Ethernet ARP packet into
  1944. the parsed version of an equivalent 1394 arp packet.
  1945. We ALWAYS set the source ethernet address AND the target ethernet
  1946. address to OUR ethernet MAC address. So other ethernet nodes think of
  1947. us as a a single ethernet mic which hosts a whole bunch of IP addresses.
  1948. We COULD use our proprietary algorithm to convert from EU64 ID to MAC
  1949. addresses and then use those for the target addresses, but we're not
  1950. sure of the ramifications of that in the bridge mode.
  1951. --*/
  1952. {
  1953. ENTER("arpConstructEthArpInfoFrom1394ArpInfo", 0x8214aa14)
  1954. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1955. ENetAddr SourceMacAddress;
  1956. do
  1957. {
  1958. MYBOOL fUnicast;
  1959. IP_ADDRESS IpDest;
  1960. ARP1394_ADAPTER * pAdapter;
  1961. UINT Ip1394OpCode = p1394PktInfo->OpCode;
  1962. UINT EthOpCode;
  1963. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1964. ARP_ZEROSTRUCT(pEthPktInfo);
  1965. if (Ip1394OpCode == IP1394_ARP_REQUEST)
  1966. {
  1967. fUnicast = FALSE;
  1968. IpDest = 0xFFFFFFFF; // IP broadcast address.
  1969. EthOpCode= ARP_ETH_REQUEST;
  1970. }
  1971. else
  1972. {
  1973. // TODO: We expect TargetIpAddress to contain the address
  1974. // of the arp request that resulted in this reply. This
  1975. // is not per ip/1394 spec, which says that the TargetIpAddress
  1976. // is to be ignored. However Kaz has suggested that we
  1977. // utilize this field in this way -- search for "Kaz" in
  1978. // arp.c
  1979. //
  1980. // If we can't rely on this, then we must either
  1981. // (a) BROADCAST arp replies over ethernet OR
  1982. // (b) keep track of outstanding arp requests which need replies.
  1983. //
  1984. fUnicast = TRUE;
  1985. IpDest = p1394PktInfo->TargetIpAddress;
  1986. EthOpCode= ARP_ETH_RESPONSE;
  1987. }
  1988. Status = arpGetSourceMacAddressFor1394Pkt (pAdapter,
  1989. p1394PktInfo->SourceNodeAdddress,
  1990. p1394PktInfo->fPktHasNodeAddress,
  1991. &SourceMacAddress,
  1992. pSR );
  1993. if (FAIL(Status))
  1994. {
  1995. break;
  1996. }
  1997. pEthPktInfo->SourceEthAddress = SourceMacAddress ;
  1998. pEthPktInfo->SenderEthAddress = SourceMacAddress ;
  1999. pEthPktInfo->TargetEthAddress = pAdapter->info.EthernetMacAddress;
  2000. Status = arpGetEthAddrFromIpAddr(
  2001. pIF,
  2002. fUnicast,
  2003. IpDest,
  2004. &pEthPktInfo->DestEthAddress,
  2005. pSR
  2006. );
  2007. if (FAIL(Status))
  2008. {
  2009. break;
  2010. }
  2011. pEthPktInfo->OpCode = EthOpCode;
  2012. pEthPktInfo->SenderIpAddress = p1394PktInfo->SenderIpAddress;
  2013. pEthPktInfo->TargetIpAddress = p1394PktInfo->TargetIpAddress;
  2014. Status = NDIS_STATUS_SUCCESS;
  2015. {
  2016. UCHAR pIp[4];
  2017. TR_WARN(("Received Arp - "));
  2018. if (EthOpCode == ARP_ETH_RESPONSE)
  2019. {
  2020. TR_WARN(("Response\n"));
  2021. }
  2022. else
  2023. {
  2024. TR_WARN (("Request\n"));
  2025. }
  2026. NdisMoveMemory (&pIp[0], &pEthPktInfo->SenderIpAddress, sizeof(IPAddr) );
  2027. TR_WARN(("Ethernet Source %x %x %x %x %x %x,IP source %d %d %d %d \n ",
  2028. pEthPktInfo->SourceEthAddress.addr[0],
  2029. pEthPktInfo->SourceEthAddress.addr[1],
  2030. pEthPktInfo->SourceEthAddress.addr[2],
  2031. pEthPktInfo->SourceEthAddress.addr[3],
  2032. pEthPktInfo->SourceEthAddress.addr[4],
  2033. pEthPktInfo->SourceEthAddress.addr[5],
  2034. pIp[0],
  2035. pIp[1],
  2036. pIp[2],
  2037. pIp[3]));
  2038. NdisMoveMemory (&pIp[0], &pEthPktInfo->TargetIpAddress, sizeof(IPAddr) );
  2039. TR_WARN(("Ethernet Target %x %x %x %x %x %x , IP Target %d %d %d %d \n",
  2040. pEthPktInfo->TargetEthAddress.addr[0],
  2041. pEthPktInfo->TargetEthAddress.addr[1],
  2042. pEthPktInfo->TargetEthAddress.addr[2],
  2043. pEthPktInfo->TargetEthAddress.addr[3],
  2044. pEthPktInfo->TargetEthAddress.addr[4],
  2045. pEthPktInfo->TargetEthAddress.addr[5],
  2046. pIp[0],
  2047. pIp[1],
  2048. pIp[2],
  2049. pIp[3]));
  2050. TR_WARN(("Ethernet Dest %x %x %x %x %x %x \n",
  2051. pEthPktInfo->DestEthAddress.addr[0],
  2052. pEthPktInfo->DestEthAddress.addr[1],
  2053. pEthPktInfo->DestEthAddress.addr[2],
  2054. pEthPktInfo->DestEthAddress.addr[3],
  2055. pEthPktInfo->DestEthAddress.addr[4],
  2056. pEthPktInfo->DestEthAddress.addr[5]));
  2057. TR_WARN(("Ethernet Sender %x %x %x %x %x %x \n\n",
  2058. pEthPktInfo->SenderEthAddress.addr[0],
  2059. pEthPktInfo->SenderEthAddress.addr[1],
  2060. pEthPktInfo->SenderEthAddress.addr[2],
  2061. pEthPktInfo->SenderEthAddress.addr[3],
  2062. pEthPktInfo->SenderEthAddress.addr[4],
  2063. pEthPktInfo->SenderEthAddress.addr[5]));
  2064. }
  2065. } while (FALSE);
  2066. return Status;
  2067. }
  2068. NDIS_STATUS
  2069. arpConstruct1394ArpInfoFromEthArpInfo(
  2070. IN PARP1394_INTERFACE pIF,
  2071. IN PETH_ARP_PKT_INFO pEthPktInfo,
  2072. OUT PIP1394_ARP_PKT_INFO p1394PktInfo,
  2073. PRM_STACK_RECORD pSR
  2074. )
  2075. /*++
  2076. Translate a parsed version of an IP1394 ARP packet into
  2077. the parsed version of an equivalent Ethernet arp packet.
  2078. We always report our own adapter info as the hw/specific info
  2079. in the arp packet. We do this for both arp requests and responses.
  2080. This means that we look like a single host with multiple ip addresses
  2081. to other ip/1394 nodes.
  2082. --*/
  2083. {
  2084. ARP1394_ADAPTER * pAdapter;
  2085. UINT Ip1394OpCode;
  2086. UINT EthOpCode = pEthPktInfo->OpCode;
  2087. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  2088. ARP_ZEROSTRUCT(p1394PktInfo);
  2089. if (EthOpCode == ARP_ETH_REQUEST)
  2090. {
  2091. Ip1394OpCode= IP1394_ARP_REQUEST;
  2092. }
  2093. else
  2094. {
  2095. Ip1394OpCode= IP1394_ARP_RESPONSE;
  2096. }
  2097. p1394PktInfo->OpCode = Ip1394OpCode;
  2098. p1394PktInfo->SenderIpAddress = pEthPktInfo->SenderIpAddress;
  2099. p1394PktInfo->TargetIpAddress = pEthPktInfo->TargetIpAddress;
  2100. // Fill out adapter info..
  2101. //
  2102. p1394PktInfo->SenderHwAddr.UniqueID = pAdapter->info.LocalUniqueID;
  2103. p1394PktInfo->SenderHwAddr.Off_Low = pIF->recvinfo.offset.Off_Low;
  2104. p1394PktInfo->SenderHwAddr.Off_High = pIF->recvinfo.offset.Off_High;
  2105. p1394PktInfo->SenderMaxRec= pAdapter->info.MaxRec;
  2106. p1394PktInfo->SenderMaxSpeedCode= pAdapter->info.MaxSpeedCode;
  2107. return NDIS_STATUS_SUCCESS;
  2108. }
  2109. VOID
  2110. arpUpdateEthArpCache(
  2111. IN PARP1394_INTERFACE pIF,
  2112. IN IP_ADDRESS DestIpAddr,
  2113. IN PARP_REMOTE_ETH_PARAMS pCreateParams, // Creation params
  2114. IN MYBOOL fCreateIfRequired,
  2115. IN PRM_STACK_RECORD pSR
  2116. )
  2117. /*++
  2118. Update the IP->EthernetMacAddress mapping maintained in
  2119. pIF->RemoteEthGroup.
  2120. --*/
  2121. {
  2122. ENTER("arpUpdateEthArpCache", 0x3a18a415)
  2123. LOCKOBJ(pIF, pSR);
  2124. do
  2125. {
  2126. ARPCB_REMOTE_ETH *pRemoteEth = NULL;
  2127. INT fCreated = FALSE;
  2128. UINT CreateFlags = 0;
  2129. NDIS_STATUS Status;
  2130. DBGMARK(0xd3b27d1f);
  2131. if (fCreateIfRequired)
  2132. {
  2133. CreateFlags |= RM_CREATE;
  2134. }
  2135. // Lookup/Create Remote IP Address
  2136. //
  2137. Status = RmLookupObjectInGroup(
  2138. &pIF->RemoteEthGroup,
  2139. CreateFlags,
  2140. (PVOID) ULongToPtr (DestIpAddr),
  2141. (PVOID) pCreateParams,
  2142. (RM_OBJECT_HEADER**) &pRemoteEth,
  2143. &fCreated, // pfCreated
  2144. pSR
  2145. );
  2146. if (FAIL(Status))
  2147. {
  2148. OBJLOG1(
  2149. pIF,
  2150. "Couldn't add remote eth entry with addr 0x%lx\n",
  2151. DestIpAddr
  2152. );
  2153. UNLOCKOBJ(pIF, pSR);
  2154. break;
  2155. }
  2156. UNLOCKOBJ(pIF, pSR);
  2157. RmTmpDereferenceObject(&pRemoteEth->Hdr, pSR);
  2158. } while (FALSE);
  2159. EXIT()
  2160. }
  2161. NDIS_STATUS
  2162. arpGetSourceMacAddressFor1394Pkt (
  2163. IN PARP1394_ADAPTER pAdapter,
  2164. IN UCHAR SourceNodeAddress,
  2165. IN BOOLEAN fIsValidSourceNodeAddress,
  2166. OUT ENetAddr* pSourceMacAddress,
  2167. PRM_STACK_RECORD pSR
  2168. )
  2169. /*++
  2170. If the Packet has a valid Source Node Address then return it or else fail
  2171. the function
  2172. --*/
  2173. {
  2174. ENetAddr InvalidMacAddress = {0,0,0,0,0,0};
  2175. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2176. NdisZeroMemory (pSourceMacAddress, sizeof(pSourceMacAddress));
  2177. do
  2178. {
  2179. //
  2180. // Get the Mac Address from the Node Address
  2181. //
  2182. if (fIsValidSourceNodeAddress == TRUE)
  2183. {
  2184. *pSourceMacAddress = (pAdapter->EuidMap.Node[SourceNodeAddress].ENetAddress);
  2185. }
  2186. else
  2187. {
  2188. ASSERT (fIsValidSourceNodeAddress == TRUE);
  2189. break;
  2190. }
  2191. //
  2192. // Is the source address all zero's
  2193. //
  2194. if (NdisEqualMemory (pSourceMacAddress, &InvalidMacAddress, sizeof (ENetAddr) ) == 1)
  2195. {
  2196. //ASSERT (NdisEqualMemory (pSourceMacAddress, &InvalidMacAddress, sizeof (ENetAddr) ) != 1);
  2197. // Get the New Topology
  2198. //
  2199. arpGetEuidTopology (pAdapter,pSR);
  2200. Status = NDIS_STATUS_FAILURE;
  2201. break;
  2202. }
  2203. //
  2204. // The SourceMacAddress should not be a broadcast or multicast address
  2205. //
  2206. if (ETH_IS_BROADCAST(pSourceMacAddress) || ETH_IS_MULTICAST(pSourceMacAddress))
  2207. {
  2208. ASSERT (ETH_IS_BROADCAST(pSourceMacAddress) == FALSE);
  2209. ASSERT (ETH_IS_MULTICAST(pSourceMacAddress) == FALSE);
  2210. Status = NDIS_STATUS_FAILURE;
  2211. break;
  2212. }
  2213. Status = NDIS_STATUS_SUCCESS;
  2214. }while (FALSE);
  2215. return Status;
  2216. }
  2217. NDIS_STATUS
  2218. arpEthConstructSTAEthHeader(
  2219. IN PUCHAR pvData,
  2220. IN UINT cbData,
  2221. OUT ENetHeader *pEthHdr
  2222. )
  2223. /*++
  2224. Constructs the Ethernet header of the STA packet .
  2225. Expects that Source Mac Address has already been filled in
  2226. Arguments:
  2227. pvData - Start of the Data packet
  2228. cbData - Length of the data
  2229. pEthHdr - output value
  2230. --*/
  2231. {
  2232. UINT LenIpData = cbData - sizeof (NIC1394_ENCAPSULATION_HEADER);
  2233. //
  2234. // First set the destination Mac address in the Ethernet Header
  2235. //
  2236. NdisMoveMemory (&pEthHdr->eh_daddr, &gSTAMacAddr, sizeof (gSTAMacAddr));
  2237. //
  2238. // Use the length of the packet to store it in the packets. Should be 0x26 or 0x7
  2239. //
  2240. pEthHdr->eh_type = H2N_USHORT(LenIpData);
  2241. return NDIS_STATUS_SUCCESS;
  2242. }
  2243. NDIS_STATUS
  2244. arpAddIpAddressToRemoteIp (
  2245. PARPCB_REMOTE_IP pRemoteIp,
  2246. PNDIS_PACKET pNdisPacket
  2247. )
  2248. /*++
  2249. Routine Description:
  2250. Parse the NdisPacket and pick out the IP address. It will
  2251. store the Destination Ip address in the RemoteIp structure
  2252. Assumes that the bridge is enabled and that it is making a copy
  2253. of the packet and therefore the
  2254. first buffer contains the IP address
  2255. Arguments:
  2256. Return Value:
  2257. Success - if parsing succeeded
  2258. --*/
  2259. {
  2260. PNDIS_BUFFER pBuffer = NULL;
  2261. PUCHAR pPacketStart = NULL;
  2262. ULONG BufferLen = 0;
  2263. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2264. IPAddr TargetIpAddress = 0;
  2265. //
  2266. // Initialize local variables
  2267. //
  2268. pBuffer = pNdisPacket->Private.Head;
  2269. pPacketStart = NdisBufferVirtualAddressSafe (pBuffer, NormalPagePriority );
  2270. BufferLen = NdisBufferLength (pBuffer);
  2271. do
  2272. {
  2273. ENetHeader *pENetHeader = NULL;
  2274. if (pPacketStart == NULL)
  2275. {
  2276. break;
  2277. }
  2278. if (BufferLen < (sizeof (ENetHeader)+sizeof (IPHeader)) )
  2279. {
  2280. // We assume that the packet is contiguous because the bridge has
  2281. // made a copy of the packet
  2282. //
  2283. ASSERT (BufferLen < (sizeof (ENetHeader)+sizeof (IPHeader)) );
  2284. break;
  2285. }
  2286. pENetHeader = (ENetHeader*)pPacketStart;
  2287. switch ( H2N_USHORT(pENetHeader->eh_type))
  2288. {
  2289. case ARP_ETH_ETYPE_IP:
  2290. {
  2291. IPHeader *pIpHeader = NULL;
  2292. pIpHeader = (IPHeader*)(pPacketStart + sizeof (ENetHeader));
  2293. TargetIpAddress = pIpHeader->iph_dest;
  2294. pRemoteIp->IpAddress= TargetIpAddress ;
  2295. Status = NDIS_STATUS_SUCCESS;
  2296. break;
  2297. }
  2298. case ARP_ETH_ETYPE_ARP:
  2299. {
  2300. ETH_ARP_PKT* pArpPkt = (ETH_ARP_PKT*)pENetHeader;
  2301. BOOLEAN fIsTarget;
  2302. BOOLEAN fIsSender;
  2303. //
  2304. // This is an arp packet. Which Ip address should we use,
  2305. // the Target or the Sender.
  2306. //
  2307. fIsTarget = NdisEqualMemory (&pArpPkt->target_hw_address,
  2308. &pRemoteIp->Key.ENetAddress,
  2309. ETH_LENGTH_OF_ADDRESS
  2310. );
  2311. fIsSender = NdisEqualMemory (&pArpPkt->sender_hw_address,
  2312. &pRemoteIp->Key.ENetAddress,
  2313. ETH_LENGTH_OF_ADDRESS );
  2314. if (fIsTarget == TRUE)
  2315. {
  2316. TargetIpAddress = pArpPkt->target_IP_address;
  2317. }
  2318. else if (fIsSender == TRUE)
  2319. {
  2320. TargetIpAddress = pArpPkt->sender_IP_address;
  2321. }
  2322. else
  2323. {
  2324. ASSERT (!"Invalid hw Address in Arp Packet\n");
  2325. break;
  2326. }
  2327. pRemoteIp->IpAddress= TargetIpAddress;
  2328. Status = NDIS_STATUS_SUCCESS;
  2329. break;
  2330. }
  2331. default :
  2332. {
  2333. ASSERT (!"Invalid EtherType in Packet\n");
  2334. break;
  2335. }
  2336. }
  2337. } while (FALSE);
  2338. return Status;
  2339. }
  2340. //
  2341. // the Bootp Code is take heavily from the bridge module
  2342. //
  2343. BOOLEAN
  2344. arpDecodeIPHeader(
  2345. IN PUCHAR pHeader,
  2346. OUT PARP_IP_HEADER_INFO piphi
  2347. )
  2348. /*++
  2349. Routine Description:
  2350. Decodes basic information from the IP header (no options)
  2351. Arguments:
  2352. pHeader Pointer to an IP header
  2353. piphi Receives the info
  2354. Return Value:
  2355. TRUE: header was valid
  2356. FALSE: packet is not an IP packet
  2357. --*/
  2358. {
  2359. // First nibble of the header encodes the packet version, which must be 4.
  2360. if( (*pHeader >> 4) != 0x04 )
  2361. {
  2362. return FALSE;
  2363. }
  2364. // Next nibble of the header encodes the length of the header in 32-bit words.
  2365. // This length must be at least 20 bytes or something is amiss.
  2366. piphi->headerSize = (*pHeader & 0x0F) * 4;
  2367. if( piphi->headerSize < 20 )
  2368. {
  2369. return FALSE;
  2370. }
  2371. // Retrieve the protocol byte (offset 10)
  2372. piphi->protocol = pHeader[9];
  2373. // The source IP address begins at the 12th byte (most significant byte first)
  2374. #if 0
  2375. piphi->ipSource = 0L;
  2376. piphi->ipSource |= pHeader[12] << 24;
  2377. piphi->ipSource |= pHeader[13] << 16;
  2378. piphi->ipSource |= pHeader[14] << 8;
  2379. piphi->ipSource |= pHeader[15];
  2380. // The destination IP address is next
  2381. piphi->ipTarget = 0L;
  2382. piphi->ipTarget |= pHeader[16] << 24;
  2383. piphi->ipTarget |= pHeader[17] << 16;
  2384. piphi->ipTarget |= pHeader[18] << 8;
  2385. piphi->ipTarget |= pHeader[19];
  2386. #endif
  2387. return TRUE;
  2388. }
  2389. PUCHAR
  2390. arpIsEthBootPPacket(
  2391. IN PUCHAR pPacketData,
  2392. IN UINT packetLen,
  2393. IN PARP_IP_HEADER_INFO piphi
  2394. )
  2395. /*++
  2396. Routine Description:
  2397. Determines whether a given packet is a BOOTP packet
  2398. Requires a phy length of six
  2399. Different from the Bridge Code, packetLen is length of the Ip Packet
  2400. Arguments:
  2401. pPacketData Pointer to the packet's data buffer
  2402. packetLen Amount of data at pPacketDaa
  2403. piphi Info about the IP header of this packet
  2404. Return Value:
  2405. A pointer to the BOOTP payload within the packet, or NULL if the packet was not
  2406. a BOOTP Packet.
  2407. --*/
  2408. {
  2409. ENTER("arpIsEthBootPPacket",0xbcdce2dd);
  2410. // After the IP header, there must be enough room for a UDP header and
  2411. // a basic BOOTP packet
  2412. if( packetLen < (UINT)piphi->headerSize + SIZE_OF_UDP_HEADER +
  2413. SIZE_OF_BASIC_BOOTP_PACKET)
  2414. {
  2415. return NULL;
  2416. }
  2417. // Protocol must be UDP
  2418. if( piphi->protocol != UDP_PROTOCOL )
  2419. {
  2420. return NULL;
  2421. }
  2422. // Jump to the beginning of the UDP packet by skipping the IP header
  2423. pPacketData += piphi->headerSize;
  2424. // The first two bytes are the source port and should be the
  2425. // BOOTP Client port (0x0044) or the BOOTP Server port (0x0043)
  2426. if( (pPacketData[0] != 00) ||
  2427. ((pPacketData[1] != 0x44) && (pPacketData[1] != 0x43)) )
  2428. {
  2429. return NULL;
  2430. }
  2431. // The next two bytes are the destination port and should be the BOOTP
  2432. // server port (0x0043) or the BOOTP client port (0x44)
  2433. if( (pPacketData[2] != 00) ||
  2434. ((pPacketData[3] != 0x43) && (pPacketData[3] != 0x44)) )
  2435. {
  2436. return NULL;
  2437. }
  2438. // Skip ahead to the beginning of the BOOTP packet
  2439. pPacketData += SIZE_OF_UDP_HEADER;
  2440. // The first byte is the op code and should be 0x01 for a request
  2441. // or 0x02 for a reply
  2442. if( pPacketData[0] > 0x02 )
  2443. {
  2444. return NULL;
  2445. }
  2446. // The next byte is the hardware type and should be 0x01 for Ethernet
  2447. // or 0x07 (officially arcnet) for ip1394
  2448. //
  2449. if( pPacketData[1] != 0x01 && pPacketData[1] != 0x07 )
  2450. {
  2451. return NULL;
  2452. }
  2453. // The next byte is the address length and should be 0x06 for Ethernet
  2454. if( pPacketData[2] != 0x06 )
  2455. {
  2456. return NULL;
  2457. }
  2458. // Everything checks out; this looks like a BOOTP request packet.
  2459. TR_INFO ( ("Received Bootp Packet \n"));
  2460. EXIT()
  2461. return pPacketData;
  2462. }
  2463. //
  2464. // The IP and UDP checksums treat the data they are checksumming as a
  2465. // sequence of 16-bit words. The checksum is carried as the bitwise
  2466. // inverse of the actual checksum (~C). The formula for calculating
  2467. // the new checksum as transmitted, ~C', given that a 16-bit word of
  2468. // the checksummed data has changed from w to w' is
  2469. //
  2470. // ~C' = ~C + w + ~w' (addition in ones-complement)
  2471. //
  2472. // This function returns the updated checksum given the original checksum
  2473. // and the original and new values of a word in the checksummed data.
  2474. // RFC 1141
  2475. //
  2476. USHORT
  2477. arpEthCompRecalcChecksum(
  2478. IN USHORT oldChecksum,
  2479. IN USHORT oldWord,
  2480. IN USHORT newWord
  2481. )
  2482. {
  2483. ULONG sum,XSum;
  2484. ULONG RfcSum, RfcXSum;
  2485. sum = oldChecksum + oldWord + ((~(newWord)) & 0xFFFF);
  2486. XSum = (USHORT)((sum & 0xFFFF) + (sum >> 16));
  2487. RfcSum = oldWord + ((~(newWord)) & 0xffff);
  2488. RfcSum += oldChecksum;
  2489. RfcSum = (RfcSum& 0xffff) + (RfcSum >>16);
  2490. RfcXSum = (RfcSum + (RfcSum >>16));
  2491. ASSERT (RfcXSum == XSum);
  2492. return (USHORT)RfcXSum;
  2493. }
  2494. VOID
  2495. arpEthRewriteBootPClientAddress(
  2496. IN PUCHAR pPacketData,
  2497. IN PARP_IP_HEADER_INFO piphi,
  2498. IN PUCHAR newMAC
  2499. )
  2500. /*++
  2501. Routine Description:
  2502. This function writes New MAC to the HW address embedded in the DHCP packet
  2503. Arguments:
  2504. Return Value:
  2505. --*/
  2506. {
  2507. USHORT checkSum;
  2508. PUCHAR pBootPData, pCheckSum, pDestMAC, pSrcMAC;
  2509. UINT i;
  2510. // The BOOTP packet lives right after the UDP header
  2511. pBootPData = pPacketData + piphi->IpHeaderOffset + piphi->headerSize + SIZE_OF_UDP_HEADER;
  2512. // The checksum lives at offset 7 in the UDP packet.
  2513. pCheckSum = pPacketData + piphi->IpHeaderOffset + piphi->headerSize + 6;
  2514. checkSum = 0;
  2515. checkSum = pCheckSum[0] << 8;
  2516. checkSum |= pCheckSum[1];
  2517. if (checkSum == 0xffff)
  2518. {
  2519. // Tcpip Illustrated - Vol 1 'UDP Checksum'
  2520. checkSum = 0;
  2521. }
  2522. // Replace the client's hardware address, updating the checksum as we go.
  2523. // The client's hardware address lives at offset 29 in the BOOTP packet
  2524. pSrcMAC = newMAC;
  2525. pDestMAC = &pBootPData[28];
  2526. for( i = 0 ; i < ETH_LENGTH_OF_ADDRESS / 2; i++ )
  2527. {
  2528. checkSum = arpEthCompRecalcChecksum( checkSum,
  2529. (USHORT)(pDestMAC[0] << 8 | pDestMAC[1]),
  2530. (USHORT)(pSrcMAC[0] << 8 | pSrcMAC[1]) );
  2531. pDestMAC[0] = pSrcMAC[0];
  2532. pDestMAC[1] = pSrcMAC[1];
  2533. pDestMAC += 2;
  2534. pSrcMAC += 2;
  2535. }
  2536. // Write the new checksum back out
  2537. pCheckSum[0] = (UCHAR)(checkSum >> 8);
  2538. pCheckSum[1] = (UCHAR)(checkSum & 0xFF);
  2539. }
  2540. NDIS_STATUS
  2541. arpEthBootP1394ToEth(
  2542. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2543. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2544. IN PREMOTE_DEST_KEY pDestAddress,
  2545. IN PUCHAR pucNewData,
  2546. IN PUCHAR pBootPData,
  2547. IN PARP_IP_HEADER_INFO piphi,
  2548. IN PRM_STACK_RECORD pSR
  2549. )
  2550. /*++
  2551. Routine Description:
  2552. This function handles the translation from 1394 to Eth. Essentially,
  2553. we look at the SRC MAC address in the Ethernet Packet, make sure the HW
  2554. Addr embedded is the same as the SRC MAC address.
  2555. We also make an entry in our table - XID, OldHWAddress, NewHWAddress.
  2556. The packet has already been rewritten into Ethernet by this time
  2557. Arguments:
  2558. pIF - pInterface
  2559. Direction - Eth To 1394 or 1394-To-Eth
  2560. pDestAddress - the Eth Hw address used in the translation
  2561. pucNewData - the Data in the new packet
  2562. pBootPdata - pointer to the Bootp part of the packet
  2563. piphi - ip header info
  2564. Return Value:
  2565. --*/
  2566. {
  2567. BOOLEAN bIsRequest = FALSE;
  2568. BOOLEAN bIsResponse;
  2569. ARP_BOOTP_INFO InfoBootP;
  2570. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2571. ENetHeader* pEnetHeader = (ENetHeader*)pucNewData;
  2572. ENetAddr NewMAC;
  2573. BOOLEAN bIs1394HwAlreadyInDhcpRequest;
  2574. ENTER ("arpEthBootP1394ToEth", 0x66206f0b);
  2575. NdisZeroMemory (&InfoBootP, sizeof(InfoBootP));
  2576. //
  2577. // Is this a DHCP Request
  2578. //
  2579. do
  2580. {
  2581. bIsResponse = ARP_IS_BOOTP_RESPONSE(pBootPData);
  2582. if (bIsResponse == TRUE)
  2583. {
  2584. //
  2585. // if this is a DHCP Reply , the do not touch the packet - there are no inconsistencies.
  2586. //
  2587. Status = NDIS_STATUS_SUCCESS;
  2588. break;
  2589. }
  2590. if( FALSE == arpEthPreprocessBootPPacket(pIF,pucNewData, pBootPData, &bIsRequest, &InfoBootP,pSR) )
  2591. {
  2592. // This is an invalid packet
  2593. ASSERT (FALSE);
  2594. break;
  2595. }
  2596. //
  2597. // This is a DHCP Request
  2598. //
  2599. //
  2600. // if the HWAddr and the Src Mac address the same.
  2601. // then are job is already done.
  2602. //
  2603. //At this point the 1394 packet is already in Ethernet format
  2604. NewMAC = pEnetHeader->eh_saddr;
  2605. TR_INFO(("DHCP REQUEST target MAC %x %x %x %x %x %x , SrcMAC %x %x %x %x %x %x \n",
  2606. InfoBootP.requestorMAC.addr[0],InfoBootP.requestorMAC.addr[1],InfoBootP.requestorMAC.addr[2],
  2607. InfoBootP.requestorMAC.addr[3],InfoBootP.requestorMAC.addr[4],InfoBootP.requestorMAC.addr[5],
  2608. NewMAC.addr[0],NewMAC.addr[1],NewMAC.addr[2],
  2609. NewMAC.addr[3],NewMAC.addr[4],NewMAC.addr[5]));
  2610. bIs1394HwAlreadyInDhcpRequest = NdisEqualMemory (&InfoBootP.requestorMAC, &NewMAC , sizeof (ENetAddr)) ;
  2611. if (TRUE == bIs1394HwAlreadyInDhcpRequest )
  2612. {
  2613. //
  2614. // Nothing to do , id the HW add and the src MAC are equal
  2615. //
  2616. Status = NDIS_STATUS_SUCCESS;
  2617. break;
  2618. }
  2619. //
  2620. // Make an entry into our table - consisting of the XID. OldHW Address and
  2621. // New HY address
  2622. // We've already done this.
  2623. //
  2624. // Overwrite the hw address embedded in the DHCP packet. - make sure to rewrite the
  2625. // checksum.
  2626. //
  2627. arpEthRewriteBootPClientAddress(pucNewData,piphi,&NewMAC.addr[0]);
  2628. TR_VERB (("arpEthBootP1394ToEth -Dhcp packet Rewriting BootpClient Address\n"));
  2629. Status = NDIS_STATUS_SUCCESS;
  2630. }while (FALSE);
  2631. EXIT();
  2632. return Status;;
  2633. }
  2634. NDIS_STATUS
  2635. arpEthBootPEthTo1394(
  2636. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2637. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2638. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  2639. IN PUCHAR pucNewData,
  2640. IN PUCHAR pBootPData,
  2641. IN PARP_IP_HEADER_INFO piphi,
  2642. IN PRM_STACK_RECORD pSR
  2643. )
  2644. /*++
  2645. Routine Description:
  2646. This function translates BootP packet from the Ethernet Net to 1394. if this is a dhcp reply (offer),
  2647. then we need to rewrite the Hw Addr in the DHCP packlet
  2648. Arguments:
  2649. pIF - pInterface
  2650. Direction - Eth To 1394 or 1394-To-Eth
  2651. pDestAddress - the Eth Hw address used in the translation
  2652. pucNewData - the Data in the new packet
  2653. Return Value:
  2654. --*/
  2655. {
  2656. BOOLEAN fIsBootpRequest = FALSE;
  2657. ARP_BOOTP_INFO InfoBootP;
  2658. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2659. ENetHeader* pEnetHeader = (ENetHeader*)pucNewData;
  2660. ENetAddr NewMAC;
  2661. PUCHAR pMACInPkt = NULL;
  2662. BOOLEAN bIs1394HwAlreadyInDhcpResponse = FALSE;
  2663. ENTER("arpEthBootPEthTo1394", 0x383f9e33);
  2664. NdisZeroMemory (&InfoBootP, sizeof(InfoBootP));
  2665. //
  2666. // Is this a DHCP Request
  2667. //
  2668. do
  2669. {
  2670. // Do a quick check .
  2671. fIsBootpRequest = ARP_IS_BOOTP_REQUEST(pBootPData);
  2672. if (fIsBootpRequest == TRUE)
  2673. {
  2674. //
  2675. // if this is a DHCP Request, the do not modify the packet -
  2676. // there are no inconsistencies in this code path.
  2677. //
  2678. Status = NDIS_STATUS_SUCCESS;
  2679. break;
  2680. }
  2681. if( FALSE == arpEthPreprocessBootPPacket(pIF,pucNewData, pBootPData, &fIsBootpRequest, &InfoBootP,pSR) )
  2682. {
  2683. // This is an uninteresting packet
  2684. break;
  2685. }
  2686. //
  2687. // InfoBootP has the original HW addr used in the corresponding Dhcp request.
  2688. // We'll put the hw Addr back into dhcp reply
  2689. //
  2690. //offset of the chaddr in bootp packet
  2691. //
  2692. pMACInPkt = &pBootPData[28];
  2693. TR_INFO(("DHCP RESPONSE target MAC %x %x %x %x %x %x , SrcMAC %x %x %x %x %x %x \n",
  2694. InfoBootP.requestorMAC.addr[0],InfoBootP.requestorMAC.addr[1],InfoBootP.requestorMAC.addr[2],
  2695. InfoBootP.requestorMAC.addr[3],InfoBootP.requestorMAC.addr[4],InfoBootP.requestorMAC.addr[5],
  2696. pMACInPkt[0],pMACInPkt[1],pMACInPkt[2],
  2697. pMACInPkt[3],pMACInPkt[4],pMACInPkt[5]));
  2698. //
  2699. // Is the HWAddr in the dhcp packet the correct one.
  2700. //
  2701. bIs1394HwAlreadyInDhcpResponse = NdisEqualMemory(&InfoBootP.requestorMAC, pMACInPkt, sizeof (InfoBootP.requestorMAC)) ;
  2702. if (TRUE == bIs1394HwAlreadyInDhcpResponse)
  2703. {
  2704. //
  2705. // Yes, they are equal, we do not rewrite the packet
  2706. //
  2707. Status = NDIS_STATUS_SUCCESS;
  2708. break;
  2709. }
  2710. TR_VERB( ("DHCP RESPONSE Rewriting Bootp Response pBootpData %p Before\n",pBootPData));
  2711. //
  2712. // Replace the CL Addr in the DHCP packet with the original HW addr
  2713. //
  2714. arpEthRewriteBootPClientAddress(pucNewData,piphi,&InfoBootP.requestorMAC.addr[0]);
  2715. //
  2716. // recompute the checksum
  2717. //
  2718. Status = NDIS_STATUS_SUCCESS;
  2719. } while (FALSE);
  2720. EXIT();
  2721. return Status;
  2722. }
  2723. NDIS_STATUS
  2724. arpEthModifyBootPPacket(
  2725. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2726. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2727. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  2728. IN PUCHAR pucNewData,
  2729. IN ULONG PacketLength,
  2730. IN PRM_STACK_RECORD pSR
  2731. )
  2732. /*++
  2733. Routine Description:
  2734. This function contains the code to process a Bootp Packet. This basically ensures that the
  2735. MAC address entered in the DHCP packet matches the Src Mac address of the Ethernet Packet
  2736. (in the 1394 - Eth mode). In the other case (Eth-1394 mode), we replace the Ch address with
  2737. the correct CH addr (if we have to).
  2738. Arguments:
  2739. pIF - pInterface
  2740. Direction - Eth To 1394 or 1394-To-Eth
  2741. pDestAddress - the Eth Hw address used in the translation
  2742. pucNewData - the Data in the new packet
  2743. Return Value:
  2744. --*/
  2745. {
  2746. ARP_IP_HEADER_INFO iphi;
  2747. PUCHAR pBootPData = NULL;
  2748. NDIS_STATUS Status= NDIS_STATUS_FAILURE;
  2749. PARP1394_ADAPTER pAdapter = (PARP1394_ADAPTER)RM_PARENT_OBJECT(pIF);
  2750. ULONG IpHeaderOffset = 0;
  2751. PUCHAR pIPHeader = NULL;
  2752. BOOLEAN fIsIpPkt;
  2753. NdisZeroMemory(&iphi, sizeof (iphi));
  2754. do
  2755. {
  2756. //
  2757. // if we are not in bridge mode - exit.
  2758. //
  2759. if (ARP_BRIDGE_ENABLED(pAdapter) == FALSE)
  2760. {
  2761. break;
  2762. }
  2763. if (Direction == ARP_ICS_FORWARD_TO_ETHERNET)
  2764. {
  2765. // Packet is in the ethernet format
  2766. IpHeaderOffset = ETHERNET_HEADER_SIZE;
  2767. }
  2768. else
  2769. {
  2770. // Packet is in the IP 1394 format
  2771. IpHeaderOffset = sizeof (NIC1394_UNFRAGMENTED_HEADER); //4
  2772. }
  2773. iphi.IpHeaderOffset = IpHeaderOffset;
  2774. iphi.IpPktLength = PacketLength - IpHeaderOffset;
  2775. pIPHeader = pucNewData + IpHeaderOffset ;
  2776. //
  2777. // if this is not a bootp packet -exit
  2778. //
  2779. fIsIpPkt = arpDecodeIPHeader (pIPHeader , &iphi);
  2780. if (fIsIpPkt == FALSE)
  2781. {
  2782. //
  2783. // not an IP pkt
  2784. //
  2785. Status = NDIS_STATUS_SUCCESS;
  2786. break;
  2787. }
  2788. pBootPData = arpIsEthBootPPacket (pIPHeader ,PacketLength-IpHeaderOffset, &iphi);
  2789. if (pBootPData == NULL)
  2790. {
  2791. Status = NDIS_STATUS_SUCCESS;
  2792. break;
  2793. }
  2794. //
  2795. // are we doing 1394 - to- Eth
  2796. //
  2797. if (Direction == ARP_ICS_FORWARD_TO_ETHERNET)
  2798. {
  2799. Status = arpEthBootP1394ToEth(pIF, Direction,pDestAddress,pucNewData,pBootPData,&iphi, pSR);
  2800. }
  2801. else
  2802. {
  2803. //
  2804. // are we doing Eth to 1394
  2805. //
  2806. Status = arpEthBootPEthTo1394(pIF, Direction,pDestAddress,pucNewData,pBootPData , &iphi,pSR);
  2807. }
  2808. Status = NDIS_STATUS_SUCCESS;
  2809. }while (FALSE);
  2810. // else we are doing Eth to 1394
  2811. return Status;
  2812. }
  2813. //
  2814. // This function is taken verbatim from the bridge
  2815. //
  2816. BOOLEAN
  2817. arpEthPreprocessBootPPacket(
  2818. IN PARP1394_INTERFACE pIF,
  2819. IN PUCHAR pPacketData,
  2820. IN PUCHAR pBootPData, // Actual BOOTP packet
  2821. OUT PBOOLEAN pbIsRequest,
  2822. PARP_BOOTP_INFO pInfoBootP,
  2823. PRM_STACK_RECORD pSR
  2824. )
  2825. /*++
  2826. Routine Description:
  2827. Does preliminary processing of a BOOTP packet common to the inbound and outbound case
  2828. Arguments:
  2829. pPacketData Pointer to a packet's data buffer
  2830. pBootPData Pointer to the BOOTP payload within the packet
  2831. pAdapt Receiving adapter (or NULL if this packet is outbound from
  2832. the local machine)
  2833. pbIsRequest Receives a flag indicating if this is a BOOTP request
  2834. ppTargetAdapt Receives the target adapter this packet should be relayed to
  2835. (only valid if bIsRequest == FALSE and return == TRUE)
  2836. requestorMAC The MAC address this packet should be relayed to (valid under
  2837. same conditions as ppTargetAdapt)
  2838. Return Value:
  2839. TRUE : packet was processed successfully
  2840. FALSE : an error occured or something is wrong with the packet
  2841. --*/
  2842. {
  2843. PARP1394_ETH_DHCP_ENTRY pEntry= NULL;
  2844. ULONG xid;
  2845. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2846. ENTER ("arpEthPreprocessBootPPacket",0x25427efc);
  2847. // Decode the xid (bytes 5 through 8)
  2848. xid = 0L;
  2849. xid |= pBootPData[4] << 24;
  2850. xid |= pBootPData[5] << 16;
  2851. xid |= pBootPData[6] << 8;
  2852. xid |= pBootPData[7];
  2853. // Byte 0 is the operation; 1 for a request, 2 for a reply
  2854. if( pBootPData[0] == 0x01 )
  2855. {
  2856. ULONG bIsNewEntry = FALSE;
  2857. // This is a request. We need to note the correspondence betweeen
  2858. // this client's XID and its adapter and MAC address
  2859. TR_INFO(("DHCP REQUEST XID: %x , HW %x %x %x %x %x %x \n", xid,
  2860. pBootPData[28],pBootPData[29],pBootPData[30],pBootPData[31],pBootPData[32],pBootPData[33]));
  2861. Status = RmLookupObjectInGroup(
  2862. &pIF->EthDhcpGroup,
  2863. RM_CREATE,
  2864. (PVOID) &xid, // pKey
  2865. (PVOID) &xid, // pvCreateParams
  2866. &(PRM_OBJECT_HEADER)pEntry,
  2867. &bIsNewEntry ,
  2868. pSR
  2869. );
  2870. if( pEntry != NULL )
  2871. {
  2872. if( bIsNewEntry )
  2873. {
  2874. // Initialize the entry.
  2875. // The client's hardware address is at offset 29
  2876. ETH_COPY_NETWORK_ADDRESS( &pEntry->requestorMAC.addr[0], &pBootPData[28] );
  2877. pEntry->xid = xid;
  2878. }
  2879. else
  2880. {
  2881. //
  2882. // An entry already existed for this XID. This is fine if the existing information
  2883. // matches what we're trying to record, but it's also possible that two stations
  2884. // decided independently to use the same XID, or that the same station changed
  2885. // apparent MAC address and/or adapter due to topology changes. Our scheme breaks
  2886. // down under these circumstances.
  2887. //
  2888. // Either way, use the most recent information possible; clobber the existing
  2889. // information with the latest.
  2890. //
  2891. LOCKOBJ(pEntry, pSR);
  2892. {
  2893. UINT Result;
  2894. ETH_COMPARE_NETWORK_ADDRESSES_EQ( &pEntry->requestorMAC.addr[0], &pBootPData[28], &Result );
  2895. // Warn if the data changed, as this probably signals a problem
  2896. if( Result != 0 )
  2897. {
  2898. TR_WARN(("ARP1394 WARNING: Station with MAC address %02x:%02x:%02x:%02x:%02x:%02x is using DHCP XID %x at the same time as station %02x:%02x:%02x:%02x:%02x:%02x!\n",
  2899. pBootPData[28], pBootPData[29], pBootPData[30], pBootPData[31], pBootPData[32], pBootPData[33],
  2900. xid, pEntry->requestorMAC.addr[0], pEntry->requestorMAC.addr[1], pEntry->requestorMAC.addr[2],
  2901. pEntry->requestorMAC.addr[3], pEntry->requestorMAC.addr[4], pEntry->requestorMAC.addr[5] ));
  2902. }
  2903. }
  2904. ETH_COPY_NETWORK_ADDRESS( &pEntry->requestorMAC.addr[0], &pBootPData[28] );
  2905. UNLOCKOBJ (pEntry, pSR);
  2906. }
  2907. RmTmpDereferenceObject (&pEntry->Hdr, pSR);
  2908. }
  2909. else
  2910. {
  2911. // This packet could not be processed
  2912. TR_INFO(("Couldn't create table entry for BOOTP packet!\n"));
  2913. return FALSE;
  2914. }
  2915. *pbIsRequest = TRUE;
  2916. pInfoBootP->bIsRequest = TRUE;
  2917. ETH_COPY_NETWORK_ADDRESS(&pInfoBootP->requestorMAC,&pEntry->requestorMAC);
  2918. return TRUE;
  2919. }
  2920. else if ( pBootPData[0] == 0x02 )
  2921. {
  2922. //
  2923. // NON-CREATE search
  2924. // Look up the xid for this transaction to recover the MAC address of the client
  2925. //
  2926. TR_INFO (("Seeing a DHCP response xid %x mac %x %x %x %x %x %x \n",
  2927. xid, pBootPData[28],pBootPData[29],pBootPData[30],pBootPData[31],pBootPData[32],pBootPData[33]));
  2928. Status = RmLookupObjectInGroup(
  2929. &pIF->EthDhcpGroup,
  2930. 0, // do not create
  2931. (PVOID) &xid, // pKey
  2932. (PVOID) &xid, // pvCreateParams
  2933. &(PRM_OBJECT_HEADER)pEntry,
  2934. NULL,
  2935. pSR
  2936. );
  2937. if( pEntry != NULL )
  2938. {
  2939. LOCKOBJ( pEntry, pSR);
  2940. ETH_COPY_NETWORK_ADDRESS( &pInfoBootP->requestorMAC.addr, pEntry->requestorMAC.addr );
  2941. UNLOCKOBJ( pEntry, pSR );
  2942. //
  2943. // We will use this adapter outside the table lock. NULL is a permissible
  2944. // value that indicates that the local machine is the requestor for
  2945. // this xid.
  2946. //
  2947. RmTmpDereferenceObject(&pEntry->Hdr, pSR);
  2948. }
  2949. if( pEntry != NULL )
  2950. {
  2951. *pbIsRequest = FALSE;
  2952. return TRUE;
  2953. }
  2954. else
  2955. {
  2956. TR_INFO (("DHCP Response:Could not find xid %x in DHCP table \n",xid);)
  2957. return FALSE;
  2958. }
  2959. }
  2960. else
  2961. {
  2962. // Someone passed us a crummy packet
  2963. return FALSE;
  2964. }
  2965. }
  2966. #if DBG
  2967. VOID
  2968. Dump(
  2969. IN CHAR* p,
  2970. IN ULONG cb,
  2971. IN BOOLEAN fAddress,
  2972. IN ULONG ulGroup )
  2973. // Hex dump 'cb' bytes starting at 'p' grouping 'ulGroup' bytes together.
  2974. // For example, with 'ulGroup' of 1, 2, and 4:
  2975. //
  2976. // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  2977. // 0000 0000 0000 0000 0000 0000 0000 0000 |................|
  2978. // 00000000 00000000 00000000 00000000 |................|
  2979. //
  2980. // If 'fAddress' is true, the memory address dumped is prepended to each
  2981. // line.
  2982. //
  2983. {
  2984. while (cb)
  2985. {
  2986. INT cbLine;
  2987. cbLine = (cb < DUMP_BytesPerLine) ? cb : DUMP_BytesPerLine;
  2988. DumpLine( p, cbLine, fAddress, ulGroup );
  2989. cb -= cbLine;
  2990. p += cbLine;
  2991. }
  2992. }
  2993. #endif
  2994. #if DBG
  2995. VOID
  2996. DumpLine(
  2997. IN CHAR* p,
  2998. IN ULONG cb,
  2999. IN BOOLEAN fAddress,
  3000. IN ULONG ulGroup )
  3001. {
  3002. CHAR* pszDigits = "0123456789ABCDEF";
  3003. CHAR szHex[ ((2 + 1) * DUMP_BytesPerLine) + 1 ];
  3004. CHAR* pszHex = szHex;
  3005. CHAR szAscii[ DUMP_BytesPerLine + 1 ];
  3006. CHAR* pszAscii = szAscii;
  3007. ULONG ulGrouped = 0;
  3008. if (fAddress)
  3009. DbgPrint( "N13: %p: ", p );
  3010. else
  3011. DbgPrint( "N13: " );
  3012. while (cb)
  3013. {
  3014. *pszHex++ = pszDigits[ ((UCHAR )*p) / 16 ];
  3015. *pszHex++ = pszDigits[ ((UCHAR )*p) % 16 ];
  3016. if (++ulGrouped >= ulGroup)
  3017. {
  3018. *pszHex++ = ' ';
  3019. ulGrouped = 0;
  3020. }
  3021. *pszAscii++ = (*p >= 32 && *p < 128) ? *p : '.';
  3022. ++p;
  3023. --cb;
  3024. }
  3025. *pszHex = '\0';
  3026. *pszAscii = '\0';
  3027. DbgPrint(
  3028. "%-*s|%-*s|\n",
  3029. (2 * DUMP_BytesPerLine) + (DUMP_BytesPerLine / ulGroup), szHex,
  3030. DUMP_BytesPerLine, szAscii );
  3031. }
  3032. #endif